aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2020-02-17 01:01:00 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-02-17 10:21:59 +0100
commit3e758800b4daf8fbc870a2ff5d54fce9d4402ce8 (patch)
treeba237b9da1c7dfd08bf13e71c5dbd6b3c2e77633
parent925a0e499a5dbdb180fd9969a79abf96006ce4fd (diff)
parent55546991e24ca6799709cbe0171b9ab87216c35f (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: src/imports/qtqml/plugin.cpp src/qml/qml/qqml.h src/qml/qml/qqmlmetatype.cpp src/qml/qml/qqmlmetatype_p.h src/qml/qml/qqmltypeloader.cpp src/qml/types/qqmlbind.cpp src/quick/items/qquickitemsmodule.cpp tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp Change-Id: I52548938a582cb6510271ed4bc3a9aa0c3c11df6
-rw-r--r--examples/qml/doc/src/qml-extending.qdoc2
-rw-r--r--examples/qml/referenceexamples/attached/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/binding/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/binding/example.qml2
-rw-r--r--examples/qml/referenceexamples/coercion/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/default/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/grouped/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/methods/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/properties/birthdayparty.cpp24
-rw-r--r--examples/qml/referenceexamples/properties/birthdayparty.h4
-rw-r--r--examples/qml/referenceexamples/signal/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/signal/example.qml2
-rw-r--r--examples/qml/referenceexamples/valuesource/birthdayparty.cpp2
-rw-r--r--examples/qml/referenceexamples/valuesource/example.qml2
-rw-r--r--examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.cpp3
-rw-r--r--examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp3
-rw-r--r--examples/quick/animation/basics/property-animation.qml1
-rw-r--r--examples/quick/animation/behaviors/tvtennis.qml9
-rw-r--r--examples/quick/animation/behaviors/wigglytext.qml3
-rw-r--r--examples/quick/animation/pathanimation/pathanimation.qml1
-rw-r--r--examples/quick/animation/pathinterpolator/pathinterpolator.qml1
-rw-r--r--examples/quick/animation/states/states.qml1
-rw-r--r--examples/quick/draganddrop/tiles/DragTile.qml10
-rw-r--r--examples/quick/draganddrop/tiles/DropTile.qml2
-rw-r--r--examples/quick/externaldraganddrop/DragAndDropTextItem.qml23
-rw-r--r--examples/quick/imageelements/animatedsprite.qml2
-rw-r--r--examples/quick/imageelements/content/BorderImageSelector.qml5
-rw-r--r--examples/quick/imageelements/content/ImageCell.qml2
-rw-r--r--examples/quick/imageelements/content/MyBorderImage.qml1
-rw-r--r--examples/quick/imageelements/image.qml34
-rw-r--r--examples/quick/keyinteraction/focus/Core/ContextMenu.qml3
-rw-r--r--examples/quick/keyinteraction/focus/Core/GridMenu.qml21
-rw-r--r--examples/quick/keyinteraction/focus/Core/ListMenu.qml20
-rw-r--r--examples/quick/keyinteraction/focus/Core/ListViewDelegate.qml6
-rw-r--r--examples/quick/keyinteraction/focus/Core/TabMenu.qml11
-rw-r--r--examples/quick/keyinteraction/focus/focus.qml34
-rw-r--r--examples/quick/localstorage/localstorage/Header.qml11
-rw-r--r--examples/quick/localstorage/localstorage/MyDelegate.qml19
-rw-r--r--examples/quick/localstorage/localstorage/localstorage.qml29
-rw-r--r--examples/quick/models/abstractitemmodel/main.cpp4
-rw-r--r--examples/quick/models/abstractitemmodel/view.qml10
-rw-r--r--examples/quick/models/objectlistmodel/main.cpp14
-rw-r--r--examples/quick/models/objectlistmodel/view.qml8
-rw-r--r--examples/quick/models/stringlistmodel/main.cpp14
-rw-r--r--examples/quick/models/stringlistmodel/view.qml8
-rw-r--r--examples/quick/mousearea/mousearea-wheel-example.qml2
-rw-r--r--examples/quick/mousearea/mousearea.qml6
-rw-r--r--examples/quick/particles/affectors/content/customaffector.qml4
-rw-r--r--examples/quick/particles/affectors/content/groupgoal.qml4
-rw-r--r--examples/quick/particles/emitters/content/burstandpulse.qml8
-rw-r--r--examples/quick/particles/emitters/content/customemitter.qml6
-rw-r--r--examples/quick/particles/imageparticle/content/sharing.qml90
-rw-r--r--examples/quick/particles/itemparticle/particleview.qml13
-rw-r--r--examples/quick/positioners/positioners-transitions.qml7
-rw-r--r--examples/quick/quick-accessibility/content/Slider.qml7
-rw-r--r--examples/quick/righttoleft/layoutdirection/layoutdirection.qml61
-rw-r--r--examples/quick/righttoleft/textalignment/textalignment.qml85
-rw-r--r--examples/quick/scenegraph/metaltextureimport/main.cpp4
-rw-r--r--examples/quick/scenegraph/metaltextureimport/metaltextureimport.h1
-rw-r--r--examples/quick/scenegraph/metaltextureimport/metaltextureimport.pro3
-rw-r--r--examples/quick/scenegraph/rendernode/main.qml2
-rw-r--r--examples/quick/scenegraph/vulkantextureimport/main.cpp3
-rw-r--r--examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.h1
-rw-r--r--examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.pro5
-rw-r--r--examples/quick/scenegraph/vulkanunderqml/main.cpp3
-rw-r--r--examples/quick/scenegraph/vulkanunderqml/vulkansquircle.h1
-rw-r--r--examples/quick/scenegraph/vulkanunderqml/vulkanunderqml.pro3
-rw-r--r--examples/quick/shared/FlickrRssModel.qml2
-rw-r--r--examples/quick/shared/LauncherList.qml3
-rw-r--r--examples/quick/shared/SimpleLauncherDelegate.qml3
-rw-r--r--examples/quick/shared/TabSet.qml9
-rw-r--r--examples/quick/tableview/gameoflife/main.qml8
-rw-r--r--examples/quick/tableview/pixelator/main.qml6
-rw-r--r--examples/quick/text/fonts/availableFonts.qml5
-rw-r--r--examples/quick/text/fonts/fonts.qml13
-rw-r--r--examples/quick/text/imgtag/TextWithImage.qml2
-rw-r--r--examples/quick/text/imgtag/imgtag.qml3
-rw-r--r--examples/quick/text/styledtext-layout.qml8
-rw-r--r--examples/quick/threading/threadedlistmodel/timedisplay.qml5
-rw-r--r--examples/quick/threading/workerscript/Spinner.qml1
-rw-r--r--examples/quick/threading/workerscript/workerscript.qml2
-rw-r--r--examples/quick/touchinteraction/flickable/content/Panel.qml168
-rw-r--r--examples/quick/touchinteraction/flickable/corkboards.qml4
-rw-r--r--examples/quick/touchinteraction/multipointtouch/content/AugmentedTouchPoint.qml2
-rw-r--r--examples/quick/views/delegatemodel/dragselection.qml5
-rw-r--r--examples/quick/views/delegatemodel/slideshow.qml4
-rw-r--r--examples/quick/views/gridview/gridview-example.qml10
-rw-r--r--examples/quick/views/listview/content/PressAndHoldButton.qml4
-rw-r--r--examples/quick/views/listview/content/ToggleButton.qml2
-rw-r--r--examples/quick/views/listview/displaymargin.qml5
-rw-r--r--examples/quick/views/listview/dynamiclist.qml37
-rw-r--r--examples/quick/views/listview/expandingdelegates.qml18
-rw-r--r--examples/quick/views/listview/highlight.qml68
-rw-r--r--examples/quick/views/listview/highlightranges.qml32
-rw-r--r--examples/quick/views/listview/sections.qml10
-rw-r--r--examples/quick/views/objectmodel/objectmodel.qml10
-rw-r--r--examples/quick/views/package/Delegate.qml10
-rw-r--r--examples/quick/views/package/view.qml4
-rw-r--r--examples/quick/window/AllScreens.qml8
-rw-r--r--examples/quick/window/CurrentScreen.qml4
-rw-r--r--examples/quick/window/Splash.qml4
-rw-r--r--examples/quick/window/window.qml63
-rw-r--r--src/imports/folderlistmodel/plugin.cpp9
-rw-r--r--src/imports/labsanimation/plugin.cpp8
-rw-r--r--src/imports/labsmodels/plugin.cpp8
-rw-r--r--src/imports/labsmodels/qqmldelegatecomponent.cpp24
-rw-r--r--src/imports/labsmodels/qqmldelegatecomponent_p.h2
-rw-r--r--src/imports/labsmodels/qqmltablemodel.cpp17
-rw-r--r--src/imports/labsmodels/qqmltablemodel_p.h2
-rw-r--r--src/imports/layouts/plugin.cpp4
-rw-r--r--src/imports/layouts/qquicklayout.cpp21
-rw-r--r--src/imports/layouts/qquicklayout_p.h4
-rw-r--r--src/imports/layouts/qquicklinearlayout.cpp10
-rw-r--r--src/imports/layouts/qquicklinearlayout_p.h4
-rw-r--r--src/imports/localstorage/plugin.cpp4
-rw-r--r--src/imports/models/plugin.cpp17
-rw-r--r--src/imports/particles/plugin.cpp7
-rw-r--r--src/imports/qtqml/plugin.cpp10
-rw-r--r--src/imports/qtquick2/plugin.cpp7
-rw-r--r--src/imports/settings/plugin.cpp8
-rw-r--r--src/imports/shapes/plugin.cpp2
-rw-r--r--src/imports/sharedimage/plugin.cpp8
-rw-r--r--src/imports/statemachine/childrenprivate.h138
-rw-r--r--src/imports/statemachine/finalstate.cpp4
-rw-r--r--src/imports/statemachine/finalstate.h2
-rw-r--r--src/imports/statemachine/plugin.cpp8
-rw-r--r--src/imports/statemachine/state.cpp4
-rw-r--r--src/imports/statemachine/state.h2
-rw-r--r--src/imports/statemachine/statemachine.cpp4
-rw-r--r--src/imports/statemachine/statemachine.h2
-rw-r--r--src/imports/testlib/TestCase.qml17
-rw-r--r--src/imports/testlib/main.cpp8
-rw-r--r--src/imports/wavefrontmesh/plugin.cpp4
-rw-r--r--src/imports/window/plugin.cpp8
-rw-r--r--src/imports/workerscript/plugin.cpp17
-rw-r--r--src/particles/qquickimageparticle.cpp18
-rw-r--r--src/particles/qquickparticlegroup.cpp13
-rw-r--r--src/particles/qtquickparticlesglobal_p.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qmldbg_preview.pro2
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp68
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h87
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.json2
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp5
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces.cpp1
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces_p.h21
-rw-r--r--src/qml/doc/snippets/code/backend/backend.h2
-rw-r--r--src/qml/doc/snippets/code/backend/backend.pro17
-rw-r--r--src/qml/doc/snippets/code/backend/main.cpp4
-rw-r--r--src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.cpp144
-rw-r--r--src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.h3
-rw-r--r--src/qml/doc/snippets/qml/integrating-javascript/scarceresources/scarceresources.pro22
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/A.qml61
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/B.qml58
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/Images.qml84
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/LabeledImageBox.qml64
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc136
-rw-r--r--src/qml/doc/src/cppintegration/topic.qdoc18
-rw-r--r--src/qml/doc/src/javascript/expressions.qdoc4
-rw-r--r--src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc113
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc52
-rw-r--r--src/qml/jsruntime/qv4engine.cpp27
-rw-r--r--src/qml/jsruntime/qv4value.cpp4
-rw-r--r--src/qml/parser/qqmljs.g20
-rw-r--r--src/qml/parser/qqmljsast.cpp257
-rw-r--r--src/qml/parser/qqmljsast_p.h311
-rw-r--r--src/qml/parser/qqmljsastfwd_p.h4
-rw-r--r--src/qml/parser/qqmljsastvisitor.cpp6
-rw-r--r--src/qml/parser/qqmljsastvisitor_p.h805
-rw-r--r--src/qml/qml/qqml.cpp37
-rw-r--r--src/qml/qml/qqml.h71
-rw-r--r--src/qml/qml/qqmlbinding.cpp9
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp31
-rw-r--r--src/qml/qml/qqmlengine.cpp6
-rw-r--r--src/qml/qml/qqmlengine_p.h16
-rw-r--r--src/qml/qml/qqmlmetatype.cpp22
-rw-r--r--src/qml/qml/qqmlmetatype_p.h2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp6
-rw-r--r--src/qml/qml/qqmlprivate.h21
-rw-r--r--src/qml/qml/qqmlproperty.cpp47
-rw-r--r--src/qml/qml/qqmlpropertyvalidator.cpp2
-rw-r--r--src/qml/qml/qqmltypecompiler.cpp6
-rw-r--r--src/qml/qml/qqmltypedata.cpp5
-rw-r--r--src/qml/qml/qqmltypeloader.cpp82
-rw-r--r--src/qml/qml/qqmltypenotavailable.cpp2
-rw-r--r--src/qml/qml/qqmltypenotavailable_p.h4
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp92
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h49
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp29
-rw-r--r--src/qml/qtqmlglobal_p.h2
-rw-r--r--src/qml/types/qqmlconnections.cpp3
-rw-r--r--src/qmldebug/qmldebug.pro4
-rw-r--r--src/qmldebug/qqmldebugtranslationclient.cpp76
-rw-r--r--src/qmldebug/qqmldebugtranslationclient_p.h81
-rw-r--r--src/qmlmodels/qqmladaptormodel.cpp3
-rw-r--r--src/qmlmodels/qqmladaptormodel_p.h5
-rw-r--r--src/qmlmodels/qqmldelegatemodel.cpp2
-rw-r--r--src/qmlmodels/qqmldelegatemodel_p.h2
-rw-r--r--src/qmlmodels/qqmllistaccessor.cpp6
-rw-r--r--src/qmlmodels/qqmllistaccessor_p.h2
-rw-r--r--src/qmlmodels/qqmlobjectmodel.cpp34
-rw-r--r--src/qmlmodels/qqmlobjectmodel_p.h2
-rw-r--r--src/qmlmodels/qqmltableinstancemodel_p.h4
-rw-r--r--src/qmlmodels/qquickpackage.cpp19
-rw-r--r--src/qmlmodels/qtqmlmodelsglobal_p.h2
-rw-r--r--src/qmlworkerscript/qquickworkerscript_p.h2
-rw-r--r--src/qmlworkerscript/qtqmlworkerscriptglobal_p.h2
-rw-r--r--src/quick/accessible/qaccessiblequickview.cpp8
-rw-r--r--src/quick/designer/qquickdesignersupportproperties.cpp8
-rw-r--r--src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml81
-rw-r--r--src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc20
-rw-r--r--src/quick/doc/src/qmltypereference.qdoc1
-rw-r--r--src/quick/handlers/qquickhandlerpoint.cpp5
-rw-r--r--src/quick/handlers/qquickhoverhandler.cpp19
-rw-r--r--src/quick/handlers/qquickhoverhandler_p.h1
-rw-r--r--src/quick/items/qquickevents.cpp162
-rw-r--r--src/quick/items/qquickevents_p_p.h71
-rw-r--r--src/quick/items/qquickflickable.cpp19
-rw-r--r--src/quick/items/qquickflickable_p_p.h2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp7
-rw-r--r--src/quick/items/qquickitemsmodule_p.h12
-rw-r--r--src/quick/items/qquickitemview.cpp2
-rw-r--r--src/quick/items/qquicklistview.cpp168
-rw-r--r--src/quick/items/qquickloader.cpp93
-rw-r--r--src/quick/items/qquickloader_p_p.h7
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp28
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h4
-rw-r--r--src/quick/items/qquickshadereffectsource.cpp4
-rw-r--r--src/quick/items/qquickspriteengine_p.h12
-rw-r--r--src/quick/items/qquickspritesequence.cpp4
-rw-r--r--src/quick/items/qquicktableview.cpp20
-rw-r--r--src/quick/items/qquicktableview_p_p.h2
-rw-r--r--src/quick/items/qquicktext.cpp7
-rw-r--r--src/quick/items/qquickwindow.cpp60
-rw-r--r--src/quick/items/qquickwindow.h3
-rw-r--r--src/quick/items/qquickwindow_p.h2
-rw-r--r--src/quick/qtquickglobal_p.h2
-rw-r--r--src/quick/quick.pro5
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp16
-rw-r--r--src/quick/util/qquickpixmapcache.cpp12
-rw-r--r--src/quick/util/qquickstate.cpp10
-rw-r--r--src/quick/util/qquickstate_p_p.h17
-rw-r--r--src/quick/util/qquickstategroup.cpp36
-rw-r--r--src/quick/util/qquicktimeline_p_p.h3
-rw-r--r--src/quickshapes/qquickshapesglobal_p.h1
-rw-r--r--tests/auto/qml/debugger/debugger.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml4
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp10
-rw-r--r--tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml41
-rw-r--r--tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro12
-rw-r--r--tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp80
-rw-r--r--tests/auto/qml/qjsvalue/tst_qjsvalue.cpp7
-rw-r--r--tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml106
-rw-r--r--tests/auto/qml/qmlformat/data/Annotations.formatted.qml106
-rw-r--r--tests/auto/qml/qmlformat/data/Annotations.qml76
-rw-r--r--tests/auto/qml/qmlformat/tst_qmlformat.cpp12
-rw-r--r--tests/auto/qml/qqmlconnections/data/underscore.qml14
-rw-r--r--tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp15
-rw-r--r--tests/auto/qml/qqmlecmascript/data/sequenceConversion.write.error.qml2
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp40
-rw-r--r--tests/auto/qml/qqmlenginecleanup/data/MyItem.qml2
-rw-r--r--tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp13
-rw-r--r--tests/auto/qml/qqmllanguage/data/SimpleItem.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/arrayToContainer.qml7
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml17
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml14
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h9
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp60
-rw-r--r--tests/auto/qml/qqmlparser/qqmlparser.pro1
-rw-r--r--tests/auto/qml/qqmlparser/tst_qqmlparser.cpp3
-rw-r--r--tests/auto/qml/qqmlproperty/data/interfaceBinding2.qml27
-rw-r--r--tests/auto/qml/qqmlproperty/interfaces.h161
-rw-r--r--tests/auto/qml/qqmlproperty/qqmlproperty.pro8
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp101
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp60
-rw-r--r--tests/auto/quick/qquickflickable/data/visibleAreaBinding.qml38
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp11
-rw-r--r--tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml31
-rw-r--r--tests/auto/quick/qquicklistview/data/headerSnapToItem.qml67
-rw-r--r--tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml15
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp658
-rw-r--r--tests/auto/quick/qquickloader/data/statusChanged.qml16
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp14
-rw-r--r--tests/auto/quick/qquickmousearea/BLACKLIST4
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp4
-rw-r--r--tests/auto/shared/astdump.pri7
-rw-r--r--tests/auto/shared/qqmljsastdumper.cpp1081
-rw-r--r--tests/auto/shared/qqmljsastdumper.h446
-rw-r--r--tests/manual/pointer/main.qml3
-rw-r--r--tests/manual/pointer/qml.qrc5
-rw-r--r--tests/manual/pointer/resources/cursor-airbrush.pngbin0 -> 823 bytes
-rw-r--r--tests/manual/pointer/resources/cursor-eraser.pngbin0 -> 1454 bytes
-rw-r--r--tests/manual/pointer/resources/cursor-felt-marker.pngbin0 -> 513 bytes
-rw-r--r--tests/manual/pointer/resources/cursor-pencil.pngbin0 -> 1307 bytes
-rw-r--r--tests/manual/pointer/tabletCanvasDrawing.qml242
-rw-r--r--tools/qml/main.cpp25
-rw-r--r--tools/qmlcachegen/qtquickcompiler.prf1
-rw-r--r--tools/qmlformat/dumpastvisitor.cpp42
-rw-r--r--tools/qmlformat/dumpastvisitor.h5
-rw-r--r--tools/qmlimportscanner/qmlimportscanner.pro4
-rw-r--r--tools/qmlscene/main.cpp3
302 files changed, 7880 insertions, 1651 deletions
diff --git a/examples/qml/doc/src/qml-extending.qdoc b/examples/qml/doc/src/qml-extending.qdoc
index 1ad3ae9a10..723e470d45 100644
--- a/examples/qml/doc/src/qml-extending.qdoc
+++ b/examples/qml/doc/src/qml-extending.qdoc
@@ -69,7 +69,7 @@ This example builds on:
\li \l {Extending QML - Adding Types Example}
\endlist
-Shows how to use \l {QQmlEngine::}{qmlRegisterExtendedType()} to provide an
+Shows how to use \l {QML_EXTENDED} to provide an
\l {Registering Extension Objects}{extension object} to a \l QLineEdit without modifying or
subclassing it.
diff --git a/examples/qml/referenceexamples/attached/birthdayparty.cpp b/examples/qml/referenceexamples/attached/birthdayparty.cpp
index da0cb800fc..888aafbc18 100644
--- a/examples/qml/referenceexamples/attached/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/attached/birthdayparty.cpp
@@ -81,7 +81,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return {this, m_guests};
+ return {this, &m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/binding/birthdayparty.cpp b/examples/qml/referenceexamples/binding/birthdayparty.cpp
index 866c1f6968..cfedf84be0 100644
--- a/examples/qml/referenceexamples/binding/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/binding/birthdayparty.cpp
@@ -87,7 +87,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return QQmlListProperty<Person>(this, m_guests);
+ return QQmlListProperty<Person>(this, &m_guests);
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/binding/example.qml b/examples/qml/referenceexamples/binding/example.qml
index a89b4bc02e..b45ef6881b 100644
--- a/examples/qml/referenceexamples/binding/example.qml
+++ b/examples/qml/referenceexamples/binding/example.qml
@@ -62,7 +62,7 @@ BirthdayParty {
shoe { size: 12; color: "white"; brand: "Nike"; price: 90.0 }
}
// ![0]
- onPartyStarted: console.log("This party started rockin' at " + time);
+ onPartyStarted: (time) => { console.log("This party started rockin' at " + time); }
Boy {
diff --git a/examples/qml/referenceexamples/coercion/birthdayparty.cpp b/examples/qml/referenceexamples/coercion/birthdayparty.cpp
index 1bae55076c..81db8ab1b8 100644
--- a/examples/qml/referenceexamples/coercion/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/coercion/birthdayparty.cpp
@@ -66,7 +66,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return {this, m_guests};
+ return {this, &m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/default/birthdayparty.cpp b/examples/qml/referenceexamples/default/birthdayparty.cpp
index 1bae55076c..81db8ab1b8 100644
--- a/examples/qml/referenceexamples/default/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/default/birthdayparty.cpp
@@ -66,7 +66,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return {this, m_guests};
+ return {this, &m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/grouped/birthdayparty.cpp b/examples/qml/referenceexamples/grouped/birthdayparty.cpp
index 1bae55076c..81db8ab1b8 100644
--- a/examples/qml/referenceexamples/grouped/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/grouped/birthdayparty.cpp
@@ -66,7 +66,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return {this, m_guests};
+ return {this, &m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/methods/birthdayparty.cpp b/examples/qml/referenceexamples/methods/birthdayparty.cpp
index 7e750e4f4b..4b30d31aeb 100644
--- a/examples/qml/referenceexamples/methods/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/methods/birthdayparty.cpp
@@ -67,7 +67,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return {this, m_guests};
+ return {this, &m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/properties/birthdayparty.cpp b/examples/qml/referenceexamples/properties/birthdayparty.cpp
index 9abb08dbd9..fe6abab3f5 100644
--- a/examples/qml/referenceexamples/properties/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/properties/birthdayparty.cpp
@@ -71,7 +71,9 @@ QQmlListProperty<Person> BirthdayParty::guests()
&BirthdayParty::appendGuest,
&BirthdayParty::guestCount,
&BirthdayParty::guest,
- &BirthdayParty::clearGuests};
+ &BirthdayParty::clearGuests,
+ &BirthdayParty::replaceGuest,
+ &BirthdayParty::removeLastGuest};
}
void BirthdayParty::appendGuest(Person* p) {
@@ -93,6 +95,16 @@ void BirthdayParty::clearGuests() {
m_guests.clear();
}
+void BirthdayParty::replaceGuest(int index, Person *p)
+{
+ m_guests[index] = p;
+}
+
+void BirthdayParty::removeLastGuest()
+{
+ m_guests.removeLast();
+}
+
// ![0]
void BirthdayParty::appendGuest(QQmlListProperty<Person>* list, Person* p) {
@@ -103,6 +115,16 @@ void BirthdayParty::clearGuests(QQmlListProperty<Person>* list) {
reinterpret_cast< BirthdayParty* >(list->data)->clearGuests();
}
+void BirthdayParty::replaceGuest(QQmlListProperty<Person> *list, int i, Person *p)
+{
+ reinterpret_cast< BirthdayParty* >(list->data)->replaceGuest(i, p);
+}
+
+void BirthdayParty::removeLastGuest(QQmlListProperty<Person> *list)
+{
+ reinterpret_cast< BirthdayParty* >(list->data)->removeLastGuest();
+}
+
Person* BirthdayParty::guest(QQmlListProperty<Person>* list, int i) {
return reinterpret_cast< BirthdayParty* >(list->data)->guest(i);
}
diff --git a/examples/qml/referenceexamples/properties/birthdayparty.h b/examples/qml/referenceexamples/properties/birthdayparty.h
index fb8b63a79d..a5704972cc 100644
--- a/examples/qml/referenceexamples/properties/birthdayparty.h
+++ b/examples/qml/referenceexamples/properties/birthdayparty.h
@@ -79,12 +79,16 @@ public:
int guestCount() const;
Person *guest(int) const;
void clearGuests();
+ void replaceGuest(int, Person*);
+ void removeLastGuest();
private:
static void appendGuest(QQmlListProperty<Person>*, Person*);
static int guestCount(QQmlListProperty<Person>*);
static Person* guest(QQmlListProperty<Person>*, int);
static void clearGuests(QQmlListProperty<Person>*);
+ static void replaceGuest(QQmlListProperty<Person>*, int, Person*);
+ static void removeLastGuest(QQmlListProperty<Person>*);
Person *m_host;
QVector<Person *> m_guests;
diff --git a/examples/qml/referenceexamples/signal/birthdayparty.cpp b/examples/qml/referenceexamples/signal/birthdayparty.cpp
index 9d34cdf146..405c8af940 100644
--- a/examples/qml/referenceexamples/signal/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/signal/birthdayparty.cpp
@@ -82,7 +82,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return {this, m_guests};
+ return {this, &m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/signal/example.qml b/examples/qml/referenceexamples/signal/example.qml
index 42d6c44939..5d80d58867 100644
--- a/examples/qml/referenceexamples/signal/example.qml
+++ b/examples/qml/referenceexamples/signal/example.qml
@@ -53,7 +53,7 @@ import QtQuick 2.0 // For QColor
BirthdayParty {
// ![0]
- onPartyStarted: console.log("This party started rockin' at " + time);
+ onPartyStarted: (time) => { console.log("This party started rockin' at " + time); }
// ![0]
host: Boy {
diff --git a/examples/qml/referenceexamples/valuesource/birthdayparty.cpp b/examples/qml/referenceexamples/valuesource/birthdayparty.cpp
index 68d5767e8d..6a5e67aa0d 100644
--- a/examples/qml/referenceexamples/valuesource/birthdayparty.cpp
+++ b/examples/qml/referenceexamples/valuesource/birthdayparty.cpp
@@ -82,7 +82,7 @@ void BirthdayParty::setHost(Person *c)
QQmlListProperty<Person> BirthdayParty::guests()
{
- return {this, m_guests};
+ return {this, &m_guests};
}
int BirthdayParty::guestCount() const
diff --git a/examples/qml/referenceexamples/valuesource/example.qml b/examples/qml/referenceexamples/valuesource/example.qml
index 0abb76261c..65d511058a 100644
--- a/examples/qml/referenceexamples/valuesource/example.qml
+++ b/examples/qml/referenceexamples/valuesource/example.qml
@@ -56,7 +56,7 @@ BirthdayParty {
HappyBirthdaySong on announcement { name: "Bob Jones" }
// ![0]
- onPartyStarted: console.log("This party started rockin' at " + time);
+ onPartyStarted: (time) => { console.log("This party started rockin' at " + time); }
host: Boy {
diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.cpp b/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.cpp
index ac680bb9c9..a8e14db542 100644
--- a/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.cpp
+++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.cpp
@@ -68,7 +68,8 @@ void PieChart::setName(const QString &name)
//![0]
QQmlListProperty<PieSlice> PieChart::slices()
{
- return QQmlListProperty<PieSlice>(this, nullptr, &PieChart::append_slice, nullptr, nullptr, nullptr);
+ return QQmlListProperty<PieSlice>(this, nullptr, &PieChart::append_slice, nullptr,
+ nullptr, nullptr, nullptr, nullptr);
}
void PieChart::append_slice(QQmlListProperty<PieSlice> *list, PieSlice *slice)
diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp
index 1c712c887a..536c0e16ae 100644
--- a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp
+++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp
@@ -67,7 +67,8 @@ void PieChart::setName(const QString &name)
QQmlListProperty<PieSlice> PieChart::slices()
{
- return QQmlListProperty<PieSlice>(this, nullptr, &PieChart::append_slice, nullptr, nullptr, nullptr);
+ return QQmlListProperty<PieSlice>(this, nullptr, &PieChart::append_slice, nullptr,
+ nullptr, nullptr, nullptr, nullptr);
}
void PieChart::append_slice(QQmlListProperty<PieSlice> *list, PieSlice *slice)
diff --git a/examples/quick/animation/basics/property-animation.qml b/examples/quick/animation/basics/property-animation.qml
index a764c395ee..8d640c9dda 100644
--- a/examples/quick/animation/basics/property-animation.qml
+++ b/examples/quick/animation/basics/property-animation.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+import QtQml 2.0
import QtQuick 2.0
Item {
diff --git a/examples/quick/animation/behaviors/tvtennis.qml b/examples/quick/animation/behaviors/tvtennis.qml
index 89d912777a..261f603de6 100644
--- a/examples/quick/animation/behaviors/tvtennis.qml
+++ b/examples/quick/animation/behaviors/tvtennis.qml
@@ -116,6 +116,13 @@ Rectangle {
Rectangle { color: "#1e1b18"; x: page.width/2+50; y: 10; width: 20; height: 40 }
Repeater {
model: page.height / 20
- Rectangle { color: "#328930"; x: page.width/2-5; y: index * 20; width: 10; height: 10 }
+ Rectangle {
+ required property int index
+ color: "#328930"
+ x: page.width / 2 - 5
+ y: index * 20
+ width: 10
+ height: 10
+ }
}
}
diff --git a/examples/quick/animation/behaviors/wigglytext.qml b/examples/quick/animation/behaviors/wigglytext.qml
index cc2e086b51..81d4a8aef9 100644
--- a/examples/quick/animation/behaviors/wigglytext.qml
+++ b/examples/quick/animation/behaviors/wigglytext.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+import QtQml 2.0
import QtQuick 2.0
Rectangle {
@@ -58,7 +59,7 @@ Rectangle {
width: 320; height: 480; color: "#474747"; focus: true
- Keys.onPressed: {
+ Keys.onPressed: (event) => {
if (event.key == Qt.Key_Delete || event.key == Qt.Key_Backspace)
container.remove()
else if (event.text != "") {
diff --git a/examples/quick/animation/pathanimation/pathanimation.qml b/examples/quick/animation/pathanimation/pathanimation.qml
index b98fbebefc..ae96b32680 100644
--- a/examples/quick/animation/pathanimation/pathanimation.qml
+++ b/examples/quick/animation/pathanimation/pathanimation.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+import QtQml 2.0
import QtQuick 2.0
Rectangle {
diff --git a/examples/quick/animation/pathinterpolator/pathinterpolator.qml b/examples/quick/animation/pathinterpolator/pathinterpolator.qml
index 0c0d7bad46..07a82fc916 100644
--- a/examples/quick/animation/pathinterpolator/pathinterpolator.qml
+++ b/examples/quick/animation/pathinterpolator/pathinterpolator.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+import QtQml 2.0
import QtQuick 2.0
Rectangle {
diff --git a/examples/quick/animation/states/states.qml b/examples/quick/animation/states/states.qml
index 498fb6867c..5ff8e5318c 100644
--- a/examples/quick/animation/states/states.qml
+++ b/examples/quick/animation/states/states.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+import QtQml 2.0
import QtQuick 2.0
Rectangle {
diff --git a/examples/quick/draganddrop/tiles/DragTile.qml b/examples/quick/draganddrop/tiles/DragTile.qml
index 78fe7a483a..47f0ebed5e 100644
--- a/examples/quick/draganddrop/tiles/DragTile.qml
+++ b/examples/quick/draganddrop/tiles/DragTile.qml
@@ -53,7 +53,9 @@ import QtQuick 2.0
//! [0]
Item {
id: root
- property string colorKey
+
+ required property string colorKey
+ required property int modelData
width: 64; height: 64
@@ -74,9 +76,9 @@ Item {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
- color: colorKey
+ color: root.colorKey
- Drag.keys: [ colorKey ]
+ Drag.keys: [ root.colorKey ]
Drag.active: mouseArea.drag.active
Drag.hotSpot.x: 32
Drag.hotSpot.y: 32
@@ -85,7 +87,7 @@ Item {
anchors.fill: parent
color: "white"
font.pixelSize: 48
- text: modelData + 1
+ text: root.modelData + 1
horizontalAlignment:Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
diff --git a/examples/quick/draganddrop/tiles/DropTile.qml b/examples/quick/draganddrop/tiles/DropTile.qml
index de4c0dee44..bf7101f0f6 100644
--- a/examples/quick/draganddrop/tiles/DropTile.qml
+++ b/examples/quick/draganddrop/tiles/DropTile.qml
@@ -64,7 +64,7 @@ DropArea {
id: dropRectangle
anchors.fill: parent
- color: colorKey
+ color: dragTarget.colorKey
states: [
State {
diff --git a/examples/quick/externaldraganddrop/DragAndDropTextItem.qml b/examples/quick/externaldraganddrop/DragAndDropTextItem.qml
index 9858a961c9..605dc07434 100644
--- a/examples/quick/externaldraganddrop/DragAndDropTextItem.qml
+++ b/examples/quick/externaldraganddrop/DragAndDropTextItem.qml
@@ -71,14 +71,18 @@ Rectangle {
id: dropArea
anchors.fill: parent
keys: ["text/plain"]
- onEntered: if (!acceptDropCB.checked) {
- drag.accepted = false
- rejectAnimation.start()
+ onEntered: (drag) => {
+ if (!acceptDropCB.checked) {
+ drag.accepted = false
+ rejectAnimation.start()
+ }
}
- onDropped: if (drop.hasText && acceptDropCB.checked) {
- if (drop.proposedAction == Qt.MoveAction || drop.proposedAction == Qt.CopyAction) {
- item.display = drop.text
- drop.acceptProposedAction()
+ onDropped: (drop) => {
+ if (drop.hasText && acceptDropCB.checked) {
+ if (drop.proposedAction == Qt.MoveAction || drop.proposedAction == Qt.CopyAction) {
+ item.display = drop.text
+ drop.acceptProposedAction()
+ }
}
}
}
@@ -95,7 +99,10 @@ Rectangle {
Drag.hotSpot.y: 0
Drag.mimeData: { "text/plain": item.display }
Drag.dragType: Drag.Automatic
- Drag.onDragFinished: if (dropAction == Qt.MoveAction) item.display = ""
+ Drag.onDragFinished: (dropAction) => {
+ if (dropAction == Qt.MoveAction)
+ item.display = ""
+ }
}
Examples.CheckBox {
id: acceptDropCB
diff --git a/examples/quick/imageelements/animatedsprite.qml b/examples/quick/imageelements/animatedsprite.qml
index 0c6bf5e28d..cc5226882a 100644
--- a/examples/quick/imageelements/animatedsprite.qml
+++ b/examples/quick/imageelements/animatedsprite.qml
@@ -73,7 +73,7 @@ Item {
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
- onClicked: {
+ onClicked: (mouse) => {
if (!sprite.running)
sprite.start();
if (!sprite.paused)
diff --git a/examples/quick/imageelements/content/BorderImageSelector.qml b/examples/quick/imageelements/content/BorderImageSelector.qml
index 93ff5136bc..d8c2101be7 100644
--- a/examples/quick/imageelements/content/BorderImageSelector.qml
+++ b/examples/quick/imageelements/content/BorderImageSelector.qml
@@ -93,7 +93,10 @@ Item {
Repeater {
model: [ "Scale", "Repeat", "Scale/Repeat", "Round" ]
delegate: Text {
- text: model.modelData
+ required property string modelData
+ required property int index
+
+ text: modelData
anchors.verticalCenter: parent.verticalCenter
x: (index - selector.curIdx) * 80 + 140
diff --git a/examples/quick/imageelements/content/ImageCell.qml b/examples/quick/imageelements/content/ImageCell.qml
index 4b147633c3..7804346bd4 100644
--- a/examples/quick/imageelements/content/ImageCell.qml
+++ b/examples/quick/imageelements/content/ImageCell.qml
@@ -53,8 +53,6 @@ Item {
property alias mode: image.fillMode
property alias caption: captionItem.text
- width: parent.cellWidth; height: parent.cellHeight
-
Image {
id: image
width: parent.width; height: parent.height - captionItem.height
diff --git a/examples/quick/imageelements/content/MyBorderImage.qml b/examples/quick/imageelements/content/MyBorderImage.qml
index 01d26a9630..3198de3bf1 100644
--- a/examples/quick/imageelements/content/MyBorderImage.qml
+++ b/examples/quick/imageelements/content/MyBorderImage.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+import QtQml 2.0
import QtQuick 2.0
Item {
diff --git a/examples/quick/imageelements/image.qml b/examples/quick/imageelements/image.qml
index d414f59629..0750ea3b79 100644
--- a/examples/quick/imageelements/image.qml
+++ b/examples/quick/imageelements/image.qml
@@ -65,12 +65,34 @@ Rectangle {
rows: 3
spacing: 30
- ImageCell { mode: Image.Stretch; caption: "Stretch" }
- ImageCell { mode: Image.PreserveAspectFit; caption: "PreserveAspectFit" }
- ImageCell { mode: Image.PreserveAspectCrop; caption: "PreserveAspectCrop" }
+ component SizedImageCell: ImageCell {
+ width: parent.cellWidth
+ height: parent.cellHeight
+ }
- ImageCell { mode: Image.Tile; caption: "Tile" }
- ImageCell { mode: Image.TileHorizontally; caption: "TileHorizontally" }
- ImageCell { mode: Image.TileVertically; caption: "TileVertically" }
+ SizedImageCell {
+ mode: Image.Stretch
+ caption: "Stretch"
+ }
+ SizedImageCell {
+ mode: Image.PreserveAspectFit
+ caption: "PreserveAspectFit"
+ }
+ SizedImageCell {
+ mode: Image.PreserveAspectCrop
+ caption: "PreserveAspectCrop"
+ }
+ SizedImageCell {
+ mode: Image.Tile
+ caption: "Tile"
+ }
+ SizedImageCell {
+ mode: Image.TileHorizontally
+ caption: "TileHorizontally"
+ }
+ SizedImageCell {
+ mode: Image.TileVertically
+ caption: "TileVertically"
+ }
}
}
diff --git a/examples/quick/keyinteraction/focus/Core/ContextMenu.qml b/examples/quick/keyinteraction/focus/Core/ContextMenu.qml
index c5430aa650..31b5e1b83d 100644
--- a/examples/quick/keyinteraction/focus/Core/ContextMenu.qml
+++ b/examples/quick/keyinteraction/focus/Core/ContextMenu.qml
@@ -52,6 +52,7 @@ import QtQuick 2.1
FocusScope {
id: container
+ required property Item keyRightTarget
property bool open: false
@@ -62,7 +63,7 @@ FocusScope {
anchors.fill: parent
color: "#D1DBBD"
focus: true
- Keys.onRightPressed: mainView.focus = true
+ Keys.onRightPressed: container.keyRightTarget.focus = true
Text {
anchors { top: parent.top; horizontalCenter: parent.horizontalCenter; margins: 30 }
diff --git a/examples/quick/keyinteraction/focus/Core/GridMenu.qml b/examples/quick/keyinteraction/focus/Core/GridMenu.qml
index 3f62adc792..78d6654957 100644
--- a/examples/quick/keyinteraction/focus/Core/GridMenu.qml
+++ b/examples/quick/keyinteraction/focus/Core/GridMenu.qml
@@ -51,12 +51,11 @@
import QtQuick 2.1
FocusScope {
+ id: menu
property alias interactive: gridView.interactive
-
- onActiveFocusChanged: {
- if (activeFocus)
- mainView.state = "showGridViews"
- }
+ required property Item keyUpTarget
+ required property Item keyDownTarget
+ required property Item keyLeftTarget
Rectangle {
anchors.fill: parent
@@ -73,13 +72,15 @@ FocusScope {
focus: true
model: 12
- KeyNavigation.up: tabMenu
- KeyNavigation.down: listMenu
- KeyNavigation.left: contextMenu
+ KeyNavigation.up: menu.keyUpTarget
+ KeyNavigation.down: menu.keyDownTarget
+ KeyNavigation.left: menu.keyLeftTarget
delegate: Item {
id: container
- width: GridView.view.cellWidth; height: GridView.view.cellHeight
+ width: GridView.view.cellWidth
+ height: GridView.view.cellHeight
+ required property int index
Rectangle {
id: content
@@ -97,7 +98,7 @@ FocusScope {
hoverEnabled: true
onClicked: {
- container.GridView.view.currentIndex = index
+ container.GridView.view.currentIndex = container.index
container.forceActiveFocus()
}
}
diff --git a/examples/quick/keyinteraction/focus/Core/ListMenu.qml b/examples/quick/keyinteraction/focus/Core/ListMenu.qml
index d8e9daba78..694ae3cac6 100644
--- a/examples/quick/keyinteraction/focus/Core/ListMenu.qml
+++ b/examples/quick/keyinteraction/focus/Core/ListMenu.qml
@@ -48,21 +48,22 @@
**
****************************************************************************/
+import QtQml 2.1
import QtQuick 2.1
FocusScope {
+ id: menu
clip: true
-
- onActiveFocusChanged: {
- if (activeFocus)
- mainView.state = "showListViews"
- }
+ required property Item keyUpTarget
+ required property Item keyLeftTarget
ListView {
id: list1
y: activeFocus ? 10 : 40; width: parent.width / 3; height: parent.height - 20
focus: true
- KeyNavigation.up: gridMenu; KeyNavigation.left: contextMenu; KeyNavigation.right: list2
+ KeyNavigation.up: menu.keyUpTarget
+ KeyNavigation.left: menu.keyLeftTarget
+ KeyNavigation.right: list2
model: 10; cacheBuffer: 200
delegate: ListViewDelegate {}
@@ -74,7 +75,9 @@ FocusScope {
ListView {
id: list2
y: activeFocus ? 10 : 40; x: parseInt(parent.width / 3); width: parent.width / 3; height: parent.height - 20
- KeyNavigation.up: gridMenu; KeyNavigation.left: list1; KeyNavigation.right: list3
+ KeyNavigation.up: menu.keyUpTarget
+ KeyNavigation.left: list1
+ KeyNavigation.right: list3
model: 10; cacheBuffer: 200
delegate: ListViewDelegate {}
@@ -86,7 +89,8 @@ FocusScope {
ListView {
id: list3
y: activeFocus ? 10 : 40; x: parseInt(2 * parent.width / 3); width: parent.width / 3; height: parent.height - 20
- KeyNavigation.up: gridMenu; KeyNavigation.left: list2
+ KeyNavigation.up: menu.keyUpTarget
+ KeyNavigation.left: list2
model: 10; cacheBuffer: 200
delegate: ListViewDelegate {}
diff --git a/examples/quick/keyinteraction/focus/Core/ListViewDelegate.qml b/examples/quick/keyinteraction/focus/Core/ListViewDelegate.qml
index b1dde9ddc5..5a2957eab0 100644
--- a/examples/quick/keyinteraction/focus/Core/ListViewDelegate.qml
+++ b/examples/quick/keyinteraction/focus/Core/ListViewDelegate.qml
@@ -52,6 +52,8 @@ import QtQuick 2.1
Item {
id: container
+ required property int index
+
width: ListView.view.width; height: 60; anchors.leftMargin: 10; anchors.rightMargin: 10
Rectangle {
@@ -67,7 +69,7 @@ Item {
Text {
id: label
anchors.centerIn: content
- text: "List element " + (index + 1)
+ text: "List element " + (container.index + 1)
color: "#193441"
font.pixelSize: 14
}
@@ -78,7 +80,7 @@ Item {
hoverEnabled: true
onClicked: {
- container.ListView.view.currentIndex = index
+ container.ListView.view.currentIndex = container.index
container.forceActiveFocus()
}
}
diff --git a/examples/quick/keyinteraction/focus/Core/TabMenu.qml b/examples/quick/keyinteraction/focus/Core/TabMenu.qml
index a40e070b2c..11b3d005c3 100644
--- a/examples/quick/keyinteraction/focus/Core/TabMenu.qml
+++ b/examples/quick/keyinteraction/focus/Core/TabMenu.qml
@@ -51,10 +51,9 @@
import QtQuick 2.1
FocusScope {
- onActiveFocusChanged: {
- if (activeFocus)
- mainView.state = "showTabViews"
- }
+ id: menu
+ required property Item keyUpTarget
+ required property Item keyDownTarget
Rectangle {
anchors.fill: parent
@@ -76,8 +75,8 @@ FocusScope {
activeFocusOnTab: true
focus: true
- KeyNavigation.up: listMenu
- KeyNavigation.down: gridMenu
+ KeyNavigation.up: menu.keyUpTarget
+ KeyNavigation.down: menu.keyDownTarget
Rectangle {
id: content
diff --git a/examples/quick/keyinteraction/focus/focus.qml b/examples/quick/keyinteraction/focus/focus.qml
index e07df57697..9db9ab48bc 100644
--- a/examples/quick/keyinteraction/focus/focus.qml
+++ b/examples/quick/keyinteraction/focus/focus.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+import QtQml 2.1
import QtQuick 2.1
import "Core"
@@ -67,20 +68,45 @@ Rectangle {
id: tabMenu
y: 160; width: parent.width; height: 160
+ keyUpTarget: listMenu
+ keyDownTarget: gridMenu
+
focus: true
activeFocusOnTab: true
+
+ onActiveFocusChanged: {
+ if (activeFocus)
+ mainView.state = "showTabViews"
+ }
}
GridMenu {
id: gridMenu
y: 320; width: parent.width; height: 320
activeFocusOnTab: true
+
+ keyUpTarget: tabMenu
+ keyDownTarget: listMenu
+ keyLeftTarget: contextMenu
+
+ onActiveFocusChanged: {
+ if (activeFocus)
+ mainView.state = "showGridViews"
+ }
}
ListMenu {
id: listMenu
y: 640; width: parent.width; height: 320
activeFocusOnTab: true
+
+ keyUpTarget: gridMenu
+ keyLeftTarget: contextMenu
+
+ onActiveFocusChanged: {
+ if (activeFocus)
+ mainView.state = "showListViews"
+ }
}
Rectangle {
@@ -129,7 +155,13 @@ Rectangle {
}
}
- ContextMenu { id: contextMenu; x: -265; width: 260; height: parent.height }
+ ContextMenu {
+ keyRightTarget: mainView
+ id: contextMenu
+ x: -265
+ width: 260
+ height: parent.height
+ }
states: State {
name: "contextMenuOpen"
diff --git a/examples/quick/localstorage/localstorage/Header.qml b/examples/quick/localstorage/localstorage/Header.qml
index e9446de55e..47879500a7 100644
--- a/examples/quick/localstorage/localstorage/Header.qml
+++ b/examples/quick/localstorage/localstorage/Header.qml
@@ -59,6 +59,9 @@ Item {
width: Screen.width / 2
height: Screen.height / 7
+ required property ListView listView
+ required property Text statusText
+
function insertrec() {
var rowid = parseInt(JS.dbInsert(dateInput.text, descInput.text, distInput.text), 10)
if (rowid) {
@@ -148,7 +151,7 @@ Item {
}
onEditingFinished: {
if (dateInput.text == "") {
- statustext.text = "Please fill in the date"
+ root.statusText.text = "Please fill in the date"
dateInput.forceActiveFocus()
}
}
@@ -161,10 +164,10 @@ Item {
activeFocusOnTab: true
onEditingFinished: {
if (descInput.text.length < 8) {
- statustext.text = "Enter a description of minimum 8 characters"
+ root.statusText.text = "Enter a description of minimum 8 characters"
descInput.forceActiveFocus()
} else {
- statustext.text = ""
+ root.statusText.text = ""
}
}
}
@@ -179,7 +182,7 @@ Item {
}
onEditingFinished: {
if (distInput.text == "") {
- statustext.text = "Please fill in the distance"
+ root.statusText.text = "Please fill in the distance"
distInput.forceActiveFocus()
}
}
diff --git a/examples/quick/localstorage/localstorage/MyDelegate.qml b/examples/quick/localstorage/localstorage/MyDelegate.qml
index 63a83bfbae..e8575d4f7a 100644
--- a/examples/quick/localstorage/localstorage/MyDelegate.qml
+++ b/examples/quick/localstorage/localstorage/MyDelegate.qml
@@ -54,18 +54,27 @@ import QtQuick.Layouts 1.1
import "Database.js" as JS
Item {
+ id: delegate
+
width: parent.width
height: rDate.implicitHeight
+ required property int index
+ required property int distance
+ required property string trip_desc
+ required property string date
+
+ signal clicked()
+
Rectangle {
id: baseRec
anchors.fill: parent
opacity: 0.8
- color: index % 2 ? "lightgrey" : "grey"
+ color: delegate.index % 2 ? "lightgrey" : "grey"
MouseArea {
anchors.fill: parent
- onClicked: listView.currentIndex = index
+ onClicked: delegate.clicked()
}
GridLayout {
anchors.fill:parent
@@ -73,21 +82,21 @@ Item {
Text {
id: rDate
- text: date
+ text: delegate.date
font.pixelSize: 22
Layout.preferredWidth: parent.width / 4
color: "black"
}
Text {
id: rDesc
- text: trip_desc
+ text: delegate.trip_desc
Layout.fillWidth: true
font.pixelSize: 22
color: "black"
}
Text {
id: rDistance
- text: distance
+ text: delegate.distance
font.pixelSize: 22
Layout.alignment: Qt.AlignRight
color: "black"
diff --git a/examples/quick/localstorage/localstorage/localstorage.qml b/examples/quick/localstorage/localstorage/localstorage.qml
index 41f5cbd561..418aab838e 100644
--- a/examples/quick/localstorage/localstorage/localstorage.qml
+++ b/examples/quick/localstorage/localstorage/localstorage.qml
@@ -55,6 +55,7 @@ import QtQuick.LocalStorage 2.0
import "Database.js" as JS
Window {
+ id: window
visible: true
width: Screen.width / 2
height: Screen.height / 1.8
@@ -72,19 +73,21 @@ Window {
Header {
id: input
Layout.fillWidth: true
+ listView: listView
+ statusText: statustext
}
RowLayout {
MyButton {
text: "New"
onClicked: {
input.initrec_new()
- creatingNewEntry = true
+ window.creatingNewEntry = true
listView.model.setProperty(listView.currentIndex, "id", 0)
}
}
MyButton {
id: saveButton
- enabled: (creatingNewEntry || editingEntry) && listView.currentIndex != -1
+ enabled: (window.creatingNewEntry || window.editingEntry) && listView.currentIndex != -1
text: "Save"
onClicked: {
var insertedRow = false;
@@ -109,8 +112,8 @@ Window {
if (insertedRow) {
input.initrec()
- creatingNewEntry = false
- editingEntry = false
+ window.creatingNewEntry = false
+ window.editingEntry = false
listView.forceLayout()
}
}
@@ -118,20 +121,20 @@ Window {
MyButton {
id: editButton
text: "Edit"
- enabled: !creatingNewEntry && !editingEntry && listView.currentIndex != -1
+ enabled: !window.creatingNewEntry && !window.editingEntry && listView.currentIndex != -1
onClicked: {
input.editrec(listView.model.get(listView.currentIndex).date,
listView.model.get(listView.currentIndex).trip_desc,
listView.model.get(listView.currentIndex).distance,
listView.model.get(listView.currentIndex).id)
- editingEntry = true
+ window.editingEntry = true
}
}
MyButton {
id: deleteButton
text: "Delete"
- enabled: !creatingNewEntry && listView.currentIndex != -1
+ enabled: !window.creatingNewEntry && listView.currentIndex != -1
onClicked: {
JS.dbDeleteRow(listView.model.get(listView.currentIndex).id)
listView.model.remove(listView.currentIndex, 1)
@@ -145,7 +148,7 @@ Window {
MyButton {
id: cancelButton
text: "Cancel"
- enabled: (creatingNewEntry || editingEntry) && listView.currentIndex != -1
+ enabled: (window.creatingNewEntry || window.editingEntry) && listView.currentIndex != -1
onClicked: {
if (listView.model.get(listView.currentIndex).id === 0) {
// This entry had an id of 0, which means it was being created and hadn't
@@ -153,8 +156,8 @@ Window {
listView.model.remove(listView.currentIndex, 1)
}
listView.forceLayout()
- creatingNewEntry = false
- editingEntry = false
+ window.creatingNewEntry = false
+ window.editingEntry = false
input.initrec()
}
}
@@ -176,9 +179,11 @@ Window {
Layout.fillWidth: true
Layout.fillHeight: true
model: MyModel {}
- delegate: MyDelegate {}
+ delegate: MyDelegate {
+ onClicked: listView.currentIndex = index
+ }
// Don't allow changing the currentIndex while the user is creating/editing values.
- enabled: !creatingNewEntry && !editingEntry
+ enabled: !window.creatingNewEntry && !window.editingEntry
highlight: highlightBar
highlightFollowsCurrentItem: true
diff --git a/examples/quick/models/abstractitemmodel/main.cpp b/examples/quick/models/abstractitemmodel/main.cpp
index 515f47ec30..dd5b368c6b 100644
--- a/examples/quick/models/abstractitemmodel/main.cpp
+++ b/examples/quick/models/abstractitemmodel/main.cpp
@@ -68,10 +68,8 @@ int main(int argc, char ** argv)
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
- QQmlContext *ctxt = view.rootContext();
- ctxt->setContextProperty("myModel", &model);
+ view.setInitialProperties({{"model", QVariant::fromValue(&model)}});
//![0]
-
view.setSource(QUrl("qrc:view.qml"));
view.show();
diff --git a/examples/quick/models/abstractitemmodel/view.qml b/examples/quick/models/abstractitemmodel/view.qml
index f699aa40c8..2b9f87df92 100644
--- a/examples/quick/models/abstractitemmodel/view.qml
+++ b/examples/quick/models/abstractitemmodel/view.qml
@@ -53,8 +53,14 @@ import QtQuick 2.0
ListView {
width: 200; height: 250
- model: myModel
- delegate: Text { text: "Animal: " + type + ", " + size }
+ required model
+
+ delegate: Text {
+ required property string type
+ required property string size
+
+ text: "Animal: " + type + ", " + size
+ }
}
//![0]
diff --git a/examples/quick/models/objectlistmodel/main.cpp b/examples/quick/models/objectlistmodel/main.cpp
index 977bbfb93b..8fbe7c183c 100644
--- a/examples/quick/models/objectlistmodel/main.cpp
+++ b/examples/quick/models/objectlistmodel/main.cpp
@@ -68,16 +68,16 @@ int main(int argc, char ** argv)
{
QGuiApplication app(argc, argv);
- QList<QObject*> dataList;
- dataList.append(new DataObject("Item 1", "red"));
- dataList.append(new DataObject("Item 2", "green"));
- dataList.append(new DataObject("Item 3", "blue"));
- dataList.append(new DataObject("Item 4", "yellow"));
+ QList<QObject *> dataList = {
+ new DataObject("Item 1", "red"),
+ new DataObject("Item 2", "green"),
+ new DataObject("Item 3", "blue"),
+ new DataObject("Item 4", "yellow")
+ };
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
- QQmlContext *ctxt = view.rootContext();
- ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
+ view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }});
//![0]
view.setSource(QUrl("qrc:view.qml"));
diff --git a/examples/quick/models/objectlistmodel/view.qml b/examples/quick/models/objectlistmodel/view.qml
index d9a32aff14..ba0c905e1e 100644
--- a/examples/quick/models/objectlistmodel/view.qml
+++ b/examples/quick/models/objectlistmodel/view.qml
@@ -53,13 +53,15 @@ import QtQuick 2.0
//![0]
ListView {
width: 100; height: 100
+ required model
- model: myModel
delegate: Rectangle {
+ required color
+ required property string name
+
height: 25
width: 100
- color: model.modelData.color
- Text { text: name }
+ Text { text: parent.name }
}
}
//![0]
diff --git a/examples/quick/models/stringlistmodel/main.cpp b/examples/quick/models/stringlistmodel/main.cpp
index 6b4db422a6..d9de69b3aa 100644
--- a/examples/quick/models/stringlistmodel/main.cpp
+++ b/examples/quick/models/stringlistmodel/main.cpp
@@ -68,15 +68,15 @@ int main(int argc, char ** argv)
QGuiApplication app(argc, argv);
//![0]
- QStringList dataList;
- dataList.append("Item 1");
- dataList.append("Item 2");
- dataList.append("Item 3");
- dataList.append("Item 4");
+ QStringList dataList = {
+ "Item 1",
+ "Item 2",
+ "Item 3",
+ "Item 4"
+ };
QQuickView view;
- QQmlContext *ctxt = view.rootContext();
- ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
+ view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }});
//![0]
view.setSource(QUrl("qrc:view.qml"));
diff --git a/examples/quick/models/stringlistmodel/view.qml b/examples/quick/models/stringlistmodel/view.qml
index f74b7db1c1..e392284d0f 100644
--- a/examples/quick/models/stringlistmodel/view.qml
+++ b/examples/quick/models/stringlistmodel/view.qml
@@ -52,13 +52,15 @@ import QtQuick 2.0
//![0]
ListView {
- width: 100; height: 100
+ width: 100
+ height: 100
+ required model
- model: myModel
delegate: Rectangle {
+ required property string modelData
height: 25
width: 100
- Text { text: modelData }
+ Text { text: parent.modelData }
}
}
//![0]
diff --git a/examples/quick/mousearea/mousearea-wheel-example.qml b/examples/quick/mousearea/mousearea-wheel-example.qml
index 44b9216285..5e8fba3ac3 100644
--- a/examples/quick/mousearea/mousearea-wheel-example.qml
+++ b/examples/quick/mousearea/mousearea-wheel-example.qml
@@ -63,6 +63,8 @@ Rectangle {
model: ["#9ACD32", "#EEEEEE", "#FFD700", "#87CEEB"]
Rectangle {
+ required property color modelData
+
property real scaleFactor: 1
height: 40 * scaleFactor
diff --git a/examples/quick/mousearea/mousearea.qml b/examples/quick/mousearea/mousearea.qml
index 1540d85fdd..cecbc2cfc8 100644
--- a/examples/quick/mousearea/mousearea.qml
+++ b/examples/quick/mousearea/mousearea.qml
@@ -76,7 +76,7 @@ Rectangle {
onEntered: info.text = 'Entered'
onExited: info.text = 'Exited (pressed=' + pressed + ')'
- onPressed: {
+ onPressed: (mouse) => {
if (mouse.button == Qt.LeftButton)
buttonID = 'LeftButton'
else if (mouse.button == Qt.RightButton)
@@ -139,14 +139,14 @@ Rectangle {
+ ' (' + posInBox.x + ',' + posInBox.y + ' in window)'
}
- onReleased: {
+ onReleased: (mouse) => {
btn.text = 'Released (isClick=' + mouse.isClick + ' wasHeld=' + mouse.wasHeld + ')'
posInfo.text = ''
}
//! [clicks]
onPressAndHold: btn.text = 'Press and hold'
- onClicked: btn.text = 'Clicked (wasHeld=' + mouse.wasHeld + ')'
+ onClicked: (mouse) => { btn.text = 'Clicked (wasHeld=' + mouse.wasHeld + ')' }
onDoubleClicked: btn.text = 'Double clicked'
//! [clicks]
}
diff --git a/examples/quick/particles/affectors/content/customaffector.qml b/examples/quick/particles/affectors/content/customaffector.qml
index 71646bcf39..6fabfb3ab2 100644
--- a/examples/quick/particles/affectors/content/customaffector.qml
+++ b/examples/quick/particles/affectors/content/customaffector.qml
@@ -81,7 +81,7 @@ Item {
property real velocity: 1.5
width: parent.width
height: parent.height - 100
- onAffectParticles: {
+ onAffectParticles: (particles, dt) => {
/* //Linear movement
if (particle.r == 0) {
particle.r = Math.random() > 0.5 ? -1 : 1;
@@ -117,7 +117,7 @@ Item {
width: parent.width + 120
height: 100
anchors.bottom: parent.bottom
- onAffectParticles: {
+ onAffectParticles: (particles, dt) => {
for (var i=0; i<particles.length; i++) {
var particle = particles[i];
var pseudoRand = (Math.floor(particle.t*1327) % 10) + 1;
diff --git a/examples/quick/particles/affectors/content/groupgoal.qml b/examples/quick/particles/affectors/content/groupgoal.qml
index 6472a3b450..9910531a98 100644
--- a/examples/quick/particles/affectors/content/groupgoal.qml
+++ b/examples/quick/particles/affectors/content/groupgoal.qml
@@ -62,7 +62,7 @@ Rectangle {
Text {
color: "white"
anchors.right: parent.right
- text: score
+ text: root.score
}
ParticleSystem {
@@ -96,7 +96,7 @@ Rectangle {
ParticleGroup {
name: "lit"
duration: 10000
- onEntered: score++;
+ onEntered: root.score++
TrailEmitter {
id: fireballFlame
group: "flame"
diff --git a/examples/quick/particles/emitters/content/burstandpulse.qml b/examples/quick/particles/emitters/content/burstandpulse.qml
index 8bd19ed8ed..d3c38c2360 100644
--- a/examples/quick/particles/emitters/content/burstandpulse.qml
+++ b/examples/quick/particles/emitters/content/burstandpulse.qml
@@ -52,6 +52,8 @@ import QtQuick 2.0
import QtQuick.Particles 2.0
Rectangle {
+ id: root
+
width: 320
height: 480
color: "black"
@@ -63,12 +65,12 @@ Rectangle {
repeat: true
onTriggered: {
//! [0]
- if (lastWasPulse) {
+ if (root.lastWasPulse) {
burstEmitter.burst(500);
- lastWasPulse = false;
+ root.lastWasPulse = false;
} else {
pulseEmitter.pulse(500);
- lastWasPulse = true;
+ root.lastWasPulse = true;
}
//! [0]
}
diff --git a/examples/quick/particles/emitters/content/customemitter.qml b/examples/quick/particles/emitters/content/customemitter.qml
index aa8ca6b2f9..f6aea13d08 100644
--- a/examples/quick/particles/emitters/content/customemitter.qml
+++ b/examples/quick/particles/emitters/content/customemitter.qml
@@ -79,7 +79,7 @@ ParticleSystem {
size: 12
anchors.centerIn: parent
//! [0]
- onEmitParticles: {
+ onEmitParticles: (particles) => {
for (var i=0; i<particles.length; i++) {
var particle = particles[i];
particle.startSize = Math.max(02,Math.min(492,Math.tan(particle.t/2)*24));
@@ -90,8 +90,8 @@ ParticleSystem {
theta /= 6.0;
theta *= 2.0*Math.PI;
theta += sys.convert(sys.petalRotation);//Convert from degrees to radians
- particle.initialVX = petalLength * Math.cos(theta);
- particle.initialVY = petalLength * Math.sin(theta);
+ particle.initialVX = sys.petalLength * Math.cos(theta);
+ particle.initialVY = sys.petalLength * Math.sin(theta);
particle.initialAX = particle.initialVX * -0.5;
particle.initialAY = particle.initialVY * -0.5;
}
diff --git a/examples/quick/particles/imageparticle/content/sharing.qml b/examples/quick/particles/imageparticle/content/sharing.qml
index 1018a8e8ba..13b0dadf85 100644
--- a/examples/quick/particles/imageparticle/content/sharing.qml
+++ b/examples/quick/particles/imageparticle/content/sharing.qml
@@ -56,6 +56,8 @@ import QtQuick 2.0
import QtQuick.Particles 2.0
Rectangle {
+ id: root
+
property real delegateHeight: 65
width: 200; height: 300
gradient: Gradient {
@@ -65,53 +67,53 @@ Rectangle {
// Define a delegate component. A component will be
// instantiated for each visible item in the list.
- Component {
- id: petDelegate
- Item {
- id: wrapper
- width: 200; height: delegateHeight
- z: 10
- Column {
- Text {color: "white"; text: name; font.pixelSize: 18 }
- Text {color: "white"; text: 'Type: ' + type; font.pixelSize: 14 }
- Text {color: "white"; text: 'Age: ' + age; font.pixelSize: 14 }
- }
- MouseArea { anchors.fill: parent; onClicked: listView.currentIndex = index; }
- // indent the item if it is the current item
- states: State {
- name: "Current"
- when: wrapper.ListView.isCurrentItem
- PropertyChanges { target: wrapper; x: 20 }
- }
- transitions: Transition {
- NumberAnimation { properties: "x"; duration: 200 }
- }
+ component PetDelegate: Item {
+ id: pet
+ width: 200; height: root.delegateHeight
+ z: 10
+
+ required property int index
+ required property string name
+ required property string type
+ required property int age
+
+ Column {
+ Text {color: "white"; text: pet.name; font.pixelSize: 18 }
+ Text {color: "white"; text: 'Type: ' + pet.type; font.pixelSize: 14 }
+ Text {color: "white"; text: 'Age: ' + pet.age; font.pixelSize: 14 }
+ }
+ MouseArea { anchors.fill: parent; onClicked: listView.currentIndex = pet.index; }
+ // indent the item if it is the current item
+ states: State {
+ name: "Current"
+ when: pet.ListView.isCurrentItem
+ PropertyChanges { target: pet; x: 20 }
+ }
+ transitions: Transition {
+ NumberAnimation { properties: "x"; duration: 200 }
}
}
// Define a highlight with customized movement between items.
- Component {
- id: highlightBar
- Rectangle {
- z: 0
- width: 200; height: delegateHeight
- gradient: Gradient {
- GradientStop { position: 0.0; color: "#99FF99" }
- GradientStop { position: 1.0; color: "#88FF88" }
- }
- y: listView.currentItem.y;
- Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
- //! [1]
- ImageParticle {
- anchors.fill: parent
- system: particles
- source: "../../images/flower.png"
- color: "red"
- clip: true
- alpha: 1.0
- }
- //! [1]
+ component HighlightBar : Rectangle {
+ z: 0
+ width: 200; height: root.delegateHeight
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "#99FF99" }
+ GradientStop { position: 1.0; color: "#88FF88" }
+ }
+ y: listView.currentItem.y;
+ Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
+ //! [1]
+ ImageParticle {
+ anchors.fill: parent
+ system: particles
+ source: "../../images/flower.png"
+ color: "red"
+ clip: true
+ alpha: 1.0
}
+ //! [1]
}
ListView {
@@ -119,12 +121,12 @@ Rectangle {
width: 200; height: parent.height
model: petsModel
- delegate: petDelegate
+ delegate: PetDelegate {}
focus: true
// Set the highlight delegate. Note we must also set highlightFollowsCurrentItem
// to false so the highlight delegate can control how the highlight is moved.
- highlight: highlightBar
+ highlight: HighlightBar {}
highlightFollowsCurrentItem: false
ParticleSystem { id: particles }
diff --git a/examples/quick/particles/itemparticle/particleview.qml b/examples/quick/particles/itemparticle/particleview.qml
index 3b412e37e5..8eb18dc283 100644
--- a/examples/quick/particles/itemparticle/particleview.qml
+++ b/examples/quick/particles/itemparticle/particleview.qml
@@ -156,7 +156,7 @@ Item {
interval: 800
onTriggered: {
force.enabled = false;
- mp.take(alertItem, true);
+ mp.take(root.alertItem, true);
centerEmitter.burst(1);
}
}
@@ -216,6 +216,11 @@ Item {
Component {
id: theDelegate
Image {
+ required property int index
+ required property string title
+ required property string media
+ required property string thumbnail
+
id: image
antialiasing: true;
source: thumbnail
@@ -237,7 +242,7 @@ Item {
width: parent.paintedWidth + 1
height: parent.paintedHeight + 1
color: "black"
- opacity: darken * (1 - depth)
+ opacity: image.darken * (1 - image.depth)
antialiasing: true;
}
Text {
@@ -247,7 +252,7 @@ Item {
width: parent.paintedWidth - 4
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
- text: title
+ text: image.title
color: "black"
}
ItemParticle.onDetached: mp.take(image); // respawns
@@ -277,7 +282,7 @@ Item {
}
PropertyChanges {
target: image
- source: media
+ source: image.media
x: 0
y: 0
width: root.width
diff --git a/examples/quick/positioners/positioners-transitions.qml b/examples/quick/positioners/positioners-transitions.qml
index fbaa05c81c..d4f3772c4e 100644
--- a/examples/quick/positioners/positioners-transitions.qml
+++ b/examples/quick/positioners/positioners-transitions.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+import QtQml 2.0
import QtQuick 2.0
Item {
@@ -215,9 +216,9 @@ Item {
opacity: page.effectiveOpacity
}
- Rectangle { color: "#80c342"; width:page. smallSize; height: page.smallSize }
- Rectangle { color: "#14aaff"; width: smallSize; height: page.smallSize }
- Rectangle { color: "#6400aa"; width: page.page.smallSize; height: page.smallSize }
+ Rectangle { color: "#80c342"; width: page.smallSize; height: page.smallSize }
+ Rectangle { color: "#14aaff"; width: page.smallSize; height: page.smallSize }
+ Rectangle { color: "#6400aa"; width: page.smallSize; height: page.smallSize }
}
Flow {
diff --git a/examples/quick/quick-accessibility/content/Slider.qml b/examples/quick/quick-accessibility/content/Slider.qml
index aa425797a7..241e5d804e 100644
--- a/examples/quick/quick-accessibility/content/Slider.qml
+++ b/examples/quick/quick-accessibility/content/Slider.qml
@@ -72,7 +72,7 @@ Rectangle {
x: 1
y: 1
height: parent.height - 2
- width: ((parent.width - 2) / maximumValue) * value
+ width: ((parent.width - 2) / slider.maximumValue) * slider.value
color: "lightgrey"
Behavior on width {
NumberAnimation { duration: 50 }
@@ -88,8 +88,9 @@ Rectangle {
MouseArea {
anchors.fill: parent
- onClicked: {
- var pos = mouse.x / slider.width * (maximumValue - minimumValue) + minimumValue
+ onClicked: (mouse) => {
+ var pos = mouse.x / slider.width * (slider.maximumValue - slider.minimumValue)
+ + slider.minimumValue
slider.value = pos
}
}
diff --git a/examples/quick/righttoleft/layoutdirection/layoutdirection.qml b/examples/quick/righttoleft/layoutdirection/layoutdirection.qml
index 4e3e93852c..de111ea025 100644
--- a/examples/quick/righttoleft/layoutdirection/layoutdirection.qml
+++ b/examples/quick/righttoleft/layoutdirection/layoutdirection.qml
@@ -84,8 +84,8 @@ Rectangle {
Repeater {
model: 3
Loader {
- property int value: index
- sourceComponent: positionerDelegate
+ required property int index
+ sourceComponent: PositionerDelegate {}
}
}
}
@@ -106,8 +106,8 @@ Rectangle {
Repeater {
model: 8
Loader {
- property int value: index
- sourceComponent: positionerDelegate
+ required property int index
+ sourceComponent: PositionerDelegate {}
}
}
}
@@ -128,8 +128,8 @@ Rectangle {
Repeater {
model: 8
Loader {
- property int value: index
- sourceComponent: positionerDelegate
+ required property int index
+ sourceComponent: PositionerDelegate {}
}
}
}
@@ -152,7 +152,7 @@ Rectangle {
layoutDirection: root.direction
orientation: Qt.Horizontal
model: 48
- delegate: viewDelegate
+ delegate: ViewDelegate {}
}
Text {
@@ -166,7 +166,7 @@ Rectangle {
cellWidth: 50; cellHeight: 50
layoutDirection: root.direction
model: 48
- delegate: viewDelegate
+ delegate: ViewDelegate {}
}
Rectangle {
@@ -230,37 +230,36 @@ Rectangle {
}
}
- Component {
- id: positionerDelegate
+ component PositionerDelegate : Rectangle {
+ width: 40
+ height: 40
+ property int lightness: parent.index + 1;
+ color: Qt.rgba(0.8 / lightness, 0.8 / lightness, 0.8 / lightness, 1.0)
+ Text {
+ text: parent.lightness
+ color: "white"
+ font.pixelSize: 18
+ anchors.centerIn: parent
+ }
+ }
+
+ component ViewDelegate : Item {
+ id: delegateItem
+ required property int index
+ width: (listView.effectiveLayoutDirection == Qt.LeftToRight ? (index == 48 - 1) : (index == 0)) ? 40 : 50
Rectangle {
width: 40; height: 40
- color: Qt.rgba(0.8/(parent.value+1),0.8/(parent.value+1),0.8/(parent.value+1),1.0)
+ color: Qt.rgba(0.5 + (48 - delegateItem.index) * Math.random() / 48,
+ 0.3 + delegateItem.index * Math.random() / 48,
+ 0.3 * Math.random(),
+ 1.0)
Text {
- text: parent.parent.value+1
+ text: delegateItem.index + 1
color: "white"
font.pixelSize: 18
anchors.centerIn: parent
}
}
}
- Component {
- id: viewDelegate
- Item {
- width: (listView.effectiveLayoutDirection == Qt.LeftToRight ? (index == 48 - 1) : (index == 0)) ? 40 : 50
- Rectangle {
- width: 40; height: 40
- color: Qt.rgba(0.5+(48 - index)*Math.random()/48,
- 0.3+index*Math.random()/48,
- 0.3*Math.random(),
- 1.0)
- Text {
- text: index+1
- color: "white"
- font.pixelSize: 18
- anchors.centerIn: parent
- }
- }
- }
- }
}
diff --git a/examples/quick/righttoleft/textalignment/textalignment.qml b/examples/quick/righttoleft/textalignment/textalignment.qml
index c5790027f2..698917a3c0 100644
--- a/examples/quick/righttoleft/textalignment/textalignment.qml
+++ b/examples/quick/righttoleft/textalignment/textalignment.qml
@@ -93,18 +93,23 @@ Rectangle {
width: 320
height: 320
id: editorTypeRow
- model: editorType.length
+ model: root.editorType.length
orientation: ListView.Horizontal
cacheBuffer: 1000//Load the really expensive ones async if possible
delegate: Item {
+ id: delegate
+
width: editorColumn.width
height: editorColumn.height
+
+ required property int index
+
Column {
id: editorColumn
spacing: 5
width: textColumn.width+10
Text {
- text: root.editorType[index]
+ text: root.editorType[delegate.index]
font.pixelSize: 16
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -113,8 +118,8 @@ Rectangle {
spacing: 5
anchors.horizontalCenter: parent.horizontalCenter
Repeater {
- model: textComponents.length
- delegate: textComponents[index]
+ model: root.textComponents.length
+ delegate: root.textComponents[delegate.index]
}
}
}
@@ -203,9 +208,11 @@ Rectangle {
Component {
id: plainTextComponent
Text {
+ required property int index
+
width: 180
text: root.text[index]
- font.pixelSize: pxSz
+ font.pixelSize: root.pxSz
wrapMode: Text.WordWrap
horizontalAlignment: root.horizontalAlignment
LayoutMirroring.enabled: root.mirror
@@ -216,10 +223,10 @@ Rectangle {
anchors.fill: parent
}
Text {
- text: root.description[index]
+ text: root.description[parent.index]
color: Qt.rgba(1,1,1,1.0)
anchors.centerIn: parent
- font.pixelSize: pxSz - 2
+ font.pixelSize: root.pxSz - 2
Rectangle {
z: -1
color: Qt.rgba(0.3, 0, 0, 0.3)
@@ -228,7 +235,7 @@ Rectangle {
}
Text {
color: "white"
- text: shortText(parent.horizontalAlignment)
+ text: root.shortText(parent.horizontalAlignment)
anchors { top: parent.top; right: parent.right; margins: 2 }
}
}
@@ -237,9 +244,11 @@ Rectangle {
Component {
id: styledTextComponent
Text {
+ required property int index
+
width: 180
text: root.text[index]
- font.pixelSize: pxSz
+ font.pixelSize: root.pxSz
wrapMode: Text.WordWrap
horizontalAlignment: root.horizontalAlignment
LayoutMirroring.enabled: root.mirror
@@ -252,10 +261,10 @@ Rectangle {
anchors.fill: parent
}
Text {
- text: root.description[index]
+ text: root.description[parent.index]
color: Qt.rgba(1,1,1,1.0)
anchors.centerIn: parent
- font.pixelSize: pxSz - 2
+ font.pixelSize: root.pxSz - 2
Rectangle {
z: -1
color: Qt.rgba(0.3, 0, 0, 0.3)
@@ -264,7 +273,7 @@ Rectangle {
}
Text {
color: "white"
- text: shortText(parent.horizontalAlignment)
+ text: root.shortText(parent.horizontalAlignment)
anchors { top: parent.top; right: parent.right; margins: 2 }
}
}
@@ -273,9 +282,11 @@ Rectangle {
Component {
id: richTextComponent
Text {
+ required property int index
+
width: 180
text: root.text[index]
- font.pixelSize: pxSz
+ font.pixelSize: root.pxSz
wrapMode: Text.WordWrap
horizontalAlignment: root.horizontalAlignment
LayoutMirroring.enabled: root.mirror
@@ -286,10 +297,10 @@ Rectangle {
anchors.fill: parent
}
Text {
- text: root.description[index]
+ text: root.description[parent.index]
color: Qt.rgba(1,1,1,1.0)
anchors.centerIn: parent
- font.pixelSize: pxSz - 2
+ font.pixelSize: root.pxSz - 2
Rectangle {
z: -1
color: Qt.rgba(0.3, 0, 0, 0.3)
@@ -298,7 +309,7 @@ Rectangle {
}
Text {
color: "white"
- text: shortText(parent.horizontalAlignment)
+ text: root.shortText(parent.horizontalAlignment)
anchors { top: parent.top; right: parent.right; margins: 2 }
}
}
@@ -307,9 +318,11 @@ Rectangle {
Component {
id: italicRichTextComponent
Text {
+ required property int index
+
width: 180
text: "<i>" + root.text[index] + "</i>"
- font.pixelSize: pxSz
+ font.pixelSize: root.pxSz
wrapMode: Text.WordWrap
horizontalAlignment: root.horizontalAlignment
LayoutMirroring.enabled: root.mirror
@@ -321,10 +334,10 @@ Rectangle {
anchors.fill: parent
}
Text {
- text: root.description[index]
+ text: root.description[parent.index]
color: Qt.rgba(1,1,1,1.0)
anchors.centerIn: parent
- font.pixelSize: pxSz - 2
+ font.pixelSize: root.pxSz - 2
Rectangle {
z: -1
color: Qt.rgba(0.3, 0, 0, 0.3)
@@ -333,7 +346,7 @@ Rectangle {
}
Text {
color: "white"
- text: shortText(parent.horizontalAlignment)
+ text: root.shortText(parent.horizontalAlignment)
anchors { top: parent.top; right: parent.right; margins: 2 }
}
}
@@ -342,9 +355,11 @@ Rectangle {
Component {
id: plainTextEdit
TextEdit {
+ required property int index
+
width: 180
text: root.text[index]
- font.pixelSize: pxSz
+ font.pixelSize: root.pxSz
cursorVisible: true
wrapMode: TextEdit.WordWrap
horizontalAlignment: root.horizontalAlignment
@@ -355,10 +370,10 @@ Rectangle {
anchors.fill: parent
}
Text {
- text: root.description[index]
+ text: root.description[parent.index]
color: Qt.rgba(1,1,1,1.0)
anchors.centerIn: parent
- font.pixelSize: pxSz - 2
+ font.pixelSize: root.pxSz - 2
Rectangle {
z: -1
color: Qt.rgba(0.3, 0, 0, 0.3)
@@ -367,7 +382,7 @@ Rectangle {
}
Text {
color: "white"
- text: shortText(parent.horizontalAlignment)
+ text: root.shortText(parent.horizontalAlignment)
anchors { top: parent.top; right: parent.right; margins: 2 }
}
}
@@ -376,9 +391,11 @@ Rectangle {
Component {
id: italicTextEdit
TextEdit {
+ required property int index
+
width: 180
text: "<i>" + root.text[index] + "<i>"
- font.pixelSize: pxSz
+ font.pixelSize: root.pxSz
cursorVisible: true
wrapMode: TextEdit.WordWrap
textFormat: TextEdit.RichText
@@ -390,10 +407,10 @@ Rectangle {
anchors.fill: parent
}
Text {
- text: root.description[index]
+ text: root.description[parent.index]
color: Qt.rgba(1,1,1,1.0)
anchors.centerIn: parent
- font.pixelSize: pxSz - 2
+ font.pixelSize: root.pxSz - 2
Rectangle {
z: -1
color: Qt.rgba(0.3, 0, 0, 0.3)
@@ -402,7 +419,7 @@ Rectangle {
}
Text {
color: "white"
- text: shortText(parent.horizontalAlignment)
+ text: root.shortText(parent.horizontalAlignment)
anchors { top: parent.top; right: parent.right; margins: 2 }
}
}
@@ -411,13 +428,15 @@ Rectangle {
Component {
id: textInput
Item {
+ id: textDelegate
+ required property int index
width: 180
height: textInput.text.length > 20 ? 3*textInput.height : textInput.height
TextInput {
id: textInput
width: 180
- text: root.text[index]
- font.pixelSize: pxSz
+ text: root.text[textDelegate.index]
+ font.pixelSize: root.pxSz
cursorVisible: true
horizontalAlignment: root.horizontalAlignment
LayoutMirroring.enabled: root.mirror
@@ -427,10 +446,10 @@ Rectangle {
anchors.fill: parent
}
Text {
- text: root.description[index]
+ text: root.description[textDelegate.index]
color: Qt.rgba(1,1,1,1.0)
anchors.centerIn: parent
- font.pixelSize: pxSz - 2
+ font.pixelSize: root.pxSz - 2
Rectangle {
z: -1
color: Qt.rgba(0.3, 0, 0, 0.3)
@@ -439,7 +458,7 @@ Rectangle {
}
Text {
color: "white"
- text: shortText(parent.horizontalAlignment)
+ text: root.shortText(parent.horizontalAlignment)
anchors { top: parent.top; right: parent.right; margins: 2 }
}
}
diff --git a/examples/quick/scenegraph/metaltextureimport/main.cpp b/examples/quick/scenegraph/metaltextureimport/main.cpp
index c969817e8f..4fc010e710 100644
--- a/examples/quick/scenegraph/metaltextureimport/main.cpp
+++ b/examples/quick/scenegraph/metaltextureimport/main.cpp
@@ -50,14 +50,10 @@
#include <QGuiApplication>
#include <QtQuick/QQuickView>
-#include "metaltextureimport.h"
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
-
- qmlRegisterType<CustomTextureItem>("MetalTextureImport", 1, 0, "CustomTextureItem");
-
QQuickWindow::setSceneGraphBackend(QSGRendererInterface::MetalRhi);
QQuickView view;
diff --git a/examples/quick/scenegraph/metaltextureimport/metaltextureimport.h b/examples/quick/scenegraph/metaltextureimport/metaltextureimport.h
index afc5aced97..49a29565a7 100644
--- a/examples/quick/scenegraph/metaltextureimport/metaltextureimport.h
+++ b/examples/quick/scenegraph/metaltextureimport/metaltextureimport.h
@@ -60,6 +60,7 @@ class CustomTextureItem : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
+ QML_ELEMENT
public:
CustomTextureItem();
diff --git a/examples/quick/scenegraph/metaltextureimport/metaltextureimport.pro b/examples/quick/scenegraph/metaltextureimport/metaltextureimport.pro
index bbdfd358d3..9e88c50dc6 100644
--- a/examples/quick/scenegraph/metaltextureimport/metaltextureimport.pro
+++ b/examples/quick/scenegraph/metaltextureimport/metaltextureimport.pro
@@ -1,6 +1,9 @@
!macos:!ios: error("This example requires macOS or iOS")
QT += qml quick
+CONFIG += qmltypes
+QML_IMPORT_NAME = MetalTextureImport
+QML_IMPORT_MAJOR_VERSION = 1
HEADERS += metaltextureimport.h
SOURCES += metaltextureimport.mm main.cpp
diff --git a/examples/quick/scenegraph/rendernode/main.qml b/examples/quick/scenegraph/rendernode/main.qml
index 2c407796cf..a02fa128d5 100644
--- a/examples/quick/scenegraph/rendernode/main.qml
+++ b/examples/quick/scenegraph/rendernode/main.qml
@@ -66,7 +66,7 @@ Item {
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
- onClicked: {
+ onClicked: (mouse) => {
if (mouse.button === Qt.LeftButton) {
clipper.clip = !clipper.clip
} else if (mouse.button === Qt.RightButton) {
diff --git a/examples/quick/scenegraph/vulkantextureimport/main.cpp b/examples/quick/scenegraph/vulkantextureimport/main.cpp
index 1c42e87043..5dc28eb8a3 100644
--- a/examples/quick/scenegraph/vulkantextureimport/main.cpp
+++ b/examples/quick/scenegraph/vulkantextureimport/main.cpp
@@ -50,14 +50,11 @@
#include <QGuiApplication>
#include <QtQuick/QQuickView>
-#include "vulkantextureimport.h"
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
- qmlRegisterType<CustomTextureItem>("VulkanTextureImport", 1, 0, "CustomTextureItem");
-
QQuickWindow::setSceneGraphBackend(QSGRendererInterface::VulkanRhi);
QQuickView view;
diff --git a/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.h b/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.h
index f604faf66f..b8c13b44f6 100644
--- a/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.h
+++ b/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.h
@@ -60,6 +60,7 @@ class CustomTextureItem : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
+ QML_ELEMENT
public:
CustomTextureItem();
diff --git a/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.pro b/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.pro
index f2f78a6ed3..11e422ecad 100644
--- a/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.pro
+++ b/examples/quick/scenegraph/vulkantextureimport/vulkantextureimport.pro
@@ -1,12 +1,13 @@
!qtConfig(vulkan): error("This example requires Qt built with Vulkan support")
QT += qml quick
+CONFIG += qmltypes
+QML_IMPORT_NAME = VulkanTextureImport
+QML_IMPORT_MAJOR_VERSION = 1
HEADERS += vulkantextureimport.h
SOURCES += vulkantextureimport.cpp main.cpp
RESOURCES += vulkantextureimport.qrc
-
-
target.path = $$[QT_INSTALL_EXAMPLES]/quick/scenegraph/vulkantextureimport
INSTALLS += target
diff --git a/examples/quick/scenegraph/vulkanunderqml/main.cpp b/examples/quick/scenegraph/vulkanunderqml/main.cpp
index a04497b1d6..6ed0efacdd 100644
--- a/examples/quick/scenegraph/vulkanunderqml/main.cpp
+++ b/examples/quick/scenegraph/vulkanunderqml/main.cpp
@@ -50,14 +50,11 @@
#include <QGuiApplication>
#include <QtQuick/QQuickView>
-#include "vulkansquircle.h"
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
- qmlRegisterType<VulkanSquircle>("VulkanUnderQML", 1, 0, "VulkanSquircle");
-
// This example needs Vulkan. It will not run otherwise.
QQuickWindow::setSceneGraphBackend(QSGRendererInterface::VulkanRhi);
diff --git a/examples/quick/scenegraph/vulkanunderqml/vulkansquircle.h b/examples/quick/scenegraph/vulkanunderqml/vulkansquircle.h
index 7e65d01a15..16feeacb5b 100644
--- a/examples/quick/scenegraph/vulkanunderqml/vulkansquircle.h
+++ b/examples/quick/scenegraph/vulkanunderqml/vulkansquircle.h
@@ -59,6 +59,7 @@ class VulkanSquircle : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
+ QML_ELEMENT
public:
VulkanSquircle();
diff --git a/examples/quick/scenegraph/vulkanunderqml/vulkanunderqml.pro b/examples/quick/scenegraph/vulkanunderqml/vulkanunderqml.pro
index 9ea57b91c3..8f7ea5861d 100644
--- a/examples/quick/scenegraph/vulkanunderqml/vulkanunderqml.pro
+++ b/examples/quick/scenegraph/vulkanunderqml/vulkanunderqml.pro
@@ -1,6 +1,9 @@
!qtConfig(vulkan): error("This example requires Qt built with Vulkan support")
QT += qml quick
+CONFIG += qmltypes
+QML_IMPORT_NAME = VulkanUnderQML
+QML_IMPORT_MAJOR_VERSION = 1
HEADERS += vulkansquircle.h
SOURCES += vulkansquircle.cpp main.cpp
diff --git a/examples/quick/shared/FlickrRssModel.qml b/examples/quick/shared/FlickrRssModel.qml
index 5f88fabcae..2fb4412ba1 100644
--- a/examples/quick/shared/FlickrRssModel.qml
+++ b/examples/quick/shared/FlickrRssModel.qml
@@ -72,7 +72,7 @@ ListModel {
var jsonText = xhr.responseText;
var objArray = JSON.parse(jsonText.replace(/\'/g,"'"))
if (objArray.errors !== undefined)
- console.log(lCategory, "Error fetching tweets: " + imageItems.errors[0].message)
+ console.log("Error fetching tweets: " + objArray.errors[0].message)
else {
for (var key in objArray.items) {
var rssItem = objArray.items[key];
diff --git a/examples/quick/shared/LauncherList.qml b/examples/quick/shared/LauncherList.qml
index f6001cc681..cb13ec4372 100644
--- a/examples/quick/shared/LauncherList.qml
+++ b/examples/quick/shared/LauncherList.qml
@@ -48,6 +48,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+import QtQml 2.12
+import QtQml.Models 2.12
import QtQuick 2.12
Rectangle {
diff --git a/examples/quick/shared/SimpleLauncherDelegate.qml b/examples/quick/shared/SimpleLauncherDelegate.qml
index 097954cb89..11d34a187e 100644
--- a/examples/quick/shared/SimpleLauncherDelegate.qml
+++ b/examples/quick/shared/SimpleLauncherDelegate.qml
@@ -58,6 +58,9 @@ Rectangle {
width: ListView.view.width
height: button.implicitHeight + 22
+ required property string name
+ required property string description
+
signal clicked()
gradient: Gradient {
diff --git a/examples/quick/shared/TabSet.qml b/examples/quick/shared/TabSet.qml
index 9e2759c3ec..ab8476ad44 100644
--- a/examples/quick/shared/TabSet.qml
+++ b/examples/quick/shared/TabSet.qml
@@ -78,6 +78,7 @@ Item {
Repeater {
model: stack.children.length
delegate: Rectangle {
+ required property int index
width: tabWidget.width / stack.children.length
height: Math.max(Screen.pixelDensity * 7, label.implicitHeight * 1.2)
@@ -90,18 +91,18 @@ Item {
anchors { fill: parent; leftMargin: 2; topMargin: 5; rightMargin: 1 }
border { left: 7; right: 7 }
source: "images/tab.png"
- visible: tabWidget.current == index
+ visible: tabWidget.current == parent.index
}
Text {
id: label
horizontalAlignment: Qt.AlignHCenter; verticalAlignment: Qt.AlignVCenter
anchors.fill: parent
- text: stack.children[index].title
+ text: stack.children[parent.index].title
elide: Text.ElideRight
- font.bold: tabWidget.current == index
+ font.bold: tabWidget.current == parent.index
}
TapHandler {
- onTapped: tabWidget.current = index
+ onTapped: tabWidget.current = parent.index
}
}
}
diff --git a/examples/quick/tableview/gameoflife/main.qml b/examples/quick/tableview/gameoflife/main.qml
index 90be69b9c0..fb3195892f 100644
--- a/examples/quick/tableview/gameoflife/main.qml
+++ b/examples/quick/tableview/gameoflife/main.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+import QtQml 2.12
import QtQuick 2.12
import QtQuick.Window 2.3
import QtQuick.Controls 2.2
@@ -81,11 +82,14 @@ ApplicationWindow {
implicitWidth: 15
implicitHeight: 15
- color: model.value ? "#f3f3f4" : "#b5b7bf"
+ required property var model
+ required property bool value
+
+ color: value ? "#f3f3f4" : "#b5b7bf"
MouseArea {
anchors.fill: parent
- onClicked: model.value = !model.value
+ onClicked: parent.model.value = !parent.value
}
}
//! [tableview]
diff --git a/examples/quick/tableview/pixelator/main.qml b/examples/quick/tableview/pixelator/main.qml
index 38a25f439f..a5edefae90 100644
--- a/examples/quick/tableview/pixelator/main.qml
+++ b/examples/quick/tableview/pixelator/main.qml
@@ -65,7 +65,9 @@ Window {
id: pixelDelegate
Item {
- readonly property real gray: model.display / 255.0
+ required property real display
+
+ readonly property real gray: display / 255.0
readonly property real size: 16
implicitWidth: size
@@ -77,7 +79,7 @@ Window {
id: rect
anchors.centerIn: parent
color: "#09102b"
- radius: size - gray * size
+ radius: parent.size - parent.gray * parent.size
implicitWidth: radius
implicitHeight: radius
//! [rectshape]
diff --git a/examples/quick/text/fonts/availableFonts.qml b/examples/quick/text/fonts/availableFonts.qml
index ea3bff22b8..41dbae0021 100644
--- a/examples/quick/text/fonts/availableFonts.qml
+++ b/examples/quick/text/fonts/availableFonts.qml
@@ -61,11 +61,12 @@ Rectangle {
delegate: Item {
height: 40; width: ListView.view.width
+ required property string modelData
Text {
anchors.centerIn: parent
- text: modelData
+ text: parent.modelData
//! [delegate]
- font.family: modelData
+ font.family: parent.modelData
//! [delegate]
font.pixelSize: 20
color: "white"
diff --git a/examples/quick/text/fonts/fonts.qml b/examples/quick/text/fonts/fonts.qml
index f4e721b6c1..aeb17c48e2 100644
--- a/examples/quick/text/fonts/fonts.qml
+++ b/examples/quick/text/fonts/fonts.qml
@@ -51,6 +51,7 @@
import QtQuick 2.0
Rectangle {
+ id: root
property string myText: "The quick brown fox jumps over the lazy dog."
width: 320; height: 480
@@ -68,7 +69,7 @@ Rectangle {
spacing: 15
Text {
- text: myText
+ text: root.myText
color: "lightsteelblue"
width: parent.width
wrapMode: Text.WordWrap
@@ -78,7 +79,7 @@ Rectangle {
font.pixelSize: 20
}
Text {
- text: myText
+ text: root.myText
color: "lightsteelblue"
width: parent.width
wrapMode: Text.WordWrap
@@ -86,7 +87,7 @@ Rectangle {
font { family: "Times"; pixelSize: 20; capitalization: Font.AllUppercase }
}
Text {
- text: myText
+ text: root.myText
color: "lightsteelblue"
width: parent.width
horizontalAlignment: Text.AlignRight
@@ -94,14 +95,14 @@ Rectangle {
font { family: "Courier"; pixelSize: 20; weight: Font.Bold; capitalization: Font.AllLowercase }
}
Text {
- text: myText
+ text: root.myText
color: "lightsteelblue"
width: parent.width
wrapMode: Text.WordWrap
font { family: "Courier"; pixelSize: 20; italic: true; capitalization: Font.SmallCaps }
}
Text {
- text: myText
+ text: root.myText
color: "lightsteelblue"
width: parent.width
wrapMode: Text.WordWrap
@@ -109,7 +110,7 @@ Rectangle {
}
Text {
text: {
- if (webFont.status == FontLoader.Ready) myText
+ if (webFont.status == FontLoader.Ready) root.myText
else if (webFont.status == FontLoader.Loading) "Loading..."
else if (webFont.status == FontLoader.Error) "Error loading font"
}
diff --git a/examples/quick/text/imgtag/TextWithImage.qml b/examples/quick/text/imgtag/TextWithImage.qml
index 1cb65e739d..d22e93146d 100644
--- a/examples/quick/text/imgtag/TextWithImage.qml
+++ b/examples/quick/text/imgtag/TextWithImage.qml
@@ -55,5 +55,5 @@ Text {
font.pointSize: 14
wrapMode: Text.WordWrap
textFormat: Text.StyledText
- horizontalAlignment: main.hAlign
+ horizontalAlignment: parent.hAlign
}
diff --git a/examples/quick/text/imgtag/imgtag.qml b/examples/quick/text/imgtag/imgtag.qml
index 1790853de2..177008940a 100644
--- a/examples/quick/text/imgtag/imgtag.qml
+++ b/examples/quick/text/imgtag/imgtag.qml
@@ -56,7 +56,7 @@ Rectangle {
focus: true
color: "#dedede"
- property var hAlign: Text.AlignLeft
+ property int hAlign: Text.AlignLeft
Flickable {
anchors.fill: parent
@@ -68,6 +68,7 @@ Rectangle {
x: 10; y: 10
spacing: 20
width: parent.width - 20
+ property int hAlign: main.hAlign
TextWithImage {
text: "This is a <b>happy</b> face<img src=\"images/face-smile.png\">"
diff --git a/examples/quick/text/styledtext-layout.qml b/examples/quick/text/styledtext-layout.qml
index 631a37b493..b399b638dc 100644
--- a/examples/quick/text/styledtext-layout.qml
+++ b/examples/quick/text/styledtext-layout.qml
@@ -71,12 +71,12 @@ Rectangle {
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at ante dui <a href=\"http://www.digia.com\">www.digia.com</a>.<br/>Curabitur ante est, pulvinar quis adipiscing a, iaculis id ipsum. Nunc blandit condimentum odio vel egestas.<br><ul type=\"bullet\"><li>Coffee<ol type=\"a\"><li>Espresso<li>Cappuccino<li>Latte</ol><li>Juice<ol type=\"1\"><li>Orange</li><li>Apple</li><li>Pineapple</li><li>Tomato</li></ol></li></ul><p><font color=\"#434343\"><i>Proin consectetur <b>sapien</b> in ipsum lacinia sit amet mattis orci interdum. Quisque vitae accumsan lectus. Ut nisi turpis, sollicitudin ut dignissim id, fermentum ac est. Maecenas nec libero leo. Sed ac leo eget ipsum ultricies viverra sit amet eu orci. Praesent et tortor risus, viverra accumsan sapien. Sed faucibus eleifend lectus, sed euismod urna porta eu. Quisque vitae accumsan lectus. Ut nisi turpis, sollicitudin ut dignissim id, fermentum ac est. Maecenas nec libero leo. Sed ac leo eget ipsum ultricies viverra sit amet eu orci."
//! [layout]
- onLineLaidOut: {
- line.width = width / 2 - (margin)
+ onLineLaidOut: (line) => {
+ line.width = width / 2 - main.margin
if (line.y + line.height >= height) {
- line.y -= height - margin
- line.x = width / 2 + margin
+ line.y -= height - main.margin
+ line.x = width / 2 + main.activeFocusmargin
}
if (line.isLast) {
diff --git a/examples/quick/threading/threadedlistmodel/timedisplay.qml b/examples/quick/threading/threadedlistmodel/timedisplay.qml
index 5ad901c676..c4e6e7b249 100644
--- a/examples/quick/threading/threadedlistmodel/timedisplay.qml
+++ b/examples/quick/threading/threadedlistmodel/timedisplay.qml
@@ -59,7 +59,10 @@ Rectangle {
anchors.fill: parent
model: listModel
delegate: Component {
- Text { text: time }
+ Text {
+ required property string time
+ text: time
+ }
}
ListModel { id: listModel }
diff --git a/examples/quick/threading/workerscript/Spinner.qml b/examples/quick/threading/workerscript/Spinner.qml
index 9c70090dba..a2257f8639 100644
--- a/examples/quick/threading/workerscript/Spinner.qml
+++ b/examples/quick/threading/workerscript/Spinner.qml
@@ -78,6 +78,7 @@ Rectangle {
clip: true
model: 64
delegate: Text {
+ required property int index
font.pixelSize: 18;
color: "white";
text: index;
diff --git a/examples/quick/threading/workerscript/workerscript.qml b/examples/quick/threading/workerscript/workerscript.qml
index 735cc8d1f1..eb8ad43d01 100644
--- a/examples/quick/threading/workerscript/workerscript.qml
+++ b/examples/quick/threading/workerscript/workerscript.qml
@@ -58,7 +58,7 @@ Rectangle {
id: myWorker
source: "workerscript.mjs"
- onMessage: {
+ onMessage: (messageObject) => {
if (messageObject.row == rowSpinner.value && messageObject.column == columnSpinner.value){ //Not an old result
if (messageObject.result == -1)
resultText.text = "Column must be <= Row";
diff --git a/examples/quick/touchinteraction/flickable/content/Panel.qml b/examples/quick/touchinteraction/flickable/content/Panel.qml
index 21f8fc8afd..0aae0635b2 100644
--- a/examples/quick/touchinteraction/flickable/content/Panel.qml
+++ b/examples/quick/touchinteraction/flickable/content/Panel.qml
@@ -50,112 +50,106 @@
import QtQuick 2.0
-Component {
- Item {
- property variant stickies
+Item {
+ required property string name
+ required property var notes
- id: page
- width: ListView.view.width+40; height: ListView.view.height
+ property real horizontalVelocity: 0
+ id: page
+ width: ListView.view.width+40; height: ListView.view.height
- Image {
- source: "cork.jpg"
- width: page.ListView.view.width
- height: page.ListView.view.height
- fillMode: Image.PreserveAspectCrop
- clip: true
- }
-
- MouseArea {
- anchors.fill: parent
- onClicked: page.focus = false;
- }
- Text {
- text: name; x: 15; y: 8; height: 40; width: 370
- font.pixelSize: 18; font.bold: true; color: "white"
- style: Text.Outline; styleColor: "black"
- }
+ Image {
+ source: "cork.jpg"
+ width: page.ListView.view.width
+ height: page.ListView.view.height
+ fillMode: Image.PreserveAspectCrop
+ clip: true
+ }
- Repeater {
- model: notes
- Item {
- id: stickyPage
+ MouseArea {
+ anchors.fill: parent
+ onClicked: page.focus = false;
+ }
- property int randomX: Math.random() * (page.ListView.view.width-0.5*stickyImage.width) +100
- property int randomY: Math.random() * (page.ListView.view.height-0.5*stickyImage.height) +50
+ Text {
+ text: page.name; x: 15; y: 8; height: 40; width: 370
+ font.pixelSize: 18; font.bold: true; color: "white"
+ style: Text.Outline; styleColor: "black"
+ }
- x: randomX; y: randomY
+ Repeater {
+ model: page.notes
+ Item {
+ id: stickyPage
+ required property string noteText
- rotation: -flickable.horizontalVelocity / 100;
- Behavior on rotation {
- SpringAnimation { spring: 2.0; damping: 0.15 }
- }
+ property int randomX: Math.random() * (page.ListView.view.width-0.5*stickyImage.width) +100
+ property int randomY: Math.random() * (page.ListView.view.height-0.5*stickyImage.height) +50
- Item {
- id: sticky
- scale: 0.7
-
- Image {
- id: stickyImage
- x: 8 + -width * 0.6 / 2; y: -20
- source: "note-yellow.png"
- scale: 0.6; transformOrigin: Item.TopLeft
- }
+ x: randomX; y: randomY
- TextEdit {
- id: myText
- x: -104; y: 36; width: 215; height: 200
- font.pixelSize: 24
- readOnly: false
- rotation: -8
- text: noteText
- }
+ rotation: -page.horizontalVelocity / 100
+ Behavior on rotation {
+ SpringAnimation { spring: 2.0; damping: 0.15 }
+ }
- Item {
- x: stickyImage.x; y: -20
- width: stickyImage.width * stickyImage.scale
- height: stickyImage.height * stickyImage.scale
-
- MouseArea {
- id: mouse
- anchors.fill: parent
- drag.target: stickyPage
- drag.axis: Drag.XAndYAxis
- drag.minimumY: 0
- drag.maximumY: page.height - 80
- drag.minimumX: 100
- drag.maximumX: page.width - 140
- onClicked: myText.forceActiveFocus()
- }
- }
- }
+ Item {
+ id: sticky
+ scale: 0.7
Image {
- x: -width / 2; y: -height * 0.5 / 2
- source: "tack.png"
- scale: 0.7; transformOrigin: Item.TopLeft
+ id: stickyImage
+ x: 8 + -width * 0.6 / 2; y: -20
+ source: "note-yellow.png"
+ scale: 0.6; transformOrigin: Item.TopLeft
}
- states: State {
- name: "pressed"
- when: mouse.pressed
- PropertyChanges { target: sticky; rotation: 8; scale: 1 }
- PropertyChanges { target: page; z: 8 }
+ TextEdit {
+ id: myText
+ x: -104; y: 36; width: 215; height: 200
+ font.pixelSize: 24
+ readOnly: false
+ rotation: -8
+ text: stickyPage.noteText
}
- transitions: Transition {
- NumberAnimation { properties: "rotation,scale"; duration: 200 }
+ Item {
+ x: stickyImage.x; y: -20
+ width: stickyImage.width * stickyImage.scale
+ height: stickyImage.height * stickyImage.scale
+
+ MouseArea {
+ id: mouse
+ anchors.fill: parent
+ drag.target: stickyPage
+ drag.axis: Drag.XAndYAxis
+ drag.minimumY: 0
+ drag.maximumY: page.height - 80
+ drag.minimumX: 100
+ drag.maximumX: page.width - 140
+ onClicked: myText.forceActiveFocus()
+ }
}
}
- }
- }
-}
-
-
-
-
-
+ Image {
+ x: -width / 2; y: -height * 0.5 / 2
+ source: "tack.png"
+ scale: 0.7; transformOrigin: Item.TopLeft
+ }
+ states: State {
+ name: "pressed"
+ when: mouse.pressed
+ PropertyChanges { target: sticky; rotation: 8; scale: 1 }
+ PropertyChanges { target: page; z: 8 }
+ }
+ transitions: Transition {
+ NumberAnimation { properties: "rotation,scale"; duration: 200 }
+ }
+ }
+ }
+}
diff --git a/examples/quick/touchinteraction/flickable/corkboards.qml b/examples/quick/touchinteraction/flickable/corkboards.qml
index afb5dd309c..4825053f3f 100644
--- a/examples/quick/touchinteraction/flickable/corkboards.qml
+++ b/examples/quick/touchinteraction/flickable/corkboards.qml
@@ -92,6 +92,8 @@ Rectangle {
orientation: ListView.Horizontal
snapMode: ListView.SnapOneItem
model: list
- delegate: Panel { }
+ delegate: Panel {
+ horizontalVelocity: flickable.horizontalVelocity
+ }
}
}
diff --git a/examples/quick/touchinteraction/multipointtouch/content/AugmentedTouchPoint.qml b/examples/quick/touchinteraction/multipointtouch/content/AugmentedTouchPoint.qml
index 5750ffcad1..56f287666f 100644
--- a/examples/quick/touchinteraction/multipointtouch/content/AugmentedTouchPoint.qml
+++ b/examples/quick/touchinteraction/multipointtouch/content/AugmentedTouchPoint.qml
@@ -66,7 +66,7 @@ TouchPoint {
interval: 100
running: false
repeat: false
- onTriggered: child.enabled = false
+ onTriggered: container.child.enabled = false
}
property Item child: SpriteGoal {
enabled: false
diff --git a/examples/quick/views/delegatemodel/dragselection.qml b/examples/quick/views/delegatemodel/dragselection.qml
index 15fd2654c2..f9a0d37311 100644
--- a/examples/quick/views/delegatemodel/dragselection.qml
+++ b/examples/quick/views/delegatemodel/dragselection.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+import QtQml 2.0
import QtQuick 2.0
import QtQml.Models 2.1
@@ -64,6 +65,8 @@ Item {
Package {
id: packageRoot
+ required property var modelData
+
MouseArea {
id: visibleContainer
Package.name: "visible"
@@ -130,7 +133,7 @@ Item {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "white"
- text: modelData
+ text: packageRoot.modelData
font.pixelSize: 18
}
diff --git a/examples/quick/views/delegatemodel/slideshow.qml b/examples/quick/views/delegatemodel/slideshow.qml
index b252519bbf..638c8bf10f 100644
--- a/examples/quick/views/delegatemodel/slideshow.qml
+++ b/examples/quick/views/delegatemodel/slideshow.qml
@@ -74,6 +74,8 @@ Rectangle {
width: 76; height: 76
+ required property string thumbnail
+
Rectangle {
id: image
x: 0; y: 0; width: 76; height: 76
@@ -86,7 +88,7 @@ Rectangle {
anchors.leftMargin: 1
anchors.topMargin: 1
- source: thumbnail
+ source: delegateItem.thumbnail
fillMode: Image.PreserveAspectFit
}
diff --git a/examples/quick/views/gridview/gridview-example.qml b/examples/quick/views/gridview/gridview-example.qml
index 76a1d8dd37..4cc30d3736 100644
--- a/examples/quick/views/gridview/gridview-example.qml
+++ b/examples/quick/views/gridview/gridview-example.qml
@@ -74,20 +74,24 @@ Rectangle {
highlight: Rectangle { width: 80; height: 80; color: "lightsteelblue" }
delegate: Item {
+ required property string icon
+ required property string name
+ required property int index
+
width: 100; height: 100
Image {
id: myIcon
y: 20; anchors.horizontalCenter: parent.horizontalCenter
- source: icon
+ source: parent.icon
}
Text {
anchors { top: myIcon.bottom; horizontalCenter: parent.horizontalCenter }
- text: name
+ text: parent.name
}
MouseArea {
anchors.fill: parent
- onClicked: parent.GridView.view.currentIndex = index
+ onClicked: parent.GridView.view.currentIndex = parent.index
}
}
}
diff --git a/examples/quick/views/listview/content/PressAndHoldButton.qml b/examples/quick/views/listview/content/PressAndHoldButton.qml
index 527394eb4d..6d633c0264 100644
--- a/examples/quick/views/listview/content/PressAndHoldButton.qml
+++ b/examples/quick/views/listview/content/PressAndHoldButton.qml
@@ -72,12 +72,12 @@ Image {
PropertyAction { target: container; property: "pressed"; value: true }
ScriptAction { script: container.clicked() }
- PauseAnimation { duration: repeatDelay }
+ PauseAnimation { duration: container.repeatDelay }
SequentialAnimation {
loops: Animation.Infinite
ScriptAction { script: container.clicked() }
- PauseAnimation { duration: repeatDuration }
+ PauseAnimation { duration: container.repeatDuration }
}
}
diff --git a/examples/quick/views/listview/content/ToggleButton.qml b/examples/quick/views/listview/content/ToggleButton.qml
index 0a2747a683..890a94570b 100644
--- a/examples/quick/views/listview/content/ToggleButton.qml
+++ b/examples/quick/views/listview/content/ToggleButton.qml
@@ -63,6 +63,6 @@ Rectangle {
Text { id: text; anchors.centerIn: parent; font.pixelSize: 14 }
MouseArea {
anchors.fill: parent
- onClicked: { active = !active; root.toggled() }
+ onClicked: { root.active = !root.active; root.toggled() }
}
}
diff --git a/examples/quick/views/listview/displaymargin.qml b/examples/quick/views/listview/displaymargin.qml
index e0024e72a9..19261caaa6 100644
--- a/examples/quick/views/listview/displaymargin.qml
+++ b/examples/quick/views/listview/displaymargin.qml
@@ -68,10 +68,13 @@ Item {
width: parent.width
height: 25
color: index % 2 ? "steelblue" : "lightsteelblue"
+
+ required property int index
+
Text {
anchors.centerIn: parent
color: "white"
- text: "Item " + (index + 1)
+ text: "Item " + (parent.index + 1)
}
}
}
diff --git a/examples/quick/views/listview/dynamiclist.qml b/examples/quick/views/listview/dynamiclist.qml
index bfc697d094..f37aab98e2 100644
--- a/examples/quick/views/listview/dynamiclist.qml
+++ b/examples/quick/views/listview/dynamiclist.qml
@@ -101,6 +101,11 @@ Rectangle {
width: listView.width; height: 80
clip: true
+ required property int index
+ required property string name
+ required property real cost
+ required property var attributes
+
Column {
id: arrows
anchors {
@@ -109,10 +114,16 @@ Rectangle {
}
Image {
source: "content/pics/arrow-up.png"
- MouseArea { anchors.fill: parent; onClicked: fruitModel.move(index, index-1, 1) }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: fruitModel.move(delegateItem.index, delegateItem.index - 1, 1)
+ }
}
Image { source: "content/pics/arrow-down.png"
- MouseArea { anchors.fill: parent; onClicked: fruitModel.move(index, index+1, 1) }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: fruitModel.move(delegateItem.index, delegateItem.index + 1, 1)
+ }
}
}
@@ -125,7 +136,7 @@ Rectangle {
Text {
anchors.horizontalCenter: parent.horizontalCenter
- text: name
+ text: delegateItem.name
font.pixelSize: 15
color: "white"
}
@@ -133,8 +144,12 @@ Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
spacing: 5
Repeater {
- model: attributes
- Text { text: description; color: "White" }
+ model: delegateItem.attributes
+ Text {
+ required property string description
+ text: description
+ color: "White"
+ }
}
}
}
@@ -154,13 +169,13 @@ Rectangle {
PressAndHoldButton {
anchors.verticalCenter: parent.verticalCenter
source: "content/pics/plus-sign.png"
- onClicked: fruitModel.setProperty(index, "cost", cost + 0.25)
+ onClicked: fruitModel.setProperty(delegateItem.index, "cost", delegateItem.cost + 0.25)
}
Text {
id: costText
anchors.verticalCenter: parent.verticalCenter
- text: '$' + Number(cost).toFixed(2)
+ text: '$' + Number(delegateItem.cost).toFixed(2)
font.pixelSize: 15
color: "white"
font.bold: true
@@ -169,12 +184,16 @@ Rectangle {
PressAndHoldButton {
anchors.verticalCenter: parent.verticalCenter
source: "content/pics/minus-sign.png"
- onClicked: fruitModel.setProperty(index, "cost", Math.max(0,cost-0.25))
+ onClicked: fruitModel.setProperty(delegateItem.index, "cost",
+ Math.max(0, delegateItem.cost - 0.25))
}
Image {
source: "content/pics/list-delete.png"
- MouseArea { anchors.fill:parent; onClicked: fruitModel.remove(index) }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: fruitModel.remove(delegateItem.index)
+ }
}
}
}
diff --git a/examples/quick/views/listview/expandingdelegates.qml b/examples/quick/views/listview/expandingdelegates.qml
index 1308e8441d..6ed1d8c341 100644
--- a/examples/quick/views/listview/expandingdelegates.qml
+++ b/examples/quick/views/listview/expandingdelegates.qml
@@ -67,6 +67,11 @@ Rectangle {
Item {
id: recipe
+ required property string title
+ required property string picture
+ required property string ingredients
+ required property string method
+
// Create a property to contain the visibility of the details.
// We can bind multiple element's opacity to this one property,
// rather than having a "PropertyChanges" line for each element we
@@ -106,7 +111,7 @@ Rectangle {
Image {
id: recipeImage
width: 50; height: 50
- source: picture
+ source: recipe.picture
}
//! [1]
Column {
@@ -114,7 +119,7 @@ Rectangle {
spacing: 5
Text {
- text: title
+ text: recipe.title
font.bold: true; font.pointSize: 16
}
@@ -125,7 +130,7 @@ Rectangle {
}
SmallText {
- text: ingredients
+ text: recipe.ingredients
wrapMode: Text.WordWrap
width: parent.width
opacity: recipe.detailsOpacity
@@ -155,7 +160,12 @@ Rectangle {
contentHeight: methodText.height
clip: true
- Text { id: methodText; text: method; wrapMode: Text.WordWrap; width: details.width }
+ Text {
+ id: methodText
+ text: recipe.method
+ wrapMode: Text.WordWrap
+ width: details.width
+ }
}
Image {
diff --git a/examples/quick/views/listview/highlight.qml b/examples/quick/views/listview/highlight.qml
index 5b03d30f25..092b4d59bd 100644
--- a/examples/quick/views/listview/highlight.qml
+++ b/examples/quick/views/listview/highlight.qml
@@ -58,44 +58,44 @@ import "content"
Rectangle {
width: 200; height: 300
- // Define a delegate component. A component will be
+ // Define a delegate component. The component will be
// instantiated for each visible item in the list.
- Component {
- id: petDelegate
- Item {
- id: wrapper
- width: 200; height: 55
- Column {
- SmallText { text: 'Name: ' + name }
- SmallText { text: 'Type: ' + type }
- SmallText { text: 'Age: ' + age }
- }
- // indent the item if it is the current item
- states: State {
- name: "Current"
- when: wrapper.ListView.isCurrentItem
- PropertyChanges { target: wrapper; x: 20 }
- }
- transitions: Transition {
- NumberAnimation { properties: "x"; duration: 200 }
- }
- MouseArea {
- anchors.fill: parent
- onClicked: wrapper.ListView.view.currentIndex = index
- }
+ component PetDelegate: Item {
+ id: pet
+ width: 200; height: 55
+
+ required property int index
+ required property string name
+ required property string type
+ required property int age
+
+ Column {
+ SmallText { text: 'Name: ' + pet.name }
+ SmallText { text: 'Type: ' + pet.type }
+ SmallText { text: 'Age: ' + pet.age }
+ }
+ // indent the item if it is the current item
+ states: State {
+ name: "Current"
+ when: pet.ListView.isCurrentItem
+ PropertyChanges { target: pet; x: 20 }
+ }
+ transitions: Transition {
+ NumberAnimation { properties: "x"; duration: 200 }
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: pet.ListView.view.currentIndex = pet.index
}
}
//! [0]
// Define a highlight with customized movement between items.
- Component {
- id: highlightBar
- Rectangle {
- width: 200; height: 50
- color: "#FFFF88"
- y: listView.currentItem.y;
- Behavior on y { SpringAnimation { spring: 2; damping: 0.1 } }
- }
+ component HighlightBar : Rectangle {
+ width: 200; height: 50
+ color: "#FFFF88"
+ y: listView.currentItem.y
+ Behavior on y { SpringAnimation { spring: 2; damping: 0.1 } }
}
ListView {
@@ -104,12 +104,12 @@ Rectangle {
x: 30
model: PetsModel {}
- delegate: petDelegate
+ delegate: PetDelegate {}
focus: true
// Set the highlight delegate. Note we must also set highlightFollowsCurrentItem
// to false so the highlight delegate can control how the highlight is moved.
- highlight: highlightBar
+ highlight: HighlightBar {}
highlightFollowsCurrentItem: false
}
//! [0]
diff --git a/examples/quick/views/listview/highlightranges.qml b/examples/quick/views/listview/highlightranges.qml
index 7bc9ab7fe1..dafd064332 100644
--- a/examples/quick/views/listview/highlightranges.qml
+++ b/examples/quick/views/listview/highlightranges.qml
@@ -62,17 +62,17 @@ Rectangle {
loops: -1
running: true
ScriptAction {
- script: if (increasing) {
- current++;
- if (current >= aModel.count -1) {
- current = aModel.count - 1;
- increasing = !increasing;
+ script: if (root.increasing) {
+ root.current++;
+ if (root.current >= aModel.count -1) {
+ root.current = aModel.count - 1;
+ root.increasing = !root.increasing;
}
} else {
- current--;
- if (current <= 0) {
- current = 0;
- increasing = !increasing;
+ root.current--;
+ if (root.current <= 0) {
+ root.current = 0;
+ root.increasing = !root.increasing;
}
}
}
@@ -161,16 +161,22 @@ Rectangle {
Item {
width: 160
height: column.height
+
+ required property int index
+ required property string name
+ required property string type
+ required property int age
+
Column {
id: column
- Text { text: 'Name: ' + name }
- Text { text: 'Type: ' + type }
- Text { text: 'Age: ' + age }
+ Text { text: 'Name: ' + parent.name }
+ Text { text: 'Type: ' + parent.type }
+ Text { text: 'Age: ' + parent.age }
}
MouseArea {
anchors.fill: parent
- onClicked: root.current = index
+ onClicked: root.current = parent.index
}
}
}
diff --git a/examples/quick/views/listview/sections.qml b/examples/quick/views/listview/sections.qml
index 75b0f5c6d9..d51ed89789 100644
--- a/examples/quick/views/listview/sections.qml
+++ b/examples/quick/views/listview/sections.qml
@@ -87,8 +87,10 @@ Rectangle {
height: childrenRect.height
color: "lightsteelblue"
+ required property string section
+
Text {
- text: section
+ text: parent.section
font.bold: true
font.pixelSize: 20
}
@@ -101,7 +103,11 @@ Rectangle {
anchors.bottom: buttonBar.top
width: parent.width
model: animalsModel
- delegate: Text { text: name; font.pixelSize: 18 }
+ delegate: Text {
+ required property string name
+ text: name
+ font.pixelSize: 18
+ }
section.property: "size"
section.criteria: ViewSection.FullString
diff --git a/examples/quick/views/objectmodel/objectmodel.qml b/examples/quick/views/objectmodel/objectmodel.qml
index 8fc2f7c386..c9e4b8a5cd 100644
--- a/examples/quick/views/objectmodel/objectmodel.qml
+++ b/examples/quick/views/objectmodel/objectmodel.qml
@@ -70,21 +70,21 @@ Rectangle {
color: "#FFFEF0"
Text { text: "Page 1"; font.bold: true; anchors.centerIn: parent }
- Component.onDestruction: if (printDestruction) print("destroyed 1")
+ Component.onDestruction: if (root.printDestruction) print("destroyed 1")
}
Rectangle {
width: view.width; height: view.height
color: "#F0FFF7"
Text { text: "Page 2"; font.bold: true; anchors.centerIn: parent }
- Component.onDestruction: if (printDestruction) print("destroyed 2")
+ Component.onDestruction: if (root.printDestruction) print("destroyed 2")
}
Rectangle {
width: view.width; height: view.height
color: "#F4F0FF"
Text { text: "Page 3"; font.bold: true; anchors.centerIn: parent }
- Component.onDestruction: if (printDestruction) print("destroyed 3")
+ Component.onDestruction: if (root.activeFocusprintDestruction) print("destroyed 3")
}
}
@@ -112,6 +112,8 @@ Rectangle {
model: itemModel.count
Rectangle {
+ required property int index
+
width: 5; height: 5
radius: 3
color: view.currentIndex == index ? "blue" : "white"
@@ -119,7 +121,7 @@ Rectangle {
MouseArea {
width: 20; height: 20
anchors.centerIn: parent
- onClicked: view.currentIndex = index
+ onClicked: view.currentIndex = parent.index
}
}
}
diff --git a/examples/quick/views/package/Delegate.qml b/examples/quick/views/package/Delegate.qml
index 7c73f35c3d..9f4f1946d8 100644
--- a/examples/quick/views/package/Delegate.qml
+++ b/examples/quick/views/package/Delegate.qml
@@ -52,6 +52,12 @@ import QtQuick 2.0
//! [0]
Package {
+ id: delegate
+
+ required property int upTo
+ required property int index
+ required property string display
+
Text { id: listDelegate; width: parent.width; height: 25; text: 'Empty'; Package.name: 'list' }
Text { id: gridDelegate; width: parent.width / 2; height: 50; text: 'Empty'; Package.name: 'grid' }
@@ -60,8 +66,8 @@ Package {
width: parent.width; height: 25
color: 'lightsteelblue'
- Text { text: display; anchors.centerIn: parent }
- state: root.upTo > index ? 'inGrid' : 'inList'
+ Text { text: delegate.display; anchors.centerIn: parent }
+ state: delegate.upTo > delegate.index ? 'inGrid' : 'inList'
states: [
State {
name: 'inList'
diff --git a/examples/quick/views/package/view.qml b/examples/quick/views/package/view.qml
index 311cc3be8e..632d27c724 100644
--- a/examples/quick/views/package/view.qml
+++ b/examples/quick/views/package/view.qml
@@ -77,7 +77,9 @@ Rectangle {
//![0]
DelegateModel {
id: visualModel
- delegate: Delegate {}
+ delegate: Delegate {
+ upTo: root.upTo
+ }
model: myModel
}
diff --git a/examples/quick/window/AllScreens.qml b/examples/quick/window/AllScreens.qml
index a5da380025..ac0e1cb821 100644
--- a/examples/quick/window/AllScreens.qml
+++ b/examples/quick/window/AllScreens.qml
@@ -69,8 +69,14 @@ Column {
id: screenInfo
model: Qt.application.screens
Shared.Label {
+ required property string name
+ required property int virtualX
+ required property int virtualY
+ required property int width
+ required property int height
+
lineHeight: 1.5
- text: name + "\n" + virtualX + ", " + virtualY + " " + modelData.width + "x" + modelData.height
+ text: name + "\n" + virtualX + ", " + virtualY + " " + width + "x" + height
}
}
}
diff --git a/examples/quick/window/CurrentScreen.qml b/examples/quick/window/CurrentScreen.qml
index 2703582399..563cca32a5 100644
--- a/examples/quick/window/CurrentScreen.qml
+++ b/examples/quick/window/CurrentScreen.qml
@@ -115,10 +115,10 @@ Item {
Shared.Label { text: Screen.virtualX + ", " + Screen.virtualY }
Shared.Label { text: "orientation" }
- Shared.Label { text: orientationToString(Screen.orientation) + " (" + Screen.orientation + ")" }
+ Shared.Label { text: root.orientationToString(Screen.orientation) + " (" + Screen.orientation + ")" }
Shared.Label { text: "primary orientation" }
- Shared.Label { text: orientationToString(Screen.primaryOrientation) + " (" + Screen.primaryOrientation + ")" }
+ Shared.Label { text: root.orientationToString(Screen.primaryOrientation) + " (" + Screen.primaryOrientation + ")" }
//! [screen]
Shared.Label { text: "10mm rectangle" }
diff --git a/examples/quick/window/Splash.qml b/examples/quick/window/Splash.qml
index c3e36d9b3b..b33ad6c168 100644
--- a/examples/quick/window/Splash.qml
+++ b/examples/quick/window/Splash.qml
@@ -78,9 +78,9 @@ Window {
}
//! [timer]
Timer {
- interval: timeoutInterval; running: true; repeat: false
+ interval: splash.timeoutInterval; running: true; repeat: false
onTriggered: {
- visible = false
+ splash.visible = false
splash.timeout()
}
}
diff --git a/examples/quick/window/window.qml b/examples/quick/window/window.qml
index 2ee7fb6e09..4280b6a4c0 100644
--- a/examples/quick/window/window.qml
+++ b/examples/quick/window/window.qml
@@ -53,65 +53,66 @@ import QtQuick.Window 2.3
import "../shared" as Shared
QtObject {
+ id: root
property real defaultSpacing: 10
property SystemPalette palette: SystemPalette { }
property var controlWindow: Window {
- width: col.implicitWidth + defaultSpacing * 2
- height: col.implicitHeight + defaultSpacing * 2
- color: palette.window
+ width: col.implicitWidth + root.defaultSpacing * 2
+ height: col.implicitHeight + root.defaultSpacing * 2
+ color: root.palette.window
title: "Control Window"
Column {
id: col
anchors.fill: parent
- anchors.margins: defaultSpacing
- spacing: defaultSpacing
+ anchors.margins: root.defaultSpacing
+ spacing: root.defaultSpacing
property real cellWidth: col.width / 3 - spacing
Shared.Label { text: "Control the second window:" }
Grid {
id: grid
columns: 3
- spacing: defaultSpacing
+ spacing: root.defaultSpacing
width: parent.width
Shared.Button {
id: showButton
width: col.cellWidth
- text: testWindow.visible ? "Hide" : "Show"
- onClicked: testWindow.visible = !testWindow.visible
+ text: root.testWindow.visible ? "Hide" : "Show"
+ onClicked: root.testWindow.visible = !root.testWindow.visible
}
//! [windowedCheckbox]
Shared.CheckBox {
text: "Windowed"
height: showButton.height
width: col.cellWidth
- Binding on checked { value: testWindow.visibility === Window.Windowed }
- onClicked: testWindow.visibility = Window.Windowed
+ Binding on checked { value: root.testWindow.visibility === Window.Windowed }
+ onClicked: root.testWindow.visibility = Window.Windowed
}
//! [windowedCheckbox]
Shared.CheckBox {
height: showButton.height
width: col.cellWidth
text: "Full Screen"
- Binding on checked { value: testWindow.visibility === Window.FullScreen }
- onClicked: testWindow.visibility = Window.FullScreen
+ Binding on checked { value: root.testWindow.visibility === Window.FullScreen }
+ onClicked: root.testWindow.visibility = Window.FullScreen
}
Shared.Button {
id: autoButton
width: col.cellWidth
text: "Automatic"
- onClicked: testWindow.visibility = Window.AutomaticVisibility
+ onClicked: root.testWindow.visibility = Window.AutomaticVisibility
}
Shared.CheckBox {
height: autoButton.height
text: "Minimized"
- Binding on checked { value: testWindow.visibility === Window.Minimized }
- onClicked: testWindow.visibility = Window.Minimized
+ Binding on checked { value: root.testWindow.visibility === Window.Minimized }
+ onClicked: root.testWindow.visibility = Window.Minimized
}
Shared.CheckBox {
height: autoButton.height
text: "Maximized"
- Binding on checked { value: testWindow.visibility === Window.Maximized }
- onClicked: testWindow.visibility = Window.Maximized
+ Binding on checked { value: root.testWindow.visibility === Window.Maximized }
+ onClicked: root.testWindow.visibility = Window.Maximized
}
}
function visibilityToString(v) {
@@ -133,17 +134,17 @@ QtObject {
}
Shared.Label {
id: visibilityLabel
- text: "second window is " + (testWindow.visible ? "visible" : "invisible") +
- " and has visibility " + parent.visibilityToString(testWindow.visibility)
+ text: "second window is " + (root.testWindow.visible ? "visible" : "invisible") +
+ " and has visibility " + parent.visibilityToString(root.testWindow.visibility)
}
Rectangle {
- color: palette.text
+ color: root.palette.text
width: parent.width
height: 1
}
CurrentScreen { }
Rectangle {
- color: palette.text
+ color: root.palette.text
width: parent.width
height: 1
}
@@ -159,40 +160,40 @@ QtObject {
flags: Qt.Window | Qt.WindowFullscreenButtonHint
Rectangle {
anchors.fill: parent
- anchors.margins: defaultSpacing
+ anchors.margins: root.defaultSpacing
Shared.Label {
anchors.centerIn: parent
text: "Second Window"
}
MouseArea {
anchors.fill: parent
- onClicked: testWindow.color = "#e0c31e"
+ onClicked: root.testWindow.color = "#e0c31e"
}
Shared.Button {
anchors.right: parent.right
anchors.top: parent.top
- anchors.margins: defaultSpacing
- text: testWindow.visibility === Window.FullScreen ? "exit fullscreen" : "go fullscreen"
+ anchors.margins: root.defaultSpacing
+ text: root.testWindow.visibility === Window.FullScreen ? "exit fullscreen" : "go fullscreen"
width: 150
onClicked: {
- if (testWindow.visibility === Window.FullScreen)
- testWindow.visibility = Window.AutomaticVisibility
+ if (root.testWindow.visibility === Window.FullScreen)
+ root.testWindow.visibility = Window.AutomaticVisibility
else
- testWindow.visibility = Window.FullScreen
+ root.testWindow.visibility = Window.FullScreen
}
}
Shared.Button {
anchors.left: parent.left
anchors.top: parent.top
- anchors.margins: defaultSpacing
+ anchors.margins: root.defaultSpacing
text: "X"
width: 30
- onClicked: testWindow.close()
+ onClicked: root.testWindow.close()
}
}
}
property var splashWindow: Splash {
- onTimeout: controlWindow.visible = true
+ onTimeout: root.controlWindow.visible = true
}
}
diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp
index 28837655ef..7a38769b77 100644
--- a/src/imports/folderlistmodel/plugin.cpp
+++ b/src/imports/folderlistmodel/plugin.cpp
@@ -42,6 +42,8 @@
#include "qquickfolderlistmodel.h"
+extern void qml_register_types_Qt_labs_folderlistmodel();
+
QT_BEGIN_NAMESPACE
//![class decl]
@@ -51,7 +53,12 @@ class QmlFolderListModelPlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
- QmlFolderListModelPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
+ QmlFolderListModelPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_Qt_labs_folderlistmodel;
+ Q_UNUSED(registration);
+ }
+
void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.folderlistmodel"));
diff --git a/src/imports/labsanimation/plugin.cpp b/src/imports/labsanimation/plugin.cpp
index bd732a6aba..9c985f0dcf 100644
--- a/src/imports/labsanimation/plugin.cpp
+++ b/src/imports/labsanimation/plugin.cpp
@@ -42,6 +42,8 @@
#include "qquickboundaryrule_p.h"
+extern void qml_register_types_Qt_labs_animation();
+
QT_BEGIN_NAMESPACE
/*!
@@ -66,7 +68,11 @@ class QtLabsAnimationPlugin : public QQmlEngineExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtLabsAnimationPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { }
+ QtLabsAnimationPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_Qt_labs_animation;
+ Q_UNUSED(registration);
+ }
};
//![class decl]
diff --git a/src/imports/labsmodels/plugin.cpp b/src/imports/labsmodels/plugin.cpp
index feb4f3ba0a..ab5e0023a6 100644
--- a/src/imports/labsmodels/plugin.cpp
+++ b/src/imports/labsmodels/plugin.cpp
@@ -50,6 +50,8 @@
#include "qqmldelegatecomponent_p.h"
#endif
+extern void qml_register_types_Qt_labs_qmlmodels();
+
QT_BEGIN_NAMESPACE
/*!
@@ -74,7 +76,11 @@ class QtQmlLabsModelsPlugin : public QQmlEngineExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQmlLabsModelsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { }
+ QtQmlLabsModelsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_Qt_labs_qmlmodels;
+ Q_UNUSED(registration);
+ }
};
//![class decl]
diff --git a/src/imports/labsmodels/qqmldelegatecomponent.cpp b/src/imports/labsmodels/qqmldelegatecomponent.cpp
index aaf3fea5da..b8eb8049b3 100644
--- a/src/imports/labsmodels/qqmldelegatecomponent.cpp
+++ b/src/imports/labsmodels/qqmldelegatecomponent.cpp
@@ -250,7 +250,9 @@ QQmlListProperty<QQmlDelegateChoice> QQmlDelegateChooser::choices()
QQmlDelegateChooser::choices_append,
QQmlDelegateChooser::choices_count,
QQmlDelegateChooser::choices_at,
- QQmlDelegateChooser::choices_clear);
+ QQmlDelegateChooser::choices_clear,
+ QQmlDelegateChooser::choices_replace,
+ QQmlDelegateChooser::choices_removeLast);
}
void QQmlDelegateChooser::choices_append(QQmlListProperty<QQmlDelegateChoice> *prop, QQmlDelegateChoice *choice)
@@ -282,6 +284,26 @@ void QQmlDelegateChooser::choices_clear(QQmlListProperty<QQmlDelegateChoice> *pr
q->delegateChanged();
}
+void QQmlDelegateChooser::choices_replace(QQmlListProperty<QQmlDelegateChoice> *prop, int index,
+ QQmlDelegateChoice *choice)
+{
+ QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser *>(prop->object);
+ disconnect(q->m_choices[index], &QQmlDelegateChoice::changed,
+ q, &QQmlAbstractDelegateComponent::delegateChanged);
+ q->m_choices[index] = choice;
+ connect(choice, &QQmlDelegateChoice::changed, q,
+ &QQmlAbstractDelegateComponent::delegateChanged);
+ q->delegateChanged();
+}
+
+void QQmlDelegateChooser::choices_removeLast(QQmlListProperty<QQmlDelegateChoice> *prop)
+{
+ QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser *>(prop->object);
+ disconnect(q->m_choices.takeLast(), &QQmlDelegateChoice::changed,
+ q, &QQmlAbstractDelegateComponent::delegateChanged);
+ q->delegateChanged();
+}
+
QQmlComponent *QQmlDelegateChooser::delegate(QQmlAdaptorModel *adaptorModel, int row, int column) const
{
QVariant v;
diff --git a/src/imports/labsmodels/qqmldelegatecomponent_p.h b/src/imports/labsmodels/qqmldelegatecomponent_p.h
index 4c39dc0d0a..8473831b1d 100644
--- a/src/imports/labsmodels/qqmldelegatecomponent_p.h
+++ b/src/imports/labsmodels/qqmldelegatecomponent_p.h
@@ -116,6 +116,8 @@ public:
static int choices_count(QQmlListProperty<QQmlDelegateChoice> *);
static QQmlDelegateChoice *choices_at(QQmlListProperty<QQmlDelegateChoice> *, int);
static void choices_clear(QQmlListProperty<QQmlDelegateChoice> *);
+ static void choices_replace(QQmlListProperty<QQmlDelegateChoice> *, int, QQmlDelegateChoice *);
+ static void choices_removeLast(QQmlListProperty<QQmlDelegateChoice> *);
QQmlComponent *delegate(QQmlAdaptorModel *adaptorModel, int row, int column = -1) const override;
diff --git a/src/imports/labsmodels/qqmltablemodel.cpp b/src/imports/labsmodels/qqmltablemodel.cpp
index b6468d760f..6ba2cecf19 100644
--- a/src/imports/labsmodels/qqmltablemodel.cpp
+++ b/src/imports/labsmodels/qqmltablemodel.cpp
@@ -644,7 +644,9 @@ QQmlListProperty<QQmlTableModelColumn> QQmlTableModel::columns()
&QQmlTableModel::columns_append,
&QQmlTableModel::columns_count,
&QQmlTableModel::columns_at,
- &QQmlTableModel::columns_clear);
+ &QQmlTableModel::columns_clear,
+ &QQmlTableModel::columns_replace,
+ &QQmlTableModel::columns_removeLast);
}
void QQmlTableModel::columns_append(QQmlListProperty<QQmlTableModelColumn> *property,
@@ -674,6 +676,19 @@ void QQmlTableModel::columns_clear(QQmlListProperty<QQmlTableModelColumn> *prope
return model->mColumns.clear();
}
+void QQmlTableModel::columns_replace(QQmlListProperty<QQmlTableModelColumn> *property, int index, QQmlTableModelColumn *value)
+{
+ QQmlTableModel *model = static_cast<QQmlTableModel*>(property->object);
+ if (QQmlTableModelColumn *column = qobject_cast<QQmlTableModelColumn*>(value))
+ return model->mColumns.replace(index, column);
+}
+
+void QQmlTableModel::columns_removeLast(QQmlListProperty<QQmlTableModelColumn> *property)
+{
+ QQmlTableModel *model = static_cast<QQmlTableModel*>(property->object);
+ model->mColumns.removeLast();
+}
+
/*!
\qmlmethod QModelIndex TableModel::index(int row, int column)
diff --git a/src/imports/labsmodels/qqmltablemodel_p.h b/src/imports/labsmodels/qqmltablemodel_p.h
index d6e982d19a..75e2768849 100644
--- a/src/imports/labsmodels/qqmltablemodel_p.h
+++ b/src/imports/labsmodels/qqmltablemodel_p.h
@@ -96,6 +96,8 @@ public:
static int columns_count(QQmlListProperty<QQmlTableModelColumn> *property);
static QQmlTableModelColumn *columns_at(QQmlListProperty<QQmlTableModelColumn> *property, int index);
static void columns_clear(QQmlListProperty<QQmlTableModelColumn> *property);
+ static void columns_replace(QQmlListProperty<QQmlTableModelColumn> *property, int index, QQmlTableModelColumn *value);
+ static void columns_removeLast(QQmlListProperty<QQmlTableModelColumn> *property);
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
diff --git a/src/imports/layouts/plugin.cpp b/src/imports/layouts/plugin.cpp
index c302b79164..af270c1732 100644
--- a/src/imports/layouts/plugin.cpp
+++ b/src/imports/layouts/plugin.cpp
@@ -42,6 +42,8 @@
#include "qquicklinearlayout_p.h"
#include "qquickstacklayout_p.h"
+extern void qml_register_types_QtQuick_Layouts();
+
QT_BEGIN_NAMESPACE
//![class decl]
@@ -52,6 +54,8 @@ class QtQuickLayoutsPlugin : public QQmlEngineExtensionPlugin
public:
QtQuickLayoutsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
+ volatile auto registration = &qml_register_types_QtQuick_Layouts;
+ Q_UNUSED(registration);
}
};
//![class decl]
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp
index 1ca4056ba9..33c27bd928 100644
--- a/src/imports/layouts/qquicklayout.cpp
+++ b/src/imports/layouts/qquicklayout.cpp
@@ -700,8 +700,10 @@ QQuickItem *QQuickLayoutAttached::item() const
QQuickLayout::QQuickLayout(QQuickLayoutPrivate &dd, QQuickItem *parent)
- : QQuickItem(dd, parent),
- m_dirty(false)
+ : QQuickItem(dd, parent)
+ , m_dirty(false)
+ , m_inUpdatePolish(false)
+ , m_polishInsideUpdatePolish(0)
{
}
@@ -728,7 +730,9 @@ QQuickLayoutAttached *QQuickLayout::qmlAttachedProperties(QObject *object)
void QQuickLayout::updatePolish()
{
+ m_inUpdatePolish = true;
rearrange(QSizeF(width(), height()));
+ m_inUpdatePolish = false;
}
void QQuickLayout::componentComplete()
@@ -749,7 +753,18 @@ void QQuickLayout::invalidate(QQuickItem * /*childItem*/)
if (!qobject_cast<QQuickLayout *>(parentItem())) {
quickLayoutDebug() << "QQuickLayout::invalidate(), polish()";
- polish();
+
+ if (m_inUpdatePolish)
+ ++m_polishInsideUpdatePolish;
+ else
+ m_polishInsideUpdatePolish = 0;
+
+ if (m_polishInsideUpdatePolish <= 2)
+ // allow at most two consecutive loops in order to respond to height-for-width
+ // (e.g QQuickText changes implicitHeight when its width gets changed)
+ polish();
+ else
+ qWarning() << "Qt Quick Layouts: Polish loop detected. Aborting after two iterations.";
}
}
diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h
index cb46c41e6c..3322d03636 100644
--- a/src/imports/layouts/qquicklayout_p.h
+++ b/src/imports/layouts/qquicklayout_p.h
@@ -123,7 +123,9 @@ protected slots:
void invalidateSenderItem();
private:
- bool m_dirty;
+ unsigned m_dirty : 1;
+ unsigned m_inUpdatePolish : 1;
+ unsigned m_polishInsideUpdatePolish : 2;
Q_DECLARE_PRIVATE(QQuickLayout)
diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp
index 344ea7237c..e47eba4164 100644
--- a/src/imports/layouts/qquicklinearlayout.cpp
+++ b/src/imports/layouts/qquicklinearlayout.cpp
@@ -469,6 +469,16 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size)
if (!isReady())
return;
+ const auto refCounter = qScopeGuard([&d] {
+ --(d->m_recurRearrangeCounter);
+ });
+ if (d->m_recurRearrangeCounter++ == 2) {
+ // allow a recursive depth of two in order to respond to height-for-width
+ // (e.g QQuickText changes implicitHeight when its width gets changed)
+ qWarning() << "Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations.";
+ return;
+ }
+
d->m_rearranging = true;
quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::rearrange()" << size;
Qt::LayoutDirection visualDir = effectiveLayoutDirection();
diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h
index 634e51a048..f36f99741d 100644
--- a/src/imports/layouts/qquicklinearlayout_p.h
+++ b/src/imports/layouts/qquicklinearlayout_p.h
@@ -106,7 +106,8 @@ class QQuickGridLayoutBasePrivate : public QQuickLayoutPrivate
Q_DECLARE_PUBLIC(QQuickGridLayoutBase)
public:
- QQuickGridLayoutBasePrivate() : m_rearranging(false)
+ QQuickGridLayoutBasePrivate() : m_recurRearrangeCounter(0)
+ , m_rearranging(false)
, m_updateAfterRearrange(false)
, m_layoutDirection(Qt::LeftToRight)
{}
@@ -119,6 +120,7 @@ public:
QQuickGridLayoutEngine engine;
Qt::Orientation orientation;
+ unsigned m_recurRearrangeCounter : 2;
unsigned m_rearranging : 1;
unsigned m_updateAfterRearrange : 1;
QVector<QQuickItem *> m_invalidateAfterRearrange;
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index ae9f37784d..e488b3d43c 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -42,6 +42,8 @@
#include <QtQml/qqmlextensionplugin.h>
#include <QtQml/qqml.h>
+extern void qml_register_types_QtQuick_LocalStorage();
+
QT_BEGIN_NAMESPACE
class QQmlLocalStoragePlugin : public QQmlEngineExtensionPlugin
@@ -52,6 +54,8 @@ class QQmlLocalStoragePlugin : public QQmlEngineExtensionPlugin
public:
QQmlLocalStoragePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
+ volatile auto registration = &qml_register_types_QtQuick_LocalStorage;
+ Q_UNUSED(registration);
}
};
diff --git a/src/imports/models/plugin.cpp b/src/imports/models/plugin.cpp
index 4aa9f27766..c15866cf05 100644
--- a/src/imports/models/plugin.cpp
+++ b/src/imports/models/plugin.cpp
@@ -37,17 +37,11 @@
**
****************************************************************************/
-#include <QtQmlModels/private/qqmlobjectmodel_p.h>
-
+#include <QtQmlModels/private/qtqmlmodelsglobal_p.h>
#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
-
-#include <QtCore/qloggingcategory.h>
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(qmlModelsPlugin, "qt.qmlModelsPlugin")
-
/*!
\qmlmodule QtQml.Models 2.\QtMinorVersion
\title Qt QML Models QML Types
@@ -92,13 +86,8 @@ class QtQmlModelsPlugin : public QQmlEngineExtensionPlugin
public:
QtQmlModelsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- if (qmlModelsPlugin().isDebugEnabled()) {
- // Superficial debug message that causes the dependency between QtQmlWorkerScript
- // and the workerscript plugin to be retained.
- // As qCDebug() can be a noop, retrieve the className in a separate step.
- const QString className = QQmlObjectModel::staticMetaObject.className();
- qCDebug(qmlModelsPlugin) << "Loading QmlModels plugin:" << className;
- }
+ volatile auto registration = &qml_register_types_QtQml_Models;
+ Q_UNUSED(registration);
}
};
//![class decl]
diff --git a/src/imports/particles/plugin.cpp b/src/imports/particles/plugin.cpp
index 4f319db9f1..6629a660af 100644
--- a/src/imports/particles/plugin.cpp
+++ b/src/imports/particles/plugin.cpp
@@ -50,7 +50,12 @@ class QtQuick2ParticlesPlugin : public QQmlExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
- QtQuick2ParticlesPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
+ QtQuick2ParticlesPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQuick_Particles;
+ Q_UNUSED(registration);
+ }
+
void registerTypes(const char *uri) override
{
Q_UNUSED(uri);
diff --git a/src/imports/qtqml/plugin.cpp b/src/imports/qtqml/plugin.cpp
index ec08992355..a32d86eeb1 100644
--- a/src/imports/qtqml/plugin.cpp
+++ b/src/imports/qtqml/plugin.cpp
@@ -37,10 +37,8 @@
**
****************************************************************************/
+#include <QtQml/private/qtqmlglobal_p.h>
#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/private/qqmlengine_p.h>
-#include <QtQml/private/qqmlcomponentattached_p.h>
-#include <QtQml/private/qqmlbind_p.h>
QT_BEGIN_NAMESPACE
@@ -66,7 +64,11 @@ class QtQmlPlugin : public QQmlEngineExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQmlPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) {}
+ QtQmlPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQml;
+ Q_UNUSED(registration);
+ }
};
//![class decl]
diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp
index 98056aa551..4e14aff15e 100644
--- a/src/imports/qtquick2/plugin.cpp
+++ b/src/imports/qtquick2/plugin.cpp
@@ -50,7 +50,12 @@ class QtQuick2Plugin : public QQmlExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
- QtQuick2Plugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
+ QtQuick2Plugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQuick;
+ Q_UNUSED(registration);
+ }
+
void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick"));
diff --git a/src/imports/settings/plugin.cpp b/src/imports/settings/plugin.cpp
index 24ff43ea6f..e8e640412b 100644
--- a/src/imports/settings/plugin.cpp
+++ b/src/imports/settings/plugin.cpp
@@ -42,6 +42,8 @@
#include "qqmlsettings_p.h"
+extern void qml_register_types_Qt_labs_settings();
+
QT_BEGIN_NAMESPACE
class QmlSettingsPlugin : public QQmlEngineExtensionPlugin
@@ -50,7 +52,11 @@ class QmlSettingsPlugin : public QQmlEngineExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QmlSettingsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) {}
+ QmlSettingsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_Qt_labs_settings;
+ Q_UNUSED(registration);
+ }
};
QT_END_NAMESPACE
diff --git a/src/imports/shapes/plugin.cpp b/src/imports/shapes/plugin.cpp
index 3855a93fc7..48eecbd8f1 100644
--- a/src/imports/shapes/plugin.cpp
+++ b/src/imports/shapes/plugin.cpp
@@ -52,6 +52,8 @@ public:
QmlShapesPlugin(QObject *parent = nullptr)
: QQmlExtensionPlugin(parent)
{
+ volatile auto registration = &qml_register_types_QtQuick_Shapes;
+ Q_UNUSED(registration);
}
void registerTypes(const char *uri) override
diff --git a/src/imports/sharedimage/plugin.cpp b/src/imports/sharedimage/plugin.cpp
index 237fa64c61..d7c2ef8d17 100644
--- a/src/imports/sharedimage/plugin.cpp
+++ b/src/imports/sharedimage/plugin.cpp
@@ -99,6 +99,8 @@
The shared image module does not provide any directly usable QML types.
*/
+extern void qml_register_types_Qt_labs_sharedimage();
+
QT_BEGIN_NAMESPACE
class QtQuickSharedImagePlugin : public QQmlEngineExtensionPlugin
@@ -106,7 +108,11 @@ class QtQuickSharedImagePlugin : public QQmlEngineExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQuickSharedImagePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) {}
+ QtQuickSharedImagePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_Qt_labs_sharedimage;
+ Q_UNUSED(registration);
+ }
void initializeEngine(QQmlEngine *engine, const char *uri) override
{
diff --git a/src/imports/statemachine/childrenprivate.h b/src/imports/statemachine/childrenprivate.h
index 57cda1c796..2dcecd6531 100644
--- a/src/imports/statemachine/childrenprivate.h
+++ b/src/imports/statemachine/childrenprivate.h
@@ -46,54 +46,142 @@
#include <QQmlInfo>
#include <QQmlListProperty>
-template <class T>
-class ChildrenPrivate
+enum class ChildrenMode {
+ None = 0x0,
+ State = 0x1,
+ Transition = 0x2,
+ StateOrTransition = State | Transition
+};
+
+template<typename T>
+static T *parentObject(QQmlListProperty<QObject> *prop) { return static_cast<T *>(prop->object); }
+
+template<class T, ChildrenMode Mode>
+struct ParentHandler
{
-public:
- ChildrenPrivate()
- {}
+ static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem);
+ static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item);
+};
- static void append(QQmlListProperty<QObject> *prop, QObject *item)
+template<class T>
+struct ParentHandler<T, ChildrenMode::None>
+{
+ static bool unparentItem(QQmlListProperty<QObject> *, QObject *) { return true; }
+ static bool parentItem(QQmlListProperty<QObject> *, QObject *) { return true; }
+};
+
+template<class T>
+struct ParentHandler<T, ChildrenMode::State>
+{
+ static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item)
+ {
+ if (QAbstractState *state = qobject_cast<QAbstractState *>(item)) {
+ state->setParent(parentObject<T>(prop));
+ return true;
+ }
+ return false;
+ }
+
+ static bool unparentItem(QQmlListProperty<QObject> *, QObject *oldItem)
+ {
+ if (QAbstractState *state = qobject_cast<QAbstractState *>(oldItem)) {
+ state->setParent(nullptr);
+ return true;
+ }
+ return false;
+ }
+};
+
+template<class T>
+struct ParentHandler<T, ChildrenMode::Transition>
+{
+ static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item)
{
- QAbstractState *state = qobject_cast<QAbstractState*>(item);
- if (state) {
- item->setParent(prop->object);
- } else {
- QAbstractTransition *trans = qobject_cast<QAbstractTransition*>(item);
- if (trans)
- static_cast<T *>(prop->object)->addTransition(trans);
+ if (QAbstractTransition *trans = qobject_cast<QAbstractTransition *>(item)) {
+ parentObject<T>(prop)->addTransition(trans);
+ return true;
}
- static_cast<ChildrenPrivate<T>*>(prop->data)->children.append(item);
- emit static_cast<T *>(prop->object)->childrenChanged();
+ return false;
}
- static void appendNoTransition(QQmlListProperty<QObject> *prop, QObject *item)
+ static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
{
- QAbstractState *state = qobject_cast<QAbstractState*>(item);
- if (state) {
- item->setParent(prop->object);
+ if (QAbstractTransition *trans = qobject_cast<QAbstractTransition *>(oldItem)) {
+ parentObject<T>(prop)->removeTransition(trans);
+ return true;
}
- static_cast<ChildrenPrivate<T>*>(prop->data)->children.append(item);
- emit static_cast<T *>(prop->object)->childrenChanged();
+ return false;
+ }
+};
+
+template<class T>
+struct ParentHandler<T, ChildrenMode::StateOrTransition>
+{
+ static bool parentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
+ {
+ return ParentHandler<T, ChildrenMode::State>::parentItem(prop, oldItem)
+ || ParentHandler<T, ChildrenMode::Transition>::parentItem(prop, oldItem);
+ }
+
+ static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
+ {
+ return ParentHandler<T, ChildrenMode::State>::unparentItem(prop, oldItem)
+ || ParentHandler<T, ChildrenMode::Transition>::unparentItem(prop, oldItem);
+ }
+};
+
+template <class T, ChildrenMode Mode>
+class ChildrenPrivate
+{
+public:
+ static void append(QQmlListProperty<QObject> *prop, QObject *item)
+ {
+ Handler::parentItem(prop, item);
+ static_cast<Self *>(prop->data)->children.append(item);
+ emit parentObject<T>(prop)->childrenChanged();
}
static int count(QQmlListProperty<QObject> *prop)
{
- return static_cast<ChildrenPrivate<T>*>(prop->data)->children.count();
+ return static_cast<Self *>(prop->data)->children.count();
}
static QObject *at(QQmlListProperty<QObject> *prop, int index)
{
- return static_cast<ChildrenPrivate<T>*>(prop->data)->children.at(index);
+ return static_cast<Self *>(prop->data)->children.at(index);
}
static void clear(QQmlListProperty<QObject> *prop)
{
- static_cast<ChildrenPrivate<T>*>(prop->data)->children.clear();
- emit static_cast<T *>(prop->object)->childrenChanged();
+ auto &children = static_cast<Self *>(prop->data)->children;
+ for (QObject *oldItem : qAsConst(children))
+ Handler::unparentItem(prop, oldItem);
+
+ children.clear();
+ emit parentObject<T>(prop)->childrenChanged();
+ }
+
+ static void replace(QQmlListProperty<QObject> *prop, int index, QObject *item)
+ {
+ auto &children = static_cast<Self *>(prop->data)->children;
+
+ Handler::unparentItem(prop, children.at(index));
+ Handler::parentItem(prop, item);
+
+ children.replace(index, item);
+ emit parentObject<T>(prop)->childrenChanged();
+ }
+
+ static void removeLast(QQmlListProperty<QObject> *prop)
+ {
+ Handler::unparentItem(prop, static_cast<Self *>(prop->data)->children.takeLast());
+ emit parentObject<T>(prop)->childrenChanged();
}
private:
+ using Self = ChildrenPrivate<T, Mode>;
+ using Handler = ParentHandler<T, Mode>;
+
QList<QObject *> children;
};
diff --git a/src/imports/statemachine/finalstate.cpp b/src/imports/statemachine/finalstate.cpp
index 54dcc82bae..4d4c6b2cc7 100644
--- a/src/imports/statemachine/finalstate.cpp
+++ b/src/imports/statemachine/finalstate.cpp
@@ -50,7 +50,9 @@ FinalState::FinalState(QState *parent)
QQmlListProperty<QObject> FinalState::children()
{
- return QQmlListProperty<QObject>(this, &m_children, m_children.appendNoTransition, m_children.count, m_children.at, m_children.clear);
+ return QQmlListProperty<QObject>(this, &m_children,
+ m_children.append, m_children.count, m_children.at,
+ m_children.clear, m_children.replace, m_children.removeLast);
}
/*!
diff --git a/src/imports/statemachine/finalstate.h b/src/imports/statemachine/finalstate.h
index 9cdbb51584..117a358e53 100644
--- a/src/imports/statemachine/finalstate.h
+++ b/src/imports/statemachine/finalstate.h
@@ -66,7 +66,7 @@ Q_SIGNALS:
void childrenChanged();
private:
- ChildrenPrivate<FinalState> m_children;
+ ChildrenPrivate<FinalState, ChildrenMode::State> m_children;
};
QT_END_NAMESPACE
diff --git a/src/imports/statemachine/plugin.cpp b/src/imports/statemachine/plugin.cpp
index 4c991994f3..c370504029 100644
--- a/src/imports/statemachine/plugin.cpp
+++ b/src/imports/statemachine/plugin.cpp
@@ -48,6 +48,8 @@
#include <QQmlExtensionPlugin>
#include <qqml.h>
+extern void qml_register_types_QtQml_StateMachine();
+
QT_BEGIN_NAMESPACE
class QtQmlStateMachinePlugin : public QQmlEngineExtensionPlugin
@@ -56,7 +58,11 @@ class QtQmlStateMachinePlugin : public QQmlEngineExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQmlStateMachinePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { }
+ QtQmlStateMachinePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQml_StateMachine;
+ Q_UNUSED(registration);
+ }
};
QT_END_NAMESPACE
diff --git a/src/imports/statemachine/state.cpp b/src/imports/statemachine/state.cpp
index af76087256..10530c2985 100644
--- a/src/imports/statemachine/state.cpp
+++ b/src/imports/statemachine/state.cpp
@@ -61,7 +61,9 @@ void State::componentComplete()
QQmlListProperty<QObject> State::children()
{
- return QQmlListProperty<QObject>(this, &m_children, m_children.append, m_children.count, m_children.at, m_children.clear);
+ return QQmlListProperty<QObject>(this, &m_children,
+ m_children.append, m_children.count, m_children.at,
+ m_children.clear, m_children.replace, m_children.removeLast);
}
/*!
diff --git a/src/imports/statemachine/state.h b/src/imports/statemachine/state.h
index 4b17ea0e5f..68184775ab 100644
--- a/src/imports/statemachine/state.h
+++ b/src/imports/statemachine/state.h
@@ -69,7 +69,7 @@ Q_SIGNALS:
void childrenChanged();
private:
- ChildrenPrivate<State> m_children;
+ ChildrenPrivate<State, ChildrenMode::StateOrTransition> m_children;
};
QT_END_NAMESPACE
diff --git a/src/imports/statemachine/statemachine.cpp b/src/imports/statemachine/statemachine.cpp
index a983644018..bdad2e6bde 100644
--- a/src/imports/statemachine/statemachine.cpp
+++ b/src/imports/statemachine/statemachine.cpp
@@ -90,7 +90,9 @@ void StateMachine::componentComplete()
QQmlListProperty<QObject> StateMachine::children()
{
- return QQmlListProperty<QObject>(this, &m_children, m_children.append, m_children.count, m_children.at, m_children.clear);
+ return QQmlListProperty<QObject>(this, &m_children,
+ m_children.append, m_children.count, m_children.at,
+ m_children.clear, m_children.replace, m_children.removeLast);
}
/*!
diff --git a/src/imports/statemachine/statemachine.h b/src/imports/statemachine/statemachine.h
index 04894477b3..cc0360db54 100644
--- a/src/imports/statemachine/statemachine.h
+++ b/src/imports/statemachine/statemachine.h
@@ -82,7 +82,7 @@ Q_SIGNALS:
void qmlRunningChanged();
private:
- ChildrenPrivate<StateMachine> m_children;
+ ChildrenPrivate<StateMachine, ChildrenMode::StateOrTransition> m_children;
bool m_completed;
bool m_running;
};
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml
index 20c5ce6418..380b7e38d7 100644
--- a/src/imports/testlib/TestCase.qml
+++ b/src/imports/testlib/TestCase.qml
@@ -198,7 +198,7 @@ import Qt.test.qtestroot 1.0
}
\endcode
- The mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence()
+ The mousePress(), mouseRelease(), mouseClick(), mouseDoubleClickSequence()
and mouseMove() methods can be used to simulate mouse events in a
similar fashion.
@@ -1331,7 +1331,7 @@ Item {
If \a item is obscured by another item, or a child of \a item occupies
that position, then the event will be delivered to the other item instead.
- \sa mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
+ \sa mouseRelease(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mousePress(item, x, y, button, modifiers, delay) {
if (!qtest_verifyItem(item, "mousePress"))
@@ -1365,7 +1365,7 @@ Item {
If \a item is obscured by another item, or a child of \a item occupies
that position, then the event will be delivered to the other item instead.
- \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
+ \sa mousePress(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mouseRelease(item, x, y, button, modifiers, delay) {
if (!qtest_verifyItem(item, "mouseRelease"))
@@ -1398,7 +1398,7 @@ Item {
If \a item is obscured by another item, or a child of \a item occupies
that position, then the event will be delivered to the other item instead.
- \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseWheel()
+ \sa mousePress(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseWheel()
*/
function mouseDrag(item, x, y, dx, dy, button, modifiers, delay) {
if (!qtest_verifyItem(item, "mouseDrag"))
@@ -1453,7 +1453,7 @@ Item {
If \a item is obscured by another item, or a child of \a item occupies
that position, then the event will be delivered to the other item instead.
- \sa mousePress(), mouseRelease(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
+ \sa mousePress(), mouseRelease(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mouseClick(item, x, y, button, modifiers, delay) {
if (!qtest_verifyItem(item, "mouseClick"))
@@ -1475,6 +1475,7 @@ Item {
/*!
\qmlmethod TestCase::mouseDoubleClick(item, x = item.width / 2, y = item.height / 2, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1)
+ \deprecated
Simulates double-clicking a mouse \a button with optional \a modifiers
on an \a item. The position of the click is defined by \a x and \a y.
@@ -1528,7 +1529,7 @@ Item {
This QML method was introduced in Qt 5.5.
- \sa mouseDoubleClick(), mousePress(), mouseRelease(), mouseClick(), mouseMove(), mouseDrag(), mouseWheel()
+ \sa mousePress(), mouseRelease(), mouseClick(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mouseDoubleClickSequence(item, x, y, button, modifiers, delay) {
if (!qtest_verifyItem(item, "mouseDoubleClickSequence"))
@@ -1560,7 +1561,7 @@ Item {
If \a item is obscured by another item, or a child of \a item occupies
that position, then the event will be delivered to the other item instead.
- \sa mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseDrag(), mouseWheel()
+ \sa mousePress(), mouseRelease(), mouseClick(), mouseDoubleClickSequence(), mouseDrag(), mouseWheel()
*/
function mouseMove(item, x, y, delay, buttons) {
if (!qtest_verifyItem(item, "mouseMove"))
@@ -1588,7 +1589,7 @@ Item {
The \a xDelta and \a yDelta contain the wheel rotation distance in eighths of a degree. see \l QWheelEvent::angleDelta() for more details.
- \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseDrag(), QWheelEvent::angleDelta()
+ \sa mousePress(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseDrag(), QWheelEvent::angleDelta()
*/
function mouseWheel(item, x, y, xDelta, yDelta, buttons, modifiers, delay) {
if (!qtest_verifyItem(item, "mouseWheel"))
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index 1914c02dd0..83fc150e6c 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -50,6 +50,8 @@ QML_DECLARE_TYPE(QuickTestResult)
QML_DECLARE_TYPE(QuickTestEvent)
QML_DECLARE_TYPE(QuickTestUtil)
+extern void qml_register_types_QtTest();
+
QT_BEGIN_NAMESPACE
class QTestQmlModule : public QQmlEngineExtensionPlugin
@@ -58,7 +60,11 @@ class QTestQmlModule : public QQmlEngineExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QTestQmlModule(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { }
+ QTestQmlModule(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtTest;
+ Q_UNUSED(registration);
+ }
};
QT_END_NAMESPACE
diff --git a/src/imports/wavefrontmesh/plugin.cpp b/src/imports/wavefrontmesh/plugin.cpp
index 9bb7a45b2f..eea0db19db 100644
--- a/src/imports/wavefrontmesh/plugin.cpp
+++ b/src/imports/wavefrontmesh/plugin.cpp
@@ -42,6 +42,8 @@
#include "qwavefrontmesh.h"
+extern void qml_register_types_Qt_labs_wavefrontmesh();
+
QT_BEGIN_NAMESPACE
class QmlWavefrontMeshPlugin : public QQmlEngineExtensionPlugin
@@ -52,6 +54,8 @@ public:
QmlWavefrontMeshPlugin(QObject *parent = nullptr)
: QQmlEngineExtensionPlugin(parent)
{
+ volatile auto registration = &qml_register_types_Qt_labs_wavefrontmesh;
+ Q_UNUSED(registration);
}
};
diff --git a/src/imports/window/plugin.cpp b/src/imports/window/plugin.cpp
index ec4f2c5d2a..5152fa02ec 100644
--- a/src/imports/window/plugin.cpp
+++ b/src/imports/window/plugin.cpp
@@ -41,6 +41,8 @@
#include "plugin.h"
+extern void qml_register_types_QtQuick_Window();
+
QT_BEGIN_NAMESPACE
/*!
@@ -64,7 +66,11 @@ class QtQuick2WindowPlugin : public QQmlEngineExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQuick2WindowPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { }
+ QtQuick2WindowPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQuick_Window;
+ Q_UNUSED(registration);
+ }
};
//![class decl]
diff --git a/src/imports/workerscript/plugin.cpp b/src/imports/workerscript/plugin.cpp
index 0961979c53..1323b17ef4 100644
--- a/src/imports/workerscript/plugin.cpp
+++ b/src/imports/workerscript/plugin.cpp
@@ -37,17 +37,11 @@
**
****************************************************************************/
-#include <QtQmlWorkerScript/private/qquickworkerscript_p.h>
-
+#include <QtQmlWorkerScript/private/qtqmlworkerscriptglobal_p.h>
#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
-
-#include <QtCore/qloggingcategory.h>
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(workerScriptPlugin, "qt.workerScriptPlugin")
-
/*!
\qmlmodule QtQml.WorkerScript 2.\QtMinorVersion
\title Qt QML WorkerScript QML Types
@@ -71,13 +65,8 @@ class QtQmlWorkerScriptPlugin : public QQmlEngineExtensionPlugin
public:
QtQmlWorkerScriptPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- if (workerScriptPlugin().isDebugEnabled()) {
- // Superficial debug message that causes the dependency between QtQmlWorkerScript
- // and the workerscript plugin to be retained.
- // As qCDebug() can be a noop, retrieve the className in a separate step.
- const QString className = QQuickWorkerScript::staticMetaObject.className();
- qCDebug(workerScriptPlugin) << "Loading WorkerScript plugin:" << className;
- }
+ volatile auto registration = &qml_register_types_QtQml_WorkerScript;
+ Q_UNUSED(registration);
}
};
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index 4ce8186c7c..4d67691771 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -1,4 +1,4 @@
-/****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
@@ -389,10 +389,10 @@ private:
QSGMaterialType DeformableMaterial::m_type;
-class SpriteMaterialShader : public QSGMaterialShader
+class ParticleSpriteMaterialShader : public QSGMaterialShader
{
public:
- SpriteMaterialShader()
+ ParticleSpriteMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -478,10 +478,10 @@ public:
QOpenGLFunctions* glFuncs;
};
-class SpriteMaterialRhiShader : public QSGMaterialRhiShader
+class ParticleSpriteMaterialRhiShader : public QSGMaterialRhiShader
{
public:
- SpriteMaterialRhiShader()
+ ParticleSpriteMaterialRhiShader()
{
setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_sprite.vert.qsb"));
setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_sprite.frag.qsb"));
@@ -544,9 +544,9 @@ public:
SpriteMaterial() { setFlag(SupportsRhiShader, true); }
QSGMaterialShader *createShader() const override {
if (flags().testFlag(RhiShaderWanted))
- return new SpriteMaterialRhiShader;
+ return new ParticleSpriteMaterialRhiShader;
else
- return new SpriteMaterialShader;
+ return new ParticleSpriteMaterialShader;
}
QSGMaterialType *type() const override { return &m_type; }
@@ -1143,7 +1143,9 @@ QQuickImageParticle::~QQuickImageParticle()
QQmlListProperty<QQuickSprite> QQuickImageParticle::sprites()
{
- return QQmlListProperty<QQuickSprite>(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
+ return QQmlListProperty<QQuickSprite>(this, &m_sprites,
+ spriteAppend, spriteCount, spriteAt,
+ spriteClear, spriteReplace, spriteRemoveLast);
}
void QQuickImageParticle::sceneGraphInvalidated()
diff --git a/src/particles/qquickparticlegroup.cpp b/src/particles/qquickparticlegroup.cpp
index 052fda6eff..902c23331d 100644
--- a/src/particles/qquickparticlegroup.cpp
+++ b/src/particles/qquickparticlegroup.cpp
@@ -106,10 +106,15 @@ void delayedRedirect(QQmlListProperty<QObject> *prop, QObject *value)
QQmlListProperty<QObject> QQuickParticleGroup::particleChildren()
{
QQuickParticleSystem* system = qobject_cast<QQuickParticleSystem*>(parent());
- if (system)
- return QQmlListProperty<QObject>(this, nullptr, &QQuickParticleSystem::statePropertyRedirect, nullptr, nullptr, nullptr);
- else
- return QQmlListProperty<QObject>(this, nullptr, &delayedRedirect, nullptr, nullptr, nullptr);
+ if (system) {
+ return QQmlListProperty<QObject>(this, nullptr,
+ &QQuickParticleSystem::statePropertyRedirect, nullptr,
+ nullptr, nullptr, nullptr, nullptr);
+ } else {
+ return QQmlListProperty<QObject>(this, nullptr,
+ &delayedRedirect, nullptr, nullptr,
+ nullptr, nullptr, nullptr);
+ }
}
void QQuickParticleGroup::setSystem(QQuickParticleSystem* arg)
diff --git a/src/particles/qtquickparticlesglobal_p.h b/src/particles/qtquickparticlesglobal_p.h
index d7647b3d97..927bc29050 100644
--- a/src/particles/qtquickparticlesglobal_p.h
+++ b/src/particles/qtquickparticlesglobal_p.h
@@ -65,4 +65,6 @@
# define Q_QUICKPARTICLES_PRIVATE_EXPORT
#endif
+void Q_QUICKPARTICLES_PRIVATE_EXPORT qml_register_types_QtQuick_Particles();
+
#endif // QTQUICKPARTICLESGLOBAL_P_H
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
index 61fea96e2f..333ce4b26f 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
@@ -66,7 +66,6 @@ void JavaScriptJob::run()
QV4::ScopedContext ctx(scope, engine->currentStackFrame ? engine->currentContext()
: engine->scriptContext());
- QObject scopeObject;
QV4::CppStackFrame *frame = engine->currentStackFrame;
@@ -76,9 +75,10 @@ void JavaScriptJob::run()
ctx = static_cast<QV4::ExecutionContext *>(&frame->jsFrame->context);
if (context >= 0) {
- QQmlContext *extraContext = qmlContext(QQmlDebugService::objectForId(context));
+ QObject *forId = QQmlDebugService::objectForId(context);
+ QQmlContext *extraContext = qmlContext(forId);
if (extraContext)
- ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(extraContext), &scopeObject);
+ ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(extraContext), forId);
} else if (frameNr < 0) { // Use QML context if available
QQmlEngine *qmlEngine = engine->qmlEngine();
if (qmlEngine) {
@@ -99,7 +99,7 @@ void JavaScriptJob::run()
}
}
if (!engine->qmlContext())
- ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(qmlRootContext), &scopeObject);
+ ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(qmlRootContext), nullptr);
}
}
diff --git a/src/plugins/qmltooling/qmldbg_preview/qmldbg_preview.pro b/src/plugins/qmltooling/qmldbg_preview/qmldbg_preview.pro
index 08686a43e3..e1cbc393f7 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qmldbg_preview.pro
+++ b/src/plugins/qmltooling/qmldbg_preview/qmldbg_preview.pro
@@ -3,6 +3,7 @@ QT += core-private qml-private packetprotocol-private network quick-private gui-
TARGET = qmldbg_preview
SOURCES += \
+ $$PWD/qqmldebugtranslationservice.cpp \
$$PWD/qqmlpreviewblacklist.cpp \
$$PWD/qqmlpreviewfileengine.cpp \
$$PWD/qqmlpreviewfileloader.cpp \
@@ -12,6 +13,7 @@ SOURCES += \
$$PWD/qqmlpreviewservicefactory.cpp
HEADERS += \
+ $$PWD/qqmldebugtranslationservice.h \
$$PWD/qqmlpreviewblacklist.h \
$$PWD/qqmlpreviewfileengine.h \
$$PWD/qqmlpreviewfileloader.h \
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp
new file mode 100644
index 0000000000..1561777202
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldebugtranslationservice.h"
+
+QT_BEGIN_NAMESPACE
+
+QQmlDebugTranslationServiceImpl::QQmlDebugTranslationServiceImpl(QObject *parent) :
+ QQmlDebugTranslationService(1, parent)
+{
+}
+
+void QQmlDebugTranslationServiceImpl::messageReceived(const QByteArray &message)
+{
+ Q_UNUSED(message)
+}
+
+QString QQmlDebugTranslationServiceImpl::foundElidedText(QObject *textObject, const QString &layoutText, const QString &elideText)
+{
+ Q_UNUSED(textObject)
+ Q_UNUSED(layoutText)
+ return elideText;
+}
+
+void QQmlDebugTranslationServiceImpl::foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject, QQmlContextData *contextData)
+{
+ Q_UNUSED(binding)
+ Q_UNUSED(scopeObject)
+ Q_UNUSED(contextData)
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h
new file mode 100644
index 0000000000..a337a937a5
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDEBUGMESSAGESERVICE_H
+#define QDEBUGMESSAGESERVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qqmldebugserviceinterfaces_p.h>
+
+#include <QtCore/qlogging.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qelapsedtimer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlDebugTranslationServicePrivate;
+
+class QQmlDebugTranslationServiceImpl : public QQmlDebugTranslationService
+{
+ Q_OBJECT
+public:
+ //needs to be in sync with QQmlDebugTranslationClient in qqmldebugtranslationclient_p.h
+ enum Command {
+ ChangeLanguage,
+ ChangeWarningColor,
+ ChangeElidedTextWarningString,
+ SetDebugTranslationServiceLogFile,
+ EnableElidedTextWarning,
+ DisableElidedTextWarning,
+ TestAllLanguages
+ };
+ QQmlDebugTranslationServiceImpl(QObject *parent = 0);
+
+ QString foundElidedText(QObject *textObject, const QString &layoutText, const QString &elideText) override;
+ void foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject, QQmlContextData *contextData) override;
+ void messageReceived(const QByteArray &message) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDEBUGMESSAGESERVICE_H
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.json b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.json
index d7e1ef1f10..5e148f8101 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.json
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.json
@@ -1,3 +1,3 @@
{
- "Keys" : [ "QmlPreview" ]
+ "Keys" : [ "QmlPreview", "DebugTranslation" ]
}
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp
index f0aa3226c8..6ff9805bbe 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp
@@ -39,12 +39,18 @@
#include "qqmlpreviewservicefactory.h"
#include "qqmlpreviewservice.h"
+#include "qqmldebugtranslationservice.h"
QT_BEGIN_NAMESPACE
QQmlDebugService *QQmlPreviewServiceFactory::create(const QString &key)
{
- return key == QQmlPreviewServiceImpl::s_key ? new QQmlPreviewServiceImpl(this) : nullptr;
+ if (key == QQmlPreviewServiceImpl::s_key)
+ return new QQmlPreviewServiceImpl(this);
+ if (key == QQmlDebugTranslationServiceImpl::s_key)
+ return new QQmlDebugTranslationServiceImpl(this);
+
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index cc663cd6b3..33b6606b44 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -422,6 +422,11 @@ void QQmlDebugServerImpl::parseArguments()
<< tr("Sends qDebug() and similar messages over the QML debug\n"
"\t\t connection. QtCreator uses this for showing debug\n"
"\t\t messages in the debugger console.") << '\n'
+ << '\n' << QQmlDebugTranslationService::s_key << "\t- "
+ //: Please preserve the line breaks and formatting
+ << tr("helps to see if a translated text\n"
+ "\t\t will result in an elided text\n"
+ "\t\t in QML elements.") << '\n'
<< tr("Other services offered by qmltooling plugins that implement "
"QQmlDebugServiceFactory and which can be found in the standard plugin "
"paths will also be available and can be specified. If no \"services\" "
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces.cpp b/src/qml/debugger/qqmldebugserviceinterfaces.cpp
index 76205c7760..3df1a21bda 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces.cpp
+++ b/src/qml/debugger/qqmldebugserviceinterfaces.cpp
@@ -48,6 +48,7 @@ const QString QQmlProfilerService::s_key = QStringLiteral("CanvasFrameRate");
const QString QDebugMessageService::s_key = QStringLiteral("DebugMessages");
const QString QQmlEngineControlService::s_key = QStringLiteral("EngineControl");
const QString QQmlNativeDebugService::s_key = QStringLiteral("NativeQmlDebugger");
+const QString QQmlDebugTranslationService::s_key = QStringLiteral("DebugTranslation");
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
index 01693aee24..644d9d6ba9 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h
+++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
@@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE
class QWindow;
class QQuickWindow;
+class QQmlTranslationBinding;
#if !QT_CONFIG(qml_debug)
@@ -103,6 +104,10 @@ public:
class QDebugMessageService {};
class QQmlEngineControlService {};
class QQmlNativeDebugService {};
+class QQmlDebugTranslationService {
+ virtual QString foundElidedText(QObject *, const QString &, const QString &) {return {};}
+ virtual void foundTranslationBinding(QQmlTranslationBinding *, QObject *, QQmlContextData *) {}
+};
#else
@@ -162,6 +167,22 @@ protected:
QQmlBoundSignal *nextSignal(QQmlBoundSignal *prev) { return prev->m_nextSignal; }
};
+class Q_QML_PRIVATE_EXPORT QQmlDebugTranslationService : public QQmlDebugService
+{
+ Q_OBJECT
+public:
+ static const QString s_key;
+
+ virtual QString foundElidedText(QObject *qQuickTextObject, const QString &layoutText, const QString &elideText) = 0;
+ virtual void foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject, QQmlContextData *contextData) = 0;
+protected:
+ friend class QQmlDebugConnector;
+
+ QQmlDebugTranslationService(float version, QObject *parent = nullptr) :
+ QQmlDebugService(s_key, version, parent) {}
+
+};
+
class Q_QML_PRIVATE_EXPORT QQmlInspectorService : public QQmlDebugService
{
Q_OBJECT
diff --git a/src/qml/doc/snippets/code/backend/backend.h b/src/qml/doc/snippets/code/backend/backend.h
index fa7ce9eb86..6c64236bc7 100644
--- a/src/qml/doc/snippets/code/backend/backend.h
+++ b/src/qml/doc/snippets/code/backend/backend.h
@@ -53,11 +53,13 @@
#include <QObject>
#include <QString>
+#include <qqml.h>
class BackEnd : public QObject
{
Q_OBJECT
Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
+ QML_ELEMENT
public:
explicit BackEnd(QObject *parent = nullptr);
diff --git a/src/qml/doc/snippets/code/backend/backend.pro b/src/qml/doc/snippets/code/backend/backend.pro
new file mode 100644
index 0000000000..8bd2422718
--- /dev/null
+++ b/src/qml/doc/snippets/code/backend/backend.pro
@@ -0,0 +1,17 @@
+QT += qml
+
+#![registration]
+CONFIG += qmltypes
+QML_IMPORT_NAME = io.qt.examples.backend
+QML_IMPORT_MAJOR_VERSION = 1
+#![registration]
+
+HEADERS += \
+ backend.h
+
+SOURCES += \
+ backend.cpp \
+ main.cpp
+
+RESOURCES += \
+ main.qml
diff --git a/src/qml/doc/snippets/code/backend/main.cpp b/src/qml/doc/snippets/code/backend/main.cpp
index 91a012dfda..52fcb38621 100644
--- a/src/qml/doc/snippets/code/backend/main.cpp
+++ b/src/qml/doc/snippets/code/backend/main.cpp
@@ -51,14 +51,10 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
-#include "backend.h"
-
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
- qmlRegisterType<BackEnd>("io.qt.examples.backend", 1, 0, "BackEnd");
-
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
diff --git a/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.cpp b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.cpp
index d74cc13d04..b41a9b4dff 100644
--- a/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.cpp
+++ b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.cpp
@@ -51,84 +51,102 @@
#include "avatarExample.h"
#include <QQmlEngine>
#include <QQmlComponent>
+#include <QGuiApplication>
-void registerTypes()
+struct Expectations
{
-//![0]
- qmlRegisterType<AvatarExample>("Qt.example", 1, 0, "AvatarExample");
-//![0]
-}
+ QQmlEngine engine;
-void expectOne()
-{
+ void expectOne()
+ {
//![1]
-QQmlComponent component(&engine, "exampleOne.qml");
-QObject *object = component.create();
-// The scarce resource will have been released automatically
-// by this point, after the binding expression was evaluated.
-delete object;
+ QQmlComponent component(&engine, "qrc:/exampleOne.qml");
+ QObject *object = component.create();
+ // The scarce resource will have been released automatically
+ // by this point, after the binding expression was evaluated.
+ bool expectedResult = (object->property("avatarWidth").toInt() == 100);
+ delete object;
//![1]
-}
+ Q_ASSERT(expectedResult);
+ }
-void expectTwo()
-{
+ void expectTwo()
+ {
//![2]
-QQmlComponent component(&engine, "exampleTwo.qml");
-QObject *object = component.create();
-// The scarce resource will not have been released automatically
-// after the binding expression was evaluated.
-// Since the scarce resource was not released explicitly prior
-// to the binding expression being evaluated, we get:
-bool expectedResult = (object->property("avatar").isValid() == true);
-delete object;
+ QQmlComponent component(&engine, "qrc:/exampleTwo.qml");
+ QObject *object = component.create();
+ // The scarce resource will not have been released automatically
+ // after the binding expression was evaluated.
+ // Since the scarce resource was not released explicitly prior
+ // to the binding expression being evaluated, we get:
+ bool expectedResult = (object->property("avatar").isValid() == true);
+ delete object;
//![2]
-}
+ Q_ASSERT(expectedResult);
+ }
-void expectThree()
-{
+ void expectThree()
+ {
//![3]
-QQmlComponent component(&engine, "exampleThree.qml");
-QObject *object = component.create();
-// The resource was preserved explicitly during evaluation of the
-// JavaScript expression. Thus, during property assignment, the
-// scarce resource was still valid, and so we get:
-bool expectedResult = (object->property("avatar").isValid() == true);
-// The scarce resource will not be released until all references to
-// the resource are released, and the JavaScript garbage collector runs.
-delete object;
+ QQmlComponent component(&engine, "qrc:/exampleThree.qml");
+ QObject *object = component.create();
+ // The resource was preserved explicitly during evaluation of the
+ // JavaScript expression. Thus, during property assignment, the
+ // scarce resource was still valid, and so we get:
+ bool expectedResult = (object->property("avatar").isValid() == true);
+ // The scarce resource will not be released until all references to
+ // the resource are released, and the JavaScript garbage collector runs.
+ delete object;
//![3]
-}
+ Q_ASSERT(expectedResult);
+ }
-void expectFour()
-{
+ void expectFour()
+ {
//![4]
-QQmlComponent component(&engine, "exampleFour.qml");
-QObject *object = component.create();
-// The scarce resource was explicitly preserved by the client during
-// the importAvatar() function, and so the scarce resource
-// remains valid until the explicit call to releaseAvatar(). As such,
-// we get the expected results:
-bool expectedResultOne = (object->property("avatarOne").isValid() == true);
-bool expectedResultTwo = (object->property("avatarTwo").isValid() == false);
-// Because the scarce resource referenced by avatarTwo was released explicitly,
-// it will no longer be consuming any system resources (beyond what a normal
-// JS Object would; that small overhead will exist until the JS GC runs, as per
-// any other JavaScript object).
-delete object;
+ QQmlComponent component(&engine, "qrc:/exampleFour.qml");
+ QObject *object = component.create();
+ // The scarce resource was explicitly preserved by the client during
+ // the importAvatar() function, and so the scarce resource
+ // remains valid until the explicit call to releaseAvatar(). As such,
+ // we get the expected results:
+ bool expectedResultOne = (object->property("avatarOne").isValid() == true);
+ bool expectedResultTwo = (object->property("avatarTwo").isValid() == false);
+ // Because the scarce resource referenced by avatarTwo was released explicitly,
+ // it will no longer be consuming any system resources (beyond what a normal
+ // JS Object would; that small overhead will exist until the JS GC runs, as per
+ // any other JavaScript object).
+ delete object;
//![4]
-}
+ Q_ASSERT(expectedResultOne);
+ Q_ASSERT(expectedResultTwo);
+ }
-void expectFive()
-{
+ void expectFive()
+ {
//![5]
-QQmlComponent component(&engine, "exampleFive.qml");
-QObject *object = component.create();
-// We have the expected results:
-bool expectedResultOne = (object->property("avatarOne").isValid() == false);
-bool expectedResultTwo = (object->property("avatarTwo").isValid() == false);
-// Because although only avatarTwo was explicitly released,
-// avatarOne and avatarTwo were referencing the same
-// scarce resource.
-delete object;
+ QQmlComponent component(&engine, "qrc:/exampleFive.qml");
+ QObject *object = component.create();
+ // We have the expected results:
+ bool expectedResultOne = (object->property("avatarOne").isValid() == false);
+ bool expectedResultTwo = (object->property("avatarTwo").isValid() == false);
+ // Because although only avatarTwo was explicitly released,
+ // avatarOne and avatarTwo were referencing the same
+ // scarce resource.
+ delete object;
//![5]
+ Q_ASSERT(expectedResultOne);
+ Q_ASSERT(expectedResultTwo);
+ }
+};
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+ Expectations expectations;
+ expectations.expectOne();
+ expectations.expectTwo();
+ expectations.expectThree();
+ expectations.expectFour();
+ expectations.expectFive();
}
diff --git a/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.h b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.h
index fb9e238512..1acc3a1c2f 100644
--- a/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.h
+++ b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.h
@@ -53,6 +53,7 @@
#include <QObject>
#include <QPixmap>
+#include <qqml.h>
//![0]
// avatarExample.h
@@ -60,6 +61,8 @@ class AvatarExample : public QObject
{
Q_OBJECT
Q_PROPERTY(QPixmap avatar READ avatar WRITE setAvatar NOTIFY avatarChanged)
+ QML_ELEMENT
+
public:
AvatarExample(QObject *parent = 0)
: QObject(parent), m_value(100, 100)
diff --git a/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/scarceresources.pro b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/scarceresources.pro
new file mode 100644
index 0000000000..d88f8f574c
--- /dev/null
+++ b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/scarceresources.pro
@@ -0,0 +1,22 @@
+QT += qml gui
+
+#![0]
+CONFIG += qmltypes
+QML_IMPORT_NAME = Qt.example
+QML_IMPORT_MAJOR_VERSION = 1
+#![0]
+
+RESOURCES += \
+ exampleFive.qml \
+ exampleFour.js \
+ exampleFour.qml \
+ exampleOne.qml \
+ exampleThree.js \
+ exampleThree.qml \
+ exampleTwo.qml
+
+HEADERS += \
+ avatarExample.h
+
+SOURCES += \
+ avatarExample.cpp
diff --git a/src/qml/doc/snippets/qml/qml-documents/A.qml b/src/qml/doc/snippets/qml/qml-documents/A.qml
new file mode 100644
index 0000000000..83c59dc5d7
--- /dev/null
+++ b/src/qml/doc/snippets/qml/qml-documents/A.qml
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+//! [document]
+// A.qml
+import QtQuick 2.15
+
+Item {
+ id: root
+ property string message: "From A"
+ component MyInlineComponent : Item {
+ Component.onCompleted: console.log(root.message)
+ }
+}
+//! [document]
diff --git a/src/qml/doc/snippets/qml/qml-documents/B.qml b/src/qml/doc/snippets/qml/qml-documents/B.qml
new file mode 100644
index 0000000000..5e603d50e0
--- /dev/null
+++ b/src/qml/doc/snippets/qml/qml-documents/B.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+//! [document]
+// B.qml
+import QtQuick 2.15
+
+Item {
+ A.MyInlineComponent {}
+}
+//! [document]
diff --git a/src/qml/doc/snippets/qml/qml-documents/Images.qml b/src/qml/doc/snippets/qml/qml-documents/Images.qml
new file mode 100644
index 0000000000..80a4d95fbb
--- /dev/null
+++ b/src/qml/doc/snippets/qml/qml-documents/Images.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+//! [document]
+// Images.qml
+import QtQuick 2.15
+
+Item {
+ component LabeledImage: Column {
+ property alias source: image.source
+ property alias caption: text.text
+
+ Image {
+ id: image
+ width: 50
+ height: 50
+ }
+ Text {
+ id: text
+ font.bold: true
+ }
+ }
+
+ Row {
+ LabeledImage {
+ id: before
+ source: "before.png"
+ caption: "Before"
+ }
+ LabeledImage {
+ id: after
+ source: "after.png"
+ caption: "After"
+ }
+ }
+ property LabeledImage selectedImage: before
+}
+// Images.qml
diff --git a/src/qml/doc/snippets/qml/qml-documents/LabeledImageBox.qml b/src/qml/doc/snippets/qml/qml-documents/LabeledImageBox.qml
new file mode 100644
index 0000000000..5a259a0cc6
--- /dev/null
+++ b/src/qml/doc/snippets/qml/qml-documents/LabeledImageBox.qml
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+//! [document]
+// LabeledImageBox.qml
+import QtQuick 2.15
+
+Rectangle {
+ property alias caption: image.caption
+ property alias source: image.source
+ border.width: 2
+ border.color: "black"
+ Images.LabeledImage {
+ id: image
+ }
+}
+//! [document]
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index 2e8102bd65..f66dc44383 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -80,9 +80,17 @@ class instance can be manipulated from QML; as
Types to QML} explains, the properties, methods and signals of any
QObject-derived class are accessible from QML code.
-To register a QObject-derived class as an instantiable QML object type, call
-qmlRegisterType() to register the class as QML type into a particular type
-namespace. Clients can then import that namespace in order to use the type.
+To register a QObject-derived class as an instantiable QML object type, add
+\c QML_ELEMENT or \c QML_NAMED_ELEMENT(<name>) to the class declaration and
+\c {CONFIG += qmltypes}, a \c {QML_IMPORT_NAME}, and a
+\c QML_IMPORT_MAJOR_VERSION to your project file. This will register the class
+into the type namespace under the given major version, using either the class
+name or an explicitly given name as QML type name. The minor version(s) will
+be derived from any revisions attached to properties, methods, or signals. The
+default minor version is \c 0. You can explicitly restrict the type to be
+available only from specific minor versions by adding the
+\c QML_ADDED_IN_MINOR_VERSION() macro to the class declaration. Clients can
+import suitable versions of the namespace in order to use the type.
For example, suppose there is a \c Message class with \c author and
\c creationDate properties:
@@ -93,17 +101,20 @@ class Message : public QObject
Q_OBJECT
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
Q_PROPERTY(QDateTime creationDate READ creationDate WRITE setCreationDate NOTIFY creationDateChanged)
+ QML_ELEMENT
public:
// ...
};
\endcode
-This type can be registered by calling qmlRegisterType() with an appropriate
-type namespace and version number. For example, to make the type available in
-the \c com.mycompany.messaging namespace with version 1.0:
+This type can be registered by adding an appropriate type namespace and version
+number to the project file. For example, to make the type available in the
+\c com.mycompany.messaging namespace with version 1.0:
\code
-qmlRegisterType<Message>("com.mycompany.messaging", 1, 0, "Message");
+CONFIG += qmltypes
+QML_IMPORT_NAME = com.mycompany.messaging
+QML_IMPORT_MAJOR_VERSION = 1
\endcode
The type can be used in an \l{qtqml-syntax-basics.html#object-declarations}
@@ -135,23 +146,25 @@ not be instantiable
should not be instantiable from QML
\endlist
-The \l {Qt QML} module provides several methods for registering non-instantiable
+The \l {Qt QML} module provides several macros for registering non-instantiable
types:
\list
-\li qmlRegisterType() (with no parameters) registers a C++ type that is not
-instantiable and cannot be referred to from QML. This enables the engine to
-coerce any inherited types that are instantiable from QML.
-\li qmlRegisterInterface() registers an existing Qt interface type. The type is
+\li QML_ANONYMOUS registers a C++ type that is not instantiable and cannot be
+referred to from QML. This enables the engine to coerce any inherited types that
+are instantiable from QML.
+\li QML_INTERFACE registers an existing Qt interface type. The type is
not instantiable from QML, and you cannot declare QML properties with it. Using
C++ properties of this type from QML will do the expected interface casts,
though.
-\li qmlRegisterUncreatableType() registers a named C++ type that is not
-instantiable but should be identifiable as a type to the QML type system. This
-is useful if a type's enums or attached properties should be accessible from QML
-but the type itself should not be instantiable.
-\li qmlRegisterSingletonType() registers a singleton type that can be imported
-from QML, as discussed below.
+\li QML_UNCREATABLE(reason) combined with with QML_ELEMENT or QML_NAMED_ELEMENT
+registers a named C++ type that is not instantiable but should be identifiable
+as a type to the QML type system. This is useful if a type's enums or attached
+properties should be accessible from QML but the type itself should not be
+instantiable. The parameter should be an error message to be emitted if an
+attempt at creating an instance of the type is detected.
+\li QML_SINGLETON combined with QML_ELEMENT or QML_NAMED_ELEMENT registers a
+singleton type that can be imported from QML, as discussed below.
\endlist
Note that all C++ types registered with the QML type system must be
@@ -195,7 +208,7 @@ Rectangle {
A QJSValue may also be exposed as a singleton type, however clients should
be aware that properties of such a singleton type cannot be bound to.
-See \l{qmlRegisterSingletonType()} for more information on how implement and
+See \l{QML_SINGLETON} for more information on how implement and
register a new singleton type, and how to use an existing singleton type.
\note Enum values for registered types in QML should start with a capital.
@@ -245,30 +258,20 @@ class CppType : public BaseType
{
Q_OBJECT
Q_PROPERTY(int root READ root WRITE setRoot NOTIFY rootChanged REVISION 1)
+ QML_ELEMENT
signals:
Q_REVISION(1) void rootChanged();
};
\endcode
-To register the new class revision to a particular version the following
-function is used:
+The revisions given this way are automatically interpreted as minor versions to
+the major version given in the project file. In this case, \c root is only
+available when \c MyTypes version 1.1 or higher is imported. Imports of
+\c MyTypes version 1.0 remain unaffected.
-\code
-template<typename T, int metaObjectRevision>
-int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
-\endcode
-
-To register \c CppType version 1 for \c {MyTypes 1.1}:
-
-\code
-qmlRegisterType<CppType,1>("MyTypes", 1, 1, "CppType")
-\endcode
-
-\c root is only available when \c MyTypes version 1.1 is imported.
-
-For the same reason, new types introduced in later versions should use
-the minor version argument of qmlRegisterType.
+For the same reason, new types introduced in later versions should be tagged
+with the QML_ADDED_IN_MINOR_VERSION macro.
This feature of the language allows for behavioural changes to be made
without breaking existing applications. Consequently QML module authors
@@ -276,29 +279,10 @@ should always remember to document what changed between minor versions, and
QML module users should check that their application still runs correctly
before deploying an updated import statement.
-You may also register the revision of a base class that your type depends
-upon using the qmlRegisterRevision() function:
-
-\code
-template<typename T, int metaObjectRevision>
-int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
-
-template<typename T, int metaObjectRevision>
-int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
-
-template<typename T, typename E, int metaObjectRevision>
-int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
-\endcode
-
-For example, if \c BaseType is changed and now has a revision 1, you can
-specify that your type uses the new revision:
-
-\code
-qmlRegisterRevision<BaseType,1>("MyTypes", 1, 1);
-\endcode
-
-This is useful when deriving from base classes provided by other authors,
-e.g. when extending classes from the Qt Quick module.
+Revisions of a base class that your type depends upon are automatically
+registered when registering the type itself. This is useful when deriving
+from base classes provided by other authors, e.g. when extending classes from
+the Qt Quick module.
\note The QML engine does not support revisions for properties or signals of
grouped and attached property objects.
@@ -323,21 +307,8 @@ merged with the original target class when used from within QML. For example:
The \c leftMargin property is a new property added to an existing C++ type, \l
QLineEdit, without modifying its source code.
-The \l {QQmlEngine::}{qmlRegisterExtendedType()} function is for registering extended types.
-Note that it has two forms.
-
-\code
-template<typename T, typename ExtendedT>
-int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
-
-template<typename T, typename ExtendedT>
-int qmlRegisterExtendedType()
-\endcode
-
-This functions should be used instead of the regular \c qmlRegisterType()
-variations. The arguments are identical to the corresponding non-extension
-registration functions, except for the ExtendedT parameter which is the type of
-the extension object.
+The \l {QML_EXTENDED(extended)} macro is for registering extended types. The
+argument is the name of another class to be used as extension.
An extension class is a regular QObject, with a constructor that takes a QObject
pointer. However, the extension class creation is delayed until the first
@@ -425,8 +396,9 @@ the attributes to be made accessible to \e attachee objects. For the
attached property accesses. Consequently the attachment object may not be
deleted until the attachee \c object is destroyed.
-\li is declared as an attaching type, by calling the QML_DECLARE_TYPEINFO()
- macro with the QML_HAS_ATTACHED_PROPERTIES flag
+\li is declared as an attaching type, by adding the QML_ATTACHED(attached) macro
+ to the class declaration. The argument is the name of the
+ \e{attached object type}
\endlist
@@ -441,6 +413,7 @@ class Message : public QObject
Q_OBJECT
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
Q_PROPERTY(QDateTime creationDate READ creationDate WRITE setCreationDate NOTIFY creationDateChanged)
+ QML_ELEMENT
public:
// ...
};
@@ -472,6 +445,7 @@ class MessageBoardAttachedType : public QObject
{
Q_OBJECT
Q_PROPERTY(bool expired READ expired WRITE setExpired NOTIFY expiredChanged)
+ QML_ANONYMOUS
public:
MessageBoardAttachedType(QObject *parent);
bool expired() const;
@@ -485,20 +459,21 @@ signals:
Then the \e {attaching type}, \c MessageBoard, must declare a \c
qmlAttachedProperties() method that returns an instance of the
\e {attached object type} as implemented by MessageBoardAttachedType.
-Additionally, \c Message board must be declared as an attached type
-through the QML_DECLARE_TYPEINFO() macro:
+Additionally, \c MessageBoard must be declared as an attaching type
+via the QML_ATTACHED() macro:
\code
class MessageBoard : public QObject
{
Q_OBJECT
+ QML_ATTACHED(MessageBoardAttachedType)
+ QML_ELEMENT
public:
static MessageBoardAttachedType *qmlAttachedProperties(QObject *object)
{
return new MessageBoardAttachedType(object);
}
};
-QML_DECLARE_TYPEINFO(MessageBoard, QML_HAS_ATTACHED_PROPERTIES)
\endcode
Now, a \c Message type can access the properties and signals of the attached
@@ -607,6 +582,7 @@ class RandomNumberGenerator : public QObject, public QQmlPropertyValueSource
Q_OBJECT
Q_INTERFACES(QQmlPropertyValueSource)
Q_PROPERTY(int maxValue READ maxValue WRITE setMaxValue NOTIFY maxValueChanged);
+ QML_ELEMENT
public:
RandomNumberGenerator(QObject *parent)
: QObject(parent), m_maxValue(100)
@@ -690,6 +666,7 @@ class MessageBoard : public QObject
Q_OBJECT
Q_PROPERTY(QQmlListProperty<Message> messages READ messages)
Q_CLASSINFO("DefaultProperty", "messages")
+ QML_ELEMENT
public:
QQmlListProperty<Message> messages();
@@ -766,6 +743,7 @@ class MyQmlType : public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
+ QML_ELEMENT
public:
virtual void componentComplete()
{
diff --git a/src/qml/doc/src/cppintegration/topic.qdoc b/src/qml/doc/src/cppintegration/topic.qdoc
index fbb654378d..bf4565a996 100644
--- a/src/qml/doc/src/cppintegration/topic.qdoc
+++ b/src/qml/doc/src/cppintegration/topic.qdoc
@@ -49,8 +49,16 @@ file contents with:
\snippet code/backend/backend.h backend_header
The \c Q_PROPERTY macro declares a property that could be accessed from QML.
+The \c QML_ELEMENT macro makes the BackEnd class available in QML.
-\li Replace its C++ file contents with:
+\li Add the following lines to your project file:
+
+\snippet code/backend/backend.pro registration
+
+The BackEnd class is automatically registered as a type, which is accessible
+from QML by importing the URL, "\c{io.qt.examples.backend 1.0}".
+
+\li Replace the contents of \c{backend.cpp} with:
\snippet code/backend/backend.cpp backend_cpp
@@ -58,14 +66,6 @@ The \c setUserName function emits the \c userNameChanged signal every time
\c m_userName value changes. The signal can be handled from QML using the
\c onUserNameChanged handler.
-\li Include \c "backend.h" in \c main.cpp and register the class as a QML type
-under a import URL as shown below:
-
-\snippet code/backend/main.cpp main_cpp
-
-The BackEnd class is registered as a type, which is accessible from QML by
-importing the URL, "\c{io.qt.examples.backend 1.0}".
-
\li Replace the contents of \c main.qml with the following code:
\snippet code/backend/main.qml main_qml
diff --git a/src/qml/doc/src/javascript/expressions.qdoc b/src/qml/doc/src/javascript/expressions.qdoc
index b83127389a..b27bde3cf9 100644
--- a/src/qml/doc/src/javascript/expressions.qdoc
+++ b/src/qml/doc/src/javascript/expressions.qdoc
@@ -147,7 +147,7 @@ Rectangle {
TapHandler {
id: inputHandler
- onTapped: {
+ onTapped: {
// arbitrary JavaScript expression
console.log("Tapped!")
}
@@ -339,7 +339,7 @@ For the following examples, imagine that we have defined the following class:
and that we have registered it with the QML type-system as follows:
-\snippet qml/integrating-javascript/scarceresources/avatarExample.cpp 0
+\snippet qml/integrating-javascript/scarceresources/scarceresources.pro 0
The AvatarExample class has a property which is a pixmap. When the property
is accessed in JavaScript scope, a copy of the resource will be created and
diff --git a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
index 2de4eb0c18..2eaedf8f9b 100644
--- a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
@@ -29,25 +29,37 @@
\title Defining Object Types through QML Documents
\brief Description of how a QML document is a reusable type definition
-One of the core features of QML is that it enables QML object types to be easily defined in a lightweight manner through QML documents to suit the needs of individual QML applications. The standard \l {Qt Quick} module provides various types like \l Rectangle, \l Text and \l Image for building a QML application; beyond these, you can easily define your own QML types to be reused within your application. This ability to create your own types forms the building blocks of any QML application.
+One of the core features of QML is that it enables QML object types to be
+easily defined in a lightweight manner through QML documents to suit the needs
+of individual QML applications. The standard \l {Qt Quick} module provides
+various types like \l Rectangle, \l Text and \l Image for building a QML
+application; beyond these, you can easily define your own QML types to be
+reused within your application. This ability to create your own types forms the
+building blocks of any QML application.
\section1 Defining an Object Type with a QML File
\section2 Naming Custom QML Object Types
-To create an object type, a QML document should be placed into a text file named as \e <TypeName>.qml where \e <TypeName> is the desired name of the type. The type name has the following requirements:
+To create an object type, a QML document should be placed into a text file
+named as \e <TypeName>.qml where \e <TypeName> is the desired name of the type.
+The type name has the following requirements:
\list
\li It must be comprised of alphanumeric characters or underscores.
\li It must begin with an uppercase letter.
\endlist
-This document is then automatically recognized by the engine as a definition of a QML type. Additionally, a type defined in this manner is automatically made available to other QML files within the same directory as the engine searches within the immediate directory when resolving QML type names.
+This document is then automatically recognized by the engine as a definition of
+a QML type. Additionally, a type defined in this manner is automatically made
+available to other QML files within the same directory as the engine searches
+within the immediate directory when resolving QML type names.
\section2 Custom QML Type Definition
-For example, below is a document that declares a \l Rectangle with a child \l MouseArea. The document has been saved to file named \c SquareButton.qml:
+For example, below is a document that declares a \l Rectangle with a child \l
+MouseArea. The document has been saved to file named \c SquareButton.qml:
\qml
// SquareButton.qml
@@ -65,7 +77,10 @@ Rectangle {
}
\endqml
-Since the file is named \c SquareButton.qml, \b {this can now be used as a type named \c SquareButton by any other QML file within the same directory}. For example, if there was a \c myapplication.qml file in the same directory, it could refer to the \c SquareButton type:
+Since the file is named \c SquareButton.qml, \b {this can now be used as a type
+named \c SquareButton by any other QML file within the same directory}. For
+example, if there was a \c myapplication.qml file in the same directory, it
+could refer to the \c SquareButton type:
\qml
// myapplication.qml
@@ -76,23 +91,79 @@ SquareButton {}
\image documents-definetypes-simple.png
-This creates a 100 x 100 red \l Rectangle with an inner \l MouseArea, as defined in \c SquareButton.qml. When this \c myapplication.qml document is loaded by the engine, it loads the SquareButton.qml document as a component and instantiates it to create a \c SquareButton object.
+This creates a 100 x 100 red \l Rectangle with an inner \l MouseArea, as
+defined in \c SquareButton.qml. When this \c myapplication.qml document is
+loaded by the engine, it loads the SquareButton.qml document as a component and
+instantiates it to create a \c SquareButton object.
+
+The \c SquareButton type encapsulates the tree of QML objects declared in \c
+SquareButton.qml. When the QML engine instantiates a \c SquareButton object
+from this type, it is instantiating an object from the \l Rectangle tree
+declared in \c SquareButton.qml.
+
+\note the letter case of the file name is significant on some (notably UNIX)
+filesystems. It is recommended the file name case matches the case of the
+desired QML type name exactly - for example, \c Box.qml and not \c BoX.qml -
+regardless of the platform to which the QML type will be deployed.
+
+\section2 Inline Components
+
+Sometimes, it can be inconvenient to create a new file for a type, for
+instance when reusing a small delegate in multiple views. If you don't actually
+need to expose the type, but only need to create an instance,
+\l{QtQml::Component}{Component} is an option.
+But if you want to declare properties with the component types, or if you
+want to use it in multiple files, \c Component is not an option. In that case,
+you can use \e {inline components}. Inline components declare a new component
+inside of a file. The syntax for that is
+\code
+component <component name> : BaseType {
+ // declare properties and bindings here
+}
+\endcode
+
+Inside the file which declares the inline component, the type can be referenced
+simply by its name.
+
+\snippet src/qml/doc/snippets/qml/qml-documents/Images.qml document
+
+In other files, it has to be prefixed with the name of its containing component.
+\snippet src/qml/doc/snippets/qml/qml-documents/LabeledImageBox.qml document
+
+\note Inline components don't share their scope with the component they are
+declared in. In the following example, when \c A.MyInlineComponent in file
+B.qml gets created, a ReferenceError will occur, as \c root does not exist as
+an id in B.qml.
+It is therefore advisable not to reference objects in an inline component
+which are not part of it.
-The \c SquareButton type encapsulates the tree of QML objects declared in \c SquareButton.qml. When the QML engine instantiates a \c SquareButton object from this type, it is instantiating an object from the \l Rectangle tree declared in \c SquareButton.qml.
+\snippet src/qml/doc/snippets/qml/qml-documents/A.qml document
+\snippet src/qml/doc/snippets/qml/qml-documents/B.qml document
-\note the letter case of the file name is significant on some (notably UNIX) filesystems. It is recommended the file name case matches the case of the desired QML type name exactly - for example, \c Box.qml and not \c BoX.qml - regardless of the platform to which the QML type will be deployed.
+\note Inline components cannot be nested.
\section2 Importing Types Defined Outside the Current Directory
If \c SquareButton.qml was not in the same directory as \c myapplication.qml,
-the \c SquareButton type would need to be specifically made available through an \e import statement in \c myapplication.qml. It could be imported from a relative path on the file system, or as an installed module; see \l {QML Modules}{module} for more details.
+the \c SquareButton type would need to be specifically made available through
+an \e import statement in \c myapplication.qml. It could be imported from a
+relative path on the file system, or as an installed module; see \l {QML
+Modules}{module} for more details.
\section1 Accessible Attributes of Custom Types
-The \b {root object} definition in a .qml file \b {defines the attributes that are available for a QML type}. All properties, signals and methods that belong to this root object - whether they are custom declared, or come from the QML type of the root object - are externally accessible and can be read and modified for objects of this type.
+The \b {root object} definition in a .qml file \b {defines the attributes that
+are available for a QML type}. All properties, signals and methods that belong
+to this root object - whether they are custom declared, or come from the QML
+type of the root object - are externally accessible and can be read and
+modified for objects of this type.
-For example, the root object type in the \c SquareButton.qml file above is \l Rectangle. This means any properties defined by the \l Rectangle type can be modified for a \c SquareButton object. The code below defines three \c SquareButton objects with customized values for some of the properties of the root \l Rectangle object of the \c SquareButton type:
+For example, the root object type in the \c SquareButton.qml file above is \l
+Rectangle. This means any properties defined by the \l Rectangle type can be
+modified for a \c SquareButton object. The code below defines three \c
+SquareButton objects with customized values for some of the properties of the
+root \l Rectangle object of the \c SquareButton type:
\qml
// application.qml
@@ -107,7 +178,12 @@ Column {
\image documents-definetypes-attributes.png
-The attributes that are accessible to objects of the custom QML type include any \l{Defining Property Attributes}{custom properties}, \l{Defining Method Attributes}{methods} and \l{Defining Signal Attributes}{signals} that have additionally been defined for an object. For example, suppose the \l Rectangle in \c SquareButton.qml had been defined as follows, with additional properties, methods and signals:
+The attributes that are accessible to objects of the custom QML type include
+any \l{Defining Property Attributes}{custom properties}, \l{Defining Method
+Attributes}{methods} and \l{Defining Signal Attributes}{signals} that have
+additionally been defined for an object. For example, suppose the \l Rectangle
+in \c SquareButton.qml had been defined as follows, with additional properties,
+methods and signals:
\qml
// SquareButton.qml
@@ -136,7 +212,9 @@ Rectangle {
}
\endqml
-Any \c SquareButton object could make use of the \c pressed property, \c buttonClicked signal and \c randomizeColor() method that have been added to the root \l Rectangle:
+Any \c SquareButton object could make use of the \c pressed property, \c
+buttonClicked signal and \c randomizeColor() method that have been added to the
+root \l Rectangle:
\qml
// application.qml
@@ -154,7 +232,14 @@ SquareButton {
}
\endqml
-Note that any of the \c id values defined in \c SquareButton.qml are not accessible to \c SquareButton objects, as id values are only accessible from within the component scope in which a component is declared. The \c SquareButton object definition above cannot refer to \c mouseArea in order to refer to the \l MouseArea child, and if it had an \c id of \c root rather than \c squareButton, this would not conflict with the \c id of the same value for the root object defined in \c SquareButton.qml as the two would be declared within separate scopes.
+Note that any of the \c id values defined in \c SquareButton.qml are not
+accessible to \c SquareButton objects, as id values are only accessible from
+within the component scope in which a component is declared. The \c
+SquareButton object definition above cannot refer to \c mouseArea in order to
+refer to the \l MouseArea child, and if it had an \c id of \c root rather than
+\c squareButton, this would not conflict with the \c id of the same value for
+the root object defined in \c SquareButton.qml as the two would be declared
+within separate scopes.
*/
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index 401e099ebf..832d9a9e26 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
@@ -112,7 +112,7 @@ Alternatively, a custom property of an object type may be defined in
an object declaration in a QML document with the following syntax:
\code
- [default] property <propertyType> <propertyName>
+ [default] [required] [readonly] property <propertyType> <propertyName>
\endcode
In this way an object declaration may \l {Defining Object Types from QML}
@@ -121,10 +121,13 @@ state more easily.
Property names must begin with a lower case letter and can only contain
letters, numbers and underscores. \l {JavaScript Reserved Words}
-{JavaScript reserved words} are not valid property names. The \c default
-keyword is optional, and modifies the semantics of the property being declared.
-See the upcoming section on \l {Default Properties}{default properties} for
-more information about the \c default property modifier.
+{JavaScript reserved words} are not valid property names. The \c default,
+\c required, and \c readonly keywords are optional, and modify the semantics
+of the property being declared.
+See the upcoming sections on \l {Default Properties}{default properties},
+\l {Required Properties}{required properties} and,
+\l {Read-Only Properties}{read-only properties} for more information
+about their respective meaning.
Declaring a custom property implicitly creates a value-change
\l{Signal attributes}{signal} for that property, as well as an associated
@@ -647,6 +650,45 @@ the \l{TabWidget Example}, which uses a default property to
automatically reassign children of the TabWidget as children of an inner
ListView. See also \l {Extending QML}.
+\section3 Required Properties
+
+An object declaration may define a property as required, using the \c required
+keyword. The syntax is
+\code
+ required property <propertyType> <propertyName>
+\endcode
+
+As the name suggests, required properties must be set when an instance of the object
+is created. Violation of this rule will result in QML applications not starting if it can be
+detected statically. In case of dynamically instantiated QML components (for instance via
+\l {QtQml::Qt::createComponent()}{Qt.createComponent()}), violating this rule results in a
+warning and a null return value.
+
+It's possible to make an existing property required with
+\code
+ required <propertyName>
+\endcode
+The following example shows how to create a custom Rectangle component, in which the color
+property always needs to be specified.
+\qml
+// ColorRectangle.qml
+Rectangle {
+ required color
+}
+\endqml
+
+\note You can't assign an initial value to a required property from QML, as that would go
+directly against the intended usage of required properties.
+
+Required properties play a special role in model-view-delegate code:
+If the delegate of a view has required properties whose names match with
+the role names of the view's model, then those properties will be initialized
+with the model's corresponding values.
+For more information, visit the \l{Models and Views in QtQuick} page.
+
+\sa {QQmlComponent::createWithInitialProperties}, {QQmlApplicationEngine::setInitialProperties}
+and {QQuickView::setInitialProperties} for ways to initialize required properties from C++.
+
\section3 Read-Only Properties
An object declaration may define a read-only property using the \c readonly
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 86e178d568..a900e710c2 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -1512,12 +1512,37 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return QVariant::fromValue(QV4::JsonObject::toJsonArray(a));
}
+ QVariant retn;
#if QT_CONFIG(qml_sequence_object)
bool succeeded = false;
- QVariant retn = QV4::SequencePrototype::toVariant(value, typeHint, &succeeded);
+ retn = QV4::SequencePrototype::toVariant(value, typeHint, &succeeded);
if (succeeded)
return retn;
#endif
+ if (typeHint != -1) {
+ retn = QVariant(typeHint, QMetaType::create(typeHint));
+ auto retnAsIterable = retn.value<QtMetaTypePrivate::QSequentialIterableImpl>();
+ if (retnAsIterable._iteratorCapabilities & QtMetaTypePrivate::ContainerIsAppendable) {
+ auto const length = a->getLength();
+ QV4::ScopedValue arrayValue(scope);
+ for (qint64 i = 0; i < length; ++i) {
+ arrayValue = a->get(i);
+ QVariant asVariant = toVariant(e, arrayValue, retnAsIterable._metaType_id, false, visitedObjects);
+ auto originalType = asVariant.userType();
+ bool couldConvert = asVariant.convert(retnAsIterable._metaType_id);
+ if (!couldConvert) {
+ qWarning() << QLatin1String("Could not convert array value at position %1 from %2 to %3")
+ .arg(QString::number(i),
+ QMetaType::typeName(originalType),
+ QMetaType::typeName(retnAsIterable._metaType_id));
+ // create default constructed value
+ asVariant = QVariant(retnAsIterable._metaType_id, nullptr);
+ }
+ retnAsIterable.append(asVariant.constData());
+ }
+ return retn;
+ }
+ }
}
if (value.isUndefined())
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index d29b060b9e..3449603a8a 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -250,6 +250,8 @@ bool Value::sameValue(Value other) const {
if (isDouble() && other.isInteger())
return other.int_32() ? (doubleValue() == double(other.int_32()))
: (doubleValue() == 0 && !std::signbit(doubleValue()));
+ if (isManaged())
+ return other.isManaged() && cast<Managed>()->isEqualTo(other.cast<Managed>());
return false;
}
@@ -269,6 +271,8 @@ bool Value::sameValueZero(Value other) const {
return true;
}
}
+ if (isManaged())
+ return other.isManaged() && cast<Managed>()->isEqualTo(other.cast<Managed>());
return false;
}
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index ce715b0b9c..a246dfba7a 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -326,6 +326,8 @@ public:
AST::UiQualifiedId *UiQualifiedId;
AST::UiEnumMemberList *UiEnumMemberList;
AST::UiVersionSpecifier *UiVersionSpecifier;
+ AST::UiAnnotation *UiAnnotation;
+ AST::UiAnnotationList *UiAnnotationList;
};
public:
@@ -967,24 +969,30 @@ UiAnnotationObjectDefinition: UiSimpleQualifiedId UiObjectInitializer;
return false;
}
- AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId, sym(2).UiObjectInitializer);
+ AST::UiAnnotation *node = new (pool) AST::UiAnnotation(sym(1).UiQualifiedId, sym(2).UiObjectInitializer);
sym(1).Node = node;
} break;
./
UiAnnotation: T_AT UiAnnotationObjectDefinition;
+/.
+case $rule_number: {
+ sym(1).Node = sym(2).Node;
+} break;
+./
+
UiAnnotationList: UiAnnotation;
/.
case $rule_number: {
- sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember);
+ sym(1).Node = new (pool) AST::UiAnnotationList(sym(1).UiAnnotation);
} break;
./
UiAnnotationList: UiAnnotationList UiAnnotation;
/.
case $rule_number: {
- AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(sym(1).UiArrayMemberList, sym(3).UiObjectMember);
+ AST::UiAnnotationList *node = new (pool) AST::UiAnnotationList(sym(1).UiAnnotationList, sym(2).UiAnnotation);
sym(1).Node = node;
} break;
./
@@ -992,7 +1000,9 @@ UiAnnotationList: UiAnnotationList UiAnnotation;
UiAnnotatedObject: UiAnnotationList UiObjectDefinition;
/.
case $rule_number: {
- sym(1).Node = sym(2).Node;
+ AST::UiObjectDefinition *node = sym(2).UiObjectDefinition;
+ node->annotations = sym(1).UiAnnotationList->finish();
+ sym(1).Node = node;
} break;
./
@@ -1060,6 +1070,8 @@ UiObjectDefinition: UiQualifiedId UiObjectInitializer;
UiAnnotatedObjectMember: UiAnnotationList UiObjectMember;
/.
case $rule_number: {
+ AST::UiObjectMember *node = sym(2).UiObjectMember;
+ node->annotations = sym(1).UiAnnotationList->finish();
sym(1).Node = sym(2).Node;
} break;
./
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 416916c547..2a34c5a66c 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -167,7 +167,7 @@ UiObjectMember *UiObjectMember::uiObjectMemberCast()
return this;
}
-void NestedExpression::accept0(Visitor *visitor)
+void NestedExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -185,7 +185,7 @@ ClassExpression *NestedExpression::asClassDefinition()
return expression->asClassDefinition();
}
-void ThisExpression::accept0(Visitor *visitor)
+void ThisExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -193,7 +193,7 @@ void ThisExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void IdentifierExpression::accept0(Visitor *visitor)
+void IdentifierExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -201,7 +201,7 @@ void IdentifierExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NullExpression::accept0(Visitor *visitor)
+void NullExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -209,7 +209,7 @@ void NullExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TrueLiteral::accept0(Visitor *visitor)
+void TrueLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -217,7 +217,7 @@ void TrueLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FalseLiteral::accept0(Visitor *visitor)
+void FalseLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -225,7 +225,7 @@ void FalseLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void SuperLiteral::accept0(Visitor *visitor)
+void SuperLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -234,7 +234,7 @@ void SuperLiteral::accept0(Visitor *visitor)
}
-void StringLiteral::accept0(Visitor *visitor)
+void StringLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -242,7 +242,7 @@ void StringLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TemplateLiteral::accept0(Visitor *visitor)
+void TemplateLiteral::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (TemplateLiteral *it = this; it && accepted; it = it->next) {
@@ -251,7 +251,7 @@ void TemplateLiteral::accept0(Visitor *visitor)
}
}
-void NumericLiteral::accept0(Visitor *visitor)
+void NumericLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -259,7 +259,7 @@ void NumericLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void RegExpLiteral::accept0(Visitor *visitor)
+void RegExpLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -267,7 +267,7 @@ void RegExpLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ArrayPattern::accept0(Visitor *visitor)
+void ArrayPattern::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this))
accept(elements, visitor);
@@ -287,7 +287,7 @@ bool ArrayPattern::isValidArrayLiteral(SourceLocation *errorLocation) const {
return true;
}
-void ObjectPattern::accept0(Visitor *visitor)
+void ObjectPattern::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(properties, visitor);
@@ -462,7 +462,7 @@ bool PatternProperty::convertLiteralToAssignmentPattern(MemoryPool *pool, Source
}
-void Elision::accept0(Visitor *visitor)
+void Elision::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
// ###
@@ -471,7 +471,7 @@ void Elision::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void IdentifierPropertyName::accept0(Visitor *visitor)
+void IdentifierPropertyName::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -479,7 +479,7 @@ void IdentifierPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void StringLiteralPropertyName::accept0(Visitor *visitor)
+void StringLiteralPropertyName::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -487,7 +487,7 @@ void StringLiteralPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NumericLiteralPropertyName::accept0(Visitor *visitor)
+void NumericLiteralPropertyName::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -517,7 +517,7 @@ QString NumericLiteralPropertyName::asString()const
return locale.toString(id, 'g', 16);
}
-void ArrayMemberExpression::accept0(Visitor *visitor)
+void ArrayMemberExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -527,7 +527,7 @@ void ArrayMemberExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FieldMemberExpression::accept0(Visitor *visitor)
+void FieldMemberExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -536,7 +536,7 @@ void FieldMemberExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NewMemberExpression::accept0(Visitor *visitor)
+void NewMemberExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -546,7 +546,7 @@ void NewMemberExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NewExpression::accept0(Visitor *visitor)
+void NewExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -555,7 +555,7 @@ void NewExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void CallExpression::accept0(Visitor *visitor)
+void CallExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -565,7 +565,7 @@ void CallExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ArgumentList::accept0(Visitor *visitor)
+void ArgumentList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (ArgumentList *it = this; it; it = it->next) {
@@ -576,7 +576,7 @@ void ArgumentList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PostIncrementExpression::accept0(Visitor *visitor)
+void PostIncrementExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -585,7 +585,7 @@ void PostIncrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PostDecrementExpression::accept0(Visitor *visitor)
+void PostDecrementExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -594,7 +594,7 @@ void PostDecrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void DeleteExpression::accept0(Visitor *visitor)
+void DeleteExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -603,7 +603,7 @@ void DeleteExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void VoidExpression::accept0(Visitor *visitor)
+void VoidExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -612,7 +612,7 @@ void VoidExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TypeOfExpression::accept0(Visitor *visitor)
+void TypeOfExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -621,7 +621,7 @@ void TypeOfExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PreIncrementExpression::accept0(Visitor *visitor)
+void PreIncrementExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -630,7 +630,7 @@ void PreIncrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PreDecrementExpression::accept0(Visitor *visitor)
+void PreDecrementExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -639,7 +639,7 @@ void PreDecrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UnaryPlusExpression::accept0(Visitor *visitor)
+void UnaryPlusExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -648,7 +648,7 @@ void UnaryPlusExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UnaryMinusExpression::accept0(Visitor *visitor)
+void UnaryMinusExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -657,7 +657,7 @@ void UnaryMinusExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TildeExpression::accept0(Visitor *visitor)
+void TildeExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -666,7 +666,7 @@ void TildeExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NotExpression::accept0(Visitor *visitor)
+void NotExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -675,7 +675,7 @@ void NotExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void BinaryExpression::accept0(Visitor *visitor)
+void BinaryExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(left, visitor);
@@ -685,7 +685,7 @@ void BinaryExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ConditionalExpression::accept0(Visitor *visitor)
+void ConditionalExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -696,7 +696,7 @@ void ConditionalExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void Expression::accept0(Visitor *visitor)
+void Expression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(left, visitor);
@@ -706,7 +706,7 @@ void Expression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void Block::accept0(Visitor *visitor)
+void Block::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statements, visitor);
@@ -715,7 +715,7 @@ void Block::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void StatementList::accept0(Visitor *visitor)
+void StatementList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (StatementList *it = this; it; it = it->next) {
@@ -726,7 +726,7 @@ void StatementList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void VariableStatement::accept0(Visitor *visitor)
+void VariableStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(declarations, visitor);
@@ -735,7 +735,7 @@ void VariableStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void VariableDeclarationList::accept0(Visitor *visitor)
+void VariableDeclarationList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (VariableDeclarationList *it = this; it; it = it->next) {
@@ -746,7 +746,7 @@ void VariableDeclarationList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void EmptyStatement::accept0(Visitor *visitor)
+void EmptyStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -754,7 +754,7 @@ void EmptyStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ExpressionStatement::accept0(Visitor *visitor)
+void ExpressionStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -763,7 +763,7 @@ void ExpressionStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void IfStatement::accept0(Visitor *visitor)
+void IfStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -774,7 +774,7 @@ void IfStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void DoWhileStatement::accept0(Visitor *visitor)
+void DoWhileStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statement, visitor);
@@ -784,7 +784,7 @@ void DoWhileStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void WhileStatement::accept0(Visitor *visitor)
+void WhileStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -794,7 +794,7 @@ void WhileStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ForStatement::accept0(Visitor *visitor)
+void ForStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(initialiser, visitor);
@@ -807,7 +807,7 @@ void ForStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ForEachStatement::accept0(Visitor *visitor)
+void ForEachStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(lhs, visitor);
@@ -818,7 +818,7 @@ void ForEachStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ContinueStatement::accept0(Visitor *visitor)
+void ContinueStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -826,7 +826,7 @@ void ContinueStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void BreakStatement::accept0(Visitor *visitor)
+void BreakStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -834,7 +834,7 @@ void BreakStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ReturnStatement::accept0(Visitor *visitor)
+void ReturnStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -843,7 +843,7 @@ void ReturnStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void YieldExpression::accept0(Visitor *visitor)
+void YieldExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -853,7 +853,7 @@ void YieldExpression::accept0(Visitor *visitor)
}
-void WithStatement::accept0(Visitor *visitor)
+void WithStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -863,7 +863,7 @@ void WithStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void SwitchStatement::accept0(Visitor *visitor)
+void SwitchStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -873,7 +873,7 @@ void SwitchStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void CaseBlock::accept0(Visitor *visitor)
+void CaseBlock::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(clauses, visitor);
@@ -884,7 +884,7 @@ void CaseBlock::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void CaseClauses::accept0(Visitor *visitor)
+void CaseClauses::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (CaseClauses *it = this; it; it = it->next) {
@@ -895,7 +895,7 @@ void CaseClauses::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void CaseClause::accept0(Visitor *visitor)
+void CaseClause::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -905,7 +905,7 @@ void CaseClause::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void DefaultClause::accept0(Visitor *visitor)
+void DefaultClause::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statements, visitor);
@@ -914,7 +914,7 @@ void DefaultClause::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void LabelledStatement::accept0(Visitor *visitor)
+void LabelledStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statement, visitor);
@@ -923,7 +923,7 @@ void LabelledStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ThrowStatement::accept0(Visitor *visitor)
+void ThrowStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -932,7 +932,7 @@ void ThrowStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TryStatement::accept0(Visitor *visitor)
+void TryStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statement, visitor);
@@ -943,7 +943,7 @@ void TryStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void Catch::accept0(Visitor *visitor)
+void Catch::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(patternElement, visitor);
@@ -953,7 +953,7 @@ void Catch::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void Finally::accept0(Visitor *visitor)
+void Finally::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statement, visitor);
@@ -962,7 +962,7 @@ void Finally::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FunctionDeclaration::accept0(Visitor *visitor)
+void FunctionDeclaration::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(formals, visitor);
@@ -973,7 +973,7 @@ void FunctionDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FunctionExpression::accept0(Visitor *visitor)
+void FunctionExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(formals, visitor);
@@ -1018,7 +1018,7 @@ BoundNames FormalParameterList::boundNames() const
return names;
}
-void FormalParameterList::accept0(Visitor *visitor)
+void FormalParameterList::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (FormalParameterList *it = this; it && accepted; it = it->next) {
@@ -1043,7 +1043,7 @@ FormalParameterList *FormalParameterList::finish(QQmlJS::MemoryPool *pool)
return front;
}
-void Program::accept0(Visitor *visitor)
+void Program::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statements, visitor);
@@ -1052,7 +1052,7 @@ void Program::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ImportSpecifier::accept0(Visitor *visitor)
+void ImportSpecifier::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
@@ -1060,7 +1060,7 @@ void ImportSpecifier::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ImportsList::accept0(Visitor *visitor)
+void ImportsList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (ImportsList *it = this; it; it = it->next) {
@@ -1071,7 +1071,7 @@ void ImportsList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NamedImports::accept0(Visitor *visitor)
+void NamedImports::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(importsList, visitor);
@@ -1080,7 +1080,7 @@ void NamedImports::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FromClause::accept0(Visitor *visitor)
+void FromClause::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1088,7 +1088,7 @@ void FromClause::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NameSpaceImport::accept0(Visitor *visitor)
+void NameSpaceImport::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1096,7 +1096,7 @@ void NameSpaceImport::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ImportClause::accept0(Visitor *visitor)
+void ImportClause::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(nameSpaceImport, visitor);
@@ -1106,7 +1106,7 @@ void ImportClause::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ImportDeclaration::accept0(Visitor *visitor)
+void ImportDeclaration::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(importClause, visitor);
@@ -1116,7 +1116,7 @@ void ImportDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ExportSpecifier::accept0(Visitor *visitor)
+void ExportSpecifier::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
@@ -1125,7 +1125,7 @@ void ExportSpecifier::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ExportsList::accept0(Visitor *visitor)
+void ExportsList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (ExportsList *it = this; it; it = it->next) {
@@ -1136,7 +1136,7 @@ void ExportsList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ExportClause::accept0(Visitor *visitor)
+void ExportClause::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(exportsList, visitor);
@@ -1145,7 +1145,7 @@ void ExportClause::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ExportDeclaration::accept0(Visitor *visitor)
+void ExportDeclaration::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(fromClause, visitor);
@@ -1156,7 +1156,7 @@ void ExportDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ESModule::accept0(Visitor *visitor)
+void ESModule::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(body, visitor);
@@ -1165,7 +1165,7 @@ void ESModule::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void DebuggerStatement::accept0(Visitor *visitor)
+void DebuggerStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1173,7 +1173,7 @@ void DebuggerStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiProgram::accept0(Visitor *visitor)
+void UiProgram::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(headers, visitor);
@@ -1183,19 +1183,23 @@ void UiProgram::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiPublicMember::accept0(Visitor *visitor)
+void UiPublicMember::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
+ // accept(memberType, visitor); // accept manually in visit if interested
accept(statement, visitor);
accept(binding, visitor);
+ // accept(parameters, visitor); // accept manually in visit if interested
}
visitor->endVisit(this);
}
-void UiObjectDefinition::accept0(Visitor *visitor)
+void UiObjectDefinition::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedTypeNameId, visitor);
accept(initializer, visitor);
}
@@ -1203,7 +1207,7 @@ void UiObjectDefinition::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiObjectInitializer::accept0(Visitor *visitor)
+void UiObjectInitializer::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(members, visitor);
@@ -1212,16 +1216,18 @@ void UiObjectInitializer::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiParameterList::accept0(Visitor *visitor)
+void UiParameterList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(type, visitor); // accept manually in visit if interested
}
visitor->endVisit(this);
}
-void UiObjectBinding::accept0(Visitor *visitor)
+void UiObjectBinding::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedId, visitor);
accept(qualifiedTypeNameId, visitor);
accept(initializer, visitor);
@@ -1230,9 +1236,10 @@ void UiObjectBinding::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiScriptBinding::accept0(Visitor *visitor)
+void UiScriptBinding::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedId, visitor);
accept(statement, visitor);
}
@@ -1240,9 +1247,10 @@ void UiScriptBinding::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiArrayBinding::accept0(Visitor *visitor)
+void UiArrayBinding::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedId, visitor);
accept(members, visitor);
}
@@ -1250,7 +1258,7 @@ void UiArrayBinding::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiObjectMemberList::accept0(Visitor *visitor)
+void UiObjectMemberList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (UiObjectMemberList *it = this; it; it = it->next)
@@ -1260,7 +1268,7 @@ void UiObjectMemberList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiArrayMemberList::accept0(Visitor *visitor)
+void UiArrayMemberList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (UiArrayMemberList *it = this; it; it = it->next)
@@ -1270,15 +1278,16 @@ void UiArrayMemberList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiQualifiedId::accept0(Visitor *visitor)
+void UiQualifiedId::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(next, visitor) // accept manually in visit if interested
}
visitor->endVisit(this);
}
-void Type::accept0(Visitor *visitor)
+void Type::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(typeId, visitor);
@@ -1288,7 +1297,7 @@ void Type::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TypeArgumentList::accept0(Visitor *visitor)
+void TypeArgumentList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (TypeArgumentList *it = this; it; it = it->next)
@@ -1298,7 +1307,7 @@ void TypeArgumentList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TypeAnnotation::accept0(Visitor *visitor)
+void TypeAnnotation::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(type, visitor);
@@ -1307,16 +1316,17 @@ void TypeAnnotation::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiImport::accept0(Visitor *visitor)
+void UiImport::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(importUri, visitor);
+ // accept(version, visitor); // accept manually in visit if interested
}
visitor->endVisit(this);
}
-void UiPragma::accept0(Visitor *visitor)
+void UiPragma::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1324,7 +1334,7 @@ void UiPragma::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiHeaderItemList::accept0(Visitor *visitor)
+void UiHeaderItemList::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (UiHeaderItemList *it = this; it && accepted; it = it->next) {
@@ -1337,25 +1347,27 @@ void UiHeaderItemList::accept0(Visitor *visitor)
}
-void UiSourceElement::accept0(Visitor *visitor)
+void UiSourceElement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(sourceElement, visitor);
}
visitor->endVisit(this);
}
-void UiEnumDeclaration::accept0(Visitor *visitor)
+void UiEnumDeclaration::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(members, visitor);
}
visitor->endVisit(this);
}
-void UiEnumMemberList::accept0(Visitor *visitor)
+void UiEnumMemberList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1363,7 +1375,7 @@ void UiEnumMemberList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TaggedTemplate::accept0(Visitor *visitor)
+void TaggedTemplate::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -1373,7 +1385,7 @@ void TaggedTemplate::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PatternElement::accept0(Visitor *visitor)
+void PatternElement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(bindingTarget, visitor);
@@ -1396,7 +1408,7 @@ void PatternElement::boundNames(BoundNames *names)
}
}
-void PatternElementList::accept0(Visitor *visitor)
+void PatternElementList::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (PatternElementList *it = this; it && accepted; it = it->next) {
@@ -1417,7 +1429,7 @@ void PatternElementList::boundNames(BoundNames *names)
}
}
-void PatternProperty::accept0(Visitor *visitor)
+void PatternProperty::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(name, visitor);
@@ -1434,7 +1446,7 @@ void PatternProperty::boundNames(BoundNames *names)
PatternElement::boundNames(names);
}
-void PatternPropertyList::accept0(Visitor *visitor)
+void PatternPropertyList::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (PatternPropertyList *it = this; it && accepted; it = it->next) {
@@ -1451,7 +1463,7 @@ void PatternPropertyList::boundNames(BoundNames *names)
it->property->boundNames(names);
}
-void ComputedPropertyName::accept0(Visitor *visitor)
+void ComputedPropertyName::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -1460,7 +1472,7 @@ void ComputedPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ClassExpression::accept0(Visitor *visitor)
+void ClassExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(heritage, visitor);
@@ -1475,7 +1487,7 @@ ClassExpression *ClassExpression::asClassDefinition()
return this;
}
-void ClassDeclaration::accept0(Visitor *visitor)
+void ClassDeclaration::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(heritage, visitor);
@@ -1485,7 +1497,7 @@ void ClassDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ClassElementList::accept0(Visitor *visitor)
+void ClassElementList::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (ClassElementList *it = this; it && accepted; it = it->next) {
@@ -1514,7 +1526,7 @@ LeftHandSideExpression *LeftHandSideExpression::leftHandSideExpressionCast()
return this;
}
-void UiVersionSpecifier::accept0(Visitor *visitor)
+void UiVersionSpecifier::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1545,16 +1557,17 @@ void Type::toString(QString *out) const
};
}
-void UiInlineComponent::accept0(Visitor *visitor)
+void UiInlineComponent::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(component, visitor);
}
visitor->endVisit(this);
}
-void UiRequired::accept0(Visitor *visitor)
+void UiRequired::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1562,6 +1575,26 @@ void UiRequired::accept0(Visitor *visitor)
visitor->endVisit(this);
}
+void UiAnnotationList::accept0(BaseVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ for (UiAnnotationList *it = this; it; it = it->next)
+ accept(it->annotation, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void UiAnnotation::accept0(BaseVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(qualifiedTypeNameId, visitor);
+ accept(initializer, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
} } // namespace QQmlJS::AST
QT_END_NAMESPACE
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 446704be91..b92a635228 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -260,7 +260,9 @@ public:
Kind_UiEnumDeclaration,
Kind_UiEnumMemberList,
Kind_UiVersionSpecifier,
- Kind_UiRequired
+ Kind_UiRequired,
+ Kind_UiAnnotation,
+ Kind_UiAnnotationList
};
inline Node() {}
@@ -282,9 +284,9 @@ public:
bool ignoreRecursionDepth() const;
- inline void accept(Visitor *visitor)
+ inline void accept(BaseVisitor *visitor)
{
- Visitor::RecursionDepthCheck recursionCheck(visitor);
+ BaseVisitor::RecursionDepthCheck recursionCheck(visitor);
// Stack overflow is uncommon, ignoreRecursionDepth() only returns true if
// QV4_CRASH_ON_STACKOVERFLOW is set, and ignoreRecursionDepth() needs to be out of line.
@@ -298,19 +300,19 @@ public:
}
}
- inline static void accept(Node *node, Visitor *visitor)
+ inline static void accept(Node *node, BaseVisitor *visitor)
{
if (node)
node->accept(visitor);
}
// ### Remove when we can. This is part of the qmldevtools library, though.
- inline static void acceptChild(Node *node, Visitor *visitor)
+ inline static void acceptChild(Node *node, BaseVisitor *visitor)
{
return accept(node, visitor);
}
- virtual void accept0(Visitor *visitor) = 0;
+ virtual void accept0(BaseVisitor *visitor) = 0;
virtual SourceLocation firstSourceLocation() const = 0;
virtual SourceLocation lastSourceLocation() const = 0;
@@ -351,7 +353,7 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
@@ -375,7 +377,7 @@ public:
, typeArguments(typeArguments)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return typeId->firstSourceLocation(); }
@@ -410,7 +412,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return typeId->firstSourceLocation(); }
@@ -439,7 +441,7 @@ public:
: type(type)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return colonToken; }
@@ -484,7 +486,7 @@ public:
: expression(expression)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lparenToken; }
@@ -509,7 +511,7 @@ public:
ThisExpression() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return thisToken; }
@@ -529,7 +531,7 @@ public:
IdentifierExpression(const QStringRef &n):
name (n) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
@@ -549,7 +551,7 @@ public:
NullExpression() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return nullToken; }
@@ -568,7 +570,7 @@ public:
TrueLiteral() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return trueToken; }
@@ -587,7 +589,7 @@ public:
FalseLiteral() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return falseToken; }
@@ -606,7 +608,7 @@ public:
SuperLiteral() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return superToken; }
@@ -627,7 +629,7 @@ public:
NumericLiteral(double v):
value(v) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return literalToken; }
@@ -650,7 +652,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override { return majorToken; }
@@ -673,7 +675,7 @@ public:
StringLiteral(const QStringRef &v):
value (v) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return literalToken; }
@@ -704,7 +706,7 @@ public:
return (last->expression ? last->expression->lastSourceLocation() : last->literalToken);
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QStringRef value;
QStringRef rawValue;
@@ -721,7 +723,7 @@ public:
RegExpLiteral(const QStringRef &p, int f):
pattern (p), flags (f) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return literalToken; }
@@ -756,7 +758,7 @@ public:
: elements(elts)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbracketToken; }
@@ -787,7 +789,7 @@ public:
: properties(plist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbraceToken; }
@@ -818,7 +820,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return commaToken; }
@@ -924,7 +926,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
virtual bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage);
SourceLocation firstSourceLocation() const override
@@ -977,7 +979,7 @@ public:
return front;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
void boundNames(BoundNames *names);
@@ -1012,7 +1014,7 @@ public:
: PatternElement(pattern, i), name(name)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return name->firstSourceLocation(); }
@@ -1048,7 +1050,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
void boundNames(BoundNames *names);
@@ -1077,7 +1079,7 @@ public:
IdentifierPropertyName(const QStringRef &n):
id (n) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QString asString() const override { return id.toString(); }
@@ -1093,7 +1095,7 @@ public:
StringLiteralPropertyName(const QStringRef &n):
id (n) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QString asString() const override { return id.toString(); }
@@ -1109,7 +1111,7 @@ public:
NumericLiteralPropertyName(double n):
id (n) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QString asString() const override;
@@ -1126,7 +1128,7 @@ public:
: expression(expression)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QString asString() const override { return QString(); }
@@ -1150,7 +1152,7 @@ public:
base (b), expression (e)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1174,7 +1176,7 @@ public:
base (b), name (n)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1198,7 +1200,7 @@ public:
: base (b), templateLiteral(t)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1220,7 +1222,7 @@ public:
base (b), arguments (a)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return newToken; }
@@ -1244,7 +1246,7 @@ public:
NewExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return newToken; }
@@ -1266,7 +1268,7 @@ public:
base (b), arguments (a)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1298,7 +1300,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return expression->firstSourceLocation(); }
@@ -1332,7 +1334,7 @@ public:
PostIncrementExpression(ExpressionNode *b):
base (b) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1353,7 +1355,7 @@ public:
PostDecrementExpression(ExpressionNode *b):
base (b) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1374,7 +1376,7 @@ public:
DeleteExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return deleteToken; }
@@ -1395,7 +1397,7 @@ public:
VoidExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return voidToken; }
@@ -1416,7 +1418,7 @@ public:
TypeOfExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return typeofToken; }
@@ -1437,7 +1439,7 @@ public:
PreIncrementExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return incrementToken; }
@@ -1458,7 +1460,7 @@ public:
PreDecrementExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return decrementToken; }
@@ -1479,7 +1481,7 @@ public:
UnaryPlusExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return plusToken; }
@@ -1500,7 +1502,7 @@ public:
UnaryMinusExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return minusToken; }
@@ -1521,7 +1523,7 @@ public:
TildeExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return tildeToken; }
@@ -1542,7 +1544,7 @@ public:
NotExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return notToken; }
@@ -1566,7 +1568,7 @@ public:
BinaryExpression *binaryExpressionCast() override;
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return left->firstSourceLocation(); }
@@ -1590,7 +1592,7 @@ public:
expression (e), ok (t), ko (f)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return expression->firstSourceLocation(); }
@@ -1614,7 +1616,7 @@ public:
Expression(ExpressionNode *l, ExpressionNode *r):
left (l), right (r) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return left->firstSourceLocation(); }
@@ -1636,7 +1638,7 @@ public:
Block(StatementList *slist):
statements (slist) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbraceToken; }
@@ -1666,7 +1668,7 @@ public:
return n;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return statement->firstSourceLocation(); }
@@ -1705,7 +1707,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return declaration->firstSourceLocation(); }
@@ -1743,7 +1745,7 @@ public:
declarations (vlist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return declarationKindToken; }
@@ -1763,7 +1765,7 @@ public:
EmptyStatement() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return semicolonToken; }
@@ -1783,7 +1785,7 @@ public:
ExpressionStatement(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return expression->firstSourceLocation(); }
@@ -1805,7 +1807,7 @@ public:
expression (e), ok (t), ko (f)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return ifToken; }
@@ -1837,7 +1839,7 @@ public:
statement (stmt), expression (e)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return doToken; }
@@ -1864,7 +1866,7 @@ public:
expression (e), statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return whileToken; }
@@ -1894,7 +1896,7 @@ public:
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return forToken; }
@@ -1932,7 +1934,7 @@ public:
: lhs(v), expression(e), statement(stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return forToken; }
@@ -1963,7 +1965,7 @@ public:
ContinueStatement(const QStringRef &l = QStringRef()):
label (l) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return continueToken; }
@@ -1986,7 +1988,7 @@ public:
BreakStatement(const QStringRef &l):
label (l) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return breakToken; }
@@ -2009,7 +2011,7 @@ public:
ReturnStatement(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return returnToken; }
@@ -2031,7 +2033,7 @@ public:
YieldExpression(ExpressionNode *e = nullptr):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return yieldToken; }
@@ -2054,7 +2056,7 @@ public:
expression (e), statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return withToken; }
@@ -2079,7 +2081,7 @@ public:
clauses (c), defaultClause (d), moreClauses (r)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbraceToken; }
@@ -2104,7 +2106,7 @@ public:
expression (e), block (b)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return switchToken; }
@@ -2129,7 +2131,7 @@ public:
expression (e), statements (slist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return caseToken; }
@@ -2161,7 +2163,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return clause->firstSourceLocation(); }
@@ -2192,7 +2194,7 @@ public:
statements (slist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return defaultToken; }
@@ -2215,7 +2217,7 @@ public:
label (l), statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
@@ -2238,7 +2240,7 @@ public:
ThrowStatement(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return throwToken; }
@@ -2261,7 +2263,7 @@ public:
: patternElement(p), statement(stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return catchToken; }
@@ -2287,7 +2289,7 @@ public:
statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return finallyToken; }
@@ -2317,7 +2319,7 @@ public:
statement (stmt), catchExpression (c), finallyExpression (nullptr)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return tryToken; }
@@ -2349,7 +2351,7 @@ public:
typeAnnotation(typeAnnotation)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return functionToken; }
@@ -2383,7 +2385,7 @@ public:
FunctionExpression(n, f, b, typeAnnotation)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
};
class QML_PARSER_EXPORT FormalParameterList: public Node
@@ -2454,7 +2456,7 @@ public:
BoundNames boundNames() const;
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return element->firstSourceLocation(); }
@@ -2480,7 +2482,7 @@ public:
: name(n), heritage(heritage), elements(elements)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return classToken; }
@@ -2509,7 +2511,7 @@ public:
: ClassExpression(n, heritage, elements)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
};
@@ -2531,7 +2533,7 @@ public:
return n;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return property->firstSourceLocation(); }
@@ -2559,7 +2561,7 @@ public:
: statements(statements)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return statements ? statements->firstSourceLocation() : SourceLocation(); }
@@ -2588,7 +2590,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifier.isNull() ? importedBindingToken : identifierToken; }
@@ -2633,7 +2635,7 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return importSpecifierToken; }
@@ -2665,7 +2667,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return leftBraceToken; }
@@ -2689,7 +2691,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
virtual SourceLocation firstSourceLocation() const override
{ return starToken; }
@@ -2739,7 +2741,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
virtual SourceLocation firstSourceLocation() const override
{ return importedDefaultBinding.isNull() ? (nameSpaceImport ? nameSpaceImport->firstSourceLocation() : namedImports->firstSourceLocation()) : importedDefaultBindingToken; }
@@ -2764,7 +2766,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return fromToken; }
@@ -2795,7 +2797,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return importToken; }
@@ -2828,7 +2830,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
@@ -2873,7 +2875,7 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return exportSpecifier->firstSourceLocation(); }
@@ -2901,7 +2903,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return leftBraceToken; }
@@ -2945,7 +2947,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return exportToken; }
@@ -2972,7 +2974,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return body ? body->firstSourceLocation() : SourceLocation(); }
@@ -2992,7 +2994,7 @@ public:
DebuggerStatement()
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return debuggerToken; }
@@ -3018,7 +3020,7 @@ public:
: importUri(uri)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return importToken; }
@@ -3045,6 +3047,9 @@ public:
SourceLocation lastSourceLocation() const override = 0;
UiObjectMember *uiObjectMemberCast() override;
+
+// attributes
+ UiAnnotationList *annotations = nullptr;
};
class QML_PARSER_EXPORT UiObjectMemberList: public Node
@@ -3064,7 +3069,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return member->firstSourceLocation(); }
@@ -3093,7 +3098,7 @@ public:
: name(name)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return pragmaToken; }
@@ -3116,7 +3121,7 @@ public:
:name(name)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return requiredToken; }
@@ -3165,7 +3170,7 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return headerItem->firstSourceLocation(); }
@@ -3187,7 +3192,7 @@ public:
: headers(headers), members(members)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{
@@ -3229,7 +3234,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return member->firstSourceLocation(); }
@@ -3259,7 +3264,7 @@ public:
: members(members)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbraceToken; }
@@ -3290,7 +3295,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *) override;
+ void accept0(BaseVisitor *) override;
SourceLocation firstSourceLocation() const override
{ return colonToken.isValid() ? identifierToken : propertyTypeToken; }
@@ -3334,7 +3339,7 @@ public:
: type(Property), memberType(memberType), name(name), statement(statement), binding(nullptr), isDefaultMember(false), isReadonlyMember(false), parameters(nullptr)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{
@@ -3391,7 +3396,7 @@ public:
: qualifiedTypeNameId(qualifiedTypeNameId), initializer(initializer)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return qualifiedTypeNameId->identifierToken; }
@@ -3413,17 +3418,18 @@ public:
: name(inlineComponentName), component(inlineComponent)
{ kind = K; }
- QStringRef name;
- UiObjectDefinition* component;
- SourceLocation componentToken;
-
SourceLocation lastSourceLocation() const override
{return component->lastSourceLocation();}
SourceLocation firstSourceLocation() const override
{return componentToken;}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
+
+ // attributes
+ QStringRef name;
+ UiObjectDefinition* component;
+ SourceLocation componentToken;
};
class QML_PARSER_EXPORT UiSourceElement: public UiObjectMember
@@ -3455,7 +3461,7 @@ public:
return SourceLocation();
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
@@ -3487,7 +3493,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return initializer->rbraceToken; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
@@ -3515,7 +3521,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return statement->lastSourceLocation(); }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
UiQualifiedId *qualifiedId;
@@ -3540,7 +3546,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return rbracketToken; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
UiQualifiedId *qualifiedId;
@@ -3584,7 +3590,7 @@ public:
return last->valueToken.isValid() ? last->valueToken : last->memberToken;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
UiEnumMemberList *finish()
{
@@ -3618,7 +3624,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return rbraceToken; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
SourceLocation enumToken;
@@ -3627,8 +3633,67 @@ public:
UiEnumMemberList *members;
};
-} } // namespace AST
+class QML_PARSER_EXPORT UiAnnotation: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(UiAnnotation)
+ UiAnnotation(UiQualifiedId *qualifiedTypeNameId,
+ UiObjectInitializer *initializer)
+ : qualifiedTypeNameId(qualifiedTypeNameId), initializer(initializer)
+ { kind = K; }
+
+ void accept0(BaseVisitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return qualifiedTypeNameId->identifierToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return initializer->rbraceToken; }
+
+// attributes
+ UiQualifiedId *qualifiedTypeNameId;
+ UiObjectInitializer *initializer;
+};
+
+class QML_PARSER_EXPORT UiAnnotationList: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(UiAnnotationList)
+
+ UiAnnotationList(UiAnnotation *annotation)
+ : next(this), annotation(annotation)
+ { kind = K; }
+
+ UiAnnotationList(UiAnnotationList *previous, UiAnnotation *annotation)
+ : annotation(annotation)
+ {
+ kind = K;
+ next = previous->next;
+ previous->next = this;
+ }
+
+ void accept0(BaseVisitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return annotation->firstSourceLocation(); }
+
+ SourceLocation lastSourceLocation() const override
+ { return lastListElement(this)->annotation->lastSourceLocation(); }
+
+ UiAnnotationList *finish()
+ {
+ UiAnnotationList *head = next;
+ next = nullptr;
+ return head;
+ }
+
+// attributes
+ UiAnnotationList *next;
+ UiAnnotation *annotation;
+};
+
+} } // namespace AST
QT_END_NAMESPACE
diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h
index fe260e2bb5..8df0be7590 100644
--- a/src/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/parser/qqmljsastfwd_p.h
@@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE
namespace QQmlJS { namespace AST {
+class BaseVisitor;
class Visitor;
class Node;
class ExpressionNode;
@@ -151,7 +152,6 @@ class NamedImport;
class ImportClause;
class FromClause;
class ImportDeclaration;
-class ModuleItem;
class ESModule;
class DebuggerStatement;
class NestedExpression;
@@ -184,6 +184,8 @@ class UiEnumDeclaration;
class UiEnumMemberList;
class UiVersionSpecifier;
class UiRequired;
+class UiAnnotation;
+class UiAnnotationList;
} // namespace AST
} // namespace QQmlJS
diff --git a/src/qml/parser/qqmljsastvisitor.cpp b/src/qml/parser/qqmljsastvisitor.cpp
index 5ecac36423..7388eccebb 100644
--- a/src/qml/parser/qqmljsastvisitor.cpp
+++ b/src/qml/parser/qqmljsastvisitor.cpp
@@ -43,11 +43,13 @@ QT_BEGIN_NAMESPACE
namespace QQmlJS { namespace AST {
-Visitor::Visitor(quint16 parentRecursionDepth) : m_recursionDepth(parentRecursionDepth)
+Visitor::Visitor(quint16 parentRecursionDepth) : BaseVisitor(parentRecursionDepth)
{
}
-Visitor::~Visitor()
+BaseVisitor::BaseVisitor(quint16 parentRecursionDepth) : m_recursionDepth(parentRecursionDepth) {}
+
+BaseVisitor::~BaseVisitor()
{
}
diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h
index fcc48da1d3..8fbdb97ee2 100644
--- a/src/qml/parser/qqmljsastvisitor_p.h
+++ b/src/qml/parser/qqmljsastvisitor_p.h
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
namespace QQmlJS { namespace AST {
-class QML_PARSER_EXPORT Visitor
+class QML_PARSER_EXPORT BaseVisitor
{
public:
class RecursionDepthCheck
@@ -68,7 +68,7 @@ public:
RecursionDepthCheck(RecursionDepthCheck &&) = delete;
RecursionDepthCheck &operator=(RecursionDepthCheck &&) = delete;
- RecursionDepthCheck(Visitor *visitor) : m_visitor(visitor)
+ RecursionDepthCheck(BaseVisitor *visitor) : m_visitor(visitor)
{
++(m_visitor->m_recursionDepth);
}
@@ -84,338 +84,338 @@ public:
private:
static const quint16 s_recursionLimit = 4096;
- Visitor *m_visitor;
+ BaseVisitor *m_visitor;
};
- Visitor(quint16 parentRecursionDepth = 0);
- virtual ~Visitor();
+ BaseVisitor(quint16 parentRecursionDepth = 0);
+ virtual ~BaseVisitor();
- virtual bool preVisit(Node *) { return true; }
- virtual void postVisit(Node *) {}
+ virtual bool preVisit(Node *) = 0;
+ virtual void postVisit(Node *) = 0;
// Ui
- virtual bool visit(UiProgram *) { return true; }
- virtual bool visit(UiHeaderItemList *) { return true; }
- virtual bool visit(UiPragma *) { return true; }
- virtual bool visit(UiImport *) { return true; }
- virtual bool visit(UiPublicMember *) { return true; }
- virtual bool visit(UiSourceElement *) { return true; }
- virtual bool visit(UiObjectDefinition *) { return true; }
- virtual bool visit(UiObjectInitializer *) { return true; }
- virtual bool visit(UiObjectBinding *) { return true; }
- virtual bool visit(UiScriptBinding *) { return true; }
- virtual bool visit(UiArrayBinding *) { return true; }
- virtual bool visit(UiParameterList *) { return true; }
- virtual bool visit(UiObjectMemberList *) { return true; }
- virtual bool visit(UiArrayMemberList *) { return true; }
- virtual bool visit(UiQualifiedId *) { return true; }
- virtual bool visit(UiEnumDeclaration *) { return true; }
- virtual bool visit(UiEnumMemberList *) { return true; }
- virtual bool visit(UiVersionSpecifier *) { return true; }
- virtual bool visit(UiInlineComponent *) { return true; }
-
- virtual void endVisit(UiProgram *) {}
- virtual void endVisit(UiImport *) {}
- virtual void endVisit(UiHeaderItemList *) {}
- virtual void endVisit(UiPragma *) {}
- virtual void endVisit(UiPublicMember *) {}
- virtual void endVisit(UiSourceElement *) {}
- virtual void endVisit(UiObjectDefinition *) {}
- virtual void endVisit(UiObjectInitializer *) {}
- virtual void endVisit(UiObjectBinding *) {}
- virtual void endVisit(UiScriptBinding *) {}
- virtual void endVisit(UiArrayBinding *) {}
- virtual void endVisit(UiParameterList *) {}
- virtual void endVisit(UiObjectMemberList *) {}
- virtual void endVisit(UiArrayMemberList *) {}
- virtual void endVisit(UiQualifiedId *) {}
- virtual void endVisit(UiEnumDeclaration *) {}
- virtual void endVisit(UiEnumMemberList *) { }
- virtual void endVisit(UiVersionSpecifier *) {}
- virtual void endVisit(UiInlineComponent *) {}
+ virtual bool visit(UiProgram *) = 0;
+ virtual bool visit(UiHeaderItemList *) = 0;
+ virtual bool visit(UiPragma *) = 0;
+ virtual bool visit(UiImport *) = 0;
+ virtual bool visit(UiPublicMember *) = 0;
+ virtual bool visit(UiSourceElement *) = 0;
+ virtual bool visit(UiObjectDefinition *) = 0;
+ virtual bool visit(UiObjectInitializer *) = 0;
+ virtual bool visit(UiObjectBinding *) = 0;
+ virtual bool visit(UiScriptBinding *) = 0;
+ virtual bool visit(UiArrayBinding *) = 0;
+ virtual bool visit(UiParameterList *) = 0;
+ virtual bool visit(UiObjectMemberList *) = 0;
+ virtual bool visit(UiArrayMemberList *) = 0;
+ virtual bool visit(UiQualifiedId *) = 0;
+ virtual bool visit(UiEnumDeclaration *) = 0;
+ virtual bool visit(UiEnumMemberList *) = 0;
+ virtual bool visit(UiVersionSpecifier *) = 0;
+ virtual bool visit(UiInlineComponent *) = 0;
+ virtual bool visit(UiAnnotation *) = 0;
+ virtual bool visit(UiAnnotationList *) = 0;
+ virtual bool visit(UiRequired *) = 0;
+
+ virtual void endVisit(UiProgram *) = 0;
+ virtual void endVisit(UiImport *) = 0;
+ virtual void endVisit(UiHeaderItemList *) = 0;
+ virtual void endVisit(UiPragma *) = 0;
+ virtual void endVisit(UiPublicMember *) = 0;
+ virtual void endVisit(UiSourceElement *) = 0;
+ virtual void endVisit(UiObjectDefinition *) = 0;
+ virtual void endVisit(UiObjectInitializer *) = 0;
+ virtual void endVisit(UiObjectBinding *) = 0;
+ virtual void endVisit(UiScriptBinding *) = 0;
+ virtual void endVisit(UiArrayBinding *) = 0;
+ virtual void endVisit(UiParameterList *) = 0;
+ virtual void endVisit(UiObjectMemberList *) = 0;
+ virtual void endVisit(UiArrayMemberList *) = 0;
+ virtual void endVisit(UiQualifiedId *) = 0;
+ virtual void endVisit(UiEnumDeclaration *) = 0;
+ virtual void endVisit(UiEnumMemberList *) = 0;
+ virtual void endVisit(UiVersionSpecifier *) = 0;
+ virtual void endVisit(UiInlineComponent *) = 0;
+ virtual void endVisit(UiAnnotation *) = 0;
+ virtual void endVisit(UiAnnotationList *) = 0;
+ virtual void endVisit(UiRequired *) = 0;
// QQmlJS
- virtual bool visit(ThisExpression *) { return true; }
- virtual void endVisit(ThisExpression *) {}
-
- virtual bool visit(IdentifierExpression *) { return true; }
- virtual void endVisit(IdentifierExpression *) {}
+ virtual bool visit(ThisExpression *) = 0;
+ virtual void endVisit(ThisExpression *) = 0;
- virtual bool visit(NullExpression *) { return true; }
- virtual void endVisit(NullExpression *) {}
+ virtual bool visit(IdentifierExpression *) = 0;
+ virtual void endVisit(IdentifierExpression *) = 0;
- virtual bool visit(TrueLiteral *) { return true; }
- virtual void endVisit(TrueLiteral *) {}
+ virtual bool visit(NullExpression *) = 0;
+ virtual void endVisit(NullExpression *) = 0;
- virtual bool visit(FalseLiteral *) { return true; }
- virtual void endVisit(FalseLiteral *) {}
+ virtual bool visit(TrueLiteral *) = 0;
+ virtual void endVisit(TrueLiteral *) = 0;
- virtual bool visit(SuperLiteral *) { return true; }
- virtual void endVisit(SuperLiteral *) {}
+ virtual bool visit(FalseLiteral *) = 0;
+ virtual void endVisit(FalseLiteral *) = 0;
- virtual bool visit(StringLiteral *) { return true; }
- virtual void endVisit(StringLiteral *) {}
+ virtual bool visit(SuperLiteral *) = 0;
+ virtual void endVisit(SuperLiteral *) = 0;
- virtual bool visit(TemplateLiteral *) { return true; }
- virtual void endVisit(TemplateLiteral *) {}
+ virtual bool visit(StringLiteral *) = 0;
+ virtual void endVisit(StringLiteral *) = 0;
- virtual bool visit(NumericLiteral *) { return true; }
- virtual void endVisit(NumericLiteral *) {}
+ virtual bool visit(TemplateLiteral *) = 0;
+ virtual void endVisit(TemplateLiteral *) = 0;
- virtual bool visit(RegExpLiteral *) { return true; }
- virtual void endVisit(RegExpLiteral *) {}
+ virtual bool visit(NumericLiteral *) = 0;
+ virtual void endVisit(NumericLiteral *) = 0;
- virtual bool visit(ArrayPattern *) { return true; }
- virtual void endVisit(ArrayPattern *) {}
+ virtual bool visit(RegExpLiteral *) = 0;
+ virtual void endVisit(RegExpLiteral *) = 0;
- virtual bool visit(ObjectPattern *) { return true; }
- virtual void endVisit(ObjectPattern *) {}
+ virtual bool visit(ArrayPattern *) = 0;
+ virtual void endVisit(ArrayPattern *) = 0;
- virtual bool visit(PatternElementList *) { return true; }
- virtual void endVisit(PatternElementList *) {}
+ virtual bool visit(ObjectPattern *) = 0;
+ virtual void endVisit(ObjectPattern *) = 0;
- virtual bool visit(PatternPropertyList *) { return true; }
- virtual void endVisit(PatternPropertyList *) {}
+ virtual bool visit(PatternElementList *) = 0;
+ virtual void endVisit(PatternElementList *) = 0;
- virtual bool visit(PatternElement *) { return true; }
- virtual void endVisit(PatternElement *) {}
+ virtual bool visit(PatternPropertyList *) = 0;
+ virtual void endVisit(PatternPropertyList *) = 0;
- virtual bool visit(PatternProperty *) { return true; }
- virtual void endVisit(PatternProperty *) {}
+ virtual bool visit(PatternElement *) = 0;
+ virtual void endVisit(PatternElement *) = 0;
- virtual bool visit(Elision *) { return true; }
- virtual void endVisit(Elision *) {}
+ virtual bool visit(PatternProperty *) = 0;
+ virtual void endVisit(PatternProperty *) = 0;
- virtual bool visit(NestedExpression *) { return true; }
- virtual void endVisit(NestedExpression *) {}
+ virtual bool visit(Elision *) = 0;
+ virtual void endVisit(Elision *) = 0;
- virtual bool visit(IdentifierPropertyName *) { return true; }
- virtual void endVisit(IdentifierPropertyName *) {}
+ virtual bool visit(NestedExpression *) = 0;
+ virtual void endVisit(NestedExpression *) = 0;
- virtual bool visit(StringLiteralPropertyName *) { return true; }
- virtual void endVisit(StringLiteralPropertyName *) {}
+ virtual bool visit(IdentifierPropertyName *) = 0;
+ virtual void endVisit(IdentifierPropertyName *) = 0;
- virtual bool visit(NumericLiteralPropertyName *) { return true; }
- virtual void endVisit(NumericLiteralPropertyName *) {}
+ virtual bool visit(StringLiteralPropertyName *) = 0;
+ virtual void endVisit(StringLiteralPropertyName *) = 0;
- virtual bool visit(ComputedPropertyName *) { return true; }
- virtual void endVisit(ComputedPropertyName *) {}
+ virtual bool visit(NumericLiteralPropertyName *) = 0;
+ virtual void endVisit(NumericLiteralPropertyName *) = 0;
- virtual bool visit(ArrayMemberExpression *) { return true; }
- virtual void endVisit(ArrayMemberExpression *) {}
+ virtual bool visit(ComputedPropertyName *) = 0;
+ virtual void endVisit(ComputedPropertyName *) = 0;
- virtual bool visit(FieldMemberExpression *) { return true; }
- virtual void endVisit(FieldMemberExpression *) {}
+ virtual bool visit(ArrayMemberExpression *) = 0;
+ virtual void endVisit(ArrayMemberExpression *) = 0;
- virtual bool visit(TaggedTemplate *) { return true; }
- virtual void endVisit(TaggedTemplate *) {}
+ virtual bool visit(FieldMemberExpression *) = 0;
+ virtual void endVisit(FieldMemberExpression *) = 0;
- virtual bool visit(NewMemberExpression *) { return true; }
- virtual void endVisit(NewMemberExpression *) {}
+ virtual bool visit(TaggedTemplate *) = 0;
+ virtual void endVisit(TaggedTemplate *) = 0;
- virtual bool visit(NewExpression *) { return true; }
- virtual void endVisit(NewExpression *) {}
+ virtual bool visit(NewMemberExpression *) = 0;
+ virtual void endVisit(NewMemberExpression *) = 0;
- virtual bool visit(CallExpression *) { return true; }
- virtual void endVisit(CallExpression *) {}
+ virtual bool visit(NewExpression *) = 0;
+ virtual void endVisit(NewExpression *) = 0;
- virtual bool visit(ArgumentList *) { return true; }
- virtual void endVisit(ArgumentList *) {}
+ virtual bool visit(CallExpression *) = 0;
+ virtual void endVisit(CallExpression *) = 0;
- virtual bool visit(PostIncrementExpression *) { return true; }
- virtual void endVisit(PostIncrementExpression *) {}
+ virtual bool visit(ArgumentList *) = 0;
+ virtual void endVisit(ArgumentList *) = 0;
- virtual bool visit(PostDecrementExpression *) { return true; }
- virtual void endVisit(PostDecrementExpression *) {}
+ virtual bool visit(PostIncrementExpression *) = 0;
+ virtual void endVisit(PostIncrementExpression *) = 0;
- virtual bool visit(DeleteExpression *) { return true; }
- virtual void endVisit(DeleteExpression *) {}
+ virtual bool visit(PostDecrementExpression *) = 0;
+ virtual void endVisit(PostDecrementExpression *) = 0;
- virtual bool visit(VoidExpression *) { return true; }
- virtual void endVisit(VoidExpression *) {}
+ virtual bool visit(DeleteExpression *) = 0;
+ virtual void endVisit(DeleteExpression *) = 0;
- virtual bool visit(TypeOfExpression *) { return true; }
- virtual void endVisit(TypeOfExpression *) {}
+ virtual bool visit(VoidExpression *) = 0;
+ virtual void endVisit(VoidExpression *) = 0;
- virtual bool visit(PreIncrementExpression *) { return true; }
- virtual void endVisit(PreIncrementExpression *) {}
+ virtual bool visit(TypeOfExpression *) = 0;
+ virtual void endVisit(TypeOfExpression *) = 0;
- virtual bool visit(PreDecrementExpression *) { return true; }
- virtual void endVisit(PreDecrementExpression *) {}
+ virtual bool visit(PreIncrementExpression *) = 0;
+ virtual void endVisit(PreIncrementExpression *) = 0;
- virtual bool visit(UnaryPlusExpression *) { return true; }
- virtual void endVisit(UnaryPlusExpression *) {}
+ virtual bool visit(PreDecrementExpression *) = 0;
+ virtual void endVisit(PreDecrementExpression *) = 0;
- virtual bool visit(UnaryMinusExpression *) { return true; }
- virtual void endVisit(UnaryMinusExpression *) {}
+ virtual bool visit(UnaryPlusExpression *) = 0;
+ virtual void endVisit(UnaryPlusExpression *) = 0;
- virtual bool visit(TildeExpression *) { return true; }
- virtual void endVisit(TildeExpression *) {}
+ virtual bool visit(UnaryMinusExpression *) = 0;
+ virtual void endVisit(UnaryMinusExpression *) = 0;
- virtual bool visit(NotExpression *) { return true; }
- virtual void endVisit(NotExpression *) {}
+ virtual bool visit(TildeExpression *) = 0;
+ virtual void endVisit(TildeExpression *) = 0;
- virtual bool visit(BinaryExpression *) { return true; }
- virtual void endVisit(BinaryExpression *) {}
+ virtual bool visit(NotExpression *) = 0;
+ virtual void endVisit(NotExpression *) = 0;
- virtual bool visit(ConditionalExpression *) { return true; }
- virtual void endVisit(ConditionalExpression *) {}
+ virtual bool visit(BinaryExpression *) = 0;
+ virtual void endVisit(BinaryExpression *) = 0;
- virtual bool visit(Expression *) { return true; }
- virtual void endVisit(Expression *) {}
+ virtual bool visit(ConditionalExpression *) = 0;
+ virtual void endVisit(ConditionalExpression *) = 0;
- virtual bool visit(Block *) { return true; }
- virtual void endVisit(Block *) {}
+ virtual bool visit(Expression *) = 0;
+ virtual void endVisit(Expression *) = 0;
- virtual bool visit(StatementList *) { return true; }
- virtual void endVisit(StatementList *) {}
+ virtual bool visit(Block *) = 0;
+ virtual void endVisit(Block *) = 0;
- virtual bool visit(VariableStatement *) { return true; }
- virtual void endVisit(VariableStatement *) {}
+ virtual bool visit(StatementList *) = 0;
+ virtual void endVisit(StatementList *) = 0;
- virtual bool visit(VariableDeclarationList *) { return true; }
- virtual void endVisit(VariableDeclarationList *) {}
+ virtual bool visit(VariableStatement *) = 0;
+ virtual void endVisit(VariableStatement *) = 0;
- virtual bool visit(EmptyStatement *) { return true; }
- virtual void endVisit(EmptyStatement *) {}
+ virtual bool visit(VariableDeclarationList *) = 0;
+ virtual void endVisit(VariableDeclarationList *) = 0;
- virtual bool visit(ExpressionStatement *) { return true; }
- virtual void endVisit(ExpressionStatement *) {}
+ virtual bool visit(EmptyStatement *) = 0;
+ virtual void endVisit(EmptyStatement *) = 0;
- virtual bool visit(IfStatement *) { return true; }
- virtual void endVisit(IfStatement *) {}
+ virtual bool visit(ExpressionStatement *) = 0;
+ virtual void endVisit(ExpressionStatement *) = 0;
- virtual bool visit(DoWhileStatement *) { return true; }
- virtual void endVisit(DoWhileStatement *) {}
+ virtual bool visit(IfStatement *) = 0;
+ virtual void endVisit(IfStatement *) = 0;
- virtual bool visit(WhileStatement *) { return true; }
- virtual void endVisit(WhileStatement *) {}
+ virtual bool visit(DoWhileStatement *) = 0;
+ virtual void endVisit(DoWhileStatement *) = 0;
- virtual bool visit(ForStatement *) { return true; }
- virtual void endVisit(ForStatement *) {}
+ virtual bool visit(WhileStatement *) = 0;
+ virtual void endVisit(WhileStatement *) = 0;
- virtual bool visit(ForEachStatement *) { return true; }
- virtual void endVisit(ForEachStatement *) {}
+ virtual bool visit(ForStatement *) = 0;
+ virtual void endVisit(ForStatement *) = 0;
- virtual bool visit(ContinueStatement *) { return true; }
- virtual void endVisit(ContinueStatement *) {}
+ virtual bool visit(ForEachStatement *) = 0;
+ virtual void endVisit(ForEachStatement *) = 0;
- virtual bool visit(BreakStatement *) { return true; }
- virtual void endVisit(BreakStatement *) {}
+ virtual bool visit(ContinueStatement *) = 0;
+ virtual void endVisit(ContinueStatement *) = 0;
- virtual bool visit(ReturnStatement *) { return true; }
- virtual void endVisit(ReturnStatement *) {}
+ virtual bool visit(BreakStatement *) = 0;
+ virtual void endVisit(BreakStatement *) = 0;
- virtual bool visit(YieldExpression *) { return true; }
- virtual void endVisit(YieldExpression *) {}
+ virtual bool visit(ReturnStatement *) = 0;
+ virtual void endVisit(ReturnStatement *) = 0;
- virtual bool visit(WithStatement *) { return true; }
- virtual void endVisit(WithStatement *) {}
+ virtual bool visit(YieldExpression *) = 0;
+ virtual void endVisit(YieldExpression *) = 0;
- virtual bool visit(SwitchStatement *) { return true; }
- virtual void endVisit(SwitchStatement *) {}
+ virtual bool visit(WithStatement *) = 0;
+ virtual void endVisit(WithStatement *) = 0;
- virtual bool visit(CaseBlock *) { return true; }
- virtual void endVisit(CaseBlock *) {}
+ virtual bool visit(SwitchStatement *) = 0;
+ virtual void endVisit(SwitchStatement *) = 0;
- virtual bool visit(CaseClauses *) { return true; }
- virtual void endVisit(CaseClauses *) {}
+ virtual bool visit(CaseBlock *) = 0;
+ virtual void endVisit(CaseBlock *) = 0;
- virtual bool visit(CaseClause *) { return true; }
- virtual void endVisit(CaseClause *) {}
+ virtual bool visit(CaseClauses *) = 0;
+ virtual void endVisit(CaseClauses *) = 0;
- virtual bool visit(DefaultClause *) { return true; }
- virtual void endVisit(DefaultClause *) {}
+ virtual bool visit(CaseClause *) = 0;
+ virtual void endVisit(CaseClause *) = 0;
- virtual bool visit(LabelledStatement *) { return true; }
- virtual void endVisit(LabelledStatement *) {}
+ virtual bool visit(DefaultClause *) = 0;
+ virtual void endVisit(DefaultClause *) = 0;
- virtual bool visit(ThrowStatement *) { return true; }
- virtual void endVisit(ThrowStatement *) {}
+ virtual bool visit(LabelledStatement *) = 0;
+ virtual void endVisit(LabelledStatement *) = 0;
- virtual bool visit(TryStatement *) { return true; }
- virtual void endVisit(TryStatement *) {}
+ virtual bool visit(ThrowStatement *) = 0;
+ virtual void endVisit(ThrowStatement *) = 0;
- virtual bool visit(Catch *) { return true; }
- virtual void endVisit(Catch *) {}
+ virtual bool visit(TryStatement *) = 0;
+ virtual void endVisit(TryStatement *) = 0;
- virtual bool visit(Finally *) { return true; }
- virtual void endVisit(Finally *) {}
+ virtual bool visit(Catch *) = 0;
+ virtual void endVisit(Catch *) = 0;
- virtual bool visit(FunctionDeclaration *) { return true; }
- virtual void endVisit(FunctionDeclaration *) {}
+ virtual bool visit(Finally *) = 0;
+ virtual void endVisit(Finally *) = 0;
- virtual bool visit(FunctionExpression *) { return true; }
- virtual void endVisit(FunctionExpression *) {}
+ virtual bool visit(FunctionDeclaration *) = 0;
+ virtual void endVisit(FunctionDeclaration *) = 0;
- virtual bool visit(FormalParameterList *) { return true; }
- virtual void endVisit(FormalParameterList *) {}
+ virtual bool visit(FunctionExpression *) = 0;
+ virtual void endVisit(FunctionExpression *) = 0;
- virtual bool visit(ClassExpression *) { return true; }
- virtual void endVisit(ClassExpression *) {}
+ virtual bool visit(FormalParameterList *) = 0;
+ virtual void endVisit(FormalParameterList *) = 0;
- virtual bool visit(ClassDeclaration *) { return true; }
- virtual void endVisit(ClassDeclaration *) {}
+ virtual bool visit(ClassExpression *) = 0;
+ virtual void endVisit(ClassExpression *) = 0;
- virtual bool visit(ClassElementList *) { return true; }
- virtual void endVisit(ClassElementList *) {}
+ virtual bool visit(ClassDeclaration *) = 0;
+ virtual void endVisit(ClassDeclaration *) = 0;
- virtual bool visit(Program *) { return true; }
- virtual void endVisit(Program *) {}
+ virtual bool visit(ClassElementList *) = 0;
+ virtual void endVisit(ClassElementList *) = 0;
- virtual bool visit(NameSpaceImport *) { return true; }
- virtual void endVisit(NameSpaceImport *) {}
+ virtual bool visit(Program *) = 0;
+ virtual void endVisit(Program *) = 0;
- virtual bool visit(ImportSpecifier *) { return true; }
- virtual void endVisit(ImportSpecifier *) {}
+ virtual bool visit(NameSpaceImport *) = 0;
+ virtual void endVisit(NameSpaceImport *) = 0;
- virtual bool visit(ImportsList *) { return true; }
- virtual void endVisit(ImportsList *) {}
+ virtual bool visit(ImportSpecifier *) = 0;
+ virtual void endVisit(ImportSpecifier *) = 0;
- virtual bool visit(NamedImports *) { return true; }
- virtual void endVisit(NamedImports *) {}
+ virtual bool visit(ImportsList *) = 0;
+ virtual void endVisit(ImportsList *) = 0;
- virtual bool visit(FromClause *) { return true; }
- virtual void endVisit(FromClause *) {}
+ virtual bool visit(NamedImports *) = 0;
+ virtual void endVisit(NamedImports *) = 0;
- virtual bool visit(ImportClause *) { return true; }
- virtual void endVisit(ImportClause *) {}
+ virtual bool visit(FromClause *) = 0;
+ virtual void endVisit(FromClause *) = 0;
- virtual bool visit(ImportDeclaration *) { return true; }
- virtual void endVisit(ImportDeclaration *) {}
+ virtual bool visit(ImportClause *) = 0;
+ virtual void endVisit(ImportClause *) = 0;
- virtual bool visit(ExportSpecifier *) { return true; }
- virtual void endVisit(ExportSpecifier *) {}
+ virtual bool visit(ImportDeclaration *) = 0;
+ virtual void endVisit(ImportDeclaration *) = 0;
- virtual bool visit(ExportsList *) { return true; }
- virtual void endVisit(ExportsList *) {}
+ virtual bool visit(ExportSpecifier *) = 0;
+ virtual void endVisit(ExportSpecifier *) = 0;
- virtual bool visit(ExportClause *) { return true; }
- virtual void endVisit(ExportClause *) {}
+ virtual bool visit(ExportsList *) = 0;
+ virtual void endVisit(ExportsList *) = 0;
- virtual bool visit(ExportDeclaration *) { return true; }
- virtual void endVisit(ExportDeclaration *) {}
+ virtual bool visit(ExportClause *) = 0;
+ virtual void endVisit(ExportClause *) = 0;
- virtual bool visit(ModuleItem *) { return true; }
- virtual void endVisit(ModuleItem *) {}
+ virtual bool visit(ExportDeclaration *) = 0;
+ virtual void endVisit(ExportDeclaration *) = 0;
- virtual bool visit(ESModule *) { return true; }
- virtual void endVisit(ESModule *) {}
+ virtual bool visit(ESModule *) = 0;
+ virtual void endVisit(ESModule *) = 0;
- virtual bool visit(DebuggerStatement *) { return true; }
- virtual void endVisit(DebuggerStatement *) {}
+ virtual bool visit(DebuggerStatement *) = 0;
+ virtual void endVisit(DebuggerStatement *) = 0;
- virtual bool visit(Type *) { return true; }
- virtual void endVisit(Type *) {}
+ virtual bool visit(Type *) = 0;
+ virtual void endVisit(Type *) = 0;
- virtual bool visit(TypeArgumentList *) { return true; }
- virtual void endVisit(TypeArgumentList *) {}
+ virtual bool visit(TypeArgumentList *) = 0;
+ virtual void endVisit(TypeArgumentList *) = 0;
- virtual bool visit(TypeAnnotation *) { return true; }
- virtual void endVisit(TypeAnnotation *) {}
-
- virtual bool visit(UiRequired *) { return true; }
- virtual void endVisit(UiRequired *) {}
+ virtual bool visit(TypeAnnotation *) = 0;
+ virtual void endVisit(TypeAnnotation *) = 0;
virtual void throwRecursionDepthError() = 0;
@@ -426,6 +426,339 @@ protected:
friend class RecursionDepthCheck;
};
+class QML_PARSER_EXPORT Visitor: public BaseVisitor
+{
+public:
+ Visitor(quint16 parentRecursionDepth = 0);
+
+ bool preVisit(Node *) override { return true; }
+ void postVisit(Node *) override {}
+
+ // Ui
+ bool visit(UiProgram *) override { return true; }
+ bool visit(UiHeaderItemList *) override { return true; }
+ bool visit(UiPragma *) override { return true; }
+ bool visit(UiImport *) override { return true; }
+ bool visit(UiPublicMember *) override { return true; }
+ bool visit(UiSourceElement *) override { return true; }
+ bool visit(UiObjectDefinition *) override { return true; }
+ bool visit(UiObjectInitializer *) override { return true; }
+ bool visit(UiObjectBinding *) override { return true; }
+ bool visit(UiScriptBinding *) override { return true; }
+ bool visit(UiArrayBinding *) override { return true; }
+ bool visit(UiParameterList *) override { return true; }
+ bool visit(UiObjectMemberList *) override { return true; }
+ bool visit(UiArrayMemberList *) override { return true; }
+ bool visit(UiQualifiedId *) override { return true; }
+ bool visit(UiEnumDeclaration *) override { return true; }
+ bool visit(UiEnumMemberList *) override { return true; }
+ bool visit(UiVersionSpecifier *) override { return true; }
+ bool visit(UiInlineComponent *) override { return true; }
+ bool visit(UiAnnotation *) override { return true; }
+ bool visit(UiAnnotationList *) override { return true; }
+ bool visit(UiRequired *) override { return true; }
+
+ void endVisit(UiProgram *) override {}
+ void endVisit(UiImport *) override {}
+ void endVisit(UiHeaderItemList *) override {}
+ void endVisit(UiPragma *) override {}
+ void endVisit(UiPublicMember *) override {}
+ void endVisit(UiSourceElement *) override {}
+ void endVisit(UiObjectDefinition *) override {}
+ void endVisit(UiObjectInitializer *) override {}
+ void endVisit(UiObjectBinding *) override {}
+ void endVisit(UiScriptBinding *) override {}
+ void endVisit(UiArrayBinding *) override {}
+ void endVisit(UiParameterList *) override {}
+ void endVisit(UiObjectMemberList *) override {}
+ void endVisit(UiArrayMemberList *) override {}
+ void endVisit(UiQualifiedId *) override {}
+ void endVisit(UiEnumDeclaration *) override {}
+ void endVisit(UiEnumMemberList *) override {}
+ void endVisit(UiVersionSpecifier *) override {}
+ void endVisit(UiInlineComponent *) override {}
+ void endVisit(UiAnnotation *) override {}
+ void endVisit(UiAnnotationList *) override {}
+ void endVisit(UiRequired *) override {}
+
+ // QQmlJS
+ bool visit(ThisExpression *) override { return true; }
+ void endVisit(ThisExpression *) override {}
+
+ bool visit(IdentifierExpression *) override { return true; }
+ void endVisit(IdentifierExpression *) override {}
+
+ bool visit(NullExpression *) override { return true; }
+ void endVisit(NullExpression *) override {}
+
+ bool visit(TrueLiteral *) override { return true; }
+ void endVisit(TrueLiteral *) override {}
+
+ bool visit(FalseLiteral *) override { return true; }
+ void endVisit(FalseLiteral *) override {}
+
+ bool visit(SuperLiteral *) override { return true; }
+ void endVisit(SuperLiteral *) override {}
+
+ bool visit(StringLiteral *) override { return true; }
+ void endVisit(StringLiteral *) override {}
+
+ bool visit(TemplateLiteral *) override { return true; }
+ void endVisit(TemplateLiteral *) override {}
+
+ bool visit(NumericLiteral *) override { return true; }
+ void endVisit(NumericLiteral *) override {}
+
+ bool visit(RegExpLiteral *) override { return true; }
+ void endVisit(RegExpLiteral *) override {}
+
+ bool visit(ArrayPattern *) override { return true; }
+ void endVisit(ArrayPattern *) override {}
+
+ bool visit(ObjectPattern *) override { return true; }
+ void endVisit(ObjectPattern *) override {}
+
+ bool visit(PatternElementList *) override { return true; }
+ void endVisit(PatternElementList *) override {}
+
+ bool visit(PatternPropertyList *) override { return true; }
+ void endVisit(PatternPropertyList *) override {}
+
+ bool visit(PatternElement *) override { return true; }
+ void endVisit(PatternElement *) override {}
+
+ bool visit(PatternProperty *) override { return true; }
+ void endVisit(PatternProperty *) override {}
+
+ bool visit(Elision *) override { return true; }
+ void endVisit(Elision *) override {}
+
+ bool visit(NestedExpression *) override { return true; }
+ void endVisit(NestedExpression *) override {}
+
+ bool visit(IdentifierPropertyName *) override { return true; }
+ void endVisit(IdentifierPropertyName *) override {}
+
+ bool visit(StringLiteralPropertyName *) override { return true; }
+ void endVisit(StringLiteralPropertyName *) override {}
+
+ bool visit(NumericLiteralPropertyName *) override { return true; }
+ void endVisit(NumericLiteralPropertyName *) override {}
+
+ bool visit(ComputedPropertyName *) override { return true; }
+ void endVisit(ComputedPropertyName *) override {}
+
+ bool visit(ArrayMemberExpression *) override { return true; }
+ void endVisit(ArrayMemberExpression *) override {}
+
+ bool visit(FieldMemberExpression *) override { return true; }
+ void endVisit(FieldMemberExpression *) override {}
+
+ bool visit(TaggedTemplate *) override { return true; }
+ void endVisit(TaggedTemplate *) override {}
+
+ bool visit(NewMemberExpression *) override { return true; }
+ void endVisit(NewMemberExpression *) override {}
+
+ bool visit(NewExpression *) override { return true; }
+ void endVisit(NewExpression *) override {}
+
+ bool visit(CallExpression *) override { return true; }
+ void endVisit(CallExpression *) override {}
+
+ bool visit(ArgumentList *) override { return true; }
+ void endVisit(ArgumentList *) override {}
+
+ bool visit(PostIncrementExpression *) override { return true; }
+ void endVisit(PostIncrementExpression *) override {}
+
+ bool visit(PostDecrementExpression *) override { return true; }
+ void endVisit(PostDecrementExpression *) override {}
+
+ bool visit(DeleteExpression *) override { return true; }
+ void endVisit(DeleteExpression *) override {}
+
+ bool visit(VoidExpression *) override { return true; }
+ void endVisit(VoidExpression *) override {}
+
+ bool visit(TypeOfExpression *) override { return true; }
+ void endVisit(TypeOfExpression *) override {}
+
+ bool visit(PreIncrementExpression *) override { return true; }
+ void endVisit(PreIncrementExpression *) override {}
+
+ bool visit(PreDecrementExpression *) override { return true; }
+ void endVisit(PreDecrementExpression *) override {}
+
+ bool visit(UnaryPlusExpression *) override { return true; }
+ void endVisit(UnaryPlusExpression *) override {}
+
+ bool visit(UnaryMinusExpression *) override { return true; }
+ void endVisit(UnaryMinusExpression *) override {}
+
+ bool visit(TildeExpression *) override { return true; }
+ void endVisit(TildeExpression *) override {}
+
+ bool visit(NotExpression *) override { return true; }
+ void endVisit(NotExpression *) override {}
+
+ bool visit(BinaryExpression *) override { return true; }
+ void endVisit(BinaryExpression *) override {}
+
+ bool visit(ConditionalExpression *) override { return true; }
+ void endVisit(ConditionalExpression *) override {}
+
+ bool visit(Expression *) override { return true; }
+ void endVisit(Expression *) override {}
+
+ bool visit(Block *) override { return true; }
+ void endVisit(Block *) override {}
+
+ bool visit(StatementList *) override { return true; }
+ void endVisit(StatementList *) override {}
+
+ bool visit(VariableStatement *) override { return true; }
+ void endVisit(VariableStatement *) override {}
+
+ bool visit(VariableDeclarationList *) override { return true; }
+ void endVisit(VariableDeclarationList *) override {}
+
+ bool visit(EmptyStatement *) override { return true; }
+ void endVisit(EmptyStatement *) override {}
+
+ bool visit(ExpressionStatement *) override { return true; }
+ void endVisit(ExpressionStatement *) override {}
+
+ bool visit(IfStatement *) override { return true; }
+ void endVisit(IfStatement *) override {}
+
+ bool visit(DoWhileStatement *) override { return true; }
+ void endVisit(DoWhileStatement *) override {}
+
+ bool visit(WhileStatement *) override { return true; }
+ void endVisit(WhileStatement *) override {}
+
+ bool visit(ForStatement *) override { return true; }
+ void endVisit(ForStatement *) override {}
+
+ bool visit(ForEachStatement *) override { return true; }
+ void endVisit(ForEachStatement *) override {}
+
+ bool visit(ContinueStatement *) override { return true; }
+ void endVisit(ContinueStatement *) override {}
+
+ bool visit(BreakStatement *) override { return true; }
+ void endVisit(BreakStatement *) override {}
+
+ bool visit(ReturnStatement *) override { return true; }
+ void endVisit(ReturnStatement *) override {}
+
+ bool visit(YieldExpression *) override { return true; }
+ void endVisit(YieldExpression *) override {}
+
+ bool visit(WithStatement *) override { return true; }
+ void endVisit(WithStatement *) override {}
+
+ bool visit(SwitchStatement *) override { return true; }
+ void endVisit(SwitchStatement *) override {}
+
+ bool visit(CaseBlock *) override { return true; }
+ void endVisit(CaseBlock *) override {}
+
+ bool visit(CaseClauses *) override { return true; }
+ void endVisit(CaseClauses *) override {}
+
+ bool visit(CaseClause *) override { return true; }
+ void endVisit(CaseClause *) override {}
+
+ bool visit(DefaultClause *) override { return true; }
+ void endVisit(DefaultClause *) override {}
+
+ bool visit(LabelledStatement *) override { return true; }
+ void endVisit(LabelledStatement *) override {}
+
+ bool visit(ThrowStatement *) override { return true; }
+ void endVisit(ThrowStatement *) override {}
+
+ bool visit(TryStatement *) override { return true; }
+ void endVisit(TryStatement *) override {}
+
+ bool visit(Catch *) override { return true; }
+ void endVisit(Catch *) override {}
+
+ bool visit(Finally *) override { return true; }
+ void endVisit(Finally *) override {}
+
+ bool visit(FunctionDeclaration *) override { return true; }
+ void endVisit(FunctionDeclaration *) override {}
+
+ bool visit(FunctionExpression *) override { return true; }
+ void endVisit(FunctionExpression *) override {}
+
+ bool visit(FormalParameterList *) override { return true; }
+ void endVisit(FormalParameterList *) override {}
+
+ bool visit(ClassExpression *) override { return true; }
+ void endVisit(ClassExpression *) override {}
+
+ bool visit(ClassDeclaration *) override { return true; }
+ void endVisit(ClassDeclaration *) override {}
+
+ bool visit(ClassElementList *) override { return true; }
+ void endVisit(ClassElementList *) override {}
+
+ bool visit(Program *) override { return true; }
+ void endVisit(Program *) override {}
+
+ bool visit(NameSpaceImport *) override { return true; }
+ void endVisit(NameSpaceImport *) override {}
+
+ bool visit(ImportSpecifier *) override { return true; }
+ void endVisit(ImportSpecifier *) override {}
+
+ bool visit(ImportsList *) override { return true; }
+ void endVisit(ImportsList *) override {}
+
+ bool visit(NamedImports *) override { return true; }
+ void endVisit(NamedImports *) override {}
+
+ bool visit(FromClause *) override { return true; }
+ void endVisit(FromClause *) override {}
+
+ bool visit(ImportClause *) override { return true; }
+ void endVisit(ImportClause *) override {}
+
+ bool visit(ImportDeclaration *) override { return true; }
+ void endVisit(ImportDeclaration *) override {}
+
+ bool visit(ExportSpecifier *) override { return true; }
+ void endVisit(ExportSpecifier *) override {}
+
+ bool visit(ExportsList *) override { return true; }
+ void endVisit(ExportsList *) override {}
+
+ bool visit(ExportClause *) override { return true; }
+ void endVisit(ExportClause *) override {}
+
+ bool visit(ExportDeclaration *) override { return true; }
+ void endVisit(ExportDeclaration *) override {}
+
+ bool visit(ESModule *) override { return true; }
+ void endVisit(ESModule *) override {}
+
+ bool visit(DebuggerStatement *) override { return true; }
+ void endVisit(DebuggerStatement *) override {}
+
+ bool visit(Type *) override { return true; }
+ void endVisit(Type *) override {}
+
+ bool visit(TypeArgumentList *) override { return true; }
+ void endVisit(TypeArgumentList *) override {}
+
+ bool visit(TypeAnnotation *) override { return true; }
+ void endVisit(TypeAnnotation *) override {}
+};
+
} } // namespace AST
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index c71e6b68b8..ea6f15e9c2 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -46,6 +46,7 @@
#include <private/qqmlmetatypedata_p.h>
#include <private/qqmltype_p_p.h>
#include <private/qqmltypemodule_p_p.h>
+#include <private/qqmltypenotavailable_p.h>
#include <QtCore/qmutex.h>
@@ -358,4 +359,40 @@ void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data)
}
}
+namespace QQmlPrivate {
+ template<>
+ void qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>(
+ const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject)
+ {
+ using T = QQmlTypeNotAvailable;
+
+ QML_GETTYPENAMES
+
+ RegisterTypeAndRevisions type = {
+ 0,
+ qRegisterNormalizedMetaType<T *>(pointerName.constData()),
+ qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ 0,
+ nullptr,
+
+ uri,
+ QTypeRevision::fromMajorVersion(versionMajor),
+
+ &QQmlTypeNotAvailable::staticMetaObject,
+ classInfoMetaObject,
+
+ attachedPropertiesFunc<T>(),
+ attachedPropertiesMetaObject<T>(),
+
+ StaticCastSelector<T, QQmlParserStatus>::cast(),
+ StaticCastSelector<T, QQmlPropertyValueSource>::cast(),
+ StaticCastSelector<T, QQmlPropertyValueInterceptor>::cast(),
+
+ nullptr, nullptr, qmlCreateCustomParser<T>
+ };
+
+ qmlregister(TypeAndRevisionsRegistration, &type);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 096bef7e4b..b9445e48a8 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -120,6 +120,16 @@
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
+#define QML_INTERFACE \
+ Q_CLASSINFO("QML.Element", "anonymous") \
+ enum class QmlIsInterface {yes = true}; \
+ template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlInterface; \
+ template<typename T, typename... Args> \
+ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
+
+#define QML_UNAVAILABLE \
+ QML_FOREIGN(QQmlTypeNotAvailable)
+
enum { /* TYPEINFO flags */
QML_HAS_ATTACHED_PROPERTIES = 0x01
};
@@ -183,7 +193,8 @@ QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegi
}
#endif
-int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message);
+int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor,
+ const char *qmlName, const QString& message);
template<typename T>
int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
@@ -422,9 +433,8 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
}
-
template<typename T, typename E>
-int qmlRegisterExtendedType()
+int qmlRegisterExtendedType(const char *uri, int versionMajor)
{
QML_GETTYPENAMES
@@ -437,7 +447,7 @@ int qmlRegisterExtendedType()
nullptr,
QString(),
- nullptr, QTypeRevision::zero(), nullptr, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -455,6 +465,15 @@ int qmlRegisterExtendedType()
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
}
+#if QT_DEPRECATED_SINCE(5, 15)
+template<typename T, typename E>
+QT_DEPRECATED_VERSION_X_5_15("Use qmlRegisterExtendedType(uri, versionMajor) instead")
+int qmlRegisterExtendedType()
+{
+ return qmlRegisterExtendedType<T, E>("", 0);
+}
+#endif
+
template<typename T, typename E>
int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
const char *qmlName)
@@ -494,7 +513,9 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
}
+#if QT_DEPRECATED_SINCE(5, 15)
template<typename T>
+QT_DEPRECATED_VERSION_X_5_15("Use qmlRegisterInterface(uri, versionMajor) instead")
int qmlRegisterInterface(const char *typeName)
{
QByteArray name(typeName);
@@ -503,12 +524,33 @@ int qmlRegisterInterface(const char *typeName)
QByteArray listName("QQmlListProperty<" + name + '>');
QQmlPrivate::RegisterInterface qmlInterface = {
- 0,
+ 1,
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
- qobject_interface_iid<T *>()
+ qobject_interface_iid<T *>(),
+ "",
+ QTypeRevision::zero()
+ };
+
+ return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface);
+}
+#endif
+
+template<typename T>
+int qmlRegisterInterface(const char *uri, int versionMajor)
+{
+ QML_GETTYPENAMES
+
+ QQmlPrivate::RegisterInterface qmlInterface = {
+ 1,
+ qRegisterNormalizedMetaType<T *>(pointerName.constData()),
+ qRegisterNormalizedMetaType<QQmlListProperty<T>>(listName.constData()),
+ qobject_interface_iid<T *>(),
+
+ uri,
+ QTypeRevision::fromVersion(versionMajor, 0)
};
return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface);
@@ -766,11 +808,11 @@ inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, i
return QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &type);
}
-template<class T, class Resolved, class Extended, bool Singleton>
+template<class T, class Resolved, class Extended, bool Singleton, bool Interface>
struct QmlTypeAndRevisionsRegistration;
template<class T, class Resolved, class Extended>
-struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false> {
+struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> {
static void registerTypeAndRevisions(const char *uri, int versionMajor)
{
QQmlPrivate::qmlRegisterTypeAndRevisions<Resolved, Extended>(
@@ -779,7 +821,7 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false> {
};
template<class T, class Resolved>
-struct QmlTypeAndRevisionsRegistration<T, Resolved, void, true> {
+struct QmlTypeAndRevisionsRegistration<T, Resolved, void, true, false> {
static void registerTypeAndRevisions(const char *uri, int versionMajor)
{
QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved>(
@@ -787,6 +829,14 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, void, true> {
}
};
+template<class T, class Resolved>
+struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true> {
+ static void registerTypeAndRevisions(const char *uri, int versionMajor)
+ {
+ qmlRegisterInterface<Resolved>(uri, versionMajor);
+ }
+};
+
template<typename T = void, typename... Args>
void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor);
@@ -796,7 +846,8 @@ void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor)
QmlTypeAndRevisionsRegistration<
T, typename QQmlPrivate::QmlResolved<T>::Type,
typename QQmlPrivate::QmlExtended<T>::Type,
- QQmlPrivate::QmlSingleton<T>::Value>
+ QQmlPrivate::QmlSingleton<T>::Value,
+ QQmlPrivate::QmlInterface<T>::Value>
::registerTypeAndRevisions(uri, versionMajor);
qmlRegisterTypesAndRevisions<Args...>(uri, versionMajor);
}
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index e14b00af22..b9566d5862 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -43,6 +43,10 @@
#include "qqmlcontext.h"
#include "qqmlinfo.h"
#include "qqmldata_p.h"
+
+#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qqmldebugconnector_p.h>
+
#include <private/qqmlprofiler_p.h>
#include <private/qqmlexpression_p.h>
#include <private/qqmlscriptstring_p.h>
@@ -392,6 +396,11 @@ QQmlBinding *QQmlBinding::createTranslationBinding(const QQmlRefPointer<QV4::Exe
b->QQmlJavaScriptExpression::setContext(ctxt);
b->setScopeObject(obj);
+ if (QQmlDebugTranslationService *service
+ = QQmlDebugConnector::service<QQmlDebugTranslationService>()) {
+ service->foundTranslationBinding(b, obj, ctxt);
+ }
+
return b;
}
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index 87f7fffe41..02c2b87a6e 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -125,8 +125,13 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
// * <TypeName>.<EnumValue>
// * <TypeName>.<ScopedEnumName>.<EnumValue>
- int dot = script.indexOf('.');
- if (dot == -1 || dot == script.length()-1)
+ auto nextDot = [&](int dot) {
+ const int nextDot = script.indexOf('.', dot + 1);
+ return (nextDot == script.length() - 1) ? -1 : nextDot;
+ };
+
+ int dot = nextDot(-1);
+ if (dot == -1)
return -1;
QString scope = QString::fromUtf8(script.left(dot));
@@ -137,18 +142,32 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
QQmlType type;
if (imports.isT1()) {
- imports.asT1()->resolveType(scope, &type, nullptr, nullptr, nullptr);
+ QQmlImportNamespace *ns = nullptr;
+ if (!imports.asT1()->resolveType(scope, &type, nullptr, &ns))
+ return -1;
+ if (!type.isValid() && ns != nullptr) {
+ dot = nextDot(dot);
+ if (dot == -1 || !imports.asT1()->resolveType(QString::fromUtf8(script.left(dot)),
+ &type, nullptr, nullptr)) {
+ return -1;
+ }
+ }
} else {
QQmlTypeNameCache::Result result = imports.asT2()->query(scope);
- if (result.isValid())
+ if (result.isValid()) {
type = result.type;
+ } else if (result.importNamespace) {
+ dot = nextDot(dot);
+ if (dot != -1)
+ type = imports.asT2()->query(QString::fromUtf8(script.left(dot))).type;
+ }
}
if (!type.isValid())
return -1;
- int dot2 = script.indexOf('.', dot+1);
- const bool dot2Valid = dot2 != -1 && dot2 != script.length()-1;
+ const int dot2 = nextDot(dot);
+ const bool dot2Valid = (dot2 != -1);
QByteArray enumValue = script.mid(dot2Valid ? dot2 + 1 : dot + 1);
QByteArray scopedEnumName = (dot2Valid ? script.mid(dot + 1, dot2 - dot - 1) : QByteArray());
if (!scopedEnumName.isEmpty())
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 7f30c4d713..c8b41d3684 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -654,11 +654,7 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
for (auto iter = m_compositeTypes.cbegin(), end = m_compositeTypes.cend(); iter != end; ++iter) {
iter.value()->isRegisteredWithEngine = false;
-
- // since unregisterInternalCompositeType() will not be called in this
- // case, we have to clean up the type registration manually
- QMetaType::unregisterType(iter.value()->metaTypeId);
- QMetaType::unregisterType(iter.value()->listMetaTypeId);
+ QQmlMetaType::unregisterInternalCompositeType({iter.value()->metaTypeId, iter.value()->listMetaTypeId});
}
#if QT_CONFIG(qml_debug)
delete profiler;
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 2c702367a4..8e292c4bbc 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -269,8 +269,24 @@ public:
mutable QMutex networkAccessManagerMutex;
+ QQmlGadgetPtrWrapper *valueTypeInstance(int typeIndex)
+ {
+ auto it = cachedValueTypeInstances.find(typeIndex);
+ if (it != cachedValueTypeInstances.end())
+ return *it;
+
+ if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(typeIndex)) {
+ QQmlGadgetPtrWrapper *instance = new QQmlGadgetPtrWrapper(valueType, q_func());
+ cachedValueTypeInstances.insert(typeIndex, instance);
+ return instance;
+ }
+
+ return nullptr;
+ }
+
private:
QHash<QQmlType, QJSValue> singletonInstances;
+ QHash<int, QQmlGadgetPtrWrapper *> cachedValueTypeInstances;
// These members must be protected by a QQmlEnginePrivate::Locker as they are required by
// the threaded loader. Only access them through their respective accessor methods.
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index c5c767df43..0baf142913 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -92,7 +92,12 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data,
d->typeId = type.typeId;
d->listId = type.listId;
d->isSetup = true;
- d->version = QTypeRevision::zero();
+ if (type.structVersion > 0) {
+ d->module = QString::fromUtf8(type.uri);
+ d->version = type.version;
+ } else {
+ d->version = QTypeRevision::zero();
+ }
data->registerType(d);
return d;
}
@@ -293,6 +298,17 @@ bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri)
return data->registerModuleTypes(uri);
}
+/*!
+ \internal
+ Method is only used to in tst_qqmlenginecleanup.cpp to test whether all
+ types have been removed from qmlLists after shutdown of QQmlEngine
+ */
+int QQmlMetaType::qmlRegisteredListTypeCount()
+{
+ QQmlMetaTypeDataPtr data;
+ return data->qmlLists.count();
+}
+
void QQmlMetaType::clearTypeRegistrations()
{
//Only cleans global static, assumed no running engine
@@ -329,7 +345,7 @@ void QQmlMetaType::unregisterAutoParentFunction(const QQmlPrivate::AutoParentFun
QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &type)
{
- if (type.structVersion > 0)
+ if (type.structVersion > 1)
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
QQmlMetaTypeDataPtr data;
@@ -338,8 +354,6 @@ QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &t
data->idToType.insert(priv->typeId, priv);
data->idToType.insert(priv->listId, priv);
- if (!priv->elementName.isEmpty())
- data->nameToType.insert(priv->elementName, priv);
if (data->interfaces.size() <= type.typeId)
data->interfaces.resize(type.typeId + 16);
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index c68bf0c551..0fc179fd34 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -202,6 +202,8 @@ public:
static void qmlRemoveModuleRegistration(const QString &uri);
static bool qmlRegisterModuleTypes(const QString &uri);
+
+ static int qmlRegisteredListTypeCount();
};
Q_DECLARE_TYPEINFO(QQmlMetaType, Q_MOVABLE_TYPE);
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 6cc2bf49c8..28dd3d4ab4 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -173,7 +173,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
context = new QQmlContextData;
context->isInternal = true;
context->imports = compilationUnit->typeNameCache;
- context->initFromTypeCompilationUnit(compilationUnit, flags & CreationFlags::NormalObject ? subComponentIndex : -1);
+ context->initFromTypeCompilationUnit(compilationUnit, subComponentIndex);
context->setParent(parentContext);
if (!sharedState->rootContext) {
@@ -856,12 +856,12 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
if (stringAt(obj->inheritedTypeNameIndex).isEmpty()) {
QObject *groupObject = nullptr;
- QQmlValueType *valueType = nullptr;
+ QQmlGadgetPtrWrapper *valueType = nullptr;
const QQmlPropertyData *valueTypeProperty = nullptr;
QObject *bindingTarget = _bindingTarget;
if (QQmlValueTypeFactory::isValueType(bindingProperty->propType())) {
- valueType = QQmlValueTypeFactory::valueType(bindingProperty->propType());
+ valueType = QQmlGadgetPtrWrapper::instance(engine, bindingProperty->propType());
if (!valueType) {
recordError(binding->location, tr("Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex)));
return false;
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 527c5ee603..2e4bc60f79 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -125,6 +125,7 @@ class QJSValue;
class QJSEngine;
class QQmlEngine;
class QQmlCustomParser;
+class QQmlTypeNotAvailable;
template<class T>
QQmlCustomParser *qmlCreateCustomParser()
@@ -406,6 +407,9 @@ namespace QQmlPrivate
int listId;
const char *iid;
+
+ const char *uri;
+ QTypeRevision version;
};
struct RegisterAutoParent {
@@ -578,6 +582,18 @@ namespace QQmlPrivate
static constexpr bool Value = bool(T::QmlIsSingleton::yes);
};
+ template<class T, class = QmlVoidT<>>
+ struct QmlInterface
+ {
+ static constexpr bool Value = false;
+ };
+
+ template<class T>
+ struct QmlInterface<T, QmlVoidT<typename T::QmlIsInterface>>
+ {
+ static constexpr bool Value = bool(T::QmlIsInterface::yes);
+ };
+
template<typename T>
void qmlRegisterSingletonAndRevisions(const char *uri, int versionMajor,
const QMetaObject *classInfoMetaObject)
@@ -636,6 +652,11 @@ namespace QQmlPrivate
qmlregister(TypeAndRevisionsRegistration, &type);
}
+
+ template<>
+ void Q_QML_EXPORT qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>(
+ const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject);
+
} // namespace QQmlPrivate
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 93020661e2..8521de6ab3 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -353,10 +353,15 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name)
if (terminal.count() >= 3 &&
terminal.at(0) == QLatin1Char('o') &&
terminal.at(1) == QLatin1Char('n') &&
- terminal.at(2).isUpper()) {
+ (terminal.at(2).isUpper() || terminal.at(2) == '_')) {
QString signalName = terminal.mid(2).toString();
- signalName[0] = signalName.at(0).toLower();
+ int firstNon_;
+ int length = signalName.length();
+ for (firstNon_ = 0; firstNon_ < length; ++firstNon_)
+ if (signalName.at(firstNon_) != '_')
+ break;
+ signalName[firstNon_] = signalName.at(firstNon_).toLower();
// XXX - this code treats methods as signals
@@ -1044,13 +1049,19 @@ QVariant QQmlProperty::read(const QObject *object, const QString &name, QQmlEngi
QVariant QQmlPropertyPrivate::readValueProperty()
{
- if (isValueType()) {
-
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType());
- Q_ASSERT(valueType);
- valueType->read(object, core.coreIndex());
- return valueType->metaObject()->property(valueTypeData.coreIndex()).read(valueType);
+ auto doRead = [&](QQmlGadgetPtrWrapper *wrapper) {
+ wrapper->read(object, core.coreIndex());
+ return wrapper->property(valueTypeData.coreIndex()).read(wrapper);
+ };
+ if (isValueType()) {
+ if (QQmlGadgetPtrWrapper *wrapper = QQmlGadgetPtrWrapper::instance(engine, core.propType()))
+ return doRead(wrapper);
+ if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) {
+ QQmlGadgetPtrWrapper wrapper(valueType, nullptr);
+ return doRead(&wrapper);
+ }
+ return QVariant();
} else if (core.isQList()) {
QQmlListProperty<QObject> prop;
@@ -1183,10 +1194,22 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object,
bool rv = false;
if (valueTypeData.isValid()) {
- QQmlValueType *writeBack = QQmlValueTypeFactory::valueType(core.propType());
- writeBack->read(object, core.coreIndex());
- rv = write(writeBack, valueTypeData, value, context, flags);
- writeBack->write(object, core.coreIndex(), flags);
+ auto doWrite = [&](QQmlGadgetPtrWrapper *wrapper) {
+ wrapper->read(object, core.coreIndex());
+ rv = write(wrapper, valueTypeData, value, context, flags);
+ wrapper->write(object, core.coreIndex(), flags);
+ };
+
+ QQmlGadgetPtrWrapper *wrapper = context
+ ? QQmlGadgetPtrWrapper::instance(context->engine, core.propType())
+ : nullptr;
+ if (wrapper) {
+ doWrite(wrapper);
+ } else if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) {
+ QQmlGadgetPtrWrapper wrapper(valueType, nullptr);
+ doWrite(&wrapper);
+ }
+
} else {
rv = write(object, core, value, context, flags);
}
diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp
index 001b19a8e5..3fb2eb399f 100644
--- a/src/qml/qml/qqmlpropertyvalidator.cpp
+++ b/src/qml/qml/qqmlpropertyvalidator.cpp
@@ -104,7 +104,7 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject(
validateObject(it->objectIndex, /* instantiatingBinding*/ nullptr);
}
- if (obj->flags & QV4::CompiledData::Object::IsComponent) {
+ if (obj->flags & QV4::CompiledData::Object::IsComponent && !(obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot)) {
Q_ASSERT(obj->nBindings == 1);
const QV4::CompiledData::Binding *componentBinding = obj->bindingTable();
Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object);
diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp
index d7a549e380..3518b21a70 100644
--- a/src/qml/qml/qqmltypecompiler.cpp
+++ b/src/qml/qml/qqmltypecompiler.cpp
@@ -881,6 +881,10 @@ bool QQmlComponentAndAliasResolver::resolve()
const int objCountWithoutSynthesizedComponents = qmlObjects->count();
for (int i = 0; i < objCountWithoutSynthesizedComponents; ++i) {
QmlIR::Object *obj = qmlObjects->at(i);
+ if (obj->isInlineComponent) {
+ componentRoots.append(i);
+ continue;
+ }
QQmlPropertyCache *cache = propertyCaches.at(i);
if (obj->inheritedTypeNameIndex == 0 && !cache)
continue;
@@ -936,7 +940,7 @@ bool QQmlComponentAndAliasResolver::resolve()
_objectsWithAliases.clear();
- if (!collectIdsAndAliases(rootBinding->value.objectIndex))
+ if (!collectIdsAndAliases(component->isInlineComponent ? componentRoots.at(i) : rootBinding->value.objectIndex))
return false;
component->namedObjectsInComponent.allocate(pool, _idToObjectIndex);
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index ec9061d04e..30d50b911e 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -829,8 +829,9 @@ void QQmlTypeData::resolveTypes()
if (ref.type.isCompositeSingleton()) {
ref.typeData = typeLoader()->getType(ref.type.sourceUrl());
- if (ref.typeData->status() == QQmlDataBlob::ResolvingDependencies || m_waitingOnMe.contains(ref.typeData.data())) {
- // TODO: give an error message? If so, we should record and show the path of the cycle.
+ if (ref.typeData->isWaiting() || m_waitingOnMe.contains(ref.typeData.data())) {
+ qWarning() << "Cyclic dependency detected between" << ref.typeData->urlString()
+ << "and" << urlString();
continue;
}
addDependency(ref.typeData.data());
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index afad15331c..d8cfd80b9b 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -602,51 +602,59 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo
scriptImported(blob, import->location, script.nameSpace, import->qualifier);
}
}
+ } else if (
+ // Major version of module already registered:
+ // We believe that the registration is complete.
+ QQmlMetaType::typeModule(import->uri, import->version)
+
+ // Otherwise, try to register further module types.
+ || (qmldirResult != QQmlImports::QmldirInterceptedToRemote
+ && QQmlMetaType::qmlRegisterModuleTypes(import->uri))
+
+ // Otherwise, there is no way to register any further types.
+ // Try with any module of that name.
+ || QQmlMetaType::isAnyModule(import->uri)) {
+
+ if (!m_importCache.addLibraryImport(
+ importDatabase, import->uri, import->qualifier, import->version,
+ QString(), QString(), false, errors)) {
+ return false;
+ }
} else {
- // Is this a module?
- if (QQmlMetaType::isAnyModule(import->uri)
- || (qmldirResult != QQmlImports::QmldirInterceptedToRemote
- && QQmlMetaType::qmlRegisterModuleTypes(import->uri))) {
+ // We haven't yet resolved this import
+ m_unresolvedImports << import;
+
+ QQmlAbstractUrlInterceptor *interceptor = typeLoader()->engine()->urlInterceptor();
+
+ // Query any network import paths for this library.
+ // Interceptor might redirect local paths.
+ QStringList remotePathList = importDatabase->importPathList(
+ interceptor ? QQmlImportDatabase::LocalOrRemote
+ : QQmlImportDatabase::Remote);
+ if (!remotePathList.isEmpty()) {
+ // Add this library and request the possible locations for it
if (!m_importCache.addLibraryImport(
importDatabase, import->uri, import->qualifier, import->version,
- QString(), QString(), false, errors))
+ QString(), QString(), true, errors))
return false;
- } else {
- // We haven't yet resolved this import
- m_unresolvedImports << import;
-
- QQmlAbstractUrlInterceptor *interceptor = typeLoader()->engine()->urlInterceptor();
-
- // Query any network import paths for this library.
- // Interceptor might redirect local paths.
- QStringList remotePathList = importDatabase->importPathList(
- interceptor ? QQmlImportDatabase::LocalOrRemote
- : QQmlImportDatabase::Remote);
- if (!remotePathList.isEmpty()) {
- // Add this library and request the possible locations for it
- if (!m_importCache.addLibraryImport(
- importDatabase, import->uri, import->qualifier, import->version,
- QString(), QString(), true, errors))
- return false;
- // Probe for all possible locations
- int priority = 0;
- const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(
- import->uri, remotePathList, import->version);
- for (const QString &qmldirPath : qmlDirPaths) {
- if (interceptor) {
- QUrl url = interceptor->intercept(
- QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
- QQmlAbstractUrlInterceptor::QmldirFile);
- if (!QQmlFile::isLocalFile(url)
- && !fetchQmldir(url, import, ++priority, errors)) {
- return false;
- }
- } else if (!fetchQmldir(QUrl(qmldirPath), import, ++priority, errors)) {
+ // Probe for all possible locations
+ int priority = 0;
+ const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(
+ import->uri, remotePathList, import->version);
+ for (const QString &qmldirPath : qmlDirPaths) {
+ if (interceptor) {
+ QUrl url = interceptor->intercept(
+ QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
+ QQmlAbstractUrlInterceptor::QmldirFile);
+ if (!QQmlFile::isLocalFile(url)
+ && !fetchQmldir(url, import, ++priority, errors)) {
return false;
}
-
+ } else if (!fetchQmldir(QUrl(qmldirPath), import, ++priority, errors)) {
+ return false;
}
+
}
}
}
diff --git a/src/qml/qml/qqmltypenotavailable.cpp b/src/qml/qml/qqmltypenotavailable.cpp
index ffa4472e4b..0e95d6062c 100644
--- a/src/qml/qml/qqmltypenotavailable.cpp
+++ b/src/qml/qml/qqmltypenotavailable.cpp
@@ -46,8 +46,6 @@ int qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMi
return qmlRegisterUncreatableType<QQmlTypeNotAvailable>(uri,versionMajor,versionMinor,qmlName,message);
}
-QQmlTypeNotAvailable::QQmlTypeNotAvailable() { }
-
QT_END_NAMESPACE
#include "moc_qqmltypenotavailable_p.cpp"
diff --git a/src/qml/qml/qqmltypenotavailable_p.h b/src/qml/qml/qqmltypenotavailable_p.h
index 8db5876b10..9bb19ed86c 100644
--- a/src/qml/qml/qqmltypenotavailable_p.h
+++ b/src/qml/qml/qqmltypenotavailable_p.h
@@ -55,14 +55,10 @@
QT_BEGIN_NAMESPACE
-
class QQmlTypeNotAvailable : public QObject {
Q_OBJECT
QML_NAMED_ELEMENT(TypeNotAvailable)
QML_UNCREATABLE("Type not available.")
-
-public:
- QQmlTypeNotAvailable();
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index 4beb6a4d07..254f1015e2 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -42,11 +42,11 @@
#include <QtCore/qmutex.h>
#include <private/qqmlglobal_p.h>
#include <QtCore/qdebug.h>
+#include <private/qqmlengine_p.h>
#include <private/qmetaobjectbuilder_p.h>
#if QT_CONFIG(qml_itemmodel)
#include <private/qqmlmodelindexvaluetype_p.h>
#endif
-#include <private/qmetatype_p.h>
Q_DECLARE_METATYPE(QQmlProperty)
@@ -221,61 +221,82 @@ void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor,
#endif
}
-QQmlValueType::QQmlValueType() :
- _metaObject(nullptr),
- gadgetPtr(nullptr),
- metaType(QMetaType::UnknownType)
+QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject)
+ : metaType(typeId)
{
+ QMetaObjectBuilder builder(gadgetMetaObject);
+ dynamicMetaObject = builder.toMetaObject();
+ *static_cast<QMetaObject*>(this) = *dynamicMetaObject;
}
-QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject)
- : gadgetPtr(QMetaType::create(typeId))
- , metaType(typeId)
+QQmlValueType::~QQmlValueType()
{
- QObjectPrivate *op = QObjectPrivate::get(this);
- Q_ASSERT(!op->metaObject);
- op->metaObject = this;
+ ::free(dynamicMetaObject);
+}
- QMetaObjectBuilder builder(gadgetMetaObject);
- _metaObject = builder.toMetaObject();
+QQmlGadgetPtrWrapper *QQmlGadgetPtrWrapper::instance(QQmlEngine *engine, int index)
+{
+ return engine ? QQmlEnginePrivate::get(engine)->valueTypeInstance(index) : nullptr;
+}
- *static_cast<QMetaObject*>(this) = *_metaObject;
+QQmlGadgetPtrWrapper::QQmlGadgetPtrWrapper(QQmlValueType *valueType, QObject *parent)
+ : QObject(parent), m_gadgetPtr(valueType->create())
+{
+ QObjectPrivate *d = QObjectPrivate::get(this);
+ Q_ASSERT(!d->metaObject);
+ d->metaObject = valueType;
}
-QQmlValueType::~QQmlValueType()
+QQmlGadgetPtrWrapper::~QQmlGadgetPtrWrapper()
{
- QObjectPrivate *op = QObjectPrivate::get(this);
- Q_ASSERT(op->metaObject == nullptr || op->metaObject == this);
- op->metaObject = nullptr;
- ::free(const_cast<QMetaObject *>(_metaObject));
- metaType.destroy(gadgetPtr);
+ QObjectPrivate *d = QObjectPrivate::get(this);
+ static_cast<const QQmlValueType *>(d->metaObject)->destroy(m_gadgetPtr);
+ d->metaObject = nullptr;
}
-void QQmlValueType::read(QObject *obj, int idx)
+void QQmlGadgetPtrWrapper::read(QObject *obj, int idx)
{
- void *a[] = { gadgetPtr, nullptr };
+ Q_ASSERT(m_gadgetPtr);
+ void *a[] = { m_gadgetPtr, nullptr };
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QQmlValueType::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags)
+void QQmlGadgetPtrWrapper::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags)
{
- Q_ASSERT(gadgetPtr);
+ Q_ASSERT(m_gadgetPtr);
int status = -1;
- void *a[] = { gadgetPtr, nullptr, &status, &flags };
+ void *a[] = { m_gadgetPtr, nullptr, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
-QVariant QQmlValueType::value()
+QVariant QQmlGadgetPtrWrapper::value()
+{
+ Q_ASSERT(m_gadgetPtr);
+ return QVariant(metaTypeId(), m_gadgetPtr);
+}
+
+void QQmlGadgetPtrWrapper::setValue(const QVariant &value)
+{
+ Q_ASSERT(m_gadgetPtr);
+ Q_ASSERT(metaTypeId() == value.userType());
+ const QQmlValueType *type = valueType();
+ type->destruct(m_gadgetPtr);
+ type->construct(m_gadgetPtr, value.constData());
+}
+
+int QQmlGadgetPtrWrapper::metaCall(QMetaObject::Call type, int id, void **argv)
{
- Q_ASSERT(gadgetPtr);
- return QVariant(metaType.id(), gadgetPtr);
+ Q_ASSERT(m_gadgetPtr);
+ const QMetaObject *metaObject = valueType();
+ QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(type, &metaObject, &id);
+ metaObject->d.static_metacall(static_cast<QObject *>(m_gadgetPtr), type, id, argv);
+ return id;
}
-void QQmlValueType::setValue(const QVariant &value)
+const QQmlValueType *QQmlGadgetPtrWrapper::valueType() const
{
- Q_ASSERT(metaType.id() == value.userType());
- metaType.destruct(gadgetPtr);
- metaType.construct(gadgetPtr, value.constData());
+ const QObjectPrivate *d = QObjectPrivate::get(this);
+ return static_cast<const QQmlValueType *>(d->metaObject);
}
QAbstractDynamicMetaObject *QQmlValueType::toDynamicMetaObject(QObject *)
@@ -287,12 +308,9 @@ void QQmlValueType::objectDestroyed(QObject *)
{
}
-int QQmlValueType::metaCall(QObject *, QMetaObject::Call type, int _id, void **argv)
+int QQmlValueType::metaCall(QObject *object, QMetaObject::Call type, int _id, void **argv)
{
- const QMetaObject *mo = _metaObject;
- QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(type, &mo, &_id);
- mo->d.static_metacall(reinterpret_cast<QObject*>(gadgetPtr), type, _id, argv);
- return _id;
+ return static_cast<QQmlGadgetPtrWrapper *>(object)->metaCall(type, _id, argv);
}
QString QQmlPointFValueType::toString() const
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index 901b7a6fd7..6768991581 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -54,7 +54,9 @@
#include "qqml.h"
#include "qqmlproperty.h"
#include "qqmlproperty_p.h"
+
#include <private/qqmlnullablevalue_p.h>
+#include <private/qmetatype_p.h>
#include <QtCore/qobject.h>
#include <QtCore/qrect.h>
@@ -65,16 +67,20 @@
QT_BEGIN_NAMESPACE
-class Q_QML_PRIVATE_EXPORT QQmlValueType : public QObject, public QAbstractDynamicMetaObject
+class Q_QML_PRIVATE_EXPORT QQmlValueType : public QAbstractDynamicMetaObject
{
public:
- QQmlValueType();
+ QQmlValueType() : metaType(QMetaType::UnknownType) {}
QQmlValueType(int userType, const QMetaObject *metaObject);
- ~QQmlValueType() override;
- void read(QObject *, int);
- void write(QObject *, int, QQmlPropertyData::WriteFlags flags);
- QVariant value();
- void setValue(const QVariant &);
+ ~QQmlValueType();
+
+ void *create() const { return metaType.create(); }
+ void destroy(void *gadgetPtr) const { metaType.destroy(gadgetPtr); }
+
+ void construct(void *gadgetPtr, const void *copy) const { metaType.construct(gadgetPtr, copy); }
+ void destruct(void *gadgetPtr) const { metaType.destruct(gadgetPtr); }
+
+ int metaTypeId() const { return metaType.id(); }
// ---- dynamic meta object data interface
QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) override;
@@ -82,12 +88,33 @@ public:
int metaCall(QObject *obj, QMetaObject::Call type, int _id, void **argv) override;
// ----
-private:
- const QMetaObject *_metaObject;
- void *gadgetPtr;
-
public:
QMetaType metaType;
+ QMetaObject *dynamicMetaObject = nullptr;
+};
+
+class Q_QML_PRIVATE_EXPORT QQmlGadgetPtrWrapper : public QObject
+{
+ Q_OBJECT
+public:
+ static QQmlGadgetPtrWrapper *instance(QQmlEngine *engine, int index);
+
+ QQmlGadgetPtrWrapper(QQmlValueType *valueType, QObject *parent);
+ ~QQmlGadgetPtrWrapper();
+
+ void read(QObject *obj, int idx);
+ void write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags);
+ QVariant value();
+ void setValue(const QVariant &value);
+
+ int metaTypeId() const { return valueType()->metaTypeId(); }
+ int metaCall(QMetaObject::Call type, int id, void **argv);
+ QMetaProperty property(int index) { return valueType()->property(index); }
+
+private:
+ const QQmlValueType *valueType() const;
+
+ void *m_gadgetPtr = nullptr;
};
class Q_QML_PRIVATE_EXPORT QQmlValueTypeFactory
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index ecb86e2f10..de23e929e2 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -136,6 +136,20 @@ static void list_clear(QQmlListProperty<QObject> *prop)
resolved.activateSignal();
}
+static void list_replace(QQmlListProperty<QObject> *prop, int index, QObject *o)
+{
+ const ResolvedList resolved(prop);
+ resolved.list()->replace(index, o);
+ resolved.activateSignal();
+}
+
+static void list_removeLast(QQmlListProperty<QObject> *prop)
+{
+ const ResolvedList resolved(prop);
+ resolved.list()->removeLast();
+ resolved.activateSignal();
+}
+
QQmlVMEVariantQObjectPtr::QQmlVMEVariantQObjectPtr()
: QQmlGuard<QObject>(nullptr), m_target(nullptr), m_index(-1)
{
@@ -289,11 +303,13 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a)
continue;
const int valueIndex = vi->m_propertyIndex.valueTypeIndex();
- int type = QQmlData::get(object)->propertyCache->property(id)->propType();
+ const QQmlData *data = QQmlData::get(object);
+ const int type = data->propertyCache->property(id)->propType();
if (type != QMetaType::UnknownType) {
if (valueIndex != -1) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type);
+ QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
+ data->context->engine, type);
Q_ASSERT(valueType);
//
@@ -327,7 +343,7 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a)
// (7) Issue the interceptor call with the new component value.
//
- QMetaProperty valueProp = valueType->metaObject()->property(valueIndex);
+ QMetaProperty valueProp = valueType->property(valueIndex);
QVariant newValue(type, a[0]);
valueType->read(object, id);
@@ -735,7 +751,8 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
*static_cast<QQmlListProperty<QObject> *>(a[0])
= QQmlListProperty<QObject>(
object, reinterpret_cast<void *>(quintptr(id)),
- list_append, list_count, list_at, list_clear);
+ list_append, list_count, list_at,
+ list_clear, list_replace, list_removeLast);
} else {
*reinterpret_cast<QObject **>(a[0]) = readPropertyAsQObject(id);
}
@@ -879,9 +896,9 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
return -1;
const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
// Value type property or deep alias
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(pd->propType());
+ QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
+ ctxt->engine, pd->propType());
if (valueType) {
-
valueType->read(target, coreIndex);
int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
diff --git a/src/qml/qtqmlglobal_p.h b/src/qml/qtqmlglobal_p.h
index 9ca0cf2abe..a729729b67 100644
--- a/src/qml/qtqmlglobal_p.h
+++ b/src/qml/qtqmlglobal_p.h
@@ -60,6 +60,8 @@
#define Q_QML_PRIVATE_EXPORT Q_QML_EXPORT
+void Q_QML_PRIVATE_EXPORT qml_register_types_QtQml();
+
#if !defined(QT_QMLDEVTOOLS_LIB) && !defined(QT_BUILD_QMLDEVTOOLS_LIB)
# define Q_QML_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT
#else
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 1e801641e5..4c44bba43e 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -238,7 +238,8 @@ void QQmlConnectionsParser::verifyBindings(const QQmlRefPointer<QV4::ExecutableC
const QV4::CompiledData::Binding *binding = props.at(ii);
const QString &propName = compilationUnit->stringAt(binding->propertyNameIndex);
- if (!propName.startsWith(QLatin1String("on")) || (propName.length() < 3 || !propName.at(2).isUpper())) {
+ const bool thirdCharacterIsValid = (propName.length() >= 2) && (propName.at(2).isUpper() || propName.at(2) == '_');
+ if (!propName.startsWith(QLatin1String("on")) || !thirdCharacterIsValid) {
error(props.at(ii), QQmlConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
return;
}
diff --git a/src/qmldebug/qmldebug.pro b/src/qmldebug/qmldebug.pro
index 94d300b765..ac3f3bf3bf 100644
--- a/src/qmldebug/qmldebug.pro
+++ b/src/qmldebug/qmldebug.pro
@@ -1,5 +1,5 @@
TARGET = QtQmlDebug
-QT = core-private network packetprotocol-private
+QT = core-private qml-private network packetprotocol-private
CONFIG += static internal_module
load(qt_module)
@@ -8,6 +8,7 @@ SOURCES += \
qqmldebugclient.cpp \
qqmldebugconnection.cpp \
qqmldebugmessageclient.cpp \
+ qqmldebugtranslationclient.cpp \
qqmlenginecontrolclient.cpp \
qqmlenginedebugclient.cpp \
qqmlinspectorclient.cpp \
@@ -24,6 +25,7 @@ HEADERS += \
qqmldebugclient_p_p.h \
qqmldebugconnection_p.h \
qqmldebugmessageclient_p.h \
+ qqmldebugtranslationclient_p.h \
qqmlenginedebugclient_p.h \
qqmlenginedebugclient_p_p.h \
qqmlenginecontrolclient_p.h \
diff --git a/src/qmldebug/qqmldebugtranslationclient.cpp b/src/qmldebug/qqmldebugtranslationclient.cpp
new file mode 100644
index 0000000000..1fd0748fa0
--- /dev/null
+++ b/src/qmldebug/qqmldebugtranslationclient.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldebugtranslationclient_p.h"
+#include "qqmldebugconnection_p.h"
+
+#include <QUrl>
+#include <QDataStream>
+
+#include <QDebug>
+#include <QtPacketProtocol/private/qpacket_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQmlDebugTranslationClient
+ \internal
+
+ \brief Client for the debug translation service
+
+ The QQmlDebugTranslationClient can test if translated texts will fit.
+ */
+
+QQmlDebugTranslationClient::QQmlDebugTranslationClient(QQmlDebugConnection *client)
+ : QQmlDebugClient(QLatin1String("DebugTranslation"), client)
+{
+}
+
+void QQmlDebugTranslationClient::messageReceived(const QByteArray &data)
+{
+ Q_UNUSED(data);
+}
+
+void QQmlDebugTranslationClient::triggerLanguage(const QUrl &url, const QString &locale)
+{
+ Q_UNUSED(url)
+ Q_UNUSED(locale)
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmldebugtranslationclient_p.h b/src/qmldebug/qqmldebugtranslationclient_p.h
new file mode 100644
index 0000000000..3163759d9e
--- /dev/null
+++ b/src/qmldebug/qqmldebugtranslationclient_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQMLDEBUGTRANSLATIONCLIENT_P_H
+#define QQMLDEBUGTRANSLATIONCLIENT_P_H
+
+#include "qqmldebugclient_p.h"
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QQmlDebugTranslationClient : public QQmlDebugClient
+{
+ Q_OBJECT
+
+public:
+ //needs to be in sync with QQmlDebugTranslationServiceImpl in qqmldebugtranslationservice.h
+ enum Command {
+ ChangeLanguage,
+ ChangeWarningColor,
+ ChangeElidedTextWarningString,
+ SetDebugTranslationServiceLogFile,
+ EnableElidedTextWarning,
+ DisableElidedTextWarning,
+ TestAllLanguages
+ };
+
+ explicit QQmlDebugTranslationClient(QQmlDebugConnection *client);
+
+ virtual void messageReceived(const QByteArray &) override;
+ void triggerLanguage(const QUrl &url, const QString &locale);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLDEBUGTRANSLATIONCLIENT_P_H
diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp
index 54bbccd617..33b57a0332 100644
--- a/src/qmlmodels/qqmladaptormodel.cpp
+++ b/src/qmlmodels/qqmladaptormodel.cpp
@@ -977,6 +977,9 @@ void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *parent, QQmlEn
} else if (list.type() == QQmlListAccessor::ListProperty) {
setObject(static_cast<const QQmlListReference *>(variant.constData())->object(), parent);
accessors = new VDMObjectDelegateDataType;
+ } else if (list.type() == QQmlListAccessor::ObjectList) {
+ setObject(nullptr, parent);
+ accessors = new VDMObjectDelegateDataType;
} else if (list.type() != QQmlListAccessor::Invalid
&& list.type() != QQmlListAccessor::Instance) { // Null QObject
setObject(nullptr, parent);
diff --git a/src/qmlmodels/qqmladaptormodel_p.h b/src/qmlmodels/qqmladaptormodel_p.h
index d243edda92..2c90ffc1d1 100644
--- a/src/qmlmodels/qqmladaptormodel_p.h
+++ b/src/qmlmodels/qqmladaptormodel_p.h
@@ -146,7 +146,10 @@ public:
return accessors->createItem(*this, metaType, index, rowAt(index), columnAt(index));
}
inline bool hasProxyObject() const {
- return list.type() == QQmlListAccessor::Instance || list.type() == QQmlListAccessor::ListProperty; }
+ return list.type() == QQmlListAccessor::Instance
+ || list.type() == QQmlListAccessor::ListProperty
+ || list.type() == QQmlListAccessor::ObjectList;
+ }
inline bool notify(
const QList<QQmlDelegateModelItem *> &items,
diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index ee407538f1..c32caafaa6 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -731,7 +731,7 @@ QQmlListProperty<QQmlDelegateModelGroup> QQmlDelegateModel::groups()
QQmlDelegateModelPrivate::group_append,
QQmlDelegateModelPrivate::group_count,
QQmlDelegateModelPrivate::group_at,
- nullptr);
+ nullptr, nullptr, nullptr);
}
/*!
diff --git a/src/qmlmodels/qqmldelegatemodel_p.h b/src/qmlmodels/qqmldelegatemodel_p.h
index adb5f7008b..8aab4badca 100644
--- a/src/qmlmodels/qqmldelegatemodel_p.h
+++ b/src/qmlmodels/qqmldelegatemodel_p.h
@@ -144,8 +144,6 @@ Q_SIGNALS:
void defaultGroupsChanged();
void rootIndexChanged();
void delegateChanged();
- void itemPooled(int index, QObject *object);
- void itemReused(int index, QObject *object);
private Q_SLOTS:
void _q_itemsChanged(int index, int count, const QVector<int> &roles);
diff --git a/src/qmlmodels/qqmllistaccessor.cpp b/src/qmlmodels/qqmllistaccessor.cpp
index c450c616e7..69427df184 100644
--- a/src/qmlmodels/qqmllistaccessor.cpp
+++ b/src/qmlmodels/qqmllistaccessor.cpp
@@ -80,6 +80,8 @@ void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine)
m_type = StringList;
} else if (d.userType() == QMetaType::QVariantList) {
m_type = VariantList;
+ } else if (d.userType() == qMetaTypeId<QList<QObject *>>()) {
+ m_type = ObjectList;
} else if (d.canConvert(QMetaType::Int)) {
// Here we have to check for an upper limit, because down the line code might (well, will)
// allocate memory depending on the number of elements. The upper limit cannot be INT_MAX:
@@ -120,6 +122,8 @@ int QQmlListAccessor::count() const
return qvariant_cast<QStringList>(d).count();
case VariantList:
return qvariant_cast<QVariantList>(d).count();
+ case ObjectList:
+ return qvariant_cast<QList<QObject *>>(d).count();
case ListProperty:
return ((const QQmlListReference *)d.constData())->count();
case Instance:
@@ -140,6 +144,8 @@ QVariant QQmlListAccessor::at(int idx) const
return QVariant::fromValue(qvariant_cast<QStringList>(d).at(idx));
case VariantList:
return qvariant_cast<QVariantList>(d).at(idx);
+ case ObjectList:
+ return QVariant::fromValue(qvariant_cast<QList<QObject *>>(d).at(idx));
case ListProperty:
return QVariant::fromValue(((const QQmlListReference *)d.constData())->at(idx));
case Instance:
diff --git a/src/qmlmodels/qqmllistaccessor_p.h b/src/qmlmodels/qqmllistaccessor_p.h
index bcd079adef..a57e4173e3 100644
--- a/src/qmlmodels/qqmllistaccessor_p.h
+++ b/src/qmlmodels/qqmllistaccessor_p.h
@@ -70,7 +70,7 @@ public:
int count() const;
QVariant at(int) const;
- enum Type { Invalid, StringList, VariantList, ListProperty, Instance, Integer };
+ enum Type { Invalid, StringList, VariantList, ObjectList, ListProperty, Instance, Integer };
Type type() const { return m_type; }
private:
diff --git a/src/qmlmodels/qqmlobjectmodel.cpp b/src/qmlmodels/qqmlobjectmodel.cpp
index 85e64cc2f9..dac868a0a2 100644
--- a/src/qmlmodels/qqmlobjectmodel.cpp
+++ b/src/qmlmodels/qqmlobjectmodel.cpp
@@ -91,6 +91,15 @@ public:
static_cast<QQmlObjectModelPrivate *>(prop->data)->clear();
}
+ static void children_replace(QQmlListProperty<QObject> *prop, int index, QObject *item) {
+ static_cast<QQmlObjectModelPrivate *>(prop->data)->replace(index, item);
+ }
+
+ static void children_removeLast(QQmlListProperty<QObject> *prop) {
+ auto data = static_cast<QQmlObjectModelPrivate *>(prop->data);
+ data->remove(data->children.count() - 1, 1);
+ }
+
void insert(int index, QObject *item) {
Q_Q(QQmlObjectModel);
children.insert(index, Item(item));
@@ -105,6 +114,18 @@ public:
emit q->childrenChanged();
}
+ void replace(int index, QObject *item) {
+ Q_Q(QQmlObjectModel);
+ auto *attached = QQmlObjectModelAttached::properties(children.at(index).item);
+ attached->setIndex(-1);
+ children.replace(index, Item(item));
+ QQmlObjectModelAttached::properties(children.at(index).item)->setIndex(index);
+ QQmlChangeSet changeSet;
+ changeSet.change(index, 1);
+ emit q->modelUpdated(changeSet, false);
+ emit q->childrenChanged();
+ }
+
void move(int from, int to, int n) {
Q_Q(QQmlObjectModel);
if (from > to) {
@@ -229,12 +250,13 @@ QQmlObjectModel::QQmlObjectModel(QObject *parent)
QQmlListProperty<QObject> QQmlObjectModel::children()
{
Q_D(QQmlObjectModel);
- return QQmlListProperty<QObject>(this,
- d,
- d->children_append,
- d->children_count,
- d->children_at,
- d->children_clear);
+ return QQmlListProperty<QObject>(this, d,
+ QQmlObjectModelPrivate::children_append,
+ QQmlObjectModelPrivate::children_count,
+ QQmlObjectModelPrivate::children_at,
+ QQmlObjectModelPrivate::children_clear,
+ QQmlObjectModelPrivate::children_replace,
+ QQmlObjectModelPrivate::children_removeLast);
}
/*!
diff --git a/src/qmlmodels/qqmlobjectmodel_p.h b/src/qmlmodels/qqmlobjectmodel_p.h
index 6c68e55012..7fb4f64676 100644
--- a/src/qmlmodels/qqmlobjectmodel_p.h
+++ b/src/qmlmodels/qqmlobjectmodel_p.h
@@ -104,6 +104,8 @@ Q_SIGNALS:
void createdItem(int index, QObject *object);
void initItem(int index, QObject *object);
void destroyingItem(QObject *object);
+ void itemPooled(int index, QObject *object);
+ void itemReused(int index, QObject *object);
protected:
QQmlInstanceModel(QObjectPrivate &dd, QObject *parent = nullptr)
diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h
index 7e28984789..80ba7ddaaf 100644
--- a/src/qmlmodels/qqmltableinstancemodel_p.h
+++ b/src/qmlmodels/qqmltableinstancemodel_p.h
@@ -122,10 +122,6 @@ public:
void setWatchedRoles(const QList<QByteArray> &) override { Q_UNREACHABLE(); }
int indexOf(QObject *, QObject *) const override { Q_UNREACHABLE(); return 0; }
-Q_SIGNALS:
- void itemPooled(int index, QObject *object);
- void itemReused(int index, QObject *object);
-
private:
QQmlComponent *resolveDelegate(int index);
diff --git a/src/qmlmodels/qquickpackage.cpp b/src/qmlmodels/qquickpackage.cpp
index 567381e5ab..42e7d0e09f 100644
--- a/src/qmlmodels/qquickpackage.cpp
+++ b/src/qmlmodels/qquickpackage.cpp
@@ -115,6 +115,14 @@ public:
QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
return list->count();
}
+ static void data_replace(QQmlListProperty<QObject> *prop, int index, QObject *o) {
+ QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
+ list->replace(index, DataGuard(o, list));
+ }
+ static void data_removeLast(QQmlListProperty<QObject> *prop) {
+ QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
+ list->removeLast();
+ }
};
QHash<QObject *, QQuickPackageAttached *> QQuickPackageAttached::attached;
@@ -152,10 +160,13 @@ QQuickPackage::~QQuickPackage()
QQmlListProperty<QObject> QQuickPackage::data()
{
Q_D(QQuickPackage);
- return QQmlListProperty<QObject>(this, &d->dataList, QQuickPackagePrivate::data_append,
- QQuickPackagePrivate::data_count,
- QQuickPackagePrivate::data_at,
- QQuickPackagePrivate::data_clear);
+ return QQmlListProperty<QObject>(this, &d->dataList,
+ QQuickPackagePrivate::data_append,
+ QQuickPackagePrivate::data_count,
+ QQuickPackagePrivate::data_at,
+ QQuickPackagePrivate::data_clear,
+ QQuickPackagePrivate::data_replace,
+ QQuickPackagePrivate::data_removeLast);
}
bool QQuickPackage::hasPart(const QString &name)
diff --git a/src/qmlmodels/qtqmlmodelsglobal_p.h b/src/qmlmodels/qtqmlmodelsglobal_p.h
index 145112c9c1..1a1157138d 100644
--- a/src/qmlmodels/qtqmlmodelsglobal_p.h
+++ b/src/qmlmodels/qtqmlmodelsglobal_p.h
@@ -58,4 +58,6 @@
#define Q_QMLMODELS_PRIVATE_EXPORT Q_QMLMODELS_EXPORT
#define Q_QMLMODELS_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT
+void Q_QMLMODELS_PRIVATE_EXPORT qml_register_types_QtQml_Models();
+
#endif // QTQMLMODELSGLOBAL_P_H
diff --git a/src/qmlworkerscript/qquickworkerscript_p.h b/src/qmlworkerscript/qquickworkerscript_p.h
index 03581089e0..22a205cfe4 100644
--- a/src/qmlworkerscript/qquickworkerscript_p.h
+++ b/src/qmlworkerscript/qquickworkerscript_p.h
@@ -84,7 +84,7 @@ private:
};
class QQmlV4Function;
-class Q_QMLWORKERSCRIPT_PRIVATE_EXPORT QQuickWorkerScript : public QObject, public QQmlParserStatus
+class Q_AUTOTEST_EXPORT QQuickWorkerScript : public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
diff --git a/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h b/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h
index 34236cd79e..c75d5f3129 100644
--- a/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h
+++ b/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h
@@ -57,4 +57,6 @@
#define Q_QMLWORKERSCRIPT_PRIVATE_EXPORT Q_QMLWORKERSCRIPT_EXPORT
#define Q_QMLWORKERSCRIPT_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT
+void Q_QMLWORKERSCRIPT_PRIVATE_EXPORT qml_register_types_QtQml_WorkerScript();
+
#endif // QTQMLWORKERSCRIPTGLOBAL_P_H
diff --git a/src/quick/accessible/qaccessiblequickview.cpp b/src/quick/accessible/qaccessiblequickview.cpp
index 41a02fc09c..b23b0316f5 100644
--- a/src/quick/accessible/qaccessiblequickview.cpp
+++ b/src/quick/accessible/qaccessiblequickview.cpp
@@ -84,8 +84,12 @@ QAccessibleInterface *QAccessibleQuickWindow::child(int index) const
QAccessibleInterface *QAccessibleQuickWindow::focusChild() const
{
QObject *focusObject = window()->focusObject();
- if (focusObject)
- return QAccessible::queryAccessibleInterface(focusObject);
+ if (focusObject) {
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(focusObject);
+ if (!iface || iface == this || !iface->focusChild())
+ return iface;
+ return iface->focusChild();
+ }
return nullptr;
}
diff --git a/src/quick/designer/qquickdesignersupportproperties.cpp b/src/quick/designer/qquickdesignersupportproperties.cpp
index c746f55daa..335795acf1 100644
--- a/src/quick/designer/qquickdesignersupportproperties.cpp
+++ b/src/quick/designer/qquickdesignersupportproperties.cpp
@@ -155,8 +155,8 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::propert
baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())
+ '.', inspectedObjects));
}
- } else if (QQmlValueTypeFactory::valueType(metaProperty.userType())) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(metaProperty.userType());
+ } else if (QQmlGadgetPtrWrapper *valueType
+ = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.userType())) {
valueType->setValue(metaProperty.read(object));
propertyNameList.append(propertyNameListForWritableProperties(valueType,
baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())
@@ -223,8 +223,8 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp
+ QQuickDesignerSupport::PropertyName(metaProperty.name())
+ '.', inspectedObjects));
}
- } else if (QQmlValueTypeFactory::valueType(metaProperty.userType())) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(metaProperty.userType());
+ } else if (QQmlGadgetPtrWrapper *valueType
+ = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.userType())) {
valueType->setValue(metaProperty.read(object));
propertyNameList.append(baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()));
propertyNameList.append(allPropertyNames(valueType,
diff --git a/src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml b/src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml
new file mode 100644
index 0000000000..e9a668ed8f
--- /dev/null
+++ b/src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+//! [document]
+import QtQuick 2.0
+
+Item {
+ width: 200
+ height: 250
+
+ ListModel {
+ id: myModel
+ ListElement { type: "Dog"; age: 8; noise: "meow" }
+ ListElement { type: "Cat"; age: 5; noise: "woof" }
+ }
+
+ component MyDelegate : Text {
+ required property string type
+ required property int age
+ text: type + ", " + age
+ // WRONG: Component.onCompleted: () => console.log(noise)
+ // The above line would cause a ReferenceError
+ // as there is no required property noise,
+ // and the presence of the required properties prevents
+ // noise from being injected into the scope
+ }
+
+ ListView {
+ anchors.fill: parent
+ model: myModel
+ delegate: MyDelegate {}
+ }
+}
+//! [document]
diff --git a/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc b/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
index 04dbf1cf20..555f730c9e 100644
--- a/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
+++ b/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
@@ -164,6 +164,16 @@ To visualize data, bind the view's \c model property to a model and the
\snippet qml/qml-data-models/listmodel-listview.qml document
+ To get finer control over which roles are accessible, and to make delegates
+ more self-contained and usable outside of views,
+ \li{Required Properties}{required properties} can be used. If a delegate
+ contains required properties, the named roles are not provided. Instead,
+ the QML engine will check if the name of a required property matches that of
+ a model role. If so, that property will be bound to the corresponding value
+ from the model.
+
+ \snippet qml/qml-data-models/listmodel-listview-required.qml document
+
If there is a naming clash between the model's properties and the delegate's
properties, the roles can be accessed with the qualified \e model name
instead. For example, if a \l Text type had \e type or \e age properties,
@@ -186,6 +196,10 @@ To visualize data, bind the view's \c model property to a model and the
modelData role is also provided for models that have only one role. In this
case the \e modelData role contains the same data as the named role.
+ \note \e model, \e index, and \e modelData roles are not accessible
+ if the delegate contains required properties, unless it has also required
+ properties with matching names.
+
QML provides several types of data models among the built-in set of QML
types. In addition, models can be created with Qt C++ and then made
available to \l{QQmlEngine} for use by
@@ -417,6 +431,12 @@ ListView {
\note The \c edit role is equal to \l Qt::EditRole. See \l{QAbstractItemModel::}{roleNames}()
for the built-in role names. However, real life models would usually register custom roles.
+\node If a model role is bound to a \li{Required Property}{required property}, assigning to
+that property will not modify the model. It will instead break the binding to the model (just
+like assigning to any other property breaks existing bindings). If you want to use
+required properties and change the model data, make model also a required property and assign to
+\e model.propertyName.
+
For more information, visit the \l{qtquick-modelviewsdata-cppmodels.html#changing-model-data}{Using C++ Models with Qt Quick Views}
article.
diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc
index 418475f100..528444cad3 100644
--- a/src/quick/doc/src/qmltypereference.qdoc
+++ b/src/quick/doc/src/qmltypereference.qdoc
@@ -179,6 +179,7 @@ available when you import \c QtQuick.
\li \l bool \c font.kerning
\li \l bool \c font.preferShaping
\li \l enumeration \c font.hintingPreference
+ \li \l string \c font.styleName
\endlist
Example:
diff --git a/src/quick/handlers/qquickhandlerpoint.cpp b/src/quick/handlers/qquickhandlerpoint.cpp
index f3d92cf200..e6148ca072 100644
--- a/src/quick/handlers/qquickhandlerpoint.cpp
+++ b/src/quick/handlers/qquickhandlerpoint.cpp
@@ -120,7 +120,10 @@ void QQuickHandlerPoint::reset(const QQuickEventPoint *point)
m_pressure = tp->pressure();
m_ellipseDiameters = tp->ellipseDiameters();
} else if (event->asPointerTabletEvent()) {
- // TODO
+ m_uniqueId = event->device()->uniqueId();
+ m_rotation = static_cast<const QQuickEventTabletPoint *>(point)->rotation();
+ m_pressure = static_cast<const QQuickEventTabletPoint *>(point)->pressure();
+ m_ellipseDiameters = QSizeF();
} else {
m_uniqueId = event->device()->uniqueId();
m_rotation = 0;
diff --git a/src/quick/handlers/qquickhoverhandler.cpp b/src/quick/handlers/qquickhoverhandler.cpp
index 1216eda477..b12d85784a 100644
--- a/src/quick/handlers/qquickhoverhandler.cpp
+++ b/src/quick/handlers/qquickhoverhandler.cpp
@@ -93,11 +93,22 @@ bool QQuickHoverHandler::wantsPointerEvent(QQuickPointerEvent *event)
{
QQuickEventPoint *point = event->point(0);
if (QQuickPointerDeviceHandler::wantsPointerEvent(event) && wantsEventPoint(point) && parentContains(point)) {
- // assume this is a mouse event, so there's only one point
+ // assume this is a mouse or tablet event, so there's only one point
setPointId(point->pointId());
return true;
}
- setHovered(false);
+
+ // Some hover events come from QQuickWindow::tabletEvent(). In between,
+ // some hover events come from QQWindowPrivate::flushFrameSynchronousEvents(),
+ // but those look like mouse events. If a particular HoverHandler instance
+ // is filtering for tablet events only (e.g. by setting
+ // acceptedDevices:PointerDevice.Stylus), those events should not cause
+ // the hovered property to transition to false prematurely.
+ // If a QQuickPointerTabletEvent caused the hovered property to become true,
+ // then only another QQuickPointerTabletEvent can make it become false.
+ if (!(m_hoveredTablet && event->asPointerMouseEvent()))
+ setHovered(false);
+
return false;
}
@@ -107,6 +118,8 @@ void QQuickHoverHandler::handleEventPoint(QQuickEventPoint *point)
if (point->state() == QQuickEventPoint::Released &&
point->pointerEvent()->device()->pointerType() == QQuickPointerDevice::Finger)
hovered = false;
+ else if (point->pointerEvent()->asPointerTabletEvent())
+ m_hoveredTablet = true;
setHovered(hovered);
setPassiveGrab(point);
}
@@ -124,6 +137,8 @@ void QQuickHoverHandler::setHovered(bool hovered)
if (m_hovered != hovered) {
qCDebug(lcHoverHandler) << objectName() << "hovered" << m_hovered << "->" << hovered;
m_hovered = hovered;
+ if (!hovered)
+ m_hoveredTablet = false;
emit hoveredChanged();
}
}
diff --git a/src/quick/handlers/qquickhoverhandler_p.h b/src/quick/handlers/qquickhoverhandler_p.h
index e4786bfa53..313b87217c 100644
--- a/src/quick/handlers/qquickhoverhandler_p.h
+++ b/src/quick/handlers/qquickhoverhandler_p.h
@@ -84,6 +84,7 @@ private:
private:
bool m_hovered = false;
+ bool m_hoveredTablet = false;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 469dc3cb4d..3c01bd2cb1 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -658,14 +658,73 @@ QQuickPointerDevice *QQuickPointerDevice::genericMouseDevice()
return g_genericMouseDevice;
}
-QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id)
-{
- auto it = g_tabletDevices->find(id);
+QQuickPointerDevice *QQuickPointerDevice::tabletDevice(const QTabletEvent *event)
+{
+ // QTabletEvent::uniqueId() is the same for the pointy end and the eraser end of the stylus.
+ // We need to make those unique. QTabletEvent::PointerType only needs 2 bits' worth of storage.
+ // The key into g_tabletDevices just needs to be unique; we don't need to extract uniqueId
+ // back out of it, because QQuickPointerDevice stores that separately anyway.
+ // So the shift-and-add can be thought of as a sort of hash function, even though
+ // most of the time the result will be recognizable because the uniqueId MSBs are often 0.
+ qint64 key = event->uniqueId() + (qint64(event->pointerType()) << 60);
+ auto it = g_tabletDevices->find(key);
if (it != g_tabletDevices->end())
return it.value();
- // ### Figure out how to populate the tablet devices
- return nullptr;
+ DeviceType type = UnknownDevice;
+ int buttonCount = 0;
+ Capabilities caps = Position | Pressure | Hover;
+ // TODO Qt 6: we can't know for sure about XTilt or YTilt until we have a
+ // QTabletDevice populated with capabilities provided by QPA plugins
+
+ switch (event->device()) {
+ case QTabletEvent::Stylus:
+ type = QQuickPointerDevice::Stylus;
+ buttonCount = 3;
+ break;
+ case QTabletEvent::RotationStylus:
+ type = QQuickPointerDevice::Stylus;
+ caps |= QQuickPointerDevice::Rotation;
+ buttonCount = 1;
+ break;
+ case QTabletEvent::Airbrush:
+ type = QQuickPointerDevice::Airbrush;
+ buttonCount = 2;
+ break;
+ case QTabletEvent::Puck:
+ type = QQuickPointerDevice::Puck;
+ buttonCount = 3;
+ break;
+ case QTabletEvent::FourDMouse:
+ type = QQuickPointerDevice::Mouse;
+ caps |= QQuickPointerDevice::Rotation;
+ buttonCount = 3;
+ break;
+ default:
+ type = QQuickPointerDevice::UnknownDevice;
+ break;
+ }
+
+ PointerType ptype = GenericPointer;
+ switch (event->pointerType()) {
+ case QTabletEvent::Pen:
+ ptype = Pen;
+ break;
+ case QTabletEvent::Eraser:
+ ptype = Eraser;
+ break;
+ case QTabletEvent::Cursor:
+ ptype = Cursor;
+ break;
+ case QTabletEvent::UnknownPointer:
+ break;
+ }
+
+ QQuickPointerDevice *device = new QQuickPointerDevice(type, ptype, caps, 1, buttonCount,
+ QLatin1String("tablet tool ") + QString::number(event->uniqueId()), event->uniqueId());
+
+ g_tabletDevices->insert(key, device);
+ return device;
}
/*!
@@ -1284,6 +1343,12 @@ QVector2D QQuickEventPoint::estimatedVelocity() const
QQuickPointerEvent::~QQuickPointerEvent()
{}
+QQuickPointerMouseEvent::QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerMouseEvent::reset(QEvent *event)
{
auto ev = static_cast<QMouseEvent*>(event);
@@ -1398,6 +1463,12 @@ void QQuickPointerTouchEvent::localize(QQuickItem *target)
}
#if QT_CONFIG(gestures)
+QQuickPointerNativeGestureEvent::QQuickPointerNativeGestureEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerNativeGestureEvent::reset(QEvent *event)
{
auto ev = static_cast<QNativeGestureEvent*>(event);
@@ -1560,6 +1631,12 @@ QQuickEventPoint *QQuickSinglePointEvent::point(int i) const
\note Many platforms provide no such information. On such platforms,
\c inverted always returns false.
*/
+QQuickPointerScrollEvent::QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerScrollEvent::reset(QEvent *event)
{
m_event = static_cast<QInputEvent*>(event);
@@ -1832,6 +1909,81 @@ QMouseEvent *QQuickPointerTouchEvent::syntheticMouseEvent(int pointID, QQuickIte
return &m_synthMouseEvent;
}
+#if QT_CONFIG(tabletevent)
+QQuickPointerTabletEvent::QQuickPointerTabletEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventTabletPoint(this);
+}
+
+QQuickPointerEvent *QQuickPointerTabletEvent::reset(QEvent *event)
+{
+ auto ev = static_cast<QTabletEvent*>(event);
+ m_event = ev;
+ if (!event)
+ return this;
+
+ Q_ASSERT(m_device == QQuickPointerDevice::tabletDevice(ev));
+ m_device->eventDeliveryTargets().clear();
+ m_button = ev->button();
+ m_pressedButtons = ev->buttons();
+ static_cast<QQuickEventTabletPoint *>(m_point)->reset(ev);
+ return this;
+}
+
+QQuickEventTabletPoint::QQuickEventTabletPoint(QQuickPointerTabletEvent *parent)
+ : QQuickEventPoint(parent)
+{
+}
+
+void QQuickEventTabletPoint::reset(const QTabletEvent *ev)
+{
+ Qt::TouchPointState state = Qt::TouchPointStationary;
+ switch (ev->type()) {
+ case QEvent::TabletPress:
+ state = Qt::TouchPointPressed;
+ clearPassiveGrabbers();
+ break;
+ case QEvent::TabletRelease:
+ state = Qt::TouchPointReleased;
+ break;
+ case QEvent::TabletMove:
+ state = Qt::TouchPointMoved;
+ break;
+ default:
+ break;
+ }
+ QQuickEventPoint::reset(state, ev->posF(), 1, ev->timestamp());
+ m_rotation = ev->rotation();
+ m_pressure = ev->pressure();
+ m_tangentialPressure = ev->tangentialPressure();
+ m_tilt = QVector2D(ev->xTilt(), ev->yTilt());
+}
+
+bool QQuickPointerTabletEvent::isPressEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletPress;
+}
+
+bool QQuickPointerTabletEvent::isUpdateEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletMove;
+}
+
+bool QQuickPointerTabletEvent::isReleaseEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletRelease;
+}
+
+QTabletEvent *QQuickPointerTabletEvent::asTabletEvent() const
+{
+ return static_cast<QTabletEvent *>(m_event);
+}
+#endif // QT_CONFIG(tabletevent)
+
#if QT_CONFIG(gestures)
bool QQuickPointerNativeGestureEvent::isPressEvent() const
{
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 94b61fd364..84450e060a 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -478,8 +478,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickSinglePointEvent : public QQuickPointerEvent
{
Q_OBJECT
public:
- QQuickSinglePointEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickPointerEvent(parent, device), m_point(new QQuickEventPoint(this)) { }
+ QQuickSinglePointEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickPointerEvent(parent, device) { }
void localize(QQuickItem *target) override;
int pointCount() const override { return 1; }
@@ -493,7 +493,7 @@ public:
bool hasExclusiveGrabber(const QQuickPointerHandler *handler) const override;
protected:
- QQuickEventPoint *m_point;
+ QQuickEventPoint *m_point = nullptr;
Q_DISABLE_COPY(QQuickSinglePointEvent)
};
@@ -507,8 +507,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerMouseEvent : public QQuickSinglePointE
QML_ADDED_IN_MINOR_VERSION(12)
public:
- QQuickPointerMouseEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
bool isPressEvent() const override;
@@ -570,6 +569,60 @@ private:
Q_DISABLE_COPY(QQuickPointerTouchEvent)
};
+#if QT_CONFIG(tabletevent)
+class Q_QUICK_PRIVATE_EXPORT QQuickEventTabletPoint : public QQuickEventPoint
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal rotation READ rotation)
+ Q_PROPERTY(qreal pressure READ pressure)
+ Q_PROPERTY(qreal tangentialPressure READ tangentialPressure)
+ Q_PROPERTY(QVector2D tilt READ tilt)
+
+ QML_NAMED_ELEMENT(EventTabletPoint)
+ QML_UNCREATABLE("EventTouchPoint is only available as a member of PointerEvent.")
+ QML_ADDED_IN_MINOR_VERSION(15)
+
+public:
+ QQuickEventTabletPoint(QQuickPointerTabletEvent *parent);
+
+ void reset(const QTabletEvent *e);
+
+ qreal rotation() const { return m_rotation; }
+ qreal pressure() const { return m_pressure; }
+ qreal tangentialPressure() const { return m_tangentialPressure; }
+ QVector2D tilt() const { return m_tilt; }
+
+private:
+ qreal m_rotation;
+ qreal m_pressure;
+ qreal m_tangentialPressure;
+ QVector2D m_tilt;
+
+ friend class QQuickPointerTouchEvent;
+
+ Q_DISABLE_COPY(QQuickEventTabletPoint)
+};
+
+class Q_QUICK_PRIVATE_EXPORT QQuickPointerTabletEvent : public QQuickSinglePointEvent
+{
+ Q_OBJECT
+public:
+ QQuickPointerTabletEvent(QObject *parent, QQuickPointerDevice *device);
+
+ QQuickPointerEvent *reset(QEvent *) override;
+ bool isPressEvent() const override;
+ bool isUpdateEvent() const override;
+ bool isReleaseEvent() const override;
+ QQuickPointerTabletEvent *asPointerTabletEvent() override { return this; }
+ const QQuickPointerTabletEvent *asPointerTabletEvent() const override { return this; }
+ const QQuickEventTabletPoint *tabletPoint() const { return static_cast<QQuickEventTabletPoint *>(m_point); }
+
+ QTabletEvent *asTabletEvent() const;
+
+ Q_DISABLE_COPY(QQuickPointerTabletEvent)
+};
+#endif // QT_CONFIG(tabletevent)
+
#if QT_CONFIG(gestures)
class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickSinglePointEvent
{
@@ -578,8 +631,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickSing
Q_PROPERTY(qreal value READ value CONSTANT)
public:
- QQuickPointerNativeGestureEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerNativeGestureEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
bool isPressEvent() const override;
@@ -608,8 +660,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerScrollEvent : public QQuickSinglePoint
QML_ADDED_IN_MINOR_VERSION(14)
public:
- QQuickPointerScrollEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
void localize(QQuickItem *target) override;
@@ -714,7 +765,7 @@ public:
static QQuickPointerDevice *touchDevice(const QTouchDevice *d);
static QList<QQuickPointerDevice *> touchDevices();
static QQuickPointerDevice *genericMouseDevice();
- static QQuickPointerDevice *tabletDevice(qint64);
+ static QQuickPointerDevice *tabletDevice(const QTabletEvent *event);
QVector<QQuickPointerHandler *> &eventDeliveryTargets() { return m_eventDeliveryTargets; }
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 8ade5b7e37..27c57e147a 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -128,8 +128,13 @@ void QQuickFlickableVisibleArea::updateVisible()
// Vertical
const qreal viewheight = flickable->height();
const qreal maxyextent = -flickable->maxYExtent() + flickable->minYExtent();
- qreal pagePos = (-p->vData.move.value() + flickable->minYExtent()) / (maxyextent + viewheight);
- qreal pageSize = viewheight / (maxyextent + viewheight);
+ const qreal maxYBounds = maxyextent + viewheight;
+ qreal pagePos = 0;
+ qreal pageSize = 0;
+ if (!qFuzzyIsNull(maxYBounds)) {
+ pagePos = (-p->vData.move.value() + flickable->minYExtent()) / maxYBounds;
+ pageSize = viewheight / maxYBounds;
+ }
if (pageSize != m_heightRatio) {
m_heightRatio = pageSize;
@@ -143,8 +148,14 @@ void QQuickFlickableVisibleArea::updateVisible()
// Horizontal
const qreal viewwidth = flickable->width();
const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent();
- pagePos = (-p->hData.move.value() + flickable->minXExtent()) / (maxxextent + viewwidth);
- pageSize = viewwidth / (maxxextent + viewwidth);
+ const qreal maxXBounds = maxxextent + viewwidth;
+ if (!qFuzzyIsNull(maxXBounds)) {
+ pagePos = (-p->hData.move.value() + flickable->minXExtent()) / maxXBounds;
+ pageSize = viewwidth / maxXBounds;
+ } else {
+ pagePos = 0;
+ pageSize = 0;
+ }
if (pageSize != m_widthRatio) {
m_widthRatio = pageSize;
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 1ff55dae90..3f5f11effd 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -73,7 +73,7 @@ class QQuickFlickableVisibleArea;
class QQuickTransition;
class QQuickFlickableReboundTransition;
-class Q_AUTOTEST_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickFlickable)
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index bd6b9d741e..125518e51b 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -183,13 +183,6 @@ static void qt_quickitems_defineModule()
qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
qRegisterMetaType<QPointingDeviceUniqueId>("QPointingDeviceUniqueId");
qRegisterMetaType<QQuickHandlerPoint>();
-
-#if !QT_CONFIG(quick_animatedimage)
- qmlRegisterTypeNotAvailable(
- "QtQuick", 2, 15, "AnimatedImage",
- QCoreApplication::translate("QQuickAnimatedImage",
- "Qt was built without support for QMovie"));
-#endif
}
static void initResources()
diff --git a/src/quick/items/qquickitemsmodule_p.h b/src/quick/items/qquickitemsmodule_p.h
index 6ceb0d56e6..28dff65dff 100644
--- a/src/quick/items/qquickitemsmodule_p.h
+++ b/src/quick/items/qquickitemsmodule_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <private/qtquickglobal_p.h>
#include <QtGui/qevent.h>
#include <qqml.h>
@@ -71,6 +72,17 @@ struct QPointingDeviceUniqueIdForeign
QML_UNCREATABLE("PointingDeviceUniqueId is only available via read-only properties.")
};
+#if !QT_CONFIG(quick_animatedimage)
+struct QQuickAnimatedImageNotAvailable
+{
+ Q_GADGET
+ QML_UNAVAILABLE
+ QML_NAMED_ELEMENT(AnimatedImage)
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_UNCREATABLE("Qt was built without support for QMovie.")
+};
+#endif
+
QT_END_NAMESPACE
#endif // QQUICKITEMSMODULE_P_H
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 7fb392233e..3e3a2c262b 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -2419,7 +2419,7 @@ void QQuickItemView::destroyingItem(QObject *object)
Q_D(QQuickItemView);
QQuickItem* item = qmlobject_cast<QQuickItem*>(object);
if (item) {
- item->setParentItem(nullptr);
+ QQuickItemPrivate::get(item)->setCulled(true);
d->unrequestedItems.remove(item);
}
}
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index badd2efe29..b91e705ad0 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -141,6 +141,8 @@ public:
QQuickItemViewAttached *getAttachedObject(const QObject *object) const override;
+ void fixupHeader();
+ void fixupHeaderCompleted();
QQuickListView::Orientation orient;
qreal visiblePos;
qreal averageSize;
@@ -169,6 +171,12 @@ public:
QString nextSection;
qreal overshootDist;
+
+ qreal desiredViewportPosition;
+ qreal fixupHeaderPosition;
+ bool headerNeedsSeparateFixup : 1;
+ bool desiredHeaderVisible : 1;
+
bool correctFlick : 1;
bool inFlickCorrection : 1;
@@ -182,7 +190,9 @@ public:
, highlightPosAnimator(nullptr), highlightWidthAnimator(nullptr), highlightHeightAnimator(nullptr)
, highlightMoveVelocity(400), highlightResizeVelocity(400), highlightResizeDuration(-1)
, sectionCriteria(nullptr), currentSectionItem(nullptr), nextSectionItem(nullptr)
- , overshootDist(0.0), correctFlick(false), inFlickCorrection(false)
+ , overshootDist(0.0), desiredViewportPosition(0.0), fixupHeaderPosition(0.0)
+ , headerNeedsSeparateFixup(false), desiredHeaderVisible(false)
+ , correctFlick(false), inFlickCorrection(false)
{
highlightMoveDuration = -1; //override default value set in base class
}
@@ -1402,6 +1412,31 @@ void QQuickListViewPrivate::updateFooter()
emit q->footerItemChanged();
}
+void QQuickListViewPrivate::fixupHeaderCompleted()
+{
+ headerNeedsSeparateFixup = false;
+ QObjectPrivate::disconnect(&timeline, &QQuickTimeLine::updated, this, &QQuickListViewPrivate::fixupHeader);
+}
+
+void QQuickListViewPrivate::fixupHeader()
+{
+ FxListItemSG *listItem = static_cast<FxListItemSG*>(header);
+ const bool fixingUp = (orient == QQuickListView::Vertical ? vData : hData).fixingUp;
+ if (fixingUp && headerPositioning == QQuickListView::PullBackHeader && visibleItems.count()) {
+ int fixupDura = timeline.duration();
+ if (fixupDura < 0)
+ fixupDura = fixupDuration/2;
+ const int t = timeline.time();
+
+ const qreal progress = qreal(t)/fixupDura;
+ const qreal ultimateHeaderPosition = desiredHeaderVisible ? desiredViewportPosition : desiredViewportPosition - headerSize();
+ const qreal headerPosition = fixupHeaderPosition * (1 - progress) + ultimateHeaderPosition * progress;
+ const qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
+ const qreal clampedPos = qBound(originPosition() - headerSize(), headerPosition, lastPosition() - size());
+ listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos));
+ }
+}
+
void QQuickListViewPrivate::updateHeader()
{
Q_Q(QQuickListView);
@@ -1419,9 +1454,14 @@ void QQuickListViewPrivate::updateHeader()
if (headerPositioning == QQuickListView::OverlayHeader) {
listItem->setPosition(isContentFlowReversed() ? -position() - size() : position());
} else if (visibleItems.count()) {
+ const bool fixingUp = (orient == QQuickListView::Vertical ? vData : hData).fixingUp;
if (headerPositioning == QQuickListView::PullBackHeader) {
- qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
- qreal clampedPos = qBound(originPosition() - headerSize(), listItem->position(), lastPosition() - headerSize() - size());
+ qreal headerPosition = listItem->position();
+ const qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
+ // Make sure the header is not shown if we absolutely do not have any plans to show it
+ if (fixingUp && !headerNeedsSeparateFixup)
+ headerPosition = viewPos - headerSize();
+ qreal clampedPos = qBound(originPosition() - headerSize(), headerPosition, lastPosition() - size());
listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos));
} else {
qreal startPos = originPosition();
@@ -1539,13 +1579,46 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
bias = -bias;
tempPosition -= bias;
}
- FxViewItem *topItem = snapItemAt(tempPosition+highlightRangeStart);
+
+ qreal snapOffset = 0;
+ qreal overlayHeaderOffset = 0;
+ bool isHeaderWithinBounds = false;
+ if (header) {
+ qreal visiblePartOfHeader = header->position() + header->size() - tempPosition;
+ isHeaderWithinBounds = visiblePartOfHeader > 0;
+ switch (headerPositioning) {
+ case QQuickListView::OverlayHeader:
+ snapOffset = header->size();
+ overlayHeaderOffset = header->size();
+ break;
+ case QQuickListView::InlineHeader:
+ if (isHeaderWithinBounds && tempPosition < originPosition())
+ // For the inline header, we want to snap to the first item
+ // if we're more than halfway down the inline header.
+ // So if we look for an item halfway down of the header
+ snapOffset = header->size() / 2;
+ break;
+ case QQuickListView::PullBackHeader:
+ desiredHeaderVisible = visiblePartOfHeader > header->size()/2;
+ if (qFuzzyCompare(header->position(), tempPosition)) {
+ // header was pulled down; make sure it remains visible and snap items to bottom of header
+ snapOffset = header->size();
+ } else if (desiredHeaderVisible) {
+ // More than 50% of the header is shown. Show it fully.
+ // Scroll the view so the next item snaps to the header.
+ snapOffset = header->size();
+ overlayHeaderOffset = header->size();
+ }
+ break;
+ }
+ }
+ FxViewItem *topItem = snapItemAt(tempPosition + snapOffset + highlightRangeStart);
if (strictHighlightRange && currentItem && (!topItem || (topItem->index != currentIndex && fixupMode == Immediate))) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
topItem = currentItem;
}
- FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
+ FxViewItem *bottomItem = snapItemAt(tempPosition + snapOffset + highlightRangeEnd);
if (strictHighlightRange && currentItem && (!bottomItem || (bottomItem->index != currentIndex && fixupMode == Immediate))) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
@@ -1553,27 +1626,92 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
}
qreal pos;
bool isInBounds = -position() > maxExtent && -position() <= minExtent;
- if (topItem && (isInBounds || strictHighlightRange)) {
- if (topItem->index == 0 && header && tempPosition+highlightRangeStart < header->position()+header->size()/2 && !strictHighlightRange) {
- pos = isContentFlowReversed() ? - header->position() + highlightRangeStart - size() : header->position() - highlightRangeStart;
+
+ if (header && !topItem && isInBounds) {
+ // We are trying to pull back further than needed
+ switch (headerPositioning) {
+ case QQuickListView::OverlayHeader:
+ pos = startPosition() - overlayHeaderOffset;
+ break;
+ case QQuickListView::InlineHeader:
+ pos = isContentFlowReversed() ? header->size() - size() : header->position();
+ break;
+ case QQuickListView::PullBackHeader:
+ pos = isContentFlowReversed() ? -size() : startPosition();
+ break;
+ }
+ } else if (topItem && (isInBounds || strictHighlightRange)) {
+ if (topItem->index == 0 && header && !hasStickyHeader() && tempPosition+highlightRangeStart < header->position()+header->size()/2 && !strictHighlightRange) {
+ pos = isContentFlowReversed() ? -header->position() + highlightRangeStart - size() : (header->position() - highlightRangeStart + header->size());
} else {
- if (isContentFlowReversed())
- pos = qMax(qMin(-static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size(), -maxExtent), -minExtent);
- else
- pos = qMax(qMin(static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart, -maxExtent), -minExtent);
+ if (header && headerPositioning == QQuickListView::PullBackHeader) {
+ // We pulled down the header. If it isn't pulled all way down, we need to snap
+ // the header.
+ if (qFuzzyCompare(tempPosition, header->position())) {
+ // It is pulled all way down. Scroll-snap the content, but not the header.
+ if (isContentFlowReversed())
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size() + snapOffset;
+ else
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart - snapOffset;
+ } else {
+ // Header is not pulled all way down, make it completely visible or hide it.
+ // Depends on how much of the header is visible.
+ if (desiredHeaderVisible) {
+ // More than half of the header is visible - show it.
+ // Scroll so that the topItem is aligned to a fully visible header
+ if (isContentFlowReversed())
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size() + headerSize();
+ else
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart - headerSize();
+ } else {
+ // Less than half is visible - hide the header. Scroll so
+ // that the topItem is aligned to the top of the view
+ if (isContentFlowReversed())
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size();
+ else
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart;
+ }
+ }
+
+ headerNeedsSeparateFixup = isHeaderWithinBounds || desiredHeaderVisible;
+ if (headerNeedsSeparateFixup) {
+ // We need to animate the header independently if it starts visible or should end as visible,
+ // since the header should not necessarily follow the content.
+ // Store the desired viewport position.
+ // Also store the header position so we know where to animate the header from (fixupHeaderPosition).
+ // We deduce the desired header position from the desiredViewportPosition variable.
+ pos = qBound(-minExtent, pos, -maxExtent);
+ desiredViewportPosition = isContentFlowReversed() ? -pos - size() : pos;
+
+ FxListItemSG *headerItem = static_cast<FxListItemSG*>(header);
+ fixupHeaderPosition = headerItem->position();
+
+ // follow the same fixup timeline
+ QObjectPrivate::connect(&timeline, &QQuickTimeLine::updated, this, &QQuickListViewPrivate::fixupHeader);
+ QObjectPrivate::connect(&timeline, &QQuickTimeLine::completed, this, &QQuickListViewPrivate::fixupHeaderCompleted);
+ }
+ } else if (isContentFlowReversed()) {
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size() + overlayHeaderOffset;
+ } else {
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart - overlayHeaderOffset;
+ }
}
} else if (bottomItem && isInBounds) {
if (isContentFlowReversed())
- pos = qMax(qMin(-static_cast<FxListItemSG*>(bottomItem)->itemPosition() + highlightRangeEnd - size(), -maxExtent), -minExtent);
+ pos = -static_cast<FxListItemSG*>(bottomItem)->itemPosition() + highlightRangeEnd - size() + overlayHeaderOffset;
else
- pos = qMax(qMin(static_cast<FxListItemSG*>(bottomItem)->itemPosition() - highlightRangeEnd, -maxExtent), -minExtent);
+ pos = static_cast<FxListItemSG*>(bottomItem)->itemPosition() - highlightRangeEnd - overlayHeaderOffset;
} else {
QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
return;
}
+ pos = qBound(-minExtent, pos, -maxExtent);
qreal dist = qAbs(data.move + pos);
- if (dist > 0) {
+ if (dist >= 0) {
+ // Even if dist == 0 we still start the timeline, because we use the same timeline for
+ // moving the header. And we might need to move the header while the content does not
+ // need moving
timeline.reset(data.move);
if (fixupMode != Immediate) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 8722a45373..1fb71272b1 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -56,7 +56,7 @@ static const QQuickItemPrivate::ChangeTypes watchedChanges
QQuickLoaderPrivate::QQuickLoaderPrivate()
: item(nullptr), object(nullptr), itemContext(nullptr), incubator(nullptr), updatingSize(false),
- active(true), loadingFromSource(false), asynchronous(false)
+ active(true), loadingFromSource(false), asynchronous(false), status(computeStatus())
{
}
@@ -379,7 +379,7 @@ void QQuickLoader::setActive(bool newVal)
d->object = nullptr;
emit itemChanged();
}
- emit statusChanged();
+ d->updateStatus();
}
emit activeChanged();
}
@@ -432,7 +432,7 @@ void QQuickLoader::loadFromSource()
Q_D(QQuickLoader);
if (d->source.isEmpty()) {
emit sourceChanged();
- emit statusChanged();
+ d->updateStatus();
emit progressChanged();
emit itemChanged();
return;
@@ -503,7 +503,7 @@ void QQuickLoader::loadFromSourceComponent()
Q_D(QQuickLoader);
if (!d->component) {
emit sourceComponentChanged();
- emit statusChanged();
+ d->updateStatus();
emit progressChanged();
emit itemChanged();
return;
@@ -619,7 +619,7 @@ void QQuickLoaderPrivate::load()
q, SLOT(_q_sourceLoaded()));
QObject::connect(component, SIGNAL(progressChanged(qreal)),
q, SIGNAL(progressChanged()));
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
if (loadingFromSource)
emit q->sourceChanged();
@@ -707,7 +707,7 @@ void QQuickLoaderPrivate::incubatorStateChanged(QQmlIncubator::Status status)
emit q->sourceChanged();
else
emit q->sourceComponentChanged();
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
if (status == QQmlIncubator::Ready)
emit q->loaded();
@@ -724,7 +724,7 @@ void QQuickLoaderPrivate::_q_sourceLoaded()
emit q->sourceChanged();
else
emit q->sourceComponentChanged();
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
emit q->itemChanged(); //Like clearing source, emit itemChanged even if previous item was also null
disposeInitialPropertyValues(); // cleanup
@@ -742,7 +742,7 @@ void QQuickLoaderPrivate::_q_sourceLoaded()
component->create(*incubator, itemContext);
if (incubator && incubator->status() == QQmlIncubator::Loading)
- emit q->statusChanged();
+ updateStatus();
}
/*!
@@ -789,37 +789,7 @@ QQuickLoader::Status QQuickLoader::status() const
{
Q_D(const QQuickLoader);
- if (!d->active)
- return Null;
-
- if (d->component) {
- switch (d->component->status()) {
- case QQmlComponent::Loading:
- return Loading;
- case QQmlComponent::Error:
- return Error;
- case QQmlComponent::Null:
- return Null;
- default:
- break;
- }
- }
-
- if (d->incubator) {
- switch (d->incubator->status()) {
- case QQmlIncubator::Loading:
- return Loading;
- case QQmlIncubator::Error:
- return Error;
- default:
- break;
- }
- }
-
- if (d->object)
- return Ready;
-
- return d->source.isEmpty() ? Null : Error;
+ return static_cast<Status>(d->status);
}
void QQuickLoader::componentComplete()
@@ -1020,6 +990,51 @@ QV4::ReturnedValue QQuickLoaderPrivate::extractInitialPropertyValues(QQmlV4Funct
return valuemap->asReturnedValue();
}
+QQuickLoader::Status QQuickLoaderPrivate::computeStatus() const
+{
+ if (!active)
+ return QQuickLoader::Status::Null;
+
+ if (component) {
+ switch (component->status()) {
+ case QQmlComponent::Loading:
+ return QQuickLoader::Status::Loading;
+ case QQmlComponent::Error:
+ return QQuickLoader::Status::Error;
+ case QQmlComponent::Null:
+ return QQuickLoader::Status::Null;
+ default:
+ break;
+ }
+ }
+
+ if (incubator) {
+ switch (incubator->status()) {
+ case QQmlIncubator::Loading:
+ return QQuickLoader::Status::Loading;
+ case QQmlIncubator::Error:
+ return QQuickLoader::Status::Error;
+ default:
+ break;
+ }
+ }
+
+ if (object)
+ return QQuickLoader::Status::Ready;
+
+ return source.isEmpty() ? QQuickLoader::Status::Null : QQuickLoader::Status::Error;
+}
+
+void QQuickLoaderPrivate::updateStatus()
+{
+ Q_Q(QQuickLoader);
+ auto newStatus = computeStatus();
+ if (status != newStatus) {
+ status = newStatus;
+ emit q->statusChanged();
+ }
+}
+
#include <moc_qquickloader_p.cpp>
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index 349b5c6c06..39d50280c5 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -96,6 +96,8 @@ public:
void disposeInitialPropertyValues();
static QUrl resolveSourceUrl(QQmlV4Function *args);
QV4::ReturnedValue extractInitialPropertyValues(QQmlV4Function *args, QObject *loader, bool *error);
+ QQuickLoader::Status computeStatus() const;
+ void updateStatus();
qreal getImplicitWidth() const override;
qreal getImplicitHeight() const override;
@@ -112,6 +114,11 @@ public:
bool active : 1;
bool loadingFromSource : 1;
bool asynchronous : 1;
+ // We need to use char instead of QQuickLoader::Status
+ // as otherwise the size of the class would increase
+ // on 32-bit systems, as sizeof(Status) == sizeof(int)
+ // and sizeof(int) > remaining padding on 32 bit
+ char status;
void _q_sourceLoaded();
void _q_updateSize(bool loaderGeometryChanged = true);
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 9a371207ce..3a807d3c66 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -88,20 +88,18 @@ void QQuickTouchPoint::setPointId(int id)
These properties hold the current position of the touch point.
*/
-void QQuickTouchPoint::setX(qreal x)
+void QQuickTouchPoint::setPosition(QPointF p)
{
- if (_x == x)
+ bool xch = (_x != p.x());
+ bool ych = (_y != p.y());
+ if (!xch && !ych)
return;
- _x = x;
- emit xChanged();
-}
-
-void QQuickTouchPoint::setY(qreal y)
-{
- if (_y == y)
- return;
- _y = y;
- emit yChanged();
+ _x = p.x();
+ _y = p.y();
+ if (xch)
+ emit xChanged();
+ if (ych)
+ emit yChanged();
}
/*!
@@ -798,8 +796,7 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QT
//TODO: if !qmlDefined, could bypass setters.
// also, should only emit signals after all values have been set
dtp->setUniqueId(p->uniqueId());
- dtp->setX(p->pos().x());
- dtp->setY(p->pos().y());
+ dtp->setPosition(p->pos());
dtp->setEllipseDiameters(p->ellipseDiameters());
dtp->setPressure(p->pressure());
dtp->setRotation(p->rotation());
@@ -817,8 +814,7 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QM
{
dtp->setPreviousX(dtp->x());
dtp->setPreviousY(dtp->y());
- dtp->setX(e->localPos().x());
- dtp->setY(e->localPos().y());
+ dtp->setPosition(e->localPos());
if (e->type() == QEvent::MouseButtonPress) {
dtp->setStartX(e->localPos().x());
dtp->setStartY(e->localPos().y());
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index 363e62593b..e34a3faad6 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -97,10 +97,8 @@ public:
void setUniqueId(const QPointingDeviceUniqueId &id);
qreal x() const { return _x; }
- void setX(qreal x);
-
qreal y() const { return _y; }
- void setY(qreal y);
+ void setPosition(QPointF pos);
QSizeF ellipseDiameters() const { return _ellipseDiameters; }
void setEllipseDiameters(const QSizeF &d);
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index f9f3e5cfa3..b298ed74da 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -161,10 +161,6 @@ public:
\l sourceItem while still handling input. For this, you can use
the \l hideSource property.
- \note If \l sourceItem is a \l Rectangle with border, by default half the
- border width falls outside the texture. To get the whole border, you can
- extend the \l sourceRect.
-
\note The ShaderEffectSource relies on FBO multisampling support
to antialias edges. If the underlying hardware does not support this,
which is the case for most embedded graphics chips, edges rendered
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index d76055c831..5ad33389de 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -330,6 +330,18 @@ inline int spriteCount(QQmlListProperty<QQuickSprite> *p)
return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->count();
}
+inline void spriteReplace(QQmlListProperty<QQuickSprite> *p, int idx, QQuickSprite *s)
+{
+ reinterpret_cast<QList<QQuickSprite *> *>(p->data)->replace(idx, s);
+ p->object->metaObject()->invokeMethod(p->object, "createEngine");
+}
+
+inline void spriteRemoveLast(QQmlListProperty<QQuickSprite> *p)
+{
+ reinterpret_cast<QList<QQuickSprite *> *>(p->data)->removeLast();
+ p->object->metaObject()->invokeMethod(p->object, "createEngine");
+}
+
QT_END_NAMESPACE
#endif // QQUICKSPRITEENGINE_P_H
diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp
index eb4b5335e7..c29938a1bb 100644
--- a/src/quick/items/qquickspritesequence.cpp
+++ b/src/quick/items/qquickspritesequence.cpp
@@ -162,7 +162,9 @@ void QQuickSpriteSequence::setInterpolate(bool arg)
QQmlListProperty<QQuickSprite> QQuickSpriteSequence::sprites()
{
Q_D(QQuickSpriteSequence);
- return QQmlListProperty<QQuickSprite>(this, &d->m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
+ return QQmlListProperty<QQuickSprite>(this, &d->m_sprites,
+ spriteAppend, spriteCount, spriteAt,
+ spriteClear, spriteReplace, spriteRemoveLast);
}
bool QQuickSpriteSequence::running() const
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 496aea73d1..56c5bedd4d 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -2352,14 +2352,11 @@ void QQuickTableViewPrivate::connectToModel()
QObjectPrivate::connect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
QObjectPrivate::connect(model, &QQmlInstanceModel::initItem, this, &QQuickTableViewPrivate::initItemCallback);
+ QObjectPrivate::connect(model, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
+ QObjectPrivate::connect(model, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- if (tableModel) {
- const auto tm = tableModel.data();
- QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
- QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- // Connect atYEndChanged to a function that fetches data if more is available
- QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
- }
+ // Connect atYEndChanged to a function that fetches data if more is available
+ QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
if (auto const aim = model->abstractItemModel()) {
// When the model exposes a QAIM, we connect to it directly. This means that if the current model is
@@ -2387,13 +2384,10 @@ void QQuickTableViewPrivate::disconnectFromModel()
QObjectPrivate::disconnect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
QObjectPrivate::disconnect(model, &QQmlInstanceModel::initItem, this, &QQuickTableViewPrivate::initItemCallback);
+ QObjectPrivate::disconnect(model, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
+ QObjectPrivate::disconnect(model, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- if (tableModel) {
- const auto tm = tableModel.data();
- QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
- QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
- }
+ QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
if (auto const aim = model->abstractItemModel()) {
disconnect(aim, &QAbstractItemModel::rowsMoved, this, &QQuickTableViewPrivate::rowsMovedCallback);
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index 03fe019916..a3cc39419f 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -91,7 +91,7 @@ private:
Q_DECLARE_PRIVATE(QQuickTableSectionSizeProvider)
};
-class Q_QML_AUTOTEST_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate
{
Q_DECLARE_PUBLIC(QQuickTableView)
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index f89e7d970f..816b48b190 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -40,6 +40,9 @@
#include "qquicktext_p.h"
#include "qquicktext_p_p.h"
+#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qqmldebugconnector_p.h>
+
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qsgadaptationlayer_p.h>
@@ -1146,6 +1149,10 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
elideLayout->setFont(layout.font());
elideLayout->setTextOption(layout.textOption());
+ if (QQmlDebugTranslationService *service
+ = QQmlDebugConnector::service<QQmlDebugTranslationService>()) {
+ elideText = service->foundElidedText(q, layoutText, elideText);
+ }
elideLayout->setText(elideText);
elideLayout->beginLayout();
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 491334f439..5832242961 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -93,6 +93,7 @@ Q_LOGGING_CATEGORY(DBG_TOUCH, "qt.quick.touch")
Q_LOGGING_CATEGORY(DBG_TOUCH_TARGET, "qt.quick.touch.target")
Q_LOGGING_CATEGORY(DBG_MOUSE, "qt.quick.mouse")
Q_LOGGING_CATEGORY(DBG_MOUSE_TARGET, "qt.quick.mouse.target")
+Q_LOGGING_CATEGORY(lcTablet, "qt.quick.tablet")
Q_LOGGING_CATEGORY(lcWheelTarget, "qt.quick.wheel.target")
Q_LOGGING_CATEGORY(lcGestureTarget, "qt.quick.gesture.target")
Q_LOGGING_CATEGORY(DBG_HOVER_TRACE, "qt.quick.hover.trace")
@@ -547,7 +548,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
else
context->endNextFrame(renderer);
- if (renderer->hasCustomRenderModeWithContinuousUpdate()) {
+ if (renderer && renderer->hasCustomRenderModeWithContinuousUpdate()) {
// For the overdraw visualizer. This update is not urgent so avoid a
// direct update() call, this is only here to keep the overdraw
// visualization box rotating even when the scene is static.
@@ -682,10 +683,13 @@ void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state)
QQmlListProperty<QObject> QQuickWindowPrivate::data()
{
- return QQmlListProperty<QObject>(q_func(), nullptr, QQuickWindowPrivate::data_append,
- QQuickWindowPrivate::data_count,
- QQuickWindowPrivate::data_at,
- QQuickWindowPrivate::data_clear);
+ return QQmlListProperty<QObject>(q_func(), nullptr,
+ QQuickWindowPrivate::data_append,
+ QQuickWindowPrivate::data_count,
+ QQuickWindowPrivate::data_at,
+ QQuickWindowPrivate::data_clear,
+ QQuickWindowPrivate::data_replace,
+ QQuickWindowPrivate::data_removeLast);
}
static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true)
@@ -2119,6 +2123,17 @@ void QQuickWindow::wheelEvent(QWheelEvent *event)
}
#endif // wheelevent
+#if QT_CONFIG(tabletevent)
+/*! \reimp */
+void QQuickWindow::tabletEvent(QTabletEvent *event)
+{
+ Q_D(QQuickWindow);
+ qCDebug(lcTablet) << event;
+ // TODO Qt 6: make sure TabletEnterProximity and TabletLeaveProximity are delivered here
+ d->deliverPointerEvent(d->pointerEventInstance(event));
+}
+#endif // tabletevent
+
bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
{
qCDebug(DBG_TOUCH) << event;
@@ -2397,8 +2412,12 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevic
#endif
ev = new QQuickPointerTouchEvent(q, device);
break;
+ case QQuickPointerDevice::Stylus:
+ case QQuickPointerDevice::Airbrush:
+ case QQuickPointerDevice::Puck:
+ ev = new QQuickPointerTabletEvent(q, device);
+ break;
default:
- // TODO tablet event types
break;
}
pointerEventInstances << ev;
@@ -2429,7 +2448,15 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) con
case QEvent::TouchCancel:
dev = QQuickPointerDevice::touchDevice(static_cast<QTouchEvent *>(event)->device());
break;
- // TODO tablet event types
+#if QT_CONFIG(tabletevent)
+ case QEvent::TabletPress:
+ case QEvent::TabletMove:
+ case QEvent::TabletRelease:
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ dev = QQuickPointerDevice::tabletDevice(static_cast<QTabletEvent *>(event));
+ break;
+#endif
#if QT_CONFIG(gestures)
case QEvent::NativeGesture:
dev = QQuickPointerDevice::touchDevice(static_cast<QNativeGestureEvent *>(event)->device());
@@ -2464,6 +2491,11 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
deliverTouchEvent(event->asPointerTouchEvent());
} else {
deliverSinglePointEventUntilAccepted(event);
+ // If any handler got interested in the tablet event, we don't want to receive a synth-mouse event from QtGui
+ // TODO Qt 6: QTabletEvent will be accepted by default, like other events
+ if (event->asPointerTabletEvent() &&
+ (!event->point(0)->passiveGrabbers().isEmpty() || event->point(0)->exclusiveGrabber()))
+ event->setAccepted(true);
}
event->reset(nullptr);
@@ -3257,6 +3289,20 @@ void QQuickWindowPrivate::data_clear(QQmlListProperty<QObject> *property)
itemProperty.clear(&itemProperty);
}
+void QQuickWindowPrivate::data_replace(QQmlListProperty<QObject> *property, int i, QObject *o)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ itemProperty.replace(&itemProperty, i, o);
+}
+
+void QQuickWindowPrivate::data_removeLast(QQmlListProperty<QObject> *property)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ itemProperty.removeLast(&itemProperty);
+}
+
bool QQuickWindowPrivate::isRenderable() const
{
Q_Q(const QQuickWindow);
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index d22bba4512..097627374c 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -252,6 +252,9 @@ protected:
#if QT_CONFIG(wheelevent)
void wheelEvent(QWheelEvent *) override;
#endif
+#if QT_CONFIG(tabletevent)
+ void tabletEvent(QTabletEvent *) override;
+#endif
private Q_SLOTS:
void maybeUpdate();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 6e6dc7a400..86bdaf6396 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -299,6 +299,8 @@ public:
static int data_count(QQmlListProperty<QObject> *);
static QObject *data_at(QQmlListProperty<QObject> *, int);
static void data_clear(QQmlListProperty<QObject> *);
+ static void data_replace(QQmlListProperty<QObject> *, int, QObject *);
+ static void data_removeLast(QQmlListProperty<QObject> *);
static void contextCreationFailureMessage(const QSurfaceFormat &format,
QString *translatedMessage,
diff --git a/src/quick/qtquickglobal_p.h b/src/quick/qtquickglobal_p.h
index f6376a6d17..80e59563c7 100644
--- a/src/quick/qtquickglobal_p.h
+++ b/src/quick/qtquickglobal_p.h
@@ -61,6 +61,8 @@
#define Q_QUICK_PRIVATE_EXPORT Q_QUICK_EXPORT
+void Q_QUICK_PRIVATE_EXPORT qml_register_types_QtQuick();
+
QT_BEGIN_NAMESPACE
void QQuick_initializeProviders();
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index 6db2ae884e..9ddd67c33d 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -23,13 +23,10 @@ exists("qqml_enable_gcov") {
QMAKE_DOCS = $$PWD/doc/qtquick.qdocconf
-ANDROID_LIB_DEPENDENCIES = \
- lib/libQt5QuickParticles.so
MODULE_PLUGIN_TYPES += \
scenegraph
ANDROID_BUNDLED_FILES += \
- qml \
- lib/libQt5QuickParticles.so
+ qml
include(util/util.pri)
include(scenegraph/scenegraph.pri)
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 4777f46f0a..9b288029b4 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -660,6 +660,11 @@ void QSGRenderThread::sync(bool inExpose, bool inGrab)
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window has bad size, sync aborted");
}
+ // Two special cases: For grabs we do not care about blocking the gui
+ // (main) thread. When this is from an expose, we will keep locked until
+ // the frame is rendered (submitted), so in that case waking happens later
+ // in syncAndRender(). Otherwise, wake now and let the main thread go on
+ // while we render.
if (!inExpose && !inGrab) {
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- sync complete, waking Gui");
waitCondition.wakeOne();
@@ -756,13 +761,11 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
QCoreApplication::postEvent(window, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest)));
// Before returning we need to ensure the same wake up logic that
// would have happened if beginFrame() had suceeded.
- if (exposeRequested) {
+ if (syncRequested && !grabRequested) {
+ // Lock like sync() would do. Note that exposeRequested always includes syncRequested.
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- bailing out due to failed beginFrame, wake Gui");
- waitCondition.wakeOne();
- mutex.unlock();
- } else if (syncRequested && !grabRequested) {
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- bailing out due to failed beginFrame, wake Gui like sync would do");
mutex.lock();
+ // Go ahead with waking because we will return right after this.
waitCondition.wakeOne();
mutex.unlock();
}
@@ -885,7 +888,8 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
// has started rendering with a bad window, causing makeCurrent to
// fail or if the window has a bad size.
if (exposeRequested) {
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after initial expose");
+ // With expose sync() did not wake gui, do it now.
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after expose");
waitCondition.wakeOne();
mutex.unlock();
}
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 2ae9debbc9..8846edcd44 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -427,11 +427,12 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e
imgio.setScaledSize(scSize);
if (!requestRegion.isNull())
imgio.setScaledClipRect(requestRegion);
+ const QSize originalSize = imgio.size();
qCDebug(lcImg) << url << "frame" << frame << "of" << imgio.imageCount()
- << "requestRegion" << requestRegion << "QImageReader size" << imgio.size() << "-> scSize" << scSize;
+ << "requestRegion" << requestRegion << "QImageReader size" << originalSize << "-> scSize" << scSize;
if (impsize)
- *impsize = imgio.size();
+ *impsize = originalSize;
if (imgio.read(image)) {
maybeRemoveAlpha(image);
@@ -1025,8 +1026,11 @@ public:
inline bool operator==(const QQuickPixmapKey &lhs, const QQuickPixmapKey &rhs)
{
- return *lhs.region == *rhs.region && *lhs.size == *rhs.size && *lhs.url == *rhs.url &&
- lhs.options == rhs.options && lhs.frame == rhs.frame;
+ return *lhs.url == *rhs.url &&
+ *lhs.region == *rhs.region &&
+ *lhs.size == *rhs.size &&
+ lhs.frame == rhs.frame &&
+ lhs.options == rhs.options;
}
inline uint qHash(const QQuickPixmapKey &key)
diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp
index c106528f45..71ab1f4d62 100644
--- a/src/quick/util/qquickstate.cpp
+++ b/src/quick/util/qquickstate.cpp
@@ -267,9 +267,13 @@ void QQuickState::setExtends(const QString &extends)
QQmlListProperty<QQuickStateOperation> QQuickState::changes()
{
Q_D(QQuickState);
- return QQmlListProperty<QQuickStateOperation>(this, &d->operations, QQuickStatePrivate::operations_append,
- QQuickStatePrivate::operations_count, QQuickStatePrivate::operations_at,
- QQuickStatePrivate::operations_clear);
+ return QQmlListProperty<QQuickStateOperation>(this, &d->operations,
+ QQuickStatePrivate::operations_append,
+ QQuickStatePrivate::operations_count,
+ QQuickStatePrivate::operations_at,
+ QQuickStatePrivate::operations_clear,
+ QQuickStatePrivate::operations_replace,
+ QQuickStatePrivate::operations_removeLast);
}
int QQuickState::operationCount() const
diff --git a/src/quick/util/qquickstate_p_p.h b/src/quick/util/qquickstate_p_p.h
index 2fa5321165..ae4ed291b5 100644
--- a/src/quick/util/qquickstate_p_p.h
+++ b/src/quick/util/qquickstate_p_p.h
@@ -244,6 +244,23 @@ public:
QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
return list->at(index);
}
+ static void operations_replace(QQmlListProperty<QQuickStateOperation> *prop, int index,
+ QQuickStateOperation *op) {
+ QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
+ auto &guard = list->at(index);
+ if (guard.object() == op) {
+ op->setState(qobject_cast<QQuickState*>(prop->object));
+ } else {
+ list->at(index)->setState(nullptr);
+ op->setState(qobject_cast<QQuickState*>(prop->object));
+ list->replace(index, OperationGuard(op, list));
+ }
+ }
+ static void operations_removeLast(QQmlListProperty<QQuickStateOperation> *prop) {
+ QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
+ list->last()->setState(nullptr);
+ list->removeLast();
+ }
QQuickTransitionManager transitionManager;
diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp
index 46e7d62fc1..2109aafc10 100644
--- a/src/quick/util/qquickstategroup.cpp
+++ b/src/quick/util/qquickstategroup.cpp
@@ -70,6 +70,8 @@ public:
static int count_state(QQmlListProperty<QQuickState> *list);
static QQuickState *at_state(QQmlListProperty<QQuickState> *list, int index);
static void clear_states(QQmlListProperty<QQuickState> *list);
+ static void replace_states(QQmlListProperty<QQuickState> *list, int index, QQuickState *state);
+ static void removeLast_states(QQmlListProperty<QQuickState> *list);
static void append_transition(QQmlListProperty<QQuickTransition> *list, QQuickTransition *state);
static int count_transitions(QQmlListProperty<QQuickTransition> *list);
@@ -163,10 +165,13 @@ QList<QQuickState *> QQuickStateGroup::states() const
QQmlListProperty<QQuickState> QQuickStateGroup::statesProperty()
{
Q_D(QQuickStateGroup);
- return QQmlListProperty<QQuickState>(this, &d->states, &QQuickStateGroupPrivate::append_state,
- &QQuickStateGroupPrivate::count_state,
- &QQuickStateGroupPrivate::at_state,
- &QQuickStateGroupPrivate::clear_states);
+ return QQmlListProperty<QQuickState>(this, &d->states,
+ &QQuickStateGroupPrivate::append_state,
+ &QQuickStateGroupPrivate::count_state,
+ &QQuickStateGroupPrivate::at_state,
+ &QQuickStateGroupPrivate::clear_states,
+ &QQuickStateGroupPrivate::replace_states,
+ &QQuickStateGroupPrivate::removeLast_states);
}
void QQuickStateGroupPrivate::append_state(QQmlListProperty<QQuickState> *list, QQuickState *state)
@@ -201,6 +206,29 @@ void QQuickStateGroupPrivate::clear_states(QQmlListProperty<QQuickState> *list)
_this->d_func()->states.clear();
}
+void QQuickStateGroupPrivate::replace_states(QQmlListProperty<QQuickState> *list, int index, QQuickState *state)
+{
+ auto *self = qobject_cast<QQuickStateGroup *>(list->object);
+ auto *d = self->d_func();
+ auto *oldState = d->states.at(index);
+ if (oldState != state) {
+ oldState->setStateGroup(nullptr);
+ state->setStateGroup(self);
+ d->states.replace(index, state);
+ if (d->currentState == oldState->name())
+ d->setCurrentStateInternal(state->name(), true);
+ }
+}
+
+void QQuickStateGroupPrivate::removeLast_states(QQmlListProperty<QQuickState> *list)
+{
+ auto *d = qobject_cast<QQuickStateGroup *>(list->object)->d_func();
+ if (d->currentState == d->states.last()->name())
+ d->setCurrentStateInternal(d->states.length() > 1 ? d->states.first()->name() : QString(), true);
+ d->states.last()->setStateGroup(nullptr);
+ d->states.removeLast();
+}
+
/*!
\qmlproperty list<Transition> QtQuick::StateGroup::transitions
This property holds a list of transitions defined by the state group.
diff --git a/src/quick/util/qquicktimeline_p_p.h b/src/quick/util/qquicktimeline_p_p.h
index abb5369b7b..fc5bd15ed1 100644
--- a/src/quick/util/qquicktimeline_p_p.h
+++ b/src/quick/util/qquicktimeline_p_p.h
@@ -52,6 +52,7 @@
//
#include <QtCore/QObject>
+#include <private/qtquickglobal_p.h>
#include "private/qabstractanimationjob_p.h"
QT_BEGIN_NAMESPACE
@@ -61,7 +62,7 @@ class QQuickTimeLineValue;
class QQuickTimeLineCallback;
struct QQuickTimeLinePrivate;
class QQuickTimeLineObject;
-class Q_AUTOTEST_EXPORT QQuickTimeLine : public QObject, QAbstractAnimationJob
+class Q_QUICK_PRIVATE_EXPORT QQuickTimeLine : public QObject, QAbstractAnimationJob
{
Q_OBJECT
public:
diff --git a/src/quickshapes/qquickshapesglobal_p.h b/src/quickshapes/qquickshapesglobal_p.h
index 2f559b45a0..40f6cfbdcf 100644
--- a/src/quickshapes/qquickshapesglobal_p.h
+++ b/src/quickshapes/qquickshapesglobal_p.h
@@ -59,5 +59,6 @@ QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
+void Q_QUICKSHAPES_PRIVATE_EXPORT qml_register_types_QtQuick_Shapes();
#endif // QQUICKSHAPESGLOBAL_P_H
diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro
index 5c328fbfcc..890e722aa3 100644
--- a/tests/auto/qml/debugger/debugger.pro
+++ b/tests/auto/qml/debugger/debugger.pro
@@ -4,6 +4,7 @@ SUBDIRS += qqmldebugjsserver
PUBLICTESTS += \
qdebugmessageservice \
+ qqmldebugtranslationservice \
qqmlenginedebugservice \
qqmldebugjs \
qqmlinspector \
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml b/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml
index deba24cf91..a7231df48b 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml
@@ -36,5 +36,9 @@ Item {
}
id: root
property int a: 10
+
+ Item {
+ property int b: 11
+ }
}
diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
index 3f424d16f2..91470e0651 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
+++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -896,6 +896,16 @@ void tst_QQmlDebugJS::evaluateInContext()
QVERIFY(waitForClientSignal(SIGNAL(result())));
QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 20);
+
+ auto childObjects = object.children;
+ QVERIFY(childObjects.count() > 0); // QQmlComponentAttached is also in there
+ QCOMPARE(childObjects[0].className, QString::fromLatin1("Item"));
+
+ // "b" accessible in context of surrounding (child) object
+ m_client->evaluate(QLatin1String("b"), -1, childObjects[0].debugId);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+
+ QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 11);
}
void tst_QQmlDebugJS::getScripts()
diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml
new file mode 100644
index 0000000000..234496577a
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Controls 2.12
+
+Item {
+ width: 360
+ height: 360
+
+ Text {
+ text: qsTr("hello")
+ width: parent.width / 10
+ elide: Text.ElideRight
+ }
+}
diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro b/tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro
new file mode 100644
index 0000000000..32e60e306d
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qdebugtranslationservice
+QT += network testlib gui-private core-private qmldebug-private
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qqmldebugtranslationservice.cpp
+
+include(../shared/debugutil.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += data/test.qml
diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp b/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp
new file mode 100644
index 0000000000..01ee805dee
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//QQmlDebugTest
+#include <debugutil_p.h>
+#include <qqmldebugprocess_p.h>
+
+#include <private/qqmldebugclient_p.h>
+#include <private/qqmldebugtranslationclient_p.h>
+#include <private/qqmldebugconnection_p.h>
+#include <private/qpacket_p.h>
+
+#include <QtCore/qstring.h>
+#include <QtCore/qlibraryinfo.h>
+#include <QtTest/qtest.h>
+
+const char *QMLFILE = "test.qml";
+
+class tst_QQmlDebugTranslationService : public QQmlDebugTest
+{
+ Q_OBJECT
+
+private slots:
+ void pluginConnection();
+
+private:
+ QList<QQmlDebugClient *> createClients() override;
+ QPointer<QQmlDebugTranslationClient> m_client;
+};
+
+QList<QQmlDebugClient *> tst_QQmlDebugTranslationService::createClients()
+{
+ m_client = new QQmlDebugTranslationClient(m_connection);
+
+ QObject::connect(m_client, &QQmlDebugClient::stateChanged, m_client, [this](QQmlDebugClient::State newState) {
+ QCOMPARE(newState, m_client->state());
+ });
+
+ return {m_client};
+}
+
+void tst_QQmlDebugTranslationService::pluginConnection()
+{
+ auto executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml";
+ auto services = "DebugTranslation";
+ auto extraArgs = testFile(QMLFILE);
+ auto block = true;
+
+ auto result = QQmlDebugTest::connectTo(executable, services, extraArgs, block);
+ QCOMPARE(result, ConnectSuccess);
+}
+
+QTEST_MAIN(tst_QQmlDebugTranslationService)
+
+#include "tst_qqmldebugtranslationservice.moc"
diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
index d6e85f973f..b561e5f398 100644
--- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
+++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
@@ -1128,6 +1128,10 @@ void tst_QJSValue::toVariant()
// array
{
+ auto handler = qInstallMessageHandler([](QtMsgType type, const QMessageLogContext &, const QString &) {
+ if (type == QtMsgType::QtWarningMsg)
+ QFAIL("Converting QJSValue to QVariant should not cause error messages");
+ });
QVariantList listIn;
listIn << 123 << "hello";
QJSValue array = eng.toScriptValue(listIn);
@@ -1145,8 +1149,9 @@ void tst_QJSValue::toVariant()
QCOMPARE(array2.property("length").toInt(), array.property("length").toInt());
for (int i = 0; i < array.property("length").toInt(); ++i)
QVERIFY(array2.property(i).strictlyEquals(array.property(i)));
- }
+ qInstallMessageHandler(handler);
+ }
}
void tst_QJSValue::toQObject_nonQObject_data()
diff --git a/tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml b/tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml
new file mode 100644
index 0000000000..a05c2125dc
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![2]
+import QtQuick 2.0
+//![2]
+import QtCharts 2.0
+
+@Pippo {
+ atg1: 3
+}
+@Annotation2 {
+}
+Item {
+ //![1]
+
+ @AnnotateMore {
+ property int x: 5
+ }
+ @AnnotateALot {
+ }
+
+ property variant othersSlice: 0
+ @Annotate {
+ }
+
+ anchors.fill: parent
+ @SuperComplete {
+ binding: late
+ }
+ Component.onCompleted: {
+ // You can also manipulate slices dynamically, like append a slice or set a slice exploded
+ othersSlice = pieSeries.append("Others", 52);
+ pieSeries.find("Volkswagen").exploded = true;
+ }
+ //![1]
+ ChartView {
+ id: chart
+
+ title: "Top-5 car brand shares in Finland"
+ anchors.fill: parent
+ legend.alignment: Qt.AlignBottom
+ antialiasing: true
+
+ @ExtraAnnotation {
+ signal pippo()
+ }
+ PieSeries {
+ id: pieSeries
+
+ PieSlice {
+ label: "Volkswagen"
+ value: 13.5
+ }
+
+ PieSlice {
+ label: "Toyota"
+ value: 10.9
+ }
+
+ PieSlice {
+ label: "Ford"
+ value: 8.6
+ }
+
+ PieSlice {
+ label: "Skoda"
+ value: 8.2
+ }
+
+ PieSlice {
+ label: "Volvo"
+ value: 6.8
+ }
+
+ }
+
+ }
+
+}
diff --git a/tests/auto/qml/qmlformat/data/Annotations.formatted.qml b/tests/auto/qml/qmlformat/data/Annotations.formatted.qml
new file mode 100644
index 0000000000..a142d4cb74
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/Annotations.formatted.qml
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![2]
+import QtCharts 2.0
+//![2]
+import QtQuick 2.0
+
+@Pippo {
+ atg1: 3
+}
+@Annotation2 {
+}
+Item {
+ //![1]
+
+ @AnnotateMore {
+ property int x: 5
+ }
+ @AnnotateALot {
+ }
+
+ property variant othersSlice: 0
+ @Annotate {
+ }
+
+ anchors.fill: parent
+ @SuperComplete {
+ binding: late
+ }
+ Component.onCompleted: {
+ // You can also manipulate slices dynamically, like append a slice or set a slice exploded
+ othersSlice = pieSeries.append("Others", 52);
+ pieSeries.find("Volkswagen").exploded = true;
+ }
+ //![1]
+ ChartView {
+ id: chart
+
+ title: "Top-5 car brand shares in Finland"
+ anchors.fill: parent
+ legend.alignment: Qt.AlignBottom
+ antialiasing: true
+
+ @ExtraAnnotation {
+ signal pippo()
+ }
+ PieSeries {
+ id: pieSeries
+
+ PieSlice {
+ label: "Volkswagen"
+ value: 13.5
+ }
+
+ PieSlice {
+ label: "Toyota"
+ value: 10.9
+ }
+
+ PieSlice {
+ label: "Ford"
+ value: 8.6
+ }
+
+ PieSlice {
+ label: "Skoda"
+ value: 8.2
+ }
+
+ PieSlice {
+ label: "Volvo"
+ value: 6.8
+ }
+
+ }
+
+ }
+
+}
diff --git a/tests/auto/qml/qmlformat/data/Annotations.qml b/tests/auto/qml/qmlformat/data/Annotations.qml
new file mode 100644
index 0000000000..2d3d7d2cfd
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/Annotations.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![2]
+import QtQuick 2.0
+//![2]
+import QtCharts 2.0
+
+@Pippo{ atg1:3 }
+@Annotation2{}
+Item {
+ @Annotate{}
+ anchors.fill: parent
+ @AnnotateMore{
+ property int x: 5
+ }
+ @AnnotateALot{}
+ property variant othersSlice: 0
+
+ //![1]
+ ChartView {
+ id: chart
+ title: "Top-5 car brand shares in Finland"
+ anchors.fill: parent
+ legend.alignment: Qt.AlignBottom
+ antialiasing: true
+
+@ExtraAnnotation{
+ signal pippo
+}
+ PieSeries {
+ id: pieSeries
+ PieSlice { label: "Volkswagen"; value: 13.5 }
+ PieSlice { label: "Toyota"; value: 10.9 }
+ PieSlice { label: "Ford"; value: 8.6 }
+ PieSlice { label: "Skoda"; value: 8.2 }
+ PieSlice { label: "Volvo"; value: 6.8 }
+ }
+ }
+
+@SuperComplete{
+binding: late
+}
+ Component.onCompleted: {
+ // You can also manipulate slices dynamically, like append a slice or set a slice exploded
+ othersSlice = pieSeries.append("Others", 52.0);
+ pieSeries.find("Volkswagen").exploded = true;
+ }
+ //![1]
+}
diff --git a/tests/auto/qml/qmlformat/tst_qmlformat.cpp b/tests/auto/qml/qmlformat/tst_qmlformat.cpp
index c7714304b8..21d5ae46a9 100644
--- a/tests/auto/qml/qmlformat/tst_qmlformat.cpp
+++ b/tests/auto/qml/qmlformat/tst_qmlformat.cpp
@@ -41,6 +41,8 @@ private Q_SLOTS:
void testFormat();
void testFormatNoSort();
+ void testAnnotations();
+ void testAnnotationsNoSort();
void testReadOnlyProps();
void testStatesAndTransitions();
@@ -185,6 +187,16 @@ void TestQmlformat::testFormatNoSort()
QCOMPARE(runQmlformat(testFile("Example1.qml"), false, true), readTestFile("Example1.formatted.nosort.qml"));
}
+void TestQmlformat::testAnnotations()
+{
+ QCOMPARE(runQmlformat(testFile("Annotations.qml"), true, true), readTestFile("Annotations.formatted.qml"));
+}
+
+void TestQmlformat::testAnnotationsNoSort()
+{
+ QCOMPARE(runQmlformat(testFile("Annotations.qml"), false, true), readTestFile("Annotations.formatted.nosort.qml"));
+}
+
void TestQmlformat::testReadOnlyProps()
{
QCOMPARE(runQmlformat(testFile("readOnlyProps.qml"), false, true), readTestFile("readOnlyProps.formatted.qml"));
diff --git a/tests/auto/qml/qqmlconnections/data/underscore.qml b/tests/auto/qml/qqmlconnections/data/underscore.qml
new file mode 100644
index 0000000000..0f73dc8f17
--- /dev/null
+++ b/tests/auto/qml/qqmlconnections/data/underscore.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.12
+
+Item {
+ id: item
+ property bool success: false
+ property bool sanityCheck: false
+ property int __underscore_property: 0
+ on__Underscore_propertyChanged: item.sanityCheck = true
+
+ Connections {
+ target: item
+ on__Underscore_propertyChanged: item.success = true
+ }
+}
diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
index 07af519a3d..f144002875 100644
--- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
+++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
@@ -77,6 +77,8 @@ private slots:
void noAcceleratedGlobalLookup_data() { prefixes(); }
void noAcceleratedGlobalLookup();
+ void bindToPropertyWithUnderscoreChangeHandler();
+
private:
QQmlEngine engine;
void prefixes();
@@ -474,6 +476,19 @@ void tst_qqmlconnections::noAcceleratedGlobalLookup()
QCOMPARE(val.toInt(), int(Proxy::EnumValue));
}
+void tst_qqmlconnections::bindToPropertyWithUnderscoreChangeHandler()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("underscore.qml"));
+ QScopedPointer<QObject> root {component.create()};
+ QVERIFY(root);
+ QQmlProperty underscoreProperty(root.get(), "__underscore_property");
+ QVERIFY(underscoreProperty.isValid());
+ underscoreProperty.write(42);
+ QVERIFY(root->property("sanityCheck").toBool());
+ QVERIFY(root->property("success").toBool());
+}
+
QTEST_MAIN(tst_qqmlconnections)
#include "tst_qqmlconnections.moc"
diff --git a/tests/auto/qml/qqmlecmascript/data/sequenceConversion.write.error.qml b/tests/auto/qml/qqmlecmascript/data/sequenceConversion.write.error.qml
index 75beafd1ee..c2c8c1b52b 100644
--- a/tests/auto/qml/qqmlecmascript/data/sequenceConversion.write.error.qml
+++ b/tests/auto/qml/qqmlecmascript/data/sequenceConversion.write.error.qml
@@ -12,7 +12,7 @@ Item {
function performTest() {
// we have NOT registered QList<QPoint> as a type
- var pointList = [ Qt.point(7,7), Qt.point(8,8), Qt.point(9,9) ];
+ var pointList = [ Qt.point(7,7), "hello world", Qt.point(8,8), Qt.point(9,9) ];
msco.pointListProperty = pointList; // error.
}
}
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index a05933d071..61dc393998 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -74,6 +74,7 @@ public:
private slots:
void initTestCase();
+ void arrayIncludesValueType();
void assignBasicTypes();
void assignDate_data();
void assignDate();
@@ -414,6 +415,36 @@ void tst_qqmlecmascript::initTestCase()
registerTypes();
}
+void tst_qqmlecmascript::arrayIncludesValueType()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ // It is vital that QtQuick is imported below else we get a warning about
+ // QQml_colorProvider and tst_qqmlecmascript::signalParameterTypes fails due
+ // to some static variable being initialized with the wrong value
+ component.setData(R"(
+ import QtQuick 2.15
+ import QtQml 2.15
+ QtObject {
+ id: root
+ property color r: Qt.rgba(1, 0, 0)
+ property color g: Qt.rgba(0, 1, 0)
+ property color b: Qt.rgba(0, 0, 1)
+ property var colors: [r, g, b]
+ property bool success: false
+
+ Component.onCompleted: {
+ root.success = root.colors.includes(root.g)
+ }
+ }
+ )", QUrl("testData"));
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(o);
+ auto success = o->property("success");
+ QVERIFY(success.isValid());
+ QVERIFY(success.toBool());
+}
+
void tst_qqmlecmascript::assignBasicTypes()
{
QQmlEngine engine;
@@ -5792,13 +5823,12 @@ void tst_qqmlecmascript::sequenceConversionWrite()
MySequenceConversionObject *seq = object->findChild<MySequenceConversionObject*>("msco");
QVERIFY(seq != nullptr);
- // we haven't registered QList<QPoint> as a sequence type, so writing shouldn't work.
- QString warningOne = qmlFile.toString() + QLatin1String(":16: Error: Cannot assign QJSValue to QVector<QPoint>");
- QTest::ignoreMessage(QtWarningMsg, warningOne.toLatin1().constData());
-
+ // Behavior change in 5.14: due to added auto-magical conversions, it is possible to assign to
+ // QList<QPoint>, even though it is not a registered sequence type
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression("Could not convert array value at position 1 from QString to QPoint"));
QMetaObject::invokeMethod(object, "performTest");
- QList<QPoint> pointList; pointList << QPoint(1, 2) << QPoint(3, 4) << QPoint(5, 6); // original values, shouldn't have changed
+ QList<QPoint> pointList; pointList << QPoint(7, 7) << QPoint(0,0) << QPoint(8, 8) << QPoint(9, 9); // original values, shouldn't have changed
QCOMPARE(seq->pointListProperty(), pointList);
delete object;
diff --git a/tests/auto/qml/qqmlenginecleanup/data/MyItem.qml b/tests/auto/qml/qqmlenginecleanup/data/MyItem.qml
new file mode 100644
index 0000000000..4bb8dfb486
--- /dev/null
+++ b/tests/auto/qml/qqmlenginecleanup/data/MyItem.qml
@@ -0,0 +1,2 @@
+import QtQuick 2.12
+Item {}
diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
index 0e70933ec6..26b2b839ea 100644
--- a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
+++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
@@ -45,6 +45,7 @@ private slots:
void test_qmlClearTypeRegistrations();
void test_valueTypeProviderModule(); // QTBUG-43004
void test_customModuleCleanup();
+ void test_qmlListCleared();
};
// A wrapper around QQmlComponent to ensure the temporary reference counts
@@ -187,6 +188,18 @@ void tst_qqmlenginecleanup::test_customModuleCleanup()
}
}
+void tst_qqmlenginecleanup::test_qmlListCleared()
+{
+ {
+ QQmlEngine engine;
+ auto url = testFileUrl("MyItem.qml");
+ QQmlComponent comp(&engine, url);
+ QScopedPointer<QObject> item {comp.create()};
+ QCOMPARE(QQmlMetaType::qmlRegisteredListTypeCount(), 1);
+ }
+ QCOMPARE(QQmlMetaType::qmlRegisteredListTypeCount(), 0);
+}
+
QTEST_MAIN(tst_qqmlenginecleanup)
#include "tst_qqmlenginecleanup.moc"
diff --git a/tests/auto/qml/qqmllanguage/data/SimpleItem.qml b/tests/auto/qml/qqmllanguage/data/SimpleItem.qml
new file mode 100644
index 0000000000..c7bce2bc78
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/SimpleItem.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+Item {
+ property int i: 42
+}
diff --git a/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml b/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml
new file mode 100644
index 0000000000..ee400eb41f
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml
@@ -0,0 +1,7 @@
+import QtQml 2.14
+import qt.test 1.0
+
+TestItem {
+ property var vector
+ positions: vector
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml
new file mode 100644
index 0000000000..ab125e9323
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.15
+
+Item {
+ id: root
+ component IC: SimpleItem {
+ width: i
+ Rectangle {
+ id: rect
+ color: "lime"
+ }
+ property alias color: rect.color
+ }
+ width: 200
+ IC {
+ objectName: "icInstance"
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml
new file mode 100644
index 0000000000..c4093bad2f
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.15
+
+Item {
+ id: root
+ component IC: SimpleItem {
+ id: root
+ width: root.i
+ property color color: "red"
+ }
+ width: 200
+ IC {
+ objectName: "icInstance"
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 39502372e6..148179cb9c 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -1440,17 +1440,22 @@ public:
int base() const { return 43; }
};
+class Local : public QObject
+{
+ Q_OBJECT
+};
+
class Foreign
{
Q_GADGET
- QML_FOREIGN(QObject)
+ QML_FOREIGN(Local)
QML_NAMED_ELEMENT(Foreign)
};
class ForeignExtended
{
Q_GADGET
- QML_FOREIGN(QObject)
+ QML_FOREIGN(Local)
QML_NAMED_ELEMENT(ForeignExtended)
QML_EXTENDED(Extension)
};
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 1e382d7ee2..d4760fa7e9 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -325,6 +325,9 @@ private slots:
void overrideSingleton();
void revisionedPropertyOfAttachedObjectProperty();
+ void arrayToContainer();
+ void qualifiedScopeInCustomParser();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -5627,6 +5630,9 @@ void tst_qqmllanguage::inlineComponent_data()
QTest::newRow("Non-toplevel IC is found") << testFileUrl("inlineComponentUser5.qml") << QColorConstants::Svg::red << 24;
QTest::newRow("Resolved in correct order") << testFileUrl("inlineComponentOrder.qml") << QColorConstants::Blue << 200;
+
+ QTest::newRow("ID resolves correctly") << testFileUrl("inlineComponentWithId.qml") << QColorConstants::Svg::red << 42;
+ QTest::newRow("Alias resolves correctly") << testFileUrl("inlineComponentWithAlias.qml") << QColorConstants::Svg::lime << 42;
}
void tst_qqmllanguage::inlineComponentReferenceCycle_data()
@@ -5717,6 +5723,60 @@ void tst_qqmllanguage::nonExistingInlineComponent()
QCOMPARE(error.column(), column);
}
+class TestItem : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY( QVector<QPointF> positions MEMBER m_points )
+
+public:
+ TestItem() = default;
+ QVector< QPointF > m_points;
+};
+
+
+Q_DECLARE_METATYPE(QVector<QPointF>);
+void tst_qqmllanguage::arrayToContainer()
+{
+ QQmlEngine engine;
+ qmlRegisterType<TestItem>("qt.test", 1, 0, "TestItem");
+ QVector<QPointF> points { QPointF (2.0, 3.0) };
+ engine.rootContext()->setContextProperty("test", QVariant::fromValue(points));
+ QQmlComponent component(&engine, testFileUrl("arrayToContainer.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<TestItem> root(qobject_cast<TestItem *>(component.createWithInitialProperties( {{"vector", QVariant::fromValue(points)}} )));
+ QVERIFY(root);
+ QCOMPARE(root->m_points.at(0), QPointF (2.0, 3.0) );
+}
+
+class EnumTester : public QObject
+{
+ Q_OBJECT
+public:
+ enum Types
+ {
+ FIRST = 0,
+ SECOND,
+ THIRD
+ };
+ Q_ENUM(Types)
+};
+
+void tst_qqmllanguage::qualifiedScopeInCustomParser()
+{
+ qmlRegisterUncreatableType<EnumTester>("scoped.custom.test", 1, 0, "EnumTester",
+ "Object only creatable in C++");
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQml.Models 2.12\n"
+ "import scoped.custom.test 1.0 as BACKEND\n"
+ "ListModel {\n"
+ " ListElement { text: \"a\"; type: BACKEND.EnumTester.FIRST }\n"
+ "}\n", QUrl());
+ QVERIFY(component.isReady());
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"
diff --git a/tests/auto/qml/qqmlparser/qqmlparser.pro b/tests/auto/qml/qqmlparser/qqmlparser.pro
index d8e4b0dd06..7f117b3157 100644
--- a/tests/auto/qml/qqmlparser/qqmlparser.pro
+++ b/tests/auto/qml/qqmlparser/qqmlparser.pro
@@ -11,3 +11,4 @@ cross_compile: DEFINES += QTEST_CROSS_COMPILED
TESTDATA = data/*
include (../../shared/util.pri)
+include (../../shared/astdump.pri)
diff --git a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp
index 981fe7407e..8483bd1f95 100644
--- a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp
+++ b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp
@@ -33,6 +33,7 @@
#include <private/qqmljsast_p.h>
#include "../../shared/util.h"
+#include "../../shared/qqmljsastdumper.h"
#include <qtest.h>
#include <QDir>
@@ -583,7 +584,7 @@ void tst_qqmlparser::annotations()
Parser parser2(&engine2);
QVERIFY(parser2.parse());
- // to do: compare for equality skipping annotations
+ QCOMPARE(AstDumper::diff(parser.ast(), parser2.rootNode(), 3, DumperOptions::NoAnnotations | DumperOptions::NoLocations), QString());
}
}
diff --git a/tests/auto/qml/qqmlproperty/data/interfaceBinding2.qml b/tests/auto/qml/qqmlproperty/data/interfaceBinding2.qml
new file mode 100644
index 0000000000..e7c5dc7344
--- /dev/null
+++ b/tests/auto/qml/qqmlproperty/data/interfaceBinding2.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.12
+import io.qt.bugreports 2.0
+Item {
+ InterfaceConsumer2 {
+ objectName: "a1"
+ i: A2 {
+ property int i: 42
+ }
+ }
+
+ InterfaceConsumer2 {
+ objectName: "a2"
+ property A2 a: A2 {
+ property int i: 43
+ }
+ i: a
+ }
+
+ InterfaceConsumer2 {
+ objectName: "a3"
+ property A2 a: A2 {
+ id : aa
+ property int i: 44
+ }
+ i: aa
+ }
+}
diff --git a/tests/auto/qml/qqmlproperty/interfaces.h b/tests/auto/qml/qqmlproperty/interfaces.h
new file mode 100644
index 0000000000..2c06c5f594
--- /dev/null
+++ b/tests/auto/qml/qqmlproperty/interfaces.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INTERFACES_H
+#define INTERFACES_H
+
+#include <QtQml/qqml.h>
+
+struct Interface {
+};
+
+QT_BEGIN_NAMESPACE
+#define MyInterface_iid "io.qt.bugreports.Interface"
+Q_DECLARE_INTERFACE(Interface, MyInterface_iid);
+QT_END_NAMESPACE
+
+class A : public QObject, Interface {
+ Q_OBJECT
+ Q_INTERFACES(Interface)
+};
+
+class B : public QObject, Interface {
+ Q_OBJECT
+ Q_INTERFACES(Interface)
+};
+
+class C : public QObject {
+ Q_OBJECT
+};
+
+struct Interface2
+{
+ Q_GADGET
+ QML_INTERFACE
+};
+
+QT_BEGIN_NAMESPACE
+#define MyInterface2_iid "io.qt.bugreports.Interface2"
+Q_DECLARE_INTERFACE(Interface2, MyInterface2_iid);
+QT_END_NAMESPACE
+
+class A2 : public QObject, Interface2 {
+ Q_OBJECT
+ QML_ELEMENT
+ Q_INTERFACES(Interface2)
+};
+
+class B2 : public QObject, Interface2 {
+ Q_OBJECT
+ QML_ELEMENT
+ Q_INTERFACES(Interface2)
+};
+
+class C2 : public QObject {
+ Q_OBJECT
+ QML_ELEMENT
+};
+
+class InterfaceConsumer : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(Interface *i READ interface WRITE setInterface NOTIFY interfaceChanged)
+ Q_PROPERTY(int testValue READ testValue NOTIFY testValueChanged)
+
+public:
+
+ Interface* interface() const
+ {
+ return m_interface;
+ }
+ void setInterface(Interface* interface)
+ {
+ QObject* object = reinterpret_cast<QObject*>(interface);
+ m_testValue = object->property("i").toInt();
+ emit testValueChanged();
+ if (m_interface == interface)
+ return;
+
+ m_interface = interface;
+ emit interfaceChanged();
+ }
+
+ int testValue() {
+ return m_testValue;
+ }
+
+signals:
+ void interfaceChanged();
+ void testValueChanged();
+
+private:
+ Interface* m_interface = nullptr;
+ int m_testValue = 0;
+};
+
+
+class InterfaceConsumer2 : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(Interface2 *i READ interface WRITE setInterface NOTIFY interfaceChanged)
+ Q_PROPERTY(int testValue READ testValue NOTIFY testValueChanged)
+
+ QML_ELEMENT
+
+public:
+
+ Interface2* interface() const
+ {
+ return m_interface;
+ }
+ void setInterface(Interface2* interface2)
+ {
+ QObject* object = reinterpret_cast<QObject*>(interface2);
+ m_testValue = object->property("i").toInt();
+ emit testValueChanged();
+ if (m_interface == interface2)
+ return;
+
+ m_interface = interface2;
+ emit interfaceChanged();
+ }
+
+ int testValue() {
+ return m_testValue;
+ }
+
+signals:
+ void interfaceChanged();
+ void testValueChanged();
+
+private:
+ Interface2 *m_interface = nullptr;
+ int m_testValue = 0;
+};
+
+#endif // INTERFACES_H
diff --git a/tests/auto/qml/qqmlproperty/qqmlproperty.pro b/tests/auto/qml/qqmlproperty/qqmlproperty.pro
index b1bcf1f17d..4d42975369 100644
--- a/tests/auto/qml/qqmlproperty/qqmlproperty.pro
+++ b/tests/auto/qml/qqmlproperty/qqmlproperty.pro
@@ -1,7 +1,10 @@
-CONFIG += testcase
+CONFIG += testcase qmltypes
TARGET = tst_qqmlproperty
macx:CONFIG -= app_bundle
+QML_IMPORT_NAME = io.qt.bugreports
+QML_IMPORT_VERSION = 2.0
+
SOURCES += tst_qqmlproperty.cpp
include (../../shared/util.pri)
@@ -9,3 +12,6 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private testlib
+
+HEADERS += \
+ interfaces.h
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 83e173f379..8a96fc52c5 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -25,6 +25,8 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#include "interfaces.h"
#include <qtest.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
@@ -160,6 +162,8 @@ private slots:
void bindingToAlias();
void nestedQQmlPropertyMap();
+
+ void underscorePropertyChangeHandler();
private:
QQmlEngine engine;
};
@@ -2090,74 +2094,20 @@ void tst_qqmlproperty::nullPropertyBinding()
QMetaObject::invokeMethod(root.get(), "tog");
}
-struct Interface {
-};
-
-QT_BEGIN_NAMESPACE
-#define MyInterface_iid "io.qt.bugreports.Interface"
-Q_DECLARE_INTERFACE(Interface, MyInterface_iid);
-QT_END_NAMESPACE
-
-class A : public QObject, Interface {
- Q_OBJECT
- Q_INTERFACES(Interface)
-};
-
-class B : public QObject, Interface {
- Q_OBJECT
- Q_INTERFACES(Interface)
-};
-
-class C : public QObject {
- Q_OBJECT
-};
-
-class InterfaceConsumer : public QObject {
- Q_OBJECT
- Q_PROPERTY(Interface* i READ interface WRITE setInterface NOTIFY interfaceChanged)
- Q_PROPERTY(int testValue READ testValue NOTIFY testValueChanged)
-
-
-public:
-
- Interface* interface() const
- {
- return m_interface;
- }
- void setInterface(Interface* interface)
- {
- QObject* object = reinterpret_cast<QObject*>(interface);
- m_testValue = object->property("i").toInt();
- emit testValueChanged();
- if (m_interface == interface)
- return;
-
- m_interface = interface;
- emit interfaceChanged();
- }
-
- int testValue() {
- return m_testValue;
- }
-
-signals:
- void interfaceChanged();
- void testValueChanged();
-
-private:
- Interface* m_interface = nullptr;
- int m_testValue = 0;
-};
void tst_qqmlproperty::interfaceBinding()
{
-
- qmlRegisterInterface<Interface>("Interface");
- qmlRegisterType<A>("io.qt.bugreports", 1, 0, "A");
- qmlRegisterType<B>("io.qt.bugreports", 1, 0, "B");
- qmlRegisterType<C>("io.qt.bugreports", 1, 0, "C");
- qmlRegisterType<InterfaceConsumer>("io.qt.bugreports", 1, 0, "InterfaceConsumer");
-
- const QUrl url = testFileUrl("interfaceBinding.qml");
+ qmlRegisterInterface<Interface>("Interface");
+ qmlRegisterType<A>("io.qt.bugreports", 1, 0, "A");
+ qmlRegisterType<B>("io.qt.bugreports", 1, 0, "B");
+ qmlRegisterType<C>("io.qt.bugreports", 1, 0, "C");
+ qmlRegisterType<InterfaceConsumer>("io.qt.bugreports", 1, 0, "InterfaceConsumer");
+
+ const QVector<QUrl> urls = {
+ testFileUrl("interfaceBinding.qml"),
+ testFileUrl("interfaceBinding2.qml")
+ };
+
+ for (const QUrl &url : urls) {
QQmlEngine engine;
QQmlComponent component(&engine, url);
QScopedPointer<QObject> root(component.create());
@@ -2165,6 +2115,7 @@ void tst_qqmlproperty::interfaceBinding()
QCOMPARE(root->findChild<QObject*>("a1")->property("testValue").toInt(), 42);
QCOMPARE(root->findChild<QObject*>("a2")->property("testValue").toInt(), 43);
QCOMPARE(root->findChild<QObject*>("a3")->property("testValue").toInt(), 44);
+ }
}
void tst_qqmlproperty::floatToStringPrecision_data()
@@ -2241,6 +2192,24 @@ void tst_qqmlproperty::nestedQQmlPropertyMap()
QCOMPARE(success.read().toString(), QLatin1String("success"));
}
+void tst_qqmlproperty::underscorePropertyChangeHandler()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(R"(
+ import QtQuick 2.12
+
+ Item {
+ property int __withUnderScore
+ }
+ )", QUrl::fromLocalFile("."));
+ QScopedPointer<QObject> root { component.create() };
+ QVERIFY(root);
+ QQmlProperty changeHandler(root.get(), "on__WithUnderScoreChanged");
+ QVERIFY(changeHandler.isValid());
+ QVERIFY(changeHandler.isSignalProperty());
+}
+
QTEST_MAIN(tst_qqmlproperty)
#include "tst_qqmlproperty.moc"
diff --git a/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp
index d0b3bc3d36..ca6463f365 100644
--- a/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp
@@ -55,6 +55,7 @@ private slots:
void initTestCase();
void singleTouch();
+ void tabletStylus();
void simultaneousMultiTouch();
void pressedMultipleButtons_data();
void pressedMultipleButtons();
@@ -136,6 +137,65 @@ void tst_PointHandler::singleTouch()
QCOMPARE(translationSpy.count(), 3);
}
+void tst_PointHandler::tabletStylus()
+{
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents, false);
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "pointTracker.qml");
+ QQuickView * window = windowPtr.data();
+ QQuickPointHandler *handler = window->rootObject()->findChild<QQuickPointHandler *>("pointHandler");
+ QVERIFY(handler);
+ handler->setAcceptedDevices(QQuickPointerDevice::Stylus);
+
+ QSignalSpy activeSpy(handler, SIGNAL(activeChanged()));
+ QSignalSpy pointSpy(handler, SIGNAL(pointChanged()));
+ QSignalSpy translationSpy(handler, SIGNAL(translationChanged()));
+
+ QPoint point(100,100);
+ const qint64 stylusId = 1234567890;
+
+ QWindowSystemInterface::handleTabletEvent(window, point, window->mapToGlobal(point),
+ QTabletEvent::Stylus, QTabletEvent::Pen, Qt::LeftButton, 0.5, 25, 35, 0.6, 12.3, 3, stylusId, Qt::NoModifier);
+ QTRY_COMPARE(handler->active(), true);
+ QCOMPARE(activeSpy.count(), 1);
+ QCOMPARE(pointSpy.count(), 1);
+ QCOMPARE(handler->point().position().toPoint(), point);
+ QCOMPARE(handler->point().scenePosition().toPoint(), point);
+ QCOMPARE(handler->point().pressedButtons(), Qt::LeftButton);
+ QCOMPARE(handler->point().pressure(), 0.5);
+ QCOMPARE(handler->point().rotation(), 12.3);
+ QCOMPARE(handler->point().uniqueId().numericId(), stylusId);
+ QCOMPARE(handler->translation(), QVector2D());
+ QCOMPARE(translationSpy.count(), 1);
+
+ point += QPoint(10, 10);
+ QWindowSystemInterface::handleTabletEvent(window, point, window->mapToGlobal(point),
+ QTabletEvent::Stylus, QTabletEvent::Pen, Qt::LeftButton, 0.45, 23, 33, 0.57, 15.6, 3.4, stylusId, Qt::NoModifier);
+ QTRY_COMPARE(pointSpy.count(), 2);
+ QCOMPARE(handler->active(), true);
+ QCOMPARE(activeSpy.count(), 1);
+ QCOMPARE(handler->point().position().toPoint(), point);
+ QCOMPARE(handler->point().scenePosition().toPoint(), point);
+ QCOMPARE(handler->point().pressPosition().toPoint(), QPoint(100, 100));
+ QCOMPARE(handler->point().scenePressPosition().toPoint(), QPoint(100, 100));
+ QCOMPARE(handler->point().pressedButtons(), Qt::LeftButton);
+ QCOMPARE(handler->point().pressure(), 0.45);
+ QCOMPARE(handler->point().rotation(), 15.6);
+ QCOMPARE(handler->point().uniqueId().numericId(), stylusId);
+ QVERIFY(handler->point().velocity().x() > 0);
+ QVERIFY(handler->point().velocity().y() > 0);
+ QCOMPARE(handler->translation(), QVector2D(10, 10));
+ QCOMPARE(translationSpy.count(), 2);
+
+ QWindowSystemInterface::handleTabletEvent(window, point, window->mapToGlobal(point),
+ QTabletEvent::Stylus, QTabletEvent::Pen, Qt::NoButton, 0, 0, 0, 0, 0, 0, stylusId, Qt::NoModifier);
+ QTRY_COMPARE(handler->active(), false);
+ QCOMPARE(activeSpy.count(), 2);
+ QCOMPARE(pointSpy.count(), 3);
+ QCOMPARE(handler->translation(), QVector2D());
+ QCOMPARE(translationSpy.count(), 3);
+}
+
void tst_PointHandler::simultaneousMultiTouch()
{
QScopedPointer<QQuickView> windowPtr;
diff --git a/tests/auto/quick/qquickflickable/data/visibleAreaBinding.qml b/tests/auto/quick/qquickflickable/data/visibleAreaBinding.qml
new file mode 100644
index 0000000000..6f7bc89793
--- /dev/null
+++ b/tests/auto/quick/qquickflickable/data/visibleAreaBinding.qml
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.14
+
+Flickable {
+ id: flickable
+ // Deliberately has no size set.
+
+ Text {
+ text: flickable.visibleArea.xPosition
+ }
+}
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 5364530ca8..f3659290eb 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -205,6 +205,7 @@ private slots:
void overshoot_reentrant();
void synchronousDrag_data();
void synchronousDrag();
+ void visibleAreaBinding();
private:
void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to);
@@ -2540,6 +2541,16 @@ void tst_qquickflickable::synchronousDrag()
QTest::touchEvent(window, touchDevice).release(0, p5, window);
}
+// QTBUG-81098: tests that a binding to visibleArea doesn't result
+// in a division-by-zero exception (when exceptions are enabled).
+void tst_qquickflickable::visibleAreaBinding()
+{
+ QScopedPointer<QQuickView> window(new QQuickView);
+ window->setSource(testFileUrl("visibleAreaBinding.qml"));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ // Shouldn't crash.
+}
+
QTEST_MAIN(tst_qquickflickable)
#include "tst_qquickflickable.moc"
diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
index 07af6a77ac..0732884c97 100644
--- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
+++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
@@ -1100,5 +1100,36 @@ Item {
waitForRendering(rootRect.layout)
compare(rootRect.item1.width, 100)
}
+
+//---------------------------
+ Component {
+ id: rowlayoutWithTextItems_Component
+ RowLayout {
+ Text {
+ Layout.fillWidth: true
+ text: "OneWord"
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ }
+ Text {
+ Layout.fillWidth: true
+ text: "OneWord"
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ }
+ }
+ }
+
+ // QTBUG-73683
+ function test_rowlayoutWithTextItems() {
+ var layout = createTemporaryObject(rowlayoutWithTextItems_Component, container)
+ waitForRendering(layout)
+ for (var i = 0; i < 3; i++) {
+ ignoreWarning(/Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations./)
+ }
+ ignoreWarning(/Qt Quick Layouts: Polish loop detected. Aborting after two iterations./)
+ layout.width = layout.width - 2 // set the size to be smaller than its "minimum size"
+ waitForRendering(layout) // do not exit before all warnings have been received
+
+ // DO NOT CRASH due to stack overflow (or loop endlessly due to updatePolish()/polish() loop)
+ }
}
}
diff --git a/tests/auto/quick/qquicklistview/data/headerSnapToItem.qml b/tests/auto/quick/qquicklistview/data/headerSnapToItem.qml
new file mode 100644
index 0000000000..1e5a811630
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/headerSnapToItem.qml
@@ -0,0 +1,67 @@
+import QtQuick 2.12
+
+Rectangle {
+
+ width: 240
+ height: 320
+ color: "#ffffff"
+
+ Component {
+ id: myDelegate
+ Rectangle {
+ id: wrapper
+ objectName: "wrapper"
+ width: list.orientation == ListView.Vertical ? 240 : 20
+ height: list.orientation == ListView.Vertical ? 20 : 240
+ border.width: 1
+ border.color: "black"
+ Text {
+ text: index + ":" + (list.orientation == ListView.Vertical ? parent.y : parent.x).toFixed(0)
+ }
+ color: ListView.isCurrentItem ? "lightsteelblue" : "white"
+ }
+ }
+
+ ListView {
+ id: list
+ objectName: "list"
+ focus: true
+ width: 240
+ height: 200
+ clip: true
+ snapMode: ListView.SnapToItem
+ headerPositioning: ListView.OverlayHeader
+ model: 30
+ delegate: myDelegate
+ orientation: ListView.Vertical
+ verticalLayoutDirection: ListView.BottomToTop
+
+ header: Rectangle {
+ width: list.orientation == Qt.Vertical ? 240 : 30
+ height: list.orientation == Qt.Vertical ? 30 : 240
+ objectName: "header";
+ color: "green"
+ z: 11
+ Text {
+ anchors.centerIn: parent
+ text: "header " + (list.orientation == ListView.Vertical ? parent.y : parent.x).toFixed(1)
+ }
+ }
+ }
+
+ Rectangle {
+ color: "red"
+ opacity: 0.5
+ width: txt.implicitWidth + 50
+ height: txt.implicitHeight
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+
+ Text {
+ id: txt
+ anchors.centerIn: parent
+ text: "header position: " + (list.orientation == ListView.Vertical ? list.headerItem.y : list.headerItem.x).toFixed(1)
+ + "\ncontent position: " + (list.orientation == ListView.Vertical ? list.contentY : list.contentX).toFixed(1)
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml b/tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml
new file mode 100644
index 0000000000..f6380ed5aa
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+
+ListView {
+ width: 100
+ height: 100
+ required model
+
+ delegate: Rectangle {
+ required color
+ required property string name
+
+ height: 25
+ width: 100
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 9a8dfee9d2..b141e235d5 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -30,6 +30,7 @@
#include <QtCore/QStringListModel>
#include <QtCore/QSortFilterProxyModel>
#include <QtGui/QStandardItemModel>
+#include <QtGui/QStyleHints>
#include <QtQuick/qquickview.h>
#include <QtQuickTest/QtQuickTest>
#include <QtQml/qqmlengine.h>
@@ -40,6 +41,7 @@
#include <QtQuick/private/qquicklistview_p.h>
#include <QtQuick/private/qquickmousearea_p.h>
#include <QtQuick/private/qquicktext_p.h>
+#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQmlModels/private/qqmlobjectmodel_p.h>
#include <QtQmlModels/private/qqmllistmodel_p.h>
#include <QtQmlModels/private/qqmldelegatemodel_p.h>
@@ -185,6 +187,8 @@ private slots:
void creationContext();
void snapToItem_data();
void snapToItem();
+ void headerSnapToItem_data();
+ void headerSnapToItem();
void snapToItemWithSpacing_QTBUG_59852();
void snapOneItemResize_QTBUG_43555();
void snapOneItem_data();
@@ -291,6 +295,8 @@ private slots:
void moveObjectModelItemToAnotherObjectModel();
void changeModelAndDestroyTheOldOne();
+ void requiredObjectListModel();
+
private:
template <class T> void items(const QUrl &source);
template <class T> void changed(const QUrl &source);
@@ -5412,6 +5418,604 @@ void tst_QQuickListView::snapToItemWithSpacing_QTBUG_59852()
releaseView(window);
}
+static void drag_helper(QWindow *window, QPoint *startPos, const QPoint &delta)
+{
+ QPoint pos = *startPos;
+ int dragDistance = delta.manhattanLength();
+ Q_ASSERT(qAbs(delta.x()) >= 1 || qAbs(delta.y()) >= 1);
+
+ const int stepSize = 8;
+ QPoint unitVector(0, 0);
+ if (delta.x())
+ unitVector.setX(qBound(-1, delta.x(), 1));
+ if (delta.y())
+ unitVector.setY(qBound(-1, delta.y(), 1));
+ QPoint dragStepSize = unitVector * stepSize;
+ int nDragSteps = qAbs(dragDistance/stepSize);
+
+ for (int i = 0 ; i < nDragSteps; ++i) {
+ QTest::mouseMove(window, pos);
+ pos += dragStepSize;
+ }
+ // Move to the final position
+ pos = *startPos + delta;
+ QTest::mouseMove(window, pos);
+ *startPos = pos;
+}
+
+static void dragtwice(QWindow *window, QPoint *startPos, const QPoint &delta1, const QPoint &delta2)
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QPoint &pos = *startPos;
+ QPoint unitVector(0, 0);
+ if (delta1.x())
+ unitVector.setX(qBound(-1, delta1.x(), 1));
+ if (delta1.y())
+ unitVector.setY(qBound(-1, delta1.y(), 1));
+
+ // go just beyond the drag theshold
+ drag_helper(window, &pos, unitVector * (dragThreshold + 1));
+ drag_helper(window, &pos, unitVector);
+
+ // next drag will actually scroll the listview
+ if (delta1.manhattanLength() >= 1)
+ drag_helper(window, &pos, delta1);
+ if (delta2.manhattanLength() >= 1)
+ drag_helper(window, &pos, delta2);
+}
+
+struct MyListView : public QQuickListView{
+ qreal contentPosition() const
+ {
+ return (orientation() == QQuickListView::Horizontal ? contentX(): contentY());
+ }
+
+ qreal headerPosition() const
+ {
+ return (orientation() == QQuickListView::Horizontal ? headerItem()->x() : headerItem()->y());
+ }
+};
+
+void tst_QQuickListView::headerSnapToItem()
+{
+ QFETCH(QQuickItemView::LayoutDirection, layoutDirection);
+ QFETCH(QQuickListView::HeaderPositioning, headerPositioning);
+ QFETCH(int, firstDragDistance);
+ QFETCH(int, secondDragDistance);
+ QFETCH(int, expectedContentPosition);
+ QFETCH(int, expectedHeaderPosition);
+
+ QQuickView *window = getView();
+ window->setSource(testFileUrl("headerSnapToItem.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ MyListView *listview = static_cast<MyListView *>(findItem<QQuickListView>(window->rootObject(), "list"));
+ QVERIFY(listview != nullptr);
+
+ const bool horizontal = layoutDirection < QQuickItemView::VerticalTopToBottom;
+ listview->setOrientation(horizontal ? QQuickListView::Horizontal : QQuickListView::Vertical);
+
+ if (horizontal)
+ listview->setLayoutDirection(static_cast<Qt::LayoutDirection>(layoutDirection));
+ else
+ listview->setVerticalLayoutDirection(static_cast<QQuickItemView::VerticalLayoutDirection>(layoutDirection));
+
+ listview->setHeaderPositioning(headerPositioning);
+ QVERIFY(QQuickTest::qWaitForItemPolished(listview));
+
+ QQuickItem *contentItem = listview->contentItem();
+ QVERIFY(contentItem != nullptr);
+ QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header != nullptr);
+ QCOMPARE(header, listview->headerItem());
+
+ QPoint startPos = (QPointF(listview->width(), listview->height())/2).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, startPos, 200);
+
+ QPoint firstDragDelta(0, firstDragDistance);
+ QPoint secondDragDelta = QPoint(0, secondDragDistance);
+ if (horizontal) {
+ firstDragDelta = firstDragDelta.transposed();
+ secondDragDelta = secondDragDelta.transposed();
+ }
+
+ dragtwice(window, &startPos, firstDragDelta, secondDragDelta);
+
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, startPos, 200); // Wait 200 ms before we release to avoid trigger a flick
+
+ // wait for the "fixup" animation to finish
+ QTest::qWaitFor([&]()
+ { return !listview->isMoving();}
+ );
+
+ QCOMPARE(listview->contentPosition(), expectedContentPosition);
+ QCOMPARE(listview->headerPosition(), expectedHeaderPosition);
+}
+
+void tst_QQuickListView::headerSnapToItem_data()
+{
+ QTest::addColumn<QQuickItemView::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickListView::HeaderPositioning>("headerPositioning");
+ QTest::addColumn<int>("firstDragDistance");
+ QTest::addColumn<int>("secondDragDistance");
+ QTest::addColumn<int>("expectedContentPosition");
+ QTest::addColumn<int>("expectedHeaderPosition");
+
+ // --------------------
+ // InlineHeader TopToBottom
+ QTest::newRow("InlineHeader TopToBottom -10") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::InlineHeader
+ << -10 << 0
+ << -30 << -30;
+
+ QTest::newRow("InlineHeader TopToBottom -14") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::InlineHeader
+ << -14 << 0
+ << -30 << -30;
+
+ QTest::newRow("InlineHeader TopToBottom -16") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::InlineHeader
+ << -16 << 0
+ << 0 << -30;
+
+ QTest::newRow("InlineHeader TopToBottom -30") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::InlineHeader
+ << -30 << 0
+ << 0 << -30;
+
+ QTest::newRow("InlineHeader TopToBottom -39") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::InlineHeader
+ << -39 << 0
+ << 0 << -30;
+
+ QTest::newRow("InlineHeader TopToBottom -41") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::InlineHeader
+ << -41 << 0
+ << 20 << -30;
+
+ QTest::newRow("InlineHeader TopToBottom -65+10") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::InlineHeader
+ << -65 << 10
+ << 20 << -30;
+
+ // --------------------
+ // InlineHeader BottomToTop
+ QTest::newRow("InlineHeader BottomToTop +10") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::InlineHeader
+ << 10 << 0
+ << -170 << 0;
+
+ QTest::newRow("InlineHeader BottomToTop +14") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::InlineHeader
+ << 14 << 0
+ << -170 << 0;
+
+ QTest::newRow("InlineHeader BottomToTop +16") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::InlineHeader
+ << 16 << 0
+ << -200 << 0;
+
+ QTest::newRow("InlineHeader BottomToTop +30") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::InlineHeader
+ << 30 << 0
+ << -200 << 0;
+
+ QTest::newRow("InlineHeader BottomToTop +39") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::InlineHeader
+ << 39 << 0
+ << -200 << 0;
+
+ QTest::newRow("InlineHeader BottomToTop +41") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::InlineHeader
+ << 41 << 0
+ << -220 << 0;
+
+ QTest::newRow("InlineHeader BottomToTop +65-10") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::InlineHeader
+ << 65 << -10
+ << -220 << 0;
+
+ // --------------------
+ // InlineHeader LeftToRight
+ QTest::newRow("InlineHeader LeftToRight -10") << QQuickItemView::LeftToRight
+ << QQuickListView::InlineHeader
+ << -10 << 0
+ << -30 << -30;
+
+ QTest::newRow("InlineHeader LeftToRight -14") << QQuickItemView::LeftToRight
+ << QQuickListView::InlineHeader
+ << -14 << 0
+ << -30 << -30;
+
+ QTest::newRow("InlineHeader LeftToRight -16") << QQuickItemView::LeftToRight
+ << QQuickListView::InlineHeader
+ << -16 << 0
+ << 0 << -30;
+
+ QTest::newRow("InlineHeader LeftToRight -30") << QQuickItemView::LeftToRight
+ << QQuickListView::InlineHeader
+ << -30 << 0
+ << 0 << -30;
+
+ QTest::newRow("InlineHeader LeftToRight -39") << QQuickItemView::LeftToRight
+ << QQuickListView::InlineHeader
+ << -39 << 0
+ << 0 << -30;
+
+ QTest::newRow("InlineHeader LeftToRight -41") << QQuickItemView::LeftToRight
+ << QQuickListView::InlineHeader
+ << -41 << 0
+ << 20 << -30;
+
+ QTest::newRow("InlineHeader LeftToRight -65+10") << QQuickItemView::LeftToRight
+ << QQuickListView::InlineHeader
+ << -65 << 10
+ << 20 << -30;
+
+ // --------------------
+ // InlineHeader RightToLeft
+ QTest::newRow("InlineHeader RightToLeft +10") << QQuickItemView::RightToLeft
+ << QQuickListView::InlineHeader
+ << 10 << 0
+ << -210 << 0;
+
+ QTest::newRow("InlineHeader RightToLeft +14") << QQuickItemView::RightToLeft
+ << QQuickListView::InlineHeader
+ << 14 << 0
+ << -210 << 0;
+
+ QTest::newRow("InlineHeader RightToLeft +16") << QQuickItemView::RightToLeft
+ << QQuickListView::InlineHeader
+ << 16 << 0
+ << -240 << 0;
+
+ QTest::newRow("InlineHeader RightToLeft +30") << QQuickItemView::RightToLeft
+ << QQuickListView::InlineHeader
+ << 30 << 0
+ << -240 << 0;
+
+ QTest::newRow("InlineHeader RightToLeft +39") << QQuickItemView::RightToLeft
+ << QQuickListView::InlineHeader
+ << 39 << 0
+ << -240 << 0;
+
+ QTest::newRow("InlineHeader RightToLeft +41") << QQuickItemView::RightToLeft
+ << QQuickListView::InlineHeader
+ << 41 << 0
+ << -260 << 0;
+
+ QTest::newRow("InlineHeader RightToLeft +65-10") << QQuickItemView::RightToLeft
+ << QQuickListView::InlineHeader
+ << 65 << -10
+ << -260 << 0;
+
+ // --------------------
+ // OverlayHeader TopToBottom
+ QTest::newRow("OverlayHeader TopToBottom +9") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::OverlayHeader
+ << 9 << 0
+ << -30 << -30;
+
+ QTest::newRow("OverlayHeader TopToBottom -9") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::OverlayHeader
+ << -9 << 0
+ << -30 << -30;
+
+ QTest::newRow("OverlayHeader TopToBottom -11") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::OverlayHeader
+ << -11 << 0
+ << -10 << -10;
+
+ QTest::newRow("OverlayHeader TopToBottom -29") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::OverlayHeader
+ << -29 << 0
+ << -10 << -10;
+
+ QTest::newRow("OverlayHeader TopToBottom -31") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::OverlayHeader
+ << -31 << 0
+ << 10 << 10;
+
+ // --------------------
+ // OverlayHeader BottomToTop
+ QTest::newRow("OverlayHeader BottomToTop -9") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::OverlayHeader
+ << -9 << 0
+ << -170 << 0;
+
+ QTest::newRow("OverlayHeader BottomToTop +9") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::OverlayHeader
+ << 9 << 0
+ << -170 << 0;
+
+ QTest::newRow("OverlayHeader BottomToTop +11") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::OverlayHeader
+ << 11 << 0
+ << -190 << -20;
+
+ QTest::newRow("OverlayHeader BottomToTop +29") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::OverlayHeader
+ << 29 << 0
+ << -190 << -20;
+
+ QTest::newRow("OverlayHeader BottomToTop +31") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::OverlayHeader
+ << 31 << 0
+ << -210 << -40;
+
+ // --------------------
+ // OverlayHeader LeftToRight
+ QTest::newRow("OverlayHeader LeftToRight +9") << QQuickItemView::LeftToRight
+ << QQuickListView::OverlayHeader
+ << 9 << 0
+ << -30 << -30;
+
+ QTest::newRow("OverlayHeader LeftToRight -9") << QQuickItemView::LeftToRight
+ << QQuickListView::OverlayHeader
+ << -9 << 0
+ << -30 << -30;
+
+ QTest::newRow("OverlayHeader LeftToRight -11") << QQuickItemView::LeftToRight
+ << QQuickListView::OverlayHeader
+ << -11 << 0
+ << -10 << -10;
+
+ QTest::newRow("OverlayHeader LeftToRight -29") << QQuickItemView::LeftToRight
+ << QQuickListView::OverlayHeader
+ << -29 << 0
+ << -10 << -10;
+
+ QTest::newRow("OverlayHeader LeftToRight -31") << QQuickItemView::LeftToRight
+ << QQuickListView::OverlayHeader
+ << -31 << 0
+ << 10 << 10;
+
+ // --------------------
+ // OverlayHeader RightToLeft
+ QTest::newRow("OverlayHeader RightToLeft -9") << QQuickItemView::RightToLeft
+ << QQuickListView::OverlayHeader
+ << -9 << 0
+ << -210 << 0;
+
+ QTest::newRow("OverlayHeader RightToLeft +9") << QQuickItemView::RightToLeft
+ << QQuickListView::OverlayHeader
+ << 9 << 0
+ << -210 << 0;
+
+ QTest::newRow("OverlayHeader RightToLeft +11") << QQuickItemView::RightToLeft
+ << QQuickListView::OverlayHeader
+ << 11 << 0
+ << -230 << -20;
+
+ QTest::newRow("OverlayHeader RightToLeft +29") << QQuickItemView::RightToLeft
+ << QQuickListView::OverlayHeader
+ << 29 << 0
+ << -230 << -20;
+
+ QTest::newRow("OverlayHeader RightToLeft +31") << QQuickItemView::RightToLeft
+ << QQuickListView::OverlayHeader
+ << 31 << 0
+ << -250 << -40;
+
+ // --------------------
+ // PullbackHeader TopToBottom
+ QTest::newRow("PullbackHeader TopToBottom -2") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::PullBackHeader
+ << -2 << 0
+ << -30 << -30;
+
+ QTest::newRow("PullbackHeader TopToBottom -10") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::PullBackHeader
+ << -10 << 0
+ << -30 << -30;
+
+ QTest::newRow("PullbackHeader TopToBottom -11") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::PullBackHeader
+ << -11 << 0
+ << -10 << -10;
+
+ QTest::newRow("PullbackHeader TopToBottom -14") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::PullBackHeader
+ << -14 << 0
+ << -10 << -10;
+
+ QTest::newRow("PullbackHeader TopToBottom -16") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::PullBackHeader
+ << -16 << 0
+ << 0 << -30;
+
+ QTest::newRow("PullbackHeader TopToBottom -20") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::PullBackHeader
+ << -20 << 0
+ << 0 << -30;
+
+ QTest::newRow("PullbackHeader TopToBottom -65+10") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::PullBackHeader
+ << -65 << 10
+ << 20 << -10;
+
+ QTest::newRow("PullbackHeader TopToBottom -65+20") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::PullBackHeader
+ << -65 << 20
+ << 10 << 10;
+
+ // Should move header even if contentY doesn't move (its aligned with top)
+ QTest::newRow("PullbackHeader TopToBottom -55+5") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::PullBackHeader
+ << -55 << 5
+ << 20 << -10;
+
+ // Should move header even if contentY doesn't move (it's aligned with header)
+ QTest::newRow("PullbackHeader TopToBottom -76+16") << QQuickItemView::VerticalTopToBottom
+ << QQuickListView::PullBackHeader
+ << -76 << 16
+ << 30 << 30;
+
+ // --------------------
+ // PullbackHeader BottomToTop
+ QTest::newRow("PullbackHeader BottomToTop +2") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::PullBackHeader
+ << +2 << 0
+ << -170 << 0;
+
+ QTest::newRow("PullbackHeader BottomToTop +9") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::PullBackHeader
+ << +9 << 0
+ << -170 << 0;
+
+ QTest::newRow("PullbackHeader BottomToTop +11") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::PullBackHeader
+ << +11 << 0
+ << -190 << -20;
+
+ QTest::newRow("PullbackHeader BottomToTop +14") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::PullBackHeader
+ << +14 << 0
+ << -190 << -20;
+
+ QTest::newRow("PullbackHeader BottomToTop +16") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::PullBackHeader
+ << +16 << 0
+ << -200 << 0;
+
+ QTest::newRow("PullbackHeader BottomToTop +20") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::PullBackHeader
+ << +20 << 0
+ << -200 << 0;
+
+ QTest::newRow("PullbackHeader BottomToTop +65-10") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::PullBackHeader
+ << +65 << -10
+ << -220 << -20;
+
+ QTest::newRow("PullbackHeader BottomToTop +65-20") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::PullBackHeader
+ << +65 << -20
+ << -210 << -40;
+
+ // Should move header even if contentY doesn't move (it's aligned with top)
+ QTest::newRow("PullbackHeader BottomToTop +55-5") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::PullBackHeader
+ << 55 << -5
+ << -220 << -20;
+
+ // Should move header even if contentY doesn't move (it's aligned with header)
+ QTest::newRow("PullbackHeader BottomToTop +76-16") << QQuickItemView::VerticalBottomToTop
+ << QQuickListView::PullBackHeader
+ << 76 << -16
+ << -230 << -60;
+
+ // --------------------
+ // PullbackHeader LeftToRight
+ QTest::newRow("PullbackHeader LeftToRight -2") << QQuickItemView::LeftToRight
+ << QQuickListView::PullBackHeader
+ << -2 << 0
+ << -30 << -30;
+
+ QTest::newRow("PullbackHeader LeftToRight -10") << QQuickItemView::LeftToRight
+ << QQuickListView::PullBackHeader
+ << -10 << 0
+ << -30 << -30;
+
+ QTest::newRow("PullbackHeader LeftToRight -11") << QQuickItemView::LeftToRight
+ << QQuickListView::PullBackHeader
+ << -11 << 0
+ << -10 << -10;
+
+ QTest::newRow("PullbackHeader LeftToRight -14") << QQuickItemView::LeftToRight
+ << QQuickListView::PullBackHeader
+ << -14 << 0
+ << -10 << -10;
+
+ QTest::newRow("PullbackHeader LeftToRight -16") << QQuickItemView::LeftToRight
+ << QQuickListView::PullBackHeader
+ << -16 << 0
+ << 0 << -30;
+
+ QTest::newRow("PullbackHeader LeftToRight -20") << QQuickItemView::LeftToRight
+ << QQuickListView::PullBackHeader
+ << -20 << 0
+ << 0 << -30;
+
+ QTest::newRow("PullbackHeader LeftToRight -65+10") << QQuickItemView::LeftToRight
+ << QQuickListView::PullBackHeader
+ << -65 << 10
+ << 20 << -10;
+
+ QTest::newRow("PullbackHeader LeftToRight -65+20") << QQuickItemView::LeftToRight
+ << QQuickListView::PullBackHeader
+ << -65 << 20
+ << 10 << 10;
+
+ // Should move header even if contentX doesn't move (its aligned with top)
+ QTest::newRow("PullbackHeader LeftToRight -55+5") << QQuickItemView::LeftToRight
+ << QQuickListView::PullBackHeader
+ << -55 << 5
+ << 20 << -10;
+
+ // Should move header even if contentX doesn't move (it's aligned with header)
+ QTest::newRow("PullbackHeader LeftToRight -76+16") << QQuickItemView::LeftToRight
+ << QQuickListView::PullBackHeader
+ << -76 << 16
+ << 30 << 30;
+
+ // --------------------
+ // PullbackHeader RightToLeft
+ QTest::newRow("PullbackHeader RightToLeft +2") << QQuickItemView::RightToLeft
+ << QQuickListView::PullBackHeader
+ << +2 << 0
+ << -210 << 0;
+
+ QTest::newRow("PullbackHeader RightToLeft +9") << QQuickItemView::RightToLeft
+ << QQuickListView::PullBackHeader
+ << +9 << 0
+ << -210 << 0;
+
+ QTest::newRow("PullbackHeader RightToLeft +11") << QQuickItemView::RightToLeft
+ << QQuickListView::PullBackHeader
+ << +11 << 0
+ << -230 << -20;
+
+ QTest::newRow("PullbackHeader RightToLeft +14") << QQuickItemView::RightToLeft
+ << QQuickListView::PullBackHeader
+ << +14 << 0
+ << -230 << -20;
+
+ QTest::newRow("PullbackHeader RightToLeft +16") << QQuickItemView::RightToLeft
+ << QQuickListView::PullBackHeader
+ << +16 << 0
+ << -240 << 0;
+
+ QTest::newRow("PullbackHeader RightToLeft +20") << QQuickItemView::RightToLeft
+ << QQuickListView::PullBackHeader
+ << +20 << 0
+ << -240 << 0;
+
+ QTest::newRow("PullbackHeader RightToLeft +65-10") << QQuickItemView::RightToLeft
+ << QQuickListView::PullBackHeader
+ << +65 << -10
+ << -260 << -20;
+
+ QTest::newRow("PullbackHeader RightToLeft +65-20") << QQuickItemView::RightToLeft
+ << QQuickListView::PullBackHeader
+ << +65 << -20
+ << -250 << -40;
+
+ // Should move header even if contentX doesn't move (it's aligned with top)
+ QTest::newRow("PullbackHeader RightToLeft +55-5") << QQuickItemView::RightToLeft
+ << QQuickListView::PullBackHeader
+ << 55 << -5
+ << -260 << -20;
+
+ // Should move header even if contentX doesn't move (it's aligned with header)
+ QTest::newRow("PullbackHeader RightToLeft +76-16") << QQuickItemView::RightToLeft
+ << QQuickListView::PullBackHeader
+ << 76 << -16
+ << -270 << -60;
+
+}
+
void tst_QQuickListView::snapOneItemResize_QTBUG_43555()
{
QScopedPointer<QQuickView> window(createView());
@@ -9431,6 +10035,60 @@ void tst_QQuickListView::changeModelAndDestroyTheOldOne() // QTBUG-80203
// no crash
}
+class DataObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString name READ name CONSTANT)
+ Q_PROPERTY(QString color READ color CONSTANT)
+
+public:
+ DataObject(QObject *parent = nullptr) : QObject(parent) {}
+ DataObject(const QString &name, const QString &color, QObject *parent = nullptr)
+ : QObject(parent), m_name(name), m_color(color) {}
+
+ QString name() const { return m_name; }
+ QString color() const { return m_color; }
+
+private:
+ QString m_name;
+ QString m_color;
+};
+
+void tst_QQuickListView::requiredObjectListModel()
+{
+ QList<QObject *> dataList = {
+ new DataObject("Item 1", "red", this),
+ new DataObject("Item 2", "green", this),
+ new DataObject("Item 3", "blue", this),
+ new DataObject("Item 4", "yellow", this)
+ };
+
+ const auto deleter = qScopeGuard([&](){ qDeleteAll(dataList); });
+ Q_UNUSED(deleter);
+
+ QQuickView view;
+ view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }});
+ view.setSource(testFileUrl("requiredObjectListModel.qml"));
+ view.show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ const auto *root = qobject_cast<QQuickListView *>(view.rootObject());
+ QVERIFY(root);
+
+ QCOMPARE(root->count(), dataList.count());
+
+ for (int i = 0, end = dataList.count(); i != end; ++i) {
+ const auto *rect = qobject_cast<QQuickRectangle *>(root->itemAtIndex(i));
+ QVERIFY(rect);
+ const auto *data = qobject_cast<DataObject *>(dataList.at(i));
+ QVERIFY(data);
+
+ QCOMPARE(rect->color(), QColor(data->color()));
+ QCOMPARE(rect->property("name").toString(), data->name());
+ }
+}
+
QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"
diff --git a/tests/auto/quick/qquickloader/data/statusChanged.qml b/tests/auto/quick/qquickloader/data/statusChanged.qml
new file mode 100644
index 0000000000..fe46bc7b24
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/statusChanged.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.12
+import QtQuick.Window 2.12
+
+Window {
+ id: root
+ property int statusChangedCounter: 0
+ property alias status: loader.status
+ visible: true; width: 640; height: 480
+ Loader {
+ id: loader
+ anchors.fill: parent
+ asynchronous: true
+ source: "./RedRect.qml"
+ onStatusChanged: root.statusChangedCounter++
+ }
+}
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index e05b7ae9ce..91d0bcab2e 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -39,6 +39,7 @@
#include "testhttpserver.h"
#include "../../shared/util.h"
#include "../shared/geometrytestutil.h"
+#include <QQmlApplicationEngine>
Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests")
@@ -128,6 +129,7 @@ private slots:
void rootContext();
void sourceURLKeepComponent();
+ void statusChangeOnlyEmittedOnce();
};
Q_DECLARE_METATYPE(QList<QQmlError>)
@@ -1456,6 +1458,18 @@ void tst_QQuickLoader::sourceURLKeepComponent()
}
+// QTBUG-82002
+void tst_QQuickLoader::statusChangeOnlyEmittedOnce()
+{
+ QQmlApplicationEngine engine;
+ auto url = testFileUrl("statusChanged.qml");
+ engine.load(url);
+ auto root = engine.rootObjects().at(0);
+ QVERIFY(root);
+ QTRY_COMPARE(QQuickLoader::Status(root->property("status").toInt()), QQuickLoader::Ready);
+ QCOMPARE(root->property("statusChangedCounter").toInt(), 2); // 1xLoading + 1xReady*/
+}
+
QTEST_MAIN(tst_QQuickLoader)
#include "tst_qquickloader.moc"
diff --git a/tests/auto/quick/qquickmousearea/BLACKLIST b/tests/auto/quick/qquickmousearea/BLACKLIST
index 6dbe3e11b6..1491116f59 100644
--- a/tests/auto/quick/qquickmousearea/BLACKLIST
+++ b/tests/auto/quick/qquickmousearea/BLACKLIST
@@ -1,2 +1,6 @@
[pressAndHold]
macos ci
+
+# QTBUG-78153
+[nestedStopAtBounds]
+opensuse-leap
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index bf58ce961c..0bf83c267a 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -2860,7 +2860,7 @@ void tst_qquickwindow::pointerEventTypeAndPointCount()
QList<QTouchEvent::TouchPoint>() << QTouchEvent::TouchPoint(1));
- QQuickPointerMouseEvent pme;
+ QQuickPointerMouseEvent pme(nullptr, QQuickPointerDevice::genericMouseDevice());
pme.reset(&me);
QCOMPARE(pme.asMouseEvent(localPosition), &me);
QVERIFY(pme.asPointerMouseEvent());
@@ -2872,7 +2872,7 @@ void tst_qquickwindow::pointerEventTypeAndPointCount()
QCOMPARE(pme.asMouseEvent(localPosition)->localPos(), localPosition);
QCOMPARE(pme.asMouseEvent(localPosition)->screenPos(), screenPosition);
- QQuickPointerTouchEvent pte;
+ QQuickPointerTouchEvent pte(nullptr, QQuickPointerDevice::touchDevice(touchDevice));
pte.reset(&te);
QCOMPARE(pte.asTouchEvent(), &te);
QVERIFY(!pte.asPointerMouseEvent());
diff --git a/tests/auto/shared/astdump.pri b/tests/auto/shared/astdump.pri
new file mode 100644
index 0000000000..365b12fc51
--- /dev/null
+++ b/tests/auto/shared/astdump.pri
@@ -0,0 +1,7 @@
+
+INCLUDEPATH += $$PWD
+HEADERS += \
+ $$PWD/qqmljsastdumper.h
+
+SOURCES += \
+ $$PWD/qqmljsastdumper.cpp
diff --git a/tests/auto/shared/qqmljsastdumper.cpp b/tests/auto/shared/qqmljsastdumper.cpp
new file mode 100644
index 0000000000..bc21d8d4e5
--- /dev/null
+++ b/tests/auto/shared/qqmljsastdumper.cpp
@@ -0,0 +1,1081 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**/
+#include "qqmljsastdumper.h"
+#include <private/qqmljsast_p.h>
+#include <QtCore/QDebug>
+#include <QtCore/QString>
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+namespace QQmlJS {
+using namespace AST;
+/*!
+\internal
+\enum QQmlJS::DumperOptions
+
+This enum type specifies the options for the AstDumper.
+The values can be combined with the '|' operator, and checked using the '&' operator.
+
+\value None
+ Default dumping options
+\value NoLocations
+ Does not dump SourceLocations, allowing one to compare equivalent AST
+ generated by code formatted differently
+\value NoAnnotations
+ Does not dump annotations
+\value DumpNode
+ Does dump a <Node></Node> in preVisit/postVisit
+*/
+
+/*!
+\internal
+\class QQmlJS::AstDumper
+\brief Dumps or compares AST in an xml like format, mostly for testing/debugging
+
+Initialize it with a lambda that dumps a string, and configure it with .setX methods.
+If \l{indent} is set to a non zero value the xml is indented by that amount, and
+\l{baseIndent} is the initial indent.
+If \l{emitNode} is true the node tag is emitted in the preVisit/postVisit.
+If \l{emitLocation} is true the SourceLocations are emitted.
+If \l{emitAnnotations} is true annotations are emitted
+
+The implementation has unnecessary roundtrips to QString, but it is supposed to be used
+for debugging purposes...
+
+Probably you will not use the visitor at all but rather the static method diff or
+the qDebug() and ostream operator << that use the visitor...
+
+\fn AstDumper::diff(AST::Node *n1, AST::Node *n2, int nContext, DumperOptions opt, int indent)
+
+\brief compares the two AST::Node n1 and n2 and returns a string describing their first difference
+
+If there are no differences the empty string is returned, so .isEmpty() can be use to check
+for no differences.
+\l{nContext} decides how much context is printed out.
+
+*/
+
+
+QDebug operator<<(QDebug d, AST::Node *n) {
+ QDebug noQuote = d.noquote().nospace();
+ AstDumper visitor([&noQuote](const QString &s){ noQuote << s; });
+ Node::accept(n, &visitor);
+ return d;
+}
+
+
+std::ostream &operator<<(std::ostream &stream, AST::Node *n) {
+ AstDumper visitor([&stream](const QString &s){ stream << s.toStdString(); });
+ Node::accept(n, &visitor);
+ return stream;
+}
+
+bool operator & (DumperOptions lhs, DumperOptions rhs) {
+ return bool(static_cast<int>(lhs) & static_cast<int>(rhs));
+}
+
+DumperOptions operator | (DumperOptions lhs, DumperOptions rhs) {
+ return DumperOptions(static_cast<int>(lhs) | static_cast<int>(rhs));
+}
+
+QString AstDumper::diff(AST::Node *n1, AST::Node *n2, int nContext, DumperOptions opt, int indent) {
+ QString s1, s2;
+ QTextStream d1(&s1), d2(&s2);
+ AstDumper visitor1=AstDumper([&d1](const QString &s){ d1 << s; }, opt, indent);
+ AstDumper visitor2=AstDumper([&d2](const QString &s){ d2 << s; }, opt, indent);
+ Node::accept(n1, &visitor1);
+ Node::accept(n2, &visitor2);
+ d1.seek(0);
+ d2.seek(0);
+ std::vector<QString> preLines(nContext);
+ int nLine = 0;
+ bool same = true;
+ QString l1, l2;
+ while (same && !d1.atEnd() && !d2.atEnd()) {
+ l1=d1.readLine();
+ l2=d2.readLine();
+ if (l1 == l2)
+ preLines[nLine++ % nContext] = l1;
+ else
+ same = false;
+ }
+ QString res;
+ QTextStream ss(&res);
+ if (!same || !d1.atEnd() || !d2.atEnd()) {
+ for (int iline = qMin(nLine, nContext); iline > 0; --iline) {
+ ss << QLatin1String(" ") << preLines[(nLine - iline) % nContext] << QLatin1String("\n");
+ }
+ int iline = 0;
+ if (!same) {
+ ss << QLatin1String("-") << l1 << QLatin1String("\n");
+ ++iline;
+ }
+ if (same && nContext == 0)
+ nContext = 1;
+ for (;iline < nContext && !d1.atEnd(); iline ++) {
+ l1 = d1.readLine();
+ ss << QLatin1String("-") << l1 << QLatin1String("\n");
+ }
+ iline = 0;
+ if (!same) {
+ ss << QLatin1String("+") << l2 << QLatin1String("\n");
+ ++iline;
+ }
+ for (;iline < nContext && !d2.atEnd(); iline ++) {
+ l2 = d2.readLine();
+ ss << QLatin1String("+") << l2 << QLatin1String("\n");
+ }
+ }
+ return res;
+}
+
+QString AstDumper::printNode(Node *n, DumperOptions opt, int indent, int baseIndent)
+{
+ QString res;
+ QTextStream d(&res);
+ AstDumper visitor=AstDumper([&d](const QString &s){ d << s; }, opt, indent, baseIndent);
+ Node::accept(n, &visitor);
+ return res;
+}
+
+AstDumper::AstDumper(const std::function<void(const QString &)> &dumper, DumperOptions options, int indent, int baseIndent):
+ dumper(dumper), options(options), indent(indent), baseIndent(baseIndent) {}
+
+void AstDumper::start(const QString &str) {
+ dumper(QString::fromLatin1(" ").repeated(baseIndent));
+ dumper(QLatin1String("<"));
+ dumper(str);
+ dumper(QLatin1String(">\n"));
+ baseIndent += indent;
+}
+
+void AstDumper::start(const char *str) {
+ start(QLatin1String(str));
+}
+
+void AstDumper::stop(const QString &str) {
+ baseIndent -= indent;
+ dumper(QString::fromLatin1(" ").repeated(baseIndent));
+ dumper(QLatin1String("</"));
+ dumper(str);
+ dumper(QLatin1String(">\n"));
+}
+
+void AstDumper::stop(const char *str) {
+ stop(QLatin1String(str));
+}
+
+QString AstDumper::qs(const QString &s) {
+ QString res(s);
+ return QLatin1String("\"") + res
+ .replace(QLatin1String("\\"), QLatin1String("\\\\"))
+ .replace(QLatin1String("\""), QLatin1String("\\\"")) + QLatin1String("\"");
+}
+
+QString AstDumper::qs(const char *s) {
+ return qs(QLatin1String(s));
+}
+
+QString AstDumper::qs(const QStringRef &s) {
+ return qs(s.toString());
+}
+
+QString AstDumper::loc(const AST::SourceLocation &s) {
+ if (noLocations() || !s.isValid())
+ return QLatin1String("\"\"");
+ else {
+ return QLatin1String("\"off:%1 len:%2 l:%3 c:%4\"").arg(QString::number(s.offset), QString::number(s.length), QString::number(s.startLine), QString::number(s.startColumn));
+ }
+}
+
+QString AstDumper::boolStr(bool v) { return (v ? qs("true"): qs("false")); }
+
+bool AstDumper::preVisit(Node *) { if (dumpNode()) start("Node"); return true; }
+
+void AstDumper::postVisit(Node *) { if (dumpNode()) stop("Node"); }
+
+bool AstDumper::visit(UiProgram *) { start("UiProgram"); return true; }
+
+bool AstDumper::visit(UiHeaderItemList *) { start("UiHeaderItemList"); return true; }
+
+bool AstDumper::visit(UiPragma *el) {
+ start(QLatin1String("UiPragma name=%1 pragmaToken=%2 semicolonToken=%3")
+ .arg(qs(el->name), loc(el->pragmaToken), loc(el->semicolonToken)));
+ return true;
+}
+
+bool AstDumper::visit(UiImport *el)
+{
+ start(QLatin1String("UiImport fileName=%1 importId=%2 importToken=%3 fileNameToken=%4 asToken=%5 importIdToken=%6 semicolonToken=%7")
+ .arg(qs(el->fileName), qs(el->importId), loc(el->importToken), loc(el->fileNameToken), loc(el->asToken), loc(el->importIdToken), loc(el->semicolonToken)));
+ return true;
+}
+
+bool AstDumper::visit(UiPublicMember *el) {
+ QString typeStr = ((el->type == UiPublicMember::Signal) ? QLatin1String("Signal") :
+ (el->type == UiPublicMember::Property) ? QLatin1String("Property") : QLatin1String("Unexpected(%1)").arg(el->type));
+ start(QLatin1String("UiPublicMember type=%1 typeModifier=%2 name=%3 isDefaultMember=%4 isReadonlyMember=%5 isRequired=%6 "
+ "defaultToken=%7 readonlyToken=%8 propertyToken=%9 requiredToken=%10 typeModifierToken=%11 typeToken=%12 "
+ "identifierToken=%13 colonToken=%14 semicolonToken=%15")
+ .arg(qs(typeStr), qs(el->typeModifier), qs(el->name),
+ el->isDefaultMember, el->isReadonlyMember, el->isRequired,
+ loc(el->defaultToken), loc(el->readonlyToken), loc(el->propertyToken),
+ loc(el->requiredToken), loc(el->typeModifierToken), loc(el->typeToken),
+ loc(el->identifierToken), loc(el->colonToken), loc(el->semicolonToken)
+ ));
+ if (!noAnnotations()) // put annotations inside the node they refer to
+ Node::accept(el->annotations, this);
+ Node::accept(el->memberType, this);
+ return true;
+}
+
+bool AstDumper::visit(AST::UiSourceElement *el) {
+ start(QLatin1String("UiSourceElement"));
+ if (!noAnnotations()) // put annotations inside the node they refer to
+ Node::accept(el->annotations, this);
+ return true;
+}
+
+bool AstDumper::visit(AST::UiObjectDefinition *el) {
+ start("UiObjectDefinition");
+ if (!noAnnotations()) // put annotations inside the node they refer to
+ Node::accept(el->annotations, this);
+ return true;
+}
+
+bool AstDumper::visit(AST::UiObjectInitializer *el) {
+ start(QLatin1String("UiObjectInitializer lbraceToken=%1 rbraceToken=%2")
+ .arg(loc(el->lbraceToken), loc(el->rbraceToken)));
+ return true;
+}
+
+bool AstDumper::visit(AST::UiObjectBinding *el) {
+ start(QLatin1String("UiObjectBinding colonToken=%1 hasOnToken=%2")
+ .arg(loc(el->colonToken), boolStr(el->hasOnToken)));
+ if (!noAnnotations()) // put annotations inside the node they refer to
+ Node::accept(el->annotations, this);
+ return true;
+}
+
+bool AstDumper::visit(AST::UiScriptBinding *el) {
+ start(QLatin1String("UiScriptBinding colonToken=%1")
+ .arg(loc(el->colonToken)));
+ if (!noAnnotations()) // put annotations inside the node they refer to
+ Node::accept(el->annotations, this);
+ return true;
+}
+
+bool AstDumper::visit(AST::UiArrayBinding *el) {
+ start(QLatin1String("UiArrayBinding colonToken=%1 lbracketToken=%2 rbracketToken=%3")
+ .arg(loc(el->colonToken), loc(el->lbracketToken), loc(el->rbracketToken)));
+ if (!noAnnotations()) // put annotations inside the node they refer to
+ Node::accept(el->annotations, this);
+ return true;
+}
+
+bool AstDumper::visit(AST::UiParameterList *el) {
+ start(QLatin1String("UiArrayBinding name=%1 commaToken=%2 propertyTypeToken=%3 identifierToken=%4 colonToken=%5")
+ .arg(qs(el->name), loc(el->commaToken), loc(el->propertyTypeToken), loc(el->identifierToken), loc(el->colonToken)));
+ Node::accept(el->type, this);
+ return true;
+}
+
+bool AstDumper::visit(AST::UiObjectMemberList *) { start("UiObjectMemberList"); return true; }
+
+bool AstDumper::visit(AST::UiArrayMemberList *el) {
+ start(QLatin1String("UiArrayMemberList commaToken=%1")
+ .arg(loc(el->commaToken)));
+ return true;
+}
+
+bool AstDumper::visit(AST::UiQualifiedId *el) {
+ start(QLatin1String("UiQualifiedId name=%1 identifierToken=%2")
+ .arg(qs(el->name), loc(el->identifierToken)));
+ Node::accept(el->next, this);
+ return true;
+}
+
+bool AstDumper::visit(AST::UiEnumDeclaration *el) {
+ start(QLatin1String("UiEnumDeclaration enumToken=%1 rbraceToken=%2 name=%3")
+ .arg(loc(el->enumToken), loc(el->rbraceToken), qs(el->name)));
+ if (!noAnnotations()) // put annotations inside the node they refer to
+ Node::accept(el->annotations, this);
+ return true;
+}
+
+bool AstDumper::visit(AST::UiEnumMemberList *el) {
+ start(QLatin1String("UiEnumMemberList member=%1 value=%2 memberToken=%3 valueToken=%4")
+ .arg(qs(el->member), qs(QString::number(el->value)), loc(el->memberToken), loc(el->valueToken)));
+ return true;
+}
+
+bool AstDumper::visit(AST::UiVersionSpecifier *el) {
+ start(QLatin1String("UiVersionSpecifier majorVersion=%1 minorVersion=%2 majorToken=%3 minorToken=%4")
+ .arg(qs(QString::number(el->version.majorVersion())),
+ qs(QString::number(el->version.minorVersion())),
+ loc(el->majorToken), loc(el->minorToken)));
+ return true;
+}
+
+bool AstDumper::visit(AST::UiInlineComponent *el) {
+ start(QLatin1String("UiInlineComponent name=%1 componentToken=%2")
+ .arg(qs(el->name), loc(el->componentToken)));
+ if (!noAnnotations()) // put annotations inside the node they refer to
+ Node::accept(el->annotations, this);
+ return true;
+}
+
+bool AstDumper::visit(UiRequired *el)
+{
+ start(QLatin1String("UiRequired name=%1 requiredToken=%2 semicolonToken=%3")
+ .arg(qs(el->name), loc(el->requiredToken), loc(el->semicolonToken)));
+ return true;
+}
+
+bool AstDumper::visit(UiAnnotation *)
+{
+ start(QLatin1String("UiAnnotation"));
+ return true;
+}
+
+bool AstDumper::visit(UiAnnotationList *)
+{
+ start(QLatin1String("UiAnnotationList"));
+ return true;
+}
+
+void AstDumper::endVisit(AST::UiProgram *) { stop("UiProgram"); }
+
+void AstDumper::endVisit(AST::UiImport *el) {
+ Node::accept(el->version, this);
+ stop("UiImport");
+}
+
+void AstDumper::endVisit(AST::UiHeaderItemList *) { stop("UiHeaderItemList"); }
+
+void AstDumper::endVisit(AST::UiPragma *) { stop("UiPragma"); }
+
+void AstDumper::endVisit(AST::UiPublicMember *el) {
+ Node::accept(el->parameters, this);
+ stop("UiPublicMember");
+}
+
+void AstDumper::endVisit(AST::UiSourceElement *) { stop("UiSourceElement"); }
+void AstDumper::endVisit(AST::UiObjectDefinition *) { stop("UiObjectDefinition"); }
+void AstDumper::endVisit(AST::UiObjectInitializer *) { stop("UiObjectInitializer"); }
+void AstDumper::endVisit(AST::UiObjectBinding *) { stop("UiObjectBinding"); }
+void AstDumper::endVisit(AST::UiScriptBinding *) { stop("UiScriptBinding"); }
+void AstDumper::endVisit(AST::UiArrayBinding *) { stop("UiArrayBinding"); }
+void AstDumper::endVisit(AST::UiParameterList *el) {
+ stop("UiParameterList");
+ Node::accept(el->next, this); // put other args at the same level as this one...
+}
+void AstDumper::endVisit(AST::UiObjectMemberList *) { stop("UiObjectMemberList"); }
+void AstDumper::endVisit(AST::UiArrayMemberList *) { stop("UiArrayMemberList"); }
+void AstDumper::endVisit(AST::UiQualifiedId *) { stop("UiQualifiedId"); }
+void AstDumper::endVisit(AST::UiEnumDeclaration *) { stop("UiEnumDeclaration"); }
+void AstDumper::endVisit(AST::UiEnumMemberList *el) {
+ stop("UiEnumMemberList");
+ Node::accept(el->next, this); // put other enum members at the same level as this one...
+}
+void AstDumper::endVisit(AST::UiVersionSpecifier *) { stop("UiVersionSpecifier"); }
+void AstDumper::endVisit(AST::UiInlineComponent *) { stop("UiInlineComponent"); }
+void AstDumper::endVisit(UiRequired *) { stop("UiRequired"); }
+void AstDumper::endVisit(UiAnnotation *) { stop("UiAnnotation"); }
+void AstDumper::endVisit(UiAnnotationList *) { stop("UiAnnotationList"); }
+
+// QQmlJS
+bool AstDumper::visit(AST::ThisExpression *el) {
+ start(QLatin1String("ThisExpression thisToken=%1")
+ .arg(loc(el->thisToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ThisExpression *) { stop("ThisExpression"); }
+
+bool AstDumper::visit(AST::IdentifierExpression *el) {
+ start(QLatin1String("IdentifierExpression name=%1 identiferToken=%2")
+ .arg(qs(el->name), loc(el->identifierToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::IdentifierExpression *) { stop("IdentifierExpression"); }
+
+bool AstDumper::visit(AST::NullExpression *el) {
+ start(QLatin1String("NullExpression nullToken=%1")
+ .arg(loc(el->nullToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::NullExpression *) { stop("NullExpression"); }
+
+bool AstDumper::visit(AST::TrueLiteral *el) {
+ start(QLatin1String("TrueLiteral trueToken=%1")
+ .arg(loc(el->trueToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::TrueLiteral *) { stop("TrueLiteral"); }
+
+bool AstDumper::visit(AST::FalseLiteral *el) {
+ start(QLatin1String("FalseLiteral falseToken=%1")
+ .arg(loc(el->falseToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::FalseLiteral *) { stop("FalseLiteral"); }
+
+bool AstDumper::visit(AST::SuperLiteral *el) {
+ start(QLatin1String("SuperLiteral superToken=%1")
+ .arg(loc(el->superToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::SuperLiteral *) { stop("SuperLiteral"); }
+
+bool AstDumper::visit(AST::StringLiteral *el) {
+ start(QLatin1String("StringLiteral value=%1 literalToken=%2")
+ .arg(qs(el->value), loc(el->literalToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::StringLiteral *) { stop("StringLiteral"); }
+
+bool AstDumper::visit(AST::TemplateLiteral *el) {
+ start(QLatin1String("TemplateLiteral value=%1 rawValue=%2 literalToken=%3")
+ .arg(qs(el->value), qs(el->rawValue), loc(el->literalToken)));
+ Node::accept(el->expression, this);
+ return true;
+}
+void AstDumper::endVisit(AST::TemplateLiteral *) { stop("TemplateLiteral"); }
+
+bool AstDumper::visit(AST::NumericLiteral *el) {
+ start(QLatin1String("NumericLiteral value=%1 literalToken=%2")
+ .arg(qs(QString::number(el->value)), loc(el->literalToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::NumericLiteral *) { stop("NumericLiteral"); }
+
+bool AstDumper::visit(AST::RegExpLiteral *el) {
+ start(QLatin1String("RegExpLiteral pattern=%1 flags=%2 literalToken=%3")
+ .arg(qs(el->pattern), qs(QString::number(el->flags, 16)), loc(el->literalToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::RegExpLiteral *) { stop("RegExpLiteral"); }
+
+bool AstDumper::visit(AST::ArrayPattern *el) {
+ start(QLatin1String("ArrayPattern lbracketToken=%1, commaToken=%2, rbracketToken=%3 parseMode=%4")
+ .arg(loc(el->lbracketToken),loc(el->commaToken),loc(el->rbracketToken), qs(QString::number(el->parseMode, 16))));
+ return true;
+}
+void AstDumper::endVisit(AST::ArrayPattern *) { stop("ArrayPattern"); }
+
+bool AstDumper::visit(AST::ObjectPattern *el) {
+ start(QLatin1String("ObjectPattern lbraceToken=%1 rbraceToken=%2 parseMode=%3")
+ .arg(loc(el->lbraceToken), loc(el->rbraceToken), qs(QString::number(el->parseMode, 16))));
+ return true;
+}
+void AstDumper::endVisit(AST::ObjectPattern *) { stop("ObjectPattern"); }
+
+bool AstDumper::visit(AST::PatternElementList *) { start("PatternElementList"); return true; }
+void AstDumper::endVisit(AST::PatternElementList *) { stop("PatternElementList"); }
+
+bool AstDumper::visit(AST::PatternPropertyList *) { start("PatternPropertyList"); return true; }
+void AstDumper::endVisit(AST::PatternPropertyList *) { stop("PatternPropertyList"); }
+
+bool AstDumper::visit(AST::PatternElement *el) {
+ start(QLatin1String("PatternElement identifierToken=%1 bindingIdentifier=%2 type=%3 scope=%4 isForDeclaration=%5")
+ .arg(loc(el->identifierToken), qs(el->bindingIdentifier), qs(QString::number(el->type, 16)),
+ qs(QString::number(static_cast<int>(el->scope), 16)), boolStr(el->isForDeclaration)));
+ return true;
+}
+void AstDumper::endVisit(AST::PatternElement *) { stop("PatternElement"); }
+
+bool AstDumper::visit(AST::PatternProperty *el) {
+ start(QLatin1String("PatternProperty identifierToken=%1 bindingIdentifier=%2 type=%3 scope=%4 isForDeclaration=%5 colonToken=%6")
+ .arg(loc(el->identifierToken), qs(el->bindingIdentifier), qs(QString::number(el->type, 16)),
+ qs(QString::number(static_cast<int>(el->scope), 16)), boolStr(el->isForDeclaration), loc(el->colonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::PatternProperty *) { stop("PatternProperty"); }
+
+bool AstDumper::visit(AST::Elision *el) {
+ start(QLatin1String("Elision commaToken=%1")
+ .arg(loc(el->commaToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::Elision *el) {
+ stop("Elision");
+ Node::accept(el->next, this); // emit other elisions at the same level
+}
+
+bool AstDumper::visit(AST::NestedExpression *el) {
+ start(QLatin1String("NestedExpression lparenToken=%1 rparenToken=%2")
+ .arg(loc(el->lparenToken), loc(el->rparenToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::NestedExpression *) { stop("NestedExpression"); }
+
+bool AstDumper::visit(AST::IdentifierPropertyName *el) {
+ start(QLatin1String("IdentifierPropertyName id=%1 propertyNameToken=%2")
+ .arg(qs(el->id), loc(el->propertyNameToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::IdentifierPropertyName *) { stop("IdentifierPropertyName"); }
+
+bool AstDumper::visit(AST::StringLiteralPropertyName *el) {
+ start(QLatin1String("StringLiteralPropertyName id=%1 propertyNameToken=%2")
+ .arg(qs(el->id), loc(el->propertyNameToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::StringLiteralPropertyName *) { stop("StringLiteralPropertyName"); }
+
+bool AstDumper::visit(AST::NumericLiteralPropertyName *el) {
+ start(QLatin1String("NumericLiteralPropertyName id=%1 propertyNameToken=%2")
+ .arg(qs(QString::number(el->id)),loc(el->propertyNameToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::NumericLiteralPropertyName *) { stop("NumericLiteralPropertyName"); }
+
+bool AstDumper::visit(AST::ComputedPropertyName *) {
+ start(QLatin1String("ComputedPropertyName"));
+ return true;
+}
+void AstDumper::endVisit(AST::ComputedPropertyName *) { stop("ComputedPropertyName"); }
+
+bool AstDumper::visit(AST::ArrayMemberExpression *el) {
+ start(QLatin1String("ArrayMemberExpression lbraketToken=%1 rbraketToken=%2")
+ .arg(loc(el->lbracketToken), loc(el->rbracketToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ArrayMemberExpression *) { stop("ArrayMemberExpression"); }
+
+bool AstDumper::visit(AST::FieldMemberExpression *el) {
+ start(QLatin1String("FieldMemberExpression name=%1 dotToken=%2 identifierToken=%3")
+ .arg(qs(el->name), loc(el->dotToken), loc(el->identifierToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::FieldMemberExpression *) { stop("FieldMemberExpression"); }
+
+bool AstDumper::visit(AST::TaggedTemplate *) {
+ start(QLatin1String("TaggedTemplate"));
+ return true;
+}
+void AstDumper::endVisit(AST::TaggedTemplate *) { stop("TaggedTemplate"); }
+
+bool AstDumper::visit(AST::NewMemberExpression *el) {
+ start(QLatin1String("NewMemberExpression newToken=%1 lparenToken=%2 rparenToken=%3")
+ .arg(loc(el->newToken), loc(el->lparenToken), loc(el->rparenToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::NewMemberExpression *) { stop("NewMemberExpression"); }
+
+bool AstDumper::visit(AST::NewExpression *el) {
+ start(QLatin1String("NewExpression newToken=%1")
+ .arg(loc(el->newToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::NewExpression *) { stop("NewExpression"); }
+
+bool AstDumper::visit(AST::CallExpression *el) {
+ start(QLatin1String("CallExpression lparenToken=%1 rparenToken=%2")
+ .arg(loc(el->lparenToken), loc(el->rparenToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::CallExpression *) { stop("CallExpression"); }
+
+bool AstDumper::visit(AST::ArgumentList *el) {
+ start(QLatin1String("ArgumentList commaToken=%1 isSpreadElement=%2")
+ .arg(loc(el->commaToken), boolStr(el->isSpreadElement)));
+ return true;
+}
+void AstDumper::endVisit(AST::ArgumentList *) { stop("ArgumentList"); }
+
+bool AstDumper::visit(AST::PostIncrementExpression *el) {
+ start(QLatin1String("PostIncrementExpression incrementToken=%1")
+ .arg(loc(el->incrementToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::PostIncrementExpression *) { stop("PostIncrementExpression"); }
+
+bool AstDumper::visit(AST::PostDecrementExpression *el) {
+ start(QLatin1String("PostDecrementExpression decrementToken=%1")
+ .arg(loc(el->decrementToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::PostDecrementExpression *) { stop("PostDecrementExpression"); }
+
+bool AstDumper::visit(AST::DeleteExpression *el) {
+ start(QLatin1String("DeleteExpression deleteToken=%1")
+ .arg(loc(el->deleteToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::DeleteExpression *) { stop("DeleteExpression"); }
+
+bool AstDumper::visit(AST::VoidExpression *el) {
+ start(QLatin1String("VoidExpression voidToken=%1")
+ .arg(loc(el->voidToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::VoidExpression *) { stop("VoidExpression"); }
+
+bool AstDumper::visit(AST::TypeOfExpression *el) {
+ start(QLatin1String("TypeOfExpression typeofToken=%1")
+ .arg(loc(el->typeofToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::TypeOfExpression *) { stop("TypeOfExpression"); }
+
+bool AstDumper::visit(AST::PreIncrementExpression *el) {
+ start(QLatin1String("PreIncrementExpression incrementToken=%1")
+ .arg(loc(el->incrementToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::PreIncrementExpression *) { stop("PreIncrementExpression"); }
+
+bool AstDumper::visit(AST::PreDecrementExpression *el) {
+ start(QLatin1String("PreDecrementExpression decrementToken=%1")
+ .arg(loc(el->decrementToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::PreDecrementExpression *) { stop("PreDecrementExpression"); }
+
+bool AstDumper::visit(AST::UnaryPlusExpression *el) {
+ start(QLatin1String("UnaryPlusExpression plusToken=%1")
+ .arg(loc(el->plusToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::UnaryPlusExpression *) { stop("UnaryPlusExpression"); }
+
+bool AstDumper::visit(AST::UnaryMinusExpression *el) {
+ start(QLatin1String("UnaryMinusExpression minusToken=%1")
+ .arg(loc(el->minusToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::UnaryMinusExpression *) { stop("UnaryMinusExpression"); }
+
+bool AstDumper::visit(AST::TildeExpression *el) {
+ start(QLatin1String("TildeExpression tildeToken=%1")
+ .arg(loc(el->tildeToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::TildeExpression *) { stop("TildeExpression"); }
+
+bool AstDumper::visit(AST::NotExpression *el) {
+ start(QLatin1String("NotExpression notToken=%1")
+ .arg(loc(el->notToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::NotExpression *) { stop("NotExpression"); }
+
+bool AstDumper::visit(AST::BinaryExpression *el) {
+ start(QLatin1String("BinaryExpression op=%1 operatorToken=%2")
+ .arg(qs(QString::number(el->op,16)), loc(el->operatorToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::BinaryExpression *) { stop("BinaryExpression"); }
+
+bool AstDumper::visit(AST::ConditionalExpression *el) {
+ start(QLatin1String("ConditionalExpression questionToken=%1 colonToken=%2")
+ .arg(loc(el->questionToken), loc(el->colonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ConditionalExpression *) { stop("ConditionalExpression"); }
+
+bool AstDumper::visit(AST::Expression *el) {
+ start(QLatin1String("Expression commaToken=%1")
+ .arg(loc(el->commaToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::Expression *) { stop("Expression"); }
+
+bool AstDumper::visit(AST::Block *el) {
+ start(QLatin1String("Block lbraceToken=%1 rbraceToken=%2")
+ .arg(loc(el->lbraceToken), loc(el->rbraceToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::Block *) { stop("Block"); }
+
+bool AstDumper::visit(AST::StatementList *) {
+ start(QLatin1String("StatementList"));
+ return true;
+}
+void AstDumper::endVisit(AST::StatementList *) { stop("StatementList"); }
+
+bool AstDumper::visit(AST::VariableStatement *el) {
+ start(QLatin1String("VariableStatement declarationKindToken=%1")
+ .arg(loc(el->declarationKindToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::VariableStatement *) { stop("VariableStatement"); }
+
+bool AstDumper::visit(AST::VariableDeclarationList *el) {
+ start(QLatin1String("VariableDeclarationList commaToken=%1")
+ .arg(loc(el->commaToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::VariableDeclarationList *) { stop("VariableDeclarationList"); }
+
+bool AstDumper::visit(AST::EmptyStatement *el) {
+ start(QLatin1String("EmptyStatement semicolonToken=%1")
+ .arg(loc(el->semicolonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::EmptyStatement *) { stop("EmptyStatement"); }
+
+bool AstDumper::visit(AST::ExpressionStatement *el) {
+ start(QLatin1String("ExpressionStatement semicolonToken=%1")
+ .arg(loc(el->semicolonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ExpressionStatement *) { stop("ExpressionStatement"); }
+
+bool AstDumper::visit(AST::IfStatement *el) {
+ start(QLatin1String("IfStatement ifToken=%1 lparenToken=%2 rparenToken=%3 elseToken=%4")
+ .arg(loc(el->ifToken), loc(el->lparenToken), loc(el->rparenToken), loc(el->elseToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::IfStatement *) { stop("IfStatement"); }
+
+bool AstDumper::visit(AST::DoWhileStatement *el) {
+ start(QLatin1String("DoWhileStatement doToken=%1 whileToken=%2 lparenToken=%3 rparenToken=%4 semicolonToken=%5")
+ .arg(loc(el->doToken), loc(el->whileToken), loc(el->lparenToken), loc(el->rparenToken), loc(el->semicolonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::DoWhileStatement *) { stop("DoWhileStatement"); }
+
+bool AstDumper::visit(AST::WhileStatement *el) {
+ start(QLatin1String("WhileStatement whileToken=%1 lparenToken=%2 rparenToken=%3")
+ .arg(loc(el->whileToken), loc(el->lparenToken), loc(el->rparenToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::WhileStatement *) { stop("WhileStatement"); }
+
+bool AstDumper::visit(AST::ForStatement *el) {
+ start(QLatin1String("ForStatement forToken=%1 lparenToken=%2 firstSemicolonToken=%3 secondSemicolonToken=%4 rparenToken=%5")
+ .arg(loc(el->forToken), loc(el->lparenToken), loc(el->firstSemicolonToken), loc(el->secondSemicolonToken), loc(el->rparenToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ForStatement *) { stop("ForStatement"); }
+
+bool AstDumper::visit(AST::ForEachStatement *el) {
+ start(QLatin1String("ForEachStatement forToken=%1 lparenToken=%2 inOfToken=%3 rparenToken=%4 type=%5")
+ .arg(loc(el->forToken), loc(el->lparenToken), loc(el->inOfToken), loc(el->rparenToken), qs(QString::number(static_cast<int>(el->type), 16))));
+ return true;
+}
+void AstDumper::endVisit(AST::ForEachStatement *) { stop("ForEachStatement"); }
+
+bool AstDumper::visit(AST::ContinueStatement *el) {
+ start(QLatin1String("ContinueStatement label=%1 continueToken=%2 identifierToken=%3 semicolonToken=%4")
+ .arg(qs(el->label), loc(el->continueToken), loc(el->identifierToken), loc(el->semicolonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ContinueStatement *) { stop("ContinueStatement"); }
+
+bool AstDumper::visit(AST::BreakStatement *el) {
+ start(QLatin1String("BreakStatement label=%1 breakToken=%2 identifierToken=%3 semicolonToken=%4")
+ .arg(qs(el->label), loc(el->breakToken), loc(el->identifierToken), loc(el->semicolonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::BreakStatement *) { stop("BreakStatement"); }
+
+bool AstDumper::visit(AST::ReturnStatement *el) {
+ start(QLatin1String("ReturnStatement returnToken=%1 semicolonToken=%2")
+ .arg(loc(el->returnToken), loc(el->semicolonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ReturnStatement *) { stop("ReturnStatement"); }
+
+bool AstDumper::visit(AST::YieldExpression *el) {
+ start(QLatin1String("YieldExpression isYieldStar=%1 yieldToken=%2")
+ .arg(boolStr(el->isYieldStar), loc(el->yieldToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::YieldExpression *) { stop("YieldExpression"); }
+
+bool AstDumper::visit(AST::WithStatement *el) {
+ start(QLatin1String("WithStatement withToken=%1 lparenToken=%2 rparenToken=%3")
+ .arg(loc(el->withToken), loc(el->lparenToken), loc(el->rparenToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::WithStatement *) { stop("WithStatement"); }
+
+bool AstDumper::visit(AST::SwitchStatement *el) {
+ start(QLatin1String("SwitchStatement switchToken=%1 lparenToken=%2 rparenToken=%3")
+ .arg(loc(el->switchToken), loc(el->lparenToken), loc(el->rparenToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::SwitchStatement *) { stop("SwitchStatement"); }
+
+bool AstDumper::visit(AST::CaseBlock *el) {
+ start(QLatin1String("CaseBlock lbraceToken=%1 rbraceToken=%2")
+ .arg(loc(el->lbraceToken), loc(el->rbraceToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::CaseBlock *) { stop("CaseBlock"); }
+
+bool AstDumper::visit(AST::CaseClauses *) {
+ start(QLatin1String("CaseClauses"));
+ return true;
+}
+void AstDumper::endVisit(AST::CaseClauses *) { stop("CaseClauses"); }
+
+bool AstDumper::visit(AST::CaseClause *el) {
+ start(QLatin1String("CaseClause caseToken=%1 colonToken=%2")
+ .arg(loc(el->caseToken), loc(el->colonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::CaseClause *) { stop("CaseClause"); }
+
+bool AstDumper::visit(AST::DefaultClause *el) {
+ start(QLatin1String("DefaultClause defaultToken=%1 colonToken=%2")
+ .arg(loc(el->defaultToken), loc(el->colonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::DefaultClause *) { stop("DefaultClause"); }
+
+bool AstDumper::visit(AST::LabelledStatement *el) {
+ start(QLatin1String("LabelledStatement label=%1 identifierToken=%2 colonToken=%3")
+ .arg(qs(el->label), loc(el->identifierToken), loc(el->colonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::LabelledStatement *) { stop("LabelledStatement"); }
+
+bool AstDumper::visit(AST::ThrowStatement *el) {
+ start(QLatin1String("ThrowStatement throwToken=%1 semicolonToken=%2")
+ .arg(loc(el->throwToken), loc(el->semicolonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ThrowStatement *) { stop("ThrowStatement"); }
+
+bool AstDumper::visit(AST::TryStatement *el) {
+ start(QLatin1String("TryStatement tryToken=%1")
+ .arg(loc(el->tryToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::TryStatement *) { stop("TryStatement"); }
+
+bool AstDumper::visit(AST::Catch *el) {
+ start(QLatin1String("Catch catchToken=%1 lparenToken=%2 identifierToken=%3 rparenToken=%4")
+ .arg(loc(el->catchToken), loc(el->lparenToken), loc(el->identifierToken), loc(el->rparenToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::Catch *) { stop("Catch"); }
+
+bool AstDumper::visit(AST::Finally *el) {
+ start(QLatin1String("Finally finallyToken=%1")
+ .arg(loc(el->finallyToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::Finally *) { stop("Finally"); }
+
+bool AstDumper::visit(AST::FunctionDeclaration *el) {
+ start(QLatin1String("FunctionDeclaration name=%1 isArrowFunction=%2 isGenerator=%3 functionToken=%4 "
+ "identifierToken=%5 lparenToken=%6 rparenToken=%7 lbraceToken=%8 rbraceToken=%9")
+ .arg(qs(el->name), boolStr(el->isArrowFunction), boolStr(el->isGenerator), loc(el->functionToken),
+ loc(el->identifierToken), loc(el->lparenToken), loc(el->rparenToken), loc(el->lbraceToken),
+ loc(el->rbraceToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::FunctionDeclaration *) { stop("FunctionDeclaration"); }
+
+bool AstDumper::visit(AST::FunctionExpression *el) {
+ start(QLatin1String("FunctionExpression name=%1 isArrowFunction=%2 isGenerator=%3 functionToken=%4 "
+ "identifierToken=%5 lparenToken=%6 rparenToken=%7 lbraceToken=%8 rbraceToken=%9")
+ .arg(qs(el->name), boolStr(el->isArrowFunction), boolStr(el->isGenerator), loc(el->functionToken),
+ loc(el->identifierToken), loc(el->lparenToken), loc(el->rparenToken), loc(el->lbraceToken),
+ loc(el->rbraceToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::FunctionExpression *) { stop("FunctionExpression"); }
+
+bool AstDumper::visit(AST::FormalParameterList *) {
+ start(QLatin1String("FormalParameterList"));
+ return true;
+}
+void AstDumper::endVisit(AST::FormalParameterList *) { stop("FormalParameterList"); }
+
+bool AstDumper::visit(AST::ClassExpression *el) {
+ start(QLatin1String("ClassExpression name=%1 classToken=%2 identifierToken=%3 lbraceToken=%4 rbraceToken=%5")
+ .arg(qs(el->name), loc(el->classToken), loc(el->identifierToken), loc(el->lbraceToken), loc(el->rbraceToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ClassExpression *) { stop("ClassExpression"); }
+
+bool AstDumper::visit(AST::ClassDeclaration *el) {
+ start(QLatin1String("ClassDeclaration name=%1 classToken=%2 identifierToken=%3 lbraceToken=%4 rbraceToken=%5")
+ .arg(qs(el->name), loc(el->classToken), loc(el->identifierToken), loc(el->lbraceToken), loc(el->rbraceToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ClassDeclaration *) { stop("ClassDeclaration"); }
+
+bool AstDumper::visit(AST::ClassElementList *el) {
+ start(QLatin1String("ClassElementList isStatic=%1")
+ .arg(boolStr(el->isStatic)));
+ return true;
+}
+void AstDumper::endVisit(AST::ClassElementList *) { stop("ClassElementList"); }
+
+bool AstDumper::visit(AST::Program *) {
+ start(QLatin1String("Program"));
+ return true;
+}
+void AstDumper::endVisit(AST::Program *) { stop("Program"); }
+
+bool AstDumper::visit(AST::NameSpaceImport *el) {
+ start(QLatin1String("NameSpaceImport starToken=%1 importedBindingToken=%2 importedBinding=%3")
+ .arg(loc(el->starToken), loc(el->importedBindingToken), qs(el->importedBinding)));
+ return true;
+}
+void AstDumper::endVisit(AST::NameSpaceImport *) { stop("NameSpaceImport"); }
+
+bool AstDumper::visit(AST::ImportSpecifier *el) {
+ start(QLatin1String("ImportSpecifier identifierToken=%1 importedBindingToken=%2 identifier=%3 importedBinding=%4")
+ .arg(loc(el->identifierToken), loc(el->importedBindingToken), qs(el->identifier), qs(el->importedBinding)));
+ return true;
+}
+void AstDumper::endVisit(AST::ImportSpecifier *) { stop("ImportSpecifier"); }
+
+bool AstDumper::visit(AST::ImportsList *el) {
+ start(QLatin1String("ImportsList importSpecifierToken=%1")
+ .arg(loc(el->importSpecifierToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ImportsList *) { stop("ImportsList"); }
+
+bool AstDumper::visit(AST::NamedImports *el) {
+ start(QLatin1String("NamedImports leftBraceToken=%1 rightBraceToken=%2")
+ .arg(loc(el->leftBraceToken), loc(el->rightBraceToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::NamedImports *) { stop("NamedImports"); }
+
+bool AstDumper::visit(AST::FromClause *el) {
+ start(QLatin1String("FromClause fromToken=%1 moduleSpecifierToken=%2 moduleSpecifier=%3")
+ .arg(loc(el->fromToken), loc(el->moduleSpecifierToken), qs(el->moduleSpecifier)));
+ return true;
+}
+void AstDumper::endVisit(AST::FromClause *) { stop("FromClause"); }
+
+bool AstDumper::visit(AST::ImportClause *el) {
+ start(QLatin1String("ImportClause importedDefaultBindingToken=%1 importedDefaultBinding=%2")
+ .arg(loc(el->importedDefaultBindingToken), qs(el->importedDefaultBinding)));
+ return true;
+}
+void AstDumper::endVisit(AST::ImportClause *) { stop("ImportClause"); }
+
+bool AstDumper::visit(AST::ImportDeclaration *el) {
+ start(QLatin1String("ImportDeclaration importToken=%1 moduleSpecifierToken=%2 moduleSpecifier=%3")
+ .arg(loc(el->importToken), loc(el->moduleSpecifierToken), qs(el->moduleSpecifier)));
+ return true;
+}
+void AstDumper::endVisit(AST::ImportDeclaration *) { stop("ImportDeclaration"); }
+
+bool AstDumper::visit(AST::ExportSpecifier *el) {
+ start(QLatin1String("ExportSpecifier identifierToken=%1 exportedIdentifierToken=%2 identifier=%3 exportedIdentifier=%4")
+ .arg(loc(el->identifierToken), loc(el->exportedIdentifierToken), qs(el->identifier), qs(el->exportedIdentifier)));
+ return true;
+}
+void AstDumper::endVisit(AST::ExportSpecifier *) { stop("ExportSpecifier"); }
+
+bool AstDumper::visit(AST::ExportsList *) {
+ start(QLatin1String("ExportsList"));
+ return true;
+}
+void AstDumper::endVisit(AST::ExportsList *) { stop("ExportsList"); }
+
+bool AstDumper::visit(AST::ExportClause *el) {
+ start(QLatin1String("ExportClause leftBraceToken=%1 rightBraceToken=%2")
+ .arg(loc(el->leftBraceToken), loc(el->rightBraceToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::ExportClause *) { stop("ExportClause"); }
+
+bool AstDumper::visit(AST::ExportDeclaration *el) {
+ start(QLatin1String("ExportDeclaration exportToken=%1 exportAll=%2 exportDefault=%3")
+ .arg(loc(el->exportToken), boolStr(el->exportAll), boolStr(el->exportDefault)));
+ return true;
+}
+void AstDumper::endVisit(AST::ExportDeclaration *) { stop("ExportDeclaration"); }
+
+bool AstDumper::visit(AST::ESModule *) {
+ start(QLatin1String("ESModule"));
+ return true;
+}
+void AstDumper::endVisit(AST::ESModule *) { stop("ESModule"); }
+
+bool AstDumper::visit(AST::DebuggerStatement *el) {
+ start(QLatin1String("DebuggerStatement debuggerToken=%1 semicolonToken=%2")
+ .arg(loc(el->debuggerToken), loc(el->semicolonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::DebuggerStatement *) { stop("DebuggerStatement"); }
+
+bool AstDumper::visit(AST::Type *) {
+ start(QLatin1String("Type"));
+ return true;
+}
+void AstDumper::endVisit(AST::Type *) { stop("Type"); }
+
+bool AstDumper::visit(AST::TypeArgumentList *) {
+ start(QLatin1String("TypeArgumentList"));
+ return true;
+}
+void AstDumper::endVisit(AST::TypeArgumentList *) { stop("TypeArgumentList"); }
+
+bool AstDumper::visit(AST::TypeAnnotation *el) {
+ start(QLatin1String("TypeAnnotation colonToken=%1")
+ .arg(loc(el->colonToken)));
+ return true;
+}
+void AstDumper::endVisit(AST::TypeAnnotation *) { stop("TypeAnnotation"); }
+
+void AstDumper::throwRecursionDepthError()
+{
+ qDebug() << "Maximum statement or expression depth exceeded in AstDumper";
+}
+
+bool AstDumper::dumpNode() {
+ return options & DumperOptions::DumpNode;
+}
+
+bool AstDumper::noLocations() {
+ return options & DumperOptions::NoLocations;
+}
+
+bool AstDumper::noAnnotations() {
+ return options & DumperOptions::NoAnnotations;
+}
+
+} // end namespace QQmlJS
+
+QT_END_NAMESPACE
diff --git a/tests/auto/shared/qqmljsastdumper.h b/tests/auto/shared/qqmljsastdumper.h
new file mode 100644
index 0000000000..d8d19e351d
--- /dev/null
+++ b/tests/auto/shared/qqmljsastdumper.h
@@ -0,0 +1,446 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**/
+#ifndef ASTDUMPER_H
+#define ASTDUMPER_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qqmljsglobal_p.h>
+#include <private/qqmljsastvisitor_p.h>
+#include <QtCore/QString>
+#include <functional>
+#include <ostream>
+
+QT_BEGIN_NAMESPACE
+class QDebug;
+
+namespace QQmlJS {
+
+enum class DumperOptions {
+ None=0,
+ NoLocations=0x1,
+ NoAnnotations=0x2,
+ DumpNode=0x4
+};
+bool operator & (DumperOptions lhs, DumperOptions rhs);
+DumperOptions operator | (DumperOptions lhs, DumperOptions rhs);
+
+// no export, currently just a supporting file...
+class AstDumper: public AST::BaseVisitor
+{
+public:
+ static QString printNode2(AST::Node *);
+
+ static QString diff(AST::Node *n1, AST::Node *n2, int nContext=3, DumperOptions opt=DumperOptions::None, int indent=0);
+ static QString printNode(AST::Node *n, DumperOptions opt=DumperOptions::None, int indent=1, int baseIndent=0);
+
+ AstDumper(const std::function <void (const QString &)> &dumper, DumperOptions options=DumperOptions::None,
+ int indent=1, int baseIndent=0);
+
+ void start(const QString &str);
+ void start(const char *str);
+ void stop(const QString &str);
+ void stop(const char *str);
+
+ QString qs(const QString &s);
+ QString qs(const char *s);
+ QString qs(const QStringRef &s);
+
+ QString loc(const AST::SourceLocation &s);
+
+ QString boolStr(bool v);
+
+ bool preVisit(AST::Node *el) override;
+ void postVisit(AST::Node *el) override;
+
+ // Ui
+ bool visit(AST::UiProgram *el) override;
+ bool visit(AST::UiHeaderItemList *) override;
+ bool visit(AST::UiPragma *el) override;
+ bool visit(AST::UiImport *el) override;
+ bool visit(AST::UiPublicMember *el) override;
+ bool visit(AST::UiSourceElement *) override;
+ bool visit(AST::UiObjectDefinition *) override;
+ bool visit(AST::UiObjectInitializer *) override;
+ bool visit(AST::UiObjectBinding *) override;
+ bool visit(AST::UiScriptBinding *) override;
+ bool visit(AST::UiArrayBinding *) override;
+ bool visit(AST::UiParameterList *) override;
+ bool visit(AST::UiObjectMemberList *) override;
+ bool visit(AST::UiArrayMemberList *) override;
+ bool visit(AST::UiQualifiedId *) override;
+ bool visit(AST::UiEnumDeclaration *) override;
+ bool visit(AST::UiEnumMemberList *) override;
+ bool visit(AST::UiVersionSpecifier *) override;
+ bool visit(AST::UiInlineComponent *) override;
+ bool visit(AST::UiRequired *) override;
+ bool visit(AST::UiAnnotation *) override;
+ bool visit(AST::UiAnnotationList *) override;
+
+ void endVisit(AST::UiProgram *) override;
+ void endVisit(AST::UiImport *) override;
+ void endVisit(AST::UiHeaderItemList *) override;
+ void endVisit(AST::UiPragma *) override;
+ void endVisit(AST::UiPublicMember *) override;
+ void endVisit(AST::UiSourceElement *) override;
+ void endVisit(AST::UiObjectDefinition *) override;
+ void endVisit(AST::UiObjectInitializer *) override;
+ void endVisit(AST::UiObjectBinding *) override;
+ void endVisit(AST::UiScriptBinding *) override;
+ void endVisit(AST::UiArrayBinding *) override;
+ void endVisit(AST::UiParameterList *) override;
+ void endVisit(AST::UiObjectMemberList *) override;
+ void endVisit(AST::UiArrayMemberList *) override;
+ void endVisit(AST::UiQualifiedId *) override;
+ void endVisit(AST::UiEnumDeclaration *) override;
+ void endVisit(AST::UiEnumMemberList *) override;
+ void endVisit(AST::UiVersionSpecifier *) override;
+ void endVisit(AST::UiInlineComponent *) override;
+ void endVisit(AST::UiRequired *) override;
+ void endVisit(AST::UiAnnotation *) override;
+ void endVisit(AST::UiAnnotationList *) override;
+
+ // QQmlJS
+ bool visit(AST::ThisExpression *) override;
+ void endVisit(AST::ThisExpression *) override;
+
+ bool visit(AST::IdentifierExpression *) override;
+ void endVisit(AST::IdentifierExpression *) override;
+
+ bool visit(AST::NullExpression *) override;
+ void endVisit(AST::NullExpression *) override;
+
+ bool visit(AST::TrueLiteral *) override;
+ void endVisit(AST::TrueLiteral *) override;
+
+ bool visit(AST::FalseLiteral *) override;
+ void endVisit(AST::FalseLiteral *) override;
+
+ bool visit(AST::SuperLiteral *) override;
+ void endVisit(AST::SuperLiteral *) override;
+
+ bool visit(AST::StringLiteral *) override;
+ void endVisit(AST::StringLiteral *) override;
+
+ bool visit(AST::TemplateLiteral *) override;
+ void endVisit(AST::TemplateLiteral *) override;
+
+ bool visit(AST::NumericLiteral *) override;
+ void endVisit(AST::NumericLiteral *) override;
+
+ bool visit(AST::RegExpLiteral *) override;
+ void endVisit(AST::RegExpLiteral *) override;
+
+ bool visit(AST::ArrayPattern *) override;
+ void endVisit(AST::ArrayPattern *) override;
+
+ bool visit(AST::ObjectPattern *) override;
+ void endVisit(AST::ObjectPattern *) override;
+
+ bool visit(AST::PatternElementList *) override;
+ void endVisit(AST::PatternElementList *) override;
+
+ bool visit(AST::PatternPropertyList *) override;
+ void endVisit(AST::PatternPropertyList *) override;
+
+ bool visit(AST::PatternElement *) override;
+ void endVisit(AST::PatternElement *) override;
+
+ bool visit(AST::PatternProperty *) override;
+ void endVisit(AST::PatternProperty *) override;
+
+ bool visit(AST::Elision *) override;
+ void endVisit(AST::Elision *) override;
+
+ bool visit(AST::NestedExpression *) override;
+ void endVisit(AST::NestedExpression *) override;
+
+ bool visit(AST::IdentifierPropertyName *) override;
+ void endVisit(AST::IdentifierPropertyName *) override;
+
+ bool visit(AST::StringLiteralPropertyName *) override;
+ void endVisit(AST::StringLiteralPropertyName *) override;
+
+ bool visit(AST::NumericLiteralPropertyName *) override;
+ void endVisit(AST::NumericLiteralPropertyName *) override;
+
+ bool visit(AST::ComputedPropertyName *) override;
+ void endVisit(AST::ComputedPropertyName *) override;
+
+ bool visit(AST::ArrayMemberExpression *) override;
+ void endVisit(AST::ArrayMemberExpression *) override;
+
+ bool visit(AST::FieldMemberExpression *) override;
+ void endVisit(AST::FieldMemberExpression *) override;
+
+ bool visit(AST::TaggedTemplate *) override;
+ void endVisit(AST::TaggedTemplate *) override;
+
+ bool visit(AST::NewMemberExpression *) override;
+ void endVisit(AST::NewMemberExpression *) override;
+
+ bool visit(AST::NewExpression *) override;
+ void endVisit(AST::NewExpression *) override;
+
+ bool visit(AST::CallExpression *) override;
+ void endVisit(AST::CallExpression *) override;
+
+ bool visit(AST::ArgumentList *) override;
+ void endVisit(AST::ArgumentList *) override;
+
+ bool visit(AST::PostIncrementExpression *) override;
+ void endVisit(AST::PostIncrementExpression *) override;
+
+ bool visit(AST::PostDecrementExpression *) override;
+ void endVisit(AST::PostDecrementExpression *) override;
+
+ bool visit(AST::DeleteExpression *) override;
+ void endVisit(AST::DeleteExpression *) override;
+
+ bool visit(AST::VoidExpression *) override;
+ void endVisit(AST::VoidExpression *) override;
+
+ bool visit(AST::TypeOfExpression *) override;
+ void endVisit(AST::TypeOfExpression *) override;
+
+ bool visit(AST::PreIncrementExpression *) override;
+ void endVisit(AST::PreIncrementExpression *) override;
+
+ bool visit(AST::PreDecrementExpression *) override;
+ void endVisit(AST::PreDecrementExpression *) override;
+
+ bool visit(AST::UnaryPlusExpression *) override;
+ void endVisit(AST::UnaryPlusExpression *) override;
+
+ bool visit(AST::UnaryMinusExpression *) override;
+ void endVisit(AST::UnaryMinusExpression *) override;
+
+ bool visit(AST::TildeExpression *) override;
+ void endVisit(AST::TildeExpression *) override;
+
+ bool visit(AST::NotExpression *) override;
+ void endVisit(AST::NotExpression *) override;
+
+ bool visit(AST::BinaryExpression *) override;
+ void endVisit(AST::BinaryExpression *) override;
+
+ bool visit(AST::ConditionalExpression *) override;
+ void endVisit(AST::ConditionalExpression *) override;
+
+ bool visit(AST::Expression *) override;
+ void endVisit(AST::Expression *) override;
+
+ bool visit(AST::Block *) override;
+ void endVisit(AST::Block *) override;
+
+ bool visit(AST::StatementList *) override;
+ void endVisit(AST::StatementList *) override;
+
+ bool visit(AST::VariableStatement *) override;
+ void endVisit(AST::VariableStatement *) override;
+
+ bool visit(AST::VariableDeclarationList *) override;
+ void endVisit(AST::VariableDeclarationList *) override;
+
+ bool visit(AST::EmptyStatement *) override;
+ void endVisit(AST::EmptyStatement *) override;
+
+ bool visit(AST::ExpressionStatement *) override;
+ void endVisit(AST::ExpressionStatement *) override;
+
+ bool visit(AST::IfStatement *) override;
+ void endVisit(AST::IfStatement *) override;
+
+ bool visit(AST::DoWhileStatement *) override;
+ void endVisit(AST::DoWhileStatement *) override;
+
+ bool visit(AST::WhileStatement *) override;
+ void endVisit(AST::WhileStatement *) override;
+
+ bool visit(AST::ForStatement *) override;
+ void endVisit(AST::ForStatement *) override;
+
+ bool visit(AST::ForEachStatement *) override;
+ void endVisit(AST::ForEachStatement *) override;
+
+ bool visit(AST::ContinueStatement *) override;
+ void endVisit(AST::ContinueStatement *) override;
+
+ bool visit(AST::BreakStatement *) override;
+ void endVisit(AST::BreakStatement *) override;
+
+ bool visit(AST::ReturnStatement *) override;
+ void endVisit(AST::ReturnStatement *) override;
+
+ bool visit(AST::YieldExpression *) override;
+ void endVisit(AST::YieldExpression *) override;
+
+ bool visit(AST::WithStatement *) override;
+ void endVisit(AST::WithStatement *) override;
+
+ bool visit(AST::SwitchStatement *) override;
+ void endVisit(AST::SwitchStatement *) override;
+
+ bool visit(AST::CaseBlock *) override;
+ void endVisit(AST::CaseBlock *) override;
+
+ bool visit(AST::CaseClauses *) override;
+ void endVisit(AST::CaseClauses *) override;
+
+ bool visit(AST::CaseClause *) override;
+ void endVisit(AST::CaseClause *) override;
+
+ bool visit(AST::DefaultClause *) override;
+ void endVisit(AST::DefaultClause *) override;
+
+ bool visit(AST::LabelledStatement *) override;
+ void endVisit(AST::LabelledStatement *) override;
+
+ bool visit(AST::ThrowStatement *) override;
+ void endVisit(AST::ThrowStatement *) override;
+
+ bool visit(AST::TryStatement *) override;
+ void endVisit(AST::TryStatement *) override;
+
+ bool visit(AST::Catch *) override;
+ void endVisit(AST::Catch *) override;
+
+ bool visit(AST::Finally *) override;
+ void endVisit(AST::Finally *) override;
+
+ bool visit(AST::FunctionDeclaration *) override;
+ void endVisit(AST::FunctionDeclaration *) override;
+
+ bool visit(AST::FunctionExpression *) override;
+ void endVisit(AST::FunctionExpression *) override;
+
+ bool visit(AST::FormalParameterList *) override;
+ void endVisit(AST::FormalParameterList *) override;
+
+ bool visit(AST::ClassExpression *) override;
+ void endVisit(AST::ClassExpression *) override;
+
+ bool visit(AST::ClassDeclaration *) override;
+ void endVisit(AST::ClassDeclaration *) override;
+
+ bool visit(AST::ClassElementList *) override;
+ void endVisit(AST::ClassElementList *) override;
+
+ bool visit(AST::Program *) override;
+ void endVisit(AST::Program *) override;
+
+ bool visit(AST::NameSpaceImport *) override;
+ void endVisit(AST::NameSpaceImport *) override;
+
+ bool visit(AST::ImportSpecifier *) override;
+ void endVisit(AST::ImportSpecifier *) override;
+
+ bool visit(AST::ImportsList *) override;
+ void endVisit(AST::ImportsList *) override;
+
+ bool visit(AST::NamedImports *) override;
+ void endVisit(AST::NamedImports *) override;
+
+ bool visit(AST::FromClause *) override;
+ void endVisit(AST::FromClause *) override;
+
+ bool visit(AST::ImportClause *) override;
+ void endVisit(AST::ImportClause *) override;
+
+ bool visit(AST::ImportDeclaration *) override;
+ void endVisit(AST::ImportDeclaration *) override;
+
+ bool visit(AST::ExportSpecifier *) override;
+ void endVisit(AST::ExportSpecifier *) override;
+
+ bool visit(AST::ExportsList *) override;
+ void endVisit(AST::ExportsList *) override;
+
+ bool visit(AST::ExportClause *) override;
+ void endVisit(AST::ExportClause *) override;
+
+ bool visit(AST::ExportDeclaration *) override;
+ void endVisit(AST::ExportDeclaration *) override;
+
+ bool visit(AST::ESModule *) override;
+ void endVisit(AST::ESModule *) override;
+
+ bool visit(AST::DebuggerStatement *) override;
+ void endVisit(AST::DebuggerStatement *) override;
+
+ bool visit(AST::Type *) override;
+ void endVisit(AST::Type *) override;
+
+ bool visit(AST::TypeArgumentList *) override;
+ void endVisit(AST::TypeArgumentList *) override;
+
+ bool visit(AST::TypeAnnotation *) override;
+ void endVisit(AST::TypeAnnotation *) override;
+
+ void throwRecursionDepthError() override;
+
+private:
+ // attributes
+ std::function <void (const QString &)> dumper;
+ DumperOptions options = DumperOptions::None;
+ int indent = 0;
+ int baseIndent = 0;
+ bool dumpNode();
+ bool noLocations();
+ bool noAnnotations();
+};
+
+QDebug operator<<(QDebug d, AST::Node *n);
+
+std::ostream &operator<<(std::ostream &stream, AST::Node *n);
+
+} // namespace AST
+
+QT_END_NAMESPACE
+
+#endif // ASTDUMPER_H
diff --git a/tests/manual/pointer/main.qml b/tests/manual/pointer/main.qml
index d382d8b23d..83e1d3b2ba 100644
--- a/tests/manual/pointer/main.qml
+++ b/tests/manual/pointer/main.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the manual tests of the Qt Toolkit.
@@ -57,6 +57,7 @@ Window {
addExample("multibuttons", "TapHandler: gesturePolicy (99 red balloons)", Qt.resolvedUrl("multibuttons.qml"))
addExample("flickable with Handlers", "Flickable with buttons, sliders etc. implemented in various ways", Qt.resolvedUrl("flickableWithHandlers.qml"))
addExample("tap and drag", "Flickable with all possible combinations of TapHandler and DragHandler children", Qt.resolvedUrl("pointerDrag.qml"))
+ addExample("tablet canvas", "PointHandler and HoverHandler with a tablet: detect the stylus, and draw", Qt.resolvedUrl("tabletCanvasDrawing.qml"))
}
}
Item {
diff --git a/tests/manual/pointer/qml.qrc b/tests/manual/pointer/qml.qrc
index 95bece180a..20956fcbac 100644
--- a/tests/manual/pointer/qml.qrc
+++ b/tests/manual/pointer/qml.qrc
@@ -13,6 +13,7 @@
<file>pointerDrag.qml</file>
<file>singlePointHandlerProperties.qml</file>
<file>sidebar.qml</file>
+ <file>tabletCanvasDrawing.qml</file>
<file>tapHandler.qml</file>
<file>content/CheckBox.qml</file>
<file>content/FakeFlickable.qml</file>
@@ -30,6 +31,10 @@
<file>content/TouchpointFeedbackSprite.qml</file>
<file>resources/arrowhead.png</file>
<file>resources/balloon.png</file>
+ <file>resources/cursor-airbrush.png</file>
+ <file>resources/cursor-eraser.png</file>
+ <file>resources/cursor-felt-marker.png</file>
+ <file>resources/cursor-pencil.png</file>
<file>resources/fighter.png</file>
<file>resources/fingersprite.png</file>
<file>resources/grabbing-location.svg</file>
diff --git a/tests/manual/pointer/resources/cursor-airbrush.png b/tests/manual/pointer/resources/cursor-airbrush.png
new file mode 100644
index 0000000000..bea756ed6f
--- /dev/null
+++ b/tests/manual/pointer/resources/cursor-airbrush.png
Binary files differ
diff --git a/tests/manual/pointer/resources/cursor-eraser.png b/tests/manual/pointer/resources/cursor-eraser.png
new file mode 100644
index 0000000000..e5488a89f2
--- /dev/null
+++ b/tests/manual/pointer/resources/cursor-eraser.png
Binary files differ
diff --git a/tests/manual/pointer/resources/cursor-felt-marker.png b/tests/manual/pointer/resources/cursor-felt-marker.png
new file mode 100644
index 0000000000..132f09aa39
--- /dev/null
+++ b/tests/manual/pointer/resources/cursor-felt-marker.png
Binary files differ
diff --git a/tests/manual/pointer/resources/cursor-pencil.png b/tests/manual/pointer/resources/cursor-pencil.png
new file mode 100644
index 0000000000..cc2f447d02
--- /dev/null
+++ b/tests/manual/pointer/resources/cursor-pencil.png
Binary files differ
diff --git a/tests/manual/pointer/tabletCanvasDrawing.qml b/tests/manual/pointer/tabletCanvasDrawing.qml
new file mode 100644
index 0000000000..c340dee5f4
--- /dev/null
+++ b/tests/manual/pointer/tabletCanvasDrawing.qml
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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.15
+import QtQuick.Layouts 1.15
+import "content"
+
+Rectangle {
+ width: 1024
+ height: 1024
+ color: "#444"
+
+ ColumnLayout {
+ x: -15; width: 80
+ height: parent.height
+ Slider {
+ id: hueSlider
+ width: 80; height: 200
+ Layout.fillHeight: true
+ label: "hue"
+ Rectangle {
+ color: "beige"
+ width: 30
+ height: 25
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 2
+ anchors.horizontalCenter: parent.horizontalCenter
+ Rectangle {
+ border.color: "white"
+ color: canvas.drawingColor
+ anchors.fill: parent
+ }
+ }
+ }
+ Slider {
+ id: saturationSlider
+ width: 80; height: 200
+ Layout.fillHeight: true
+ label: "sat"
+ }
+ Slider {
+ id: lightnessSlider
+ width: 80; height: 200
+ Layout.fillHeight: true
+ label: "light"
+ }
+ }
+
+ ColumnLayout {
+ x: parent.width - 65; width: 80
+ height: parent.height
+ Slider {
+ id: widthSlider
+ width: 80; height: 200
+ Layout.fillHeight: true
+ label: "width"
+ }
+ Slider {
+ id: alphaSlider
+ width: 80; height: 200
+ Layout.fillHeight: true
+ label: "alpha"
+ }
+ }
+
+ Rectangle {
+ id: rect
+ width: 640
+ height: 480
+ color: "beige"
+ anchors {
+ fill: parent
+ margins: 10
+ leftMargin: 50
+ rightMargin: 50
+ }
+
+ Canvas {
+ id: canvas
+ anchors.fill: parent
+ antialiasing: true
+ renderTarget: Canvas.FramebufferObject
+ property color drawingColor: Qt.hsla(hueSlider.value / 100.0,
+ saturationSlider.value / 100.0,
+ lightnessSlider.value / 100.0,
+ alphaSlider.value / 100.0)
+ property var points: []
+ property var pressures: []
+ property var pointerType: PointerDevice.Pen
+ onPaint: {
+ if (points.length < 2)
+ return
+ var ctx = canvas.getContext('2d');
+ ctx.save()
+ ctx.strokeStyle = pointerType === PointerDevice.Pen ? drawingColor : "beige"
+ ctx.lineCap = "round"
+ if (pressures.length === points.length) {
+ for (var i = 1; i < points.length; i++) {
+ ctx.lineWidth = pressures[i] * widthSlider.value
+ ctx.beginPath()
+ ctx.moveTo(points[i - 1].x, points[i - 1].y)
+ ctx.lineTo(points[i].x, points[i].y)
+ ctx.stroke()
+ }
+ points = points.slice(points.length - 2, 1)
+ pressures = pressures.slice(pressures.length - 2, 1)
+ } else {
+ ctx.beginPath()
+ ctx.moveTo(points[0].x, points[0].y)
+ for (var i = 1; i < points.length; i++)
+ ctx.lineTo(points[i].x, points[i].y)
+ ctx.lineWidth = widthSlider
+ ctx.stroke()
+ points = points.slice(points.length - 2, 1)
+ pressures = []
+ }
+ ctx.restore()
+ }
+ }
+
+ PointHandler {
+ acceptedPointerTypes: PointerDevice.Pen
+ onActiveChanged:
+ if (active) {
+ canvas.pointerType = PointerDevice.Pen
+ } else {
+ canvas.points = []
+ canvas.pressures = []
+ }
+ onPointChanged:
+ if (active) {
+ canvas.points.push(point.position)
+ canvas.pressures.push(point.pressure)
+ canvas.requestPaint()
+ }
+ }
+
+ PointHandler {
+ acceptedPointerTypes: PointerDevice.Eraser
+ onActiveChanged:
+ if (active) {
+ canvas.pointerType = PointerDevice.Eraser
+ } else {
+ canvas.points = []
+ canvas.pressures = []
+ }
+ onPointChanged:
+ if (active) {
+ canvas.points.push(point.position)
+ canvas.pressures.push(point.pressure)
+ canvas.requestPaint()
+ }
+ }
+
+ HoverHandler {
+ id: stylusHandler
+ acceptedDevices: PointerDevice.Stylus
+ acceptedPointerTypes: PointerDevice.Pen
+ target: Image {
+ parent: rect
+ source: stylusHandler.point.rotation === 0 ?
+ "resources/cursor-pencil.png" : "resources/cursor-felt-marker.png"
+ visible: stylusHandler.hovered
+ rotation: stylusHandler.point.rotation
+ x: stylusHandler.point.position.x
+ y: stylusHandler.point.position.y
+ }
+ }
+
+ HoverHandler {
+ id: airbrushHandler
+ acceptedDevices: PointerDevice.Airbrush
+ acceptedPointerTypes: PointerDevice.Pen
+ target: Image {
+ parent: rect
+ source: "resources/cursor-airbrush.png"
+ visible: airbrushHandler.hovered
+ x: airbrushHandler.point.position.x
+ y: airbrushHandler.point.position.y
+ }
+ }
+
+ HoverHandler {
+ id: eraserHandler
+ acceptedPointerTypes: PointerDevice.Eraser
+ target: Image {
+ parent: rect
+ source: "resources/cursor-eraser.png"
+ visible: eraserHandler.hovered
+ x: eraserHandler.point.position.x
+ y: eraserHandler.point.position.y - 32
+ }
+ }
+ }
+}
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp
index 618dab6690..bd7a33482d 100644
--- a/tools/qml/main.cpp
+++ b/tools/qml/main.cpp
@@ -37,6 +37,7 @@
#include <QFileOpenEvent>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
+#include <QSurfaceFormat>
#ifdef QT_WIDGETS_LIB
#include <QApplication>
#endif // QT_WIDGETS_LIB
@@ -59,6 +60,7 @@
#include <QLibraryInfo>
#include <qqml.h>
#include <qqmldebug.h>
+#include <qqmlfileselector.h>
#include <private/qmemory_p.h>
#include <private/qtqmlglobal_p.h>
@@ -511,6 +513,9 @@ int main(int argc, char *argv[])
"Backend is one of: default, vulkan, metal, d3d11, gl"),
QStringLiteral("backend"));
parser.addOption(rhiOption);
+ QCommandLineOption selectorOption(QStringLiteral("S"), QCoreApplication::translate("main",
+ "Add selector to the list of QQmlFileSelectors."), QStringLiteral("selector"));
+ parser.addOption(selectorOption);
// Positional arguments
parser.addPositionalArgument("files",
@@ -550,6 +555,26 @@ int main(int argc, char *argv[])
#endif
for (const QString &importPath : parser.values(importOption))
e.addImportPath(importPath);
+
+ QStringList customSelectors;
+ for (const QString &selector : parser.values(selectorOption))
+ customSelectors.append(selector);
+ if (!customSelectors.isEmpty()) {
+ QQmlFileSelector *selector = QQmlFileSelector::get(&e);
+ selector->setExtraSelectors(customSelectors);
+ }
+
+#if defined(QT_GUI_LIB) && QT_CONFIG(opengl)
+ if (qEnvironmentVariableIsSet("QSG_CORE_PROFILE") || qEnvironmentVariableIsSet("QML_CORE_PROFILE")) {
+ QSurfaceFormat surfaceFormat;
+ surfaceFormat.setStencilBufferSize(8);
+ surfaceFormat.setDepthBufferSize(24);
+ surfaceFormat.setVersion(4, 1);
+ surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
+ QSurfaceFormat::setDefaultFormat(surfaceFormat);
+ }
+#endif
+
files << parser.values(qmlFileOption);
if (parser.isSet(configOption))
confFile = parser.value(configOption);
diff --git a/tools/qmlcachegen/qtquickcompiler.prf b/tools/qmlcachegen/qtquickcompiler.prf
index 8aac3b9e07..7353dfb17a 100644
--- a/tools/qmlcachegen/qtquickcompiler.prf
+++ b/tools/qmlcachegen/qtquickcompiler.prf
@@ -29,6 +29,7 @@ defineReplace(qmlCacheResourceFileOutputName) {
# Flatten RESOURCES that may contain individual files or objects
load(resources_functions)
qtFlattenResources()
+qtEnsurePluginResourcesCpp()
NEWRESOURCES =
QMLCACHE_RESOURCE_FILES =
diff --git a/tools/qmlformat/dumpastvisitor.cpp b/tools/qmlformat/dumpastvisitor.cpp
index af0e0aeff0..75712975cc 100644
--- a/tools/qmlformat/dumpastvisitor.cpp
+++ b/tools/qmlformat/dumpastvisitor.cpp
@@ -52,6 +52,14 @@ DumpAstVisitor::DumpAstVisitor(Node *rootNode, CommentAstVisitor *comment): m_co
m_result = lines.join("\n");
}
+bool DumpAstVisitor::preVisit(Node *el)
+{
+ UiObjectMember *m = el->uiObjectMemberCast();
+ if (m != 0)
+ Node::accept(m->annotations, this);
+ return true;
+}
+
static QString parseUiQualifiedId(UiQualifiedId *id)
{
QString name = id->name.toString();
@@ -1247,3 +1255,37 @@ bool DumpAstVisitor::visit(UiPragma *node) {
return true;
}
+
+bool DumpAstVisitor::visit(UiAnnotation *node)
+{
+ if (scope().m_firstObject) {
+ if (scope().m_firstOfAll)
+ scope().m_firstOfAll = false;
+ else
+ addNewLine();
+
+ scope().m_firstObject = false;
+ }
+
+ addLine(getComment(node, Comment::Location::Front));
+ addLine(QLatin1String("@") + parseUiQualifiedId(node->qualifiedTypeNameId) + " {");
+
+ m_indentLevel++;
+
+ ScopeProperties props;
+ props.m_bindings = findBindings(node->initializer->members);
+ m_scope_properties.push(props);
+
+ m_result += getOrphanedComments(node);
+
+ return true;
+}
+
+void DumpAstVisitor::endVisit(UiAnnotation *node) {
+ m_indentLevel--;
+
+ m_scope_properties.pop();
+
+ addLine("}");
+ addLine(getComment(node, Comment::Location::Back));
+}
diff --git a/tools/qmlformat/dumpastvisitor.h b/tools/qmlformat/dumpastvisitor.h
index 8c34e01960..1e25bd9190 100644
--- a/tools/qmlformat/dumpastvisitor.h
+++ b/tools/qmlformat/dumpastvisitor.h
@@ -46,6 +46,8 @@ public:
QString toString() const { return m_result; }
+ bool preVisit(Node *) override;
+
bool visit(UiScriptBinding *node) override;
bool visit(UiArrayBinding *node) override;
@@ -67,6 +69,9 @@ public:
bool visit(UiImport *node) override;
bool visit(UiPragma *node) override;
+ bool visit(UiAnnotation *node) override;
+ void endVisit(UiAnnotation *node) override;
+
void throwRecursionDepthError() override {}
bool error() const { return m_error; }
diff --git a/tools/qmlimportscanner/qmlimportscanner.pro b/tools/qmlimportscanner/qmlimportscanner.pro
index d69f1a3b0b..33089a5c48 100644
--- a/tools/qmlimportscanner/qmlimportscanner.pro
+++ b/tools/qmlimportscanner/qmlimportscanner.pro
@@ -14,9 +14,9 @@ contains(CMAKE_BIN_DIR, "^\\.\\./.*") {
CMAKE_BIN_DIR_IS_ABSOLUTE = True
}
-CMAKE_QML_DIR = $$cmakeRelativePath($$[QT_INSTALL_QML/get], $$[QT_INSTALL_PREFIX])
+CMAKE_QML_DIR = $$cmakeRelativePath($$[QT_INSTALL_QML], $$[QT_INSTALL_PREFIX])
contains(CMAKE_QML_DIR, "^\\.\\./.*") {
- CMAKE_QML_DIR = $$[QT_INSTALL_QML/get]/
+ CMAKE_QML_DIR = $$[QT_INSTALL_QML]/
CMAKE_QML_DIR_IS_ABSOLUTE = True
}
load(qt_build_paths)
diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp
index 28370cb522..b0635a7e87 100644
--- a/tools/qmlscene/main.cpp
+++ b/tools/qmlscene/main.cpp
@@ -500,7 +500,8 @@ int main(int argc, char ** argv)
}
}
- if (qEnvironmentVariableIsSet("QMLSCENE_CORE_PROFILE"))
+ if (qEnvironmentVariableIsSet("QMLSCENE_CORE_PROFILE")
+ || qEnvironmentVariableIsSet("QSG_CORE_PROFILE"))
options.coreProfile = true;
// Set default surface format before creating the window