aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/masm/assembler/LinkBuffer.h28
-rw-r--r--src/imports/folderlistmodel/folderlistmodel.pro1
-rw-r--r--src/imports/folderlistmodel/plugin.cpp23
-rw-r--r--src/imports/folderlistmodel/plugins.qmltypes351
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.cpp12
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.h4
-rw-r--r--src/imports/labsanimation/labsanimation.pro5
-rw-r--r--src/imports/labsanimation/plugin.cpp16
-rw-r--r--src/imports/labsanimation/plugins.qmltypes36
-rw-r--r--src/imports/labsanimation/qquickboundaryrule.cpp (renamed from src/quick/util/qquickboundaryrule.cpp)0
-rw-r--r--src/imports/labsanimation/qquickboundaryrule_p.h (renamed from src/quick/util/qquickboundaryrule_p.h)3
-rw-r--r--src/imports/labsmodels/labsmodels.pro21
-rw-r--r--src/imports/labsmodels/plugin.cpp23
-rw-r--r--src/imports/labsmodels/plugins.qmltypes414
-rw-r--r--src/imports/labsmodels/qqmldelegatecomponent.cpp (renamed from src/qmlmodels/qqmldelegatecomponent.cpp)52
-rw-r--r--src/imports/labsmodels/qqmldelegatecomponent_p.h (renamed from src/qmlmodels/qqmldelegatecomponent_p.h)36
-rw-r--r--src/imports/labsmodels/qqmltablemodel.cpp (renamed from src/qmlmodels/qqmltablemodel.cpp)33
-rw-r--r--src/imports/labsmodels/qqmltablemodel_p.h (renamed from src/qmlmodels/qqmltablemodel_p.h)12
-rw-r--r--src/imports/labsmodels/qqmltablemodelcolumn.cpp (renamed from src/qmlmodels/qqmltablemodelcolumn.cpp)0
-rw-r--r--src/imports/labsmodels/qqmltablemodelcolumn_p.h (renamed from src/qmlmodels/qqmltablemodelcolumn_p.h)3
-rw-r--r--src/imports/layouts/layouts.pro2
-rw-r--r--src/imports/layouts/plugin.cpp27
-rw-r--r--src/imports/layouts/plugins.qmltypes102
-rw-r--r--src/imports/layouts/qquickgridlayoutengine.cpp2
-rw-r--r--src/imports/layouts/qquickgridlayoutengine_p.h2
-rw-r--r--src/imports/layouts/qquicklayout.cpp3
-rw-r--r--src/imports/layouts/qquicklayout_p.h5
-rw-r--r--src/imports/layouts/qquicklinearlayout.cpp4
-rw-r--r--src/imports/layouts/qquicklinearlayout_p.h5
-rw-r--r--src/imports/layouts/qquickstacklayout_p.h2
-rw-r--r--src/imports/localstorage/localstorage.pro8
-rw-r--r--src/imports/localstorage/plugin.cpp791
-rw-r--r--src/imports/localstorage/plugins.qmltypes23
-rw-r--r--src/imports/localstorage/qquicklocalstorage.cpp792
-rw-r--r--src/imports/localstorage/qquicklocalstorage_p.h (renamed from src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h)27
-rw-r--r--src/imports/models/plugin.cpp18
-rw-r--r--src/imports/models/plugins.qmltypes710
-rw-r--r--src/imports/particles/plugin.cpp12
-rw-r--r--src/imports/particles/plugins.qmltypes1257
-rw-r--r--src/imports/qtqml/plugin.cpp32
-rw-r--r--src/imports/qtqml/plugins.qmltypes245
-rw-r--r--src/imports/qtquick2/plugin.cpp10
-rw-r--r--src/imports/qtquick2/plugins.qmltypes5709
-rw-r--r--src/imports/settings/plugin.cpp14
-rw-r--r--src/imports/settings/plugins.qmltypes36
-rw-r--r--src/imports/settings/qqmlsettings.cpp2
-rw-r--r--src/imports/settings/qqmlsettings_p.h1
-rw-r--r--src/imports/settings/settings.pro2
-rw-r--r--src/imports/shapes/plugin.cpp20
-rw-r--r--src/imports/shapes/plugins.qmltypes154
-rw-r--r--src/imports/sharedimage/plugin.cpp14
-rw-r--r--src/imports/sharedimage/plugins.qmltypes11
-rw-r--r--src/imports/sharedimage/sharedimage.pro1
-rw-r--r--src/imports/statemachine/childrenprivate.h138
-rw-r--r--src/imports/statemachine/finalstate.cpp4
-rw-r--r--src/imports/statemachine/finalstate.h4
-rw-r--r--src/imports/statemachine/plugin.cpp25
-rw-r--r--src/imports/statemachine/plugins.qmltypes173
-rw-r--r--src/imports/statemachine/signaltransition.cpp2
-rw-r--r--src/imports/statemachine/signaltransition.h7
-rw-r--r--src/imports/statemachine/state.cpp11
-rw-r--r--src/imports/statemachine/state.h4
-rw-r--r--src/imports/statemachine/statemachine.cpp8
-rw-r--r--src/imports/statemachine/statemachine.h4
-rw-r--r--src/imports/statemachine/statemachine.pro5
-rw-r--r--src/imports/statemachine/statemachineforeign.h80
-rw-r--r--src/imports/statemachine/timeouttransition.h2
-rw-r--r--src/imports/testlib/TestCase.qml17
-rw-r--r--src/imports/testlib/dependencies.json1
-rw-r--r--src/imports/testlib/main.cpp116
-rw-r--r--src/imports/testlib/plugins.qmltypes368
-rw-r--r--src/imports/testlib/quicktestevent.cpp (renamed from src/qmltest/quicktestevent.cpp)6
-rw-r--r--src/imports/testlib/quicktestevent_p.h (renamed from src/qmltest/quicktestevent_p.h)9
-rw-r--r--src/imports/testlib/quicktestresultforeign_p.h (renamed from src/quick/util/qquickutilmodule_p.h)20
-rw-r--r--src/imports/testlib/quicktestutil.cpp111
-rw-r--r--src/imports/testlib/quicktestutil_p.h88
-rw-r--r--src/imports/testlib/testlib.pro13
-rw-r--r--src/imports/wavefrontmesh/plugin.cpp19
-rw-r--r--src/imports/wavefrontmesh/plugins.qmltypes37
-rw-r--r--src/imports/wavefrontmesh/qwavefrontmesh.cpp10
-rw-r--r--src/imports/wavefrontmesh/qwavefrontmesh.h2
-rw-r--r--src/imports/wavefrontmesh/wavefrontmesh.pro1
-rw-r--r--src/imports/window/plugin.cpp19
-rw-r--r--src/imports/window/plugin.h128
-rw-r--r--src/imports/window/plugins.qmltypes373
-rw-r--r--src/imports/window/window.pro4
-rw-r--r--src/imports/workerscript/plugin.cpp18
-rw-r--r--src/imports/workerscript/plugins.qmltypes26
-rw-r--r--src/particles/particles.pro6
-rw-r--r--src/particles/qquickage_p.h1
-rw-r--r--src/particles/qquickangledirection_p.h3
-rw-r--r--src/particles/qquickcumulativedirection.cpp2
-rw-r--r--src/particles/qquickcumulativedirection_p.h3
-rw-r--r--src/particles/qquickcustomaffector.cpp2
-rw-r--r--src/particles/qquickcustomaffector_p.h2
-rw-r--r--src/particles/qquickcustomparticle_p.h1
-rw-r--r--src/particles/qquickdirection_p.h4
-rw-r--r--src/particles/qquickellipseextruder_p.h1
-rw-r--r--src/particles/qquickfriction_p.h1
-rw-r--r--src/particles/qquickgravity_p.h2
-rw-r--r--src/particles/qquickgroupgoal_p.h1
-rw-r--r--src/particles/qquickimageparticle.cpp4
-rw-r--r--src/particles/qquickimageparticle_p.h1
-rw-r--r--src/particles/qquickitemparticle.cpp25
-rw-r--r--src/particles/qquickitemparticle_p.h7
-rw-r--r--src/particles/qquicklineextruder_p.h1
-rw-r--r--src/particles/qquickmaskextruder_p.h1
-rw-r--r--src/particles/qquickparticleaffector.cpp2
-rw-r--r--src/particles/qquickparticleaffector_p.h3
-rw-r--r--src/particles/qquickparticleemitter.cpp2
-rw-r--r--src/particles/qquickparticleemitter_p.h1
-rw-r--r--src/particles/qquickparticleextruder_p.h4
-rw-r--r--src/particles/qquickparticlegroup.cpp13
-rw-r--r--src/particles/qquickparticlegroup_p.h1
-rw-r--r--src/particles/qquickparticlepainter_p.h3
-rw-r--r--src/particles/qquickparticlesmodule.cpp44
-rw-r--r--src/particles/qquickparticlesystem_p.h1
-rw-r--r--src/particles/qquickpointattractor_p.h1
-rw-r--r--src/particles/qquickpointdirection_p.h1
-rw-r--r--src/particles/qquickrectangleextruder_p.h1
-rw-r--r--src/particles/qquickspritegoal_p.h1
-rw-r--r--src/particles/qquicktargetdirection_p.h3
-rw-r--r--src/particles/qquicktrailemitter.cpp2
-rw-r--r--src/particles/qquicktrailemitter_p.h1
-rw-r--r--src/particles/qquickturbulence_p.h4
-rw-r--r--src/particles/qquickwander_p.h1
-rw-r--r--src/particles/qtquickparticlesglobal_p.h2
-rw-r--r--src/particles/shaders_ng/imageparticle_colored.frag.qsbbin1990 -> 1506 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_colored.vert.qsbbin3677 -> 3293 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_deformed.frag.qsbbin2028 -> 1516 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_deformed.vert.qsbbin5044 -> 4641 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_simple.frag.qsbbin2000 -> 1512 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_simple.vert.qsbbin3639 -> 3160 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_sprite.frag.qsbbin2369 -> 1846 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_sprite.vert.qsbbin5964 -> 5330 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_tabled.frag.qsbbin2240 -> 1709 bytes
-rw-r--r--src/particles/shaders_ng/imageparticle_tabled.vert.qsbbin5462 -> 4987 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp2
-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/qqmlpreviewfileengine.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.cpp1
-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_profiler/qqmlprofileradapter.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp7
-rw-r--r--src/plugins/scenegraph/d3d12/d3d12.pro12
-rw-r--r--src/plugins/scenegraph/d3d12/d3d12.tracepoints0
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h4
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp12
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp22
-rw-r--r--src/plugins/scenegraph/openvg/openvg.pro12
-rw-r--r--src/plugins/scenegraph/openvg/openvg.tracepoints0
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp12
-rw-r--r--src/qml/Qt5QmlConfigExtras.cmake.in10
-rw-r--r--src/qml/animations/qabstractanimationjob.cpp4
-rw-r--r--src/qml/animations/qcontinuinganimationgroupjob.cpp2
-rw-r--r--src/qml/animations/qparallelanimationgroupjob.cpp2
-rw-r--r--src/qml/animations/qpauseanimationjob.cpp2
-rw-r--r--src/qml/animations/qsequentialanimationgroupjob.cpp2
-rw-r--r--src/qml/common/common.pri1
-rw-r--r--src/qml/common/qqmlapiversion_p.h2
-rw-r--r--src/qml/common/qqmljsdiagnosticmessage_p.h5
-rw-r--r--src/qml/common/qqmljssourcelocation_p.h (renamed from src/qml/parser/qqmljssourcelocation_p.h)6
-rw-r--r--src/qml/common/qv4compileddata_p.h78
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp202
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h80
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp2
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h4
-rw-r--r--src/qml/compiler/qv4codegen.cpp43
-rw-r--r--src/qml/compiler/qv4codegen_p.h12
-rw-r--r--src/qml/compiler/qv4compilercontext.cpp5
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h12
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp6
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions_p.h2
-rw-r--r--src/qml/debugger/qqmldebug.cpp10
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces.cpp1
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces_p.h22
-rw-r--r--src/qml/dependencies.json1
-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/data.qdoc13
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc136
-rw-r--r--src/qml/doc/src/cppintegration/extending-tutorial.qdoc48
-rw-r--r--src/qml/doc/src/cppintegration/topic.qdoc18
-rw-r--r--src/qml/doc/src/external-resources.qdoc6
-rw-r--r--src/qml/doc/src/javascript/expressions.qdoc4
-rw-r--r--src/qml/doc/src/javascript/finetuning.qdoc104
-rw-r--r--src/qml/doc/src/javascript/hostenvironment.qdoc2
-rw-r--r--src/qml/doc/src/javascript/imports.qdoc2
-rw-r--r--src/qml/doc/src/javascript/topic.qdoc7
-rw-r--r--src/qml/doc/src/qmldiskcache.qdoc77
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc305
-rw-r--r--src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc114
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc48
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc51
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/imports.qdoc19
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc52
-rw-r--r--src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc33
-rw-r--r--src/qml/doc/src/qtqml.qdoc2
-rw-r--r--src/qml/inlinecomponentutils_p.h161
-rw-r--r--src/qml/jit/qv4assemblercommon.cpp21
-rw-r--r--src/qml/jit/qv4assemblercommon_p.h6
-rw-r--r--src/qml/jit/qv4baselineassembler.cpp62
-rw-r--r--src/qml/jit/qv4baselineassembler_p.h13
-rw-r--r--src/qml/jsapi/qjsengine.cpp38
-rw-r--r--src/qml/jsapi/qjsengine.h7
-rw-r--r--src/qml/jsapi/qjsengine_p.h1
-rw-r--r--src/qml/jsapi/qjsvalue.cpp12
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp72
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp2
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4engine.cpp50
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp149
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit_p.h104
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp1
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp11
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp127
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtimecodegen.cpp4
-rw-r--r--src/qml/jsruntime/qv4runtimecodegen_p.h4
-rw-r--r--src/qml/jsruntime/qv4script.cpp9
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp209
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h1
-rw-r--r--src/qml/jsruntime/qv4value.cpp4
-rw-r--r--src/qml/jsruntime/qv4value_p.h25
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp20
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp2
-rw-r--r--src/qml/memory/qv4mm.cpp26
-rw-r--r--src/qml/memory/qv4mmdefs_p.h42
-rw-r--r--src/qml/parser/parser.pri4
-rw-r--r--src/qml/parser/qqmljs.g505
-rw-r--r--src/qml/parser/qqmljsast.cpp276
-rw-r--r--src/qml/parser/qqmljsast_p.h426
-rw-r--r--src/qml/parser/qqmljsastfwd_p.h8
-rw-r--r--src/qml/parser/qqmljsastvisitor.cpp6
-rw-r--r--src/qml/parser/qqmljsastvisitor_p.h800
-rw-r--r--src/qml/parser/qqmljsengine_p.cpp4
-rw-r--r--src/qml/parser/qqmljsengine_p.h6
-rw-r--r--src/qml/parser/qqmljskeywords_p.h31
-rw-r--r--src/qml/parser/qqmljslexer.cpp101
-rw-r--r--src/qml/qml.pro8
-rw-r--r--src/qml/qml/ftw/qhashedstring.cpp19
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h1
-rw-r--r--src/qml/qml/qml.pri2
-rw-r--r--src/qml/qml/qqml.cpp220
-rw-r--r--src/qml/qml/qqml.h208
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp39
-rw-r--r--src/qml/qml/qqmlapplicationengine.h1
-rw-r--r--src/qml/qml/qqmlapplicationengine_p.h6
-rw-r--r--src/qml/qml/qqmlbinding.cpp17
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp5
-rw-r--r--src/qml/qml/qqmlcomponent.cpp148
-rw-r--r--src/qml/qml/qqmlcomponent.h27
-rw-r--r--src/qml/qml/qqmlcomponent_p.h8
-rw-r--r--src/qml/qml/qqmlcomponentattached_p.h5
-rw-r--r--src/qml/qml/qqmlcontext.cpp2
-rw-r--r--src/qml/qml/qqmlcontext_p.h11
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp40
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h9
-rw-r--r--src/qml/qml/qqmldatablob.cpp15
-rw-r--r--src/qml/qml/qqmldatablob_p.h2
-rw-r--r--src/qml/qml/qqmlengine.cpp122
-rw-r--r--src/qml/qml/qqmlengine_p.h8
-rw-r--r--src/qml/qml/qqmlerror.cpp15
-rw-r--r--src/qml/qml/qqmlextensioninterface.h11
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp53
-rw-r--r--src/qml/qml/qqmlextensionplugin.h13
-rw-r--r--src/qml/qml/qqmlimport.cpp407
-rw-r--r--src/qml/qml/qqmlimport_p.h33
-rw-r--r--src/qml/qml/qqmlincubator.cpp93
-rw-r--r--src/qml/qml/qqmlincubator.h10
-rw-r--r--src/qml/qml/qqmlincubator_p.h7
-rw-r--r--src/qml/qml/qqmlinfo.cpp5
-rw-r--r--src/qml/qml/qqmlirloader.cpp13
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp5
-rw-r--r--src/qml/qml/qqmllist.cpp132
-rw-r--r--src/qml/qml/qqmllist.h129
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp82
-rw-r--r--src/qml/qml/qqmllocale.cpp32
-rw-r--r--src/qml/qml/qqmllocale_p.h16
-rw-r--r--src/qml/qml/qqmlloggingcategory_p.h3
-rw-r--r--src/qml/qml/qqmlmetatype.cpp186
-rw-r--r--src/qml/qml/qqmlmetatype_p.h24
-rw-r--r--src/qml/qml/qqmlmetatypedata.cpp10
-rw-r--r--src/qml/qml/qqmlmetatypedata_p.h12
-rw-r--r--src/qml/qml/qqmlmoduleregistration.cpp66
-rw-r--r--src/qml/qml/qqmlmoduleregistration.h61
-rw-r--r--src/qml/qml/qqmlnotifier.cpp4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp339
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h45
-rw-r--r--src/qml/qml/qqmlplatform.cpp2
-rw-r--r--src/qml/qml/qqmlprivate.h410
-rw-r--r--src/qml/qml/qqmlproperty.cpp48
-rw-r--r--src/qml/qml/qqmlproperty_p.h4
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp54
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h1
-rw-r--r--src/qml/qml/qqmlpropertycachecreator.cpp16
-rw-r--r--src/qml/qml/qqmlpropertycachecreator_p.h202
-rw-r--r--src/qml/qml/qqmlpropertydata_p.h201
-rw-r--r--src/qml/qml/qqmlpropertyvalidator.cpp93
-rw-r--r--src/qml/qml/qqmlpropertyvalidator_p.h13
-rw-r--r--src/qml/qml/qqmlscriptblob.cpp5
-rw-r--r--src/qml/qml/qqmltype.cpp120
-rw-r--r--src/qml/qml/qqmltype_p.h16
-rw-r--r--src/qml/qml/qqmltype_p_p.h19
-rw-r--r--src/qml/qml/qqmltypecompiler.cpp46
-rw-r--r--src/qml/qml/qqmltypecompiler_p.h18
-rw-r--r--src/qml/qml/qqmltypedata.cpp283
-rw-r--r--src/qml/qml/qqmltypedata_p.h24
-rw-r--r--src/qml/qml/qqmltypeloader.cpp198
-rw-r--r--src/qml/qml/qqmltypeloader_p.h2
-rw-r--r--src/qml/qml/qqmltypeloaderqmldircontent.cpp9
-rw-r--r--src/qml/qml/qqmltypeloaderthread.cpp17
-rw-r--r--src/qml/qml/qqmltypeloaderthread_p.h5
-rw-r--r--src/qml/qml/qqmltypemodule.cpp8
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp4
-rw-r--r--src/qml/qml/qqmltypenotavailable.cpp2
-rw-r--r--src/qml/qml/qqmltypenotavailable_p.h6
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp2
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp39
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h13
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp98
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h37
-rw-r--r--src/qml/qml/qqmlvme_p.h43
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp160
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h2
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp42
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp261
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h2
-rw-r--r--src/qml/qmldirparser/qqmldirparser.cpp18
-rw-r--r--src/qml/qmldirparser/qqmldirparser_p.h18
-rw-r--r--src/qml/qtqml.tracepoints7
-rw-r--r--src/qml/qtqmlglobal_p.h2
-rw-r--r--src/qml/types/qqmlbind.cpp4
-rw-r--r--src/qml/types/qqmlbind_p.h1
-rw-r--r--src/qml/types/qqmlconnections_p.h8
-rw-r--r--src/qml/types/qqmltimer.cpp2
-rw-r--r--src/qml/types/qqmltimer_p.h1
-rw-r--r--src/qmldebug/qmldebug.pro4
-rw-r--r--src/qmldebug/qqmldebugconnection.cpp5
-rw-r--r--src/qmldebug/qqmldebugtranslationclient.cpp76
-rw-r--r--src/qmldebug/qqmldebugtranslationclient_p.h81
-rw-r--r--src/qmlmodels/dependencies.json (renamed from src/imports/models/dependencies.json)0
-rw-r--r--src/qmlmodels/qmlmodels.pro18
-rw-r--r--src/qmlmodels/qqmlabstractdelegatecomponent.cpp61
-rw-r--r--src/qmlmodels/qqmlabstractdelegatecomponent_p.h85
-rw-r--r--src/qmlmodels/qqmladaptormodel.cpp36
-rw-r--r--src/qmlmodels/qqmladaptormodel_p.h14
-rw-r--r--src/qmlmodels/qqmldelegatemodel.cpp434
-rw-r--r--src/qmlmodels/qqmldelegatemodel_p.h12
-rw-r--r--src/qmlmodels/qqmldelegatemodel_p_p.h49
-rw-r--r--src/qmlmodels/qqmlinstantiator.cpp4
-rw-r--r--src/qmlmodels/qqmlinstantiator_p.h2
-rw-r--r--src/qmlmodels/qqmllistaccessor.cpp10
-rw-r--r--src/qmlmodels/qqmllistaccessor_p.h2
-rw-r--r--src/qmlmodels/qqmllistmodel.cpp26
-rw-r--r--src/qmlmodels/qqmllistmodel_p.h12
-rw-r--r--src/qmlmodels/qqmllistmodelworkeragent_p.h2
-rw-r--r--src/qmlmodels/qqmlmodelsmodule.cpp54
-rw-r--r--src/qmlmodels/qqmlmodelsmodule_p.h17
-rw-r--r--src/qmlmodels/qqmlobjectmodel.cpp40
-rw-r--r--src/qmlmodels/qqmlobjectmodel_p.h21
-rw-r--r--src/qmlmodels/qqmltableinstancemodel.cpp124
-rw-r--r--src/qmlmodels/qqmltableinstancemodel_p.h27
-rw-r--r--src/qmlmodels/qquickpackage.cpp19
-rw-r--r--src/qmlmodels/qquickpackage_p.h4
-rw-r--r--src/qmlmodels/qtqmlmodelsglobal_p.h2
-rw-r--r--src/qmltest/qmldir2
-rw-r--r--src/qmltest/qmltest.pro19
-rw-r--r--src/qmltest/quicktest.cpp63
-rw-r--r--src/qmltest/quicktest_p.h113
-rw-r--r--src/qmltest/quicktestresult.cpp12
-rw-r--r--src/qmltest/quicktestresult_p.h1
-rw-r--r--src/qmltyperegistrar/qmltyperegistrar.cpp463
-rw-r--r--src/qmltyperegistrar/qmltyperegistrar.pro32
-rw-r--r--src/qmltyperegistrar/qmltypes.prf97
-rw-r--r--src/qmltyperegistrar/qmltypesclassdescription.cpp186
-rw-r--r--src/qmltyperegistrar/qmltypesclassdescription.h67
-rw-r--r--src/qmltyperegistrar/qmltypescreator.cpp381
-rw-r--r--src/qmltyperegistrar/qmltypescreator.h68
-rw-r--r--src/qmlworkerscript/dependencies.json (renamed from src/imports/workerscript/dependencies.json)0
-rw-r--r--src/qmlworkerscript/qmlworkerscript.pro6
-rw-r--r--src/qmlworkerscript/qqmlworkerscriptmodule.cpp7
-rw-r--r--src/qmlworkerscript/qqmlworkerscriptmodule_p.h1
-rw-r--r--src/qmlworkerscript/qquickworkerscript.cpp15
-rw-r--r--src/qmlworkerscript/qquickworkerscript_p.h7
-rw-r--r--src/qmlworkerscript/qtqmlworkerscriptglobal_p.h2
-rw-r--r--src/qmlworkerscript/qv4serialize.cpp49
-rw-r--r--src/quick/dependencies.json1
-rw-r--r--src/quick/designer/qqmldesignermetaobject.cpp2
-rw-r--r--src/quick/designer/qquickdesignercustomobjectdata.cpp4
-rw-r--r--src/quick/doc/snippets/qml/listview/ReusableDelegate.qml82
-rw-r--r--src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml81
-rw-r--r--src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp47
-rw-r--r--src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h94
-rw-r--r--src/quick/doc/snippets/qml/tableview/tableview.pro20
-rw-r--r--src/quick/doc/src/advtutorial.qdoc4
-rw-r--r--src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc20
-rw-r--r--src/quick/doc/src/dynamicview-tutorial.qdoc4
-rw-r--r--src/quick/doc/src/examples.qdoc1
-rw-r--r--src/quick/doc/src/tutorial.qdoc3
-rw-r--r--src/quick/handlers/qquickdragaxis_p.h4
-rw-r--r--src/quick/handlers/qquickdraghandler.cpp3
-rw-r--r--src/quick/handlers/qquickdraghandler_p.h2
-rw-r--r--src/quick/handlers/qquickhandlerpoint.cpp7
-rw-r--r--src/quick/handlers/qquickhoverhandler.cpp70
-rw-r--r--src/quick/handlers/qquickhoverhandler_p.h3
-rw-r--r--src/quick/handlers/qquickpinchhandler.cpp9
-rw-r--r--src/quick/handlers/qquickpinchhandler_p.h2
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp157
-rw-r--r--src/quick/handlers/qquickpointerhandler_p.h23
-rw-r--r--src/quick/handlers/qquickpointerhandler_p_p.h9
-rw-r--r--src/quick/handlers/qquickpointhandler_p.h2
-rw-r--r--src/quick/handlers/qquicksinglepointhandler.cpp2
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp9
-rw-r--r--src/quick/handlers/qquicktaphandler_p.h3
-rw-r--r--src/quick/handlers/qquickwheelhandler_p.h3
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp6
-rw-r--r--src/quick/items/context2d/qquickcanvasitem_p.h1
-rw-r--r--src/quick/items/qquickaccessibleattached.cpp20
-rw-r--r--src/quick/items/qquickaccessibleattached_p.h5
-rw-r--r--src/quick/items/qquickanchors_p.h1
-rw-r--r--src/quick/items/qquickanimatedimage.cpp9
-rw-r--r--src/quick/items/qquickanimatedimage_p.h1
-rw-r--r--src/quick/items/qquickanimatedsprite.cpp64
-rw-r--r--src/quick/items/qquickanimatedsprite_p.h12
-rw-r--r--src/quick/items/qquickanimatedsprite_p_p.h5
-rw-r--r--src/quick/items/qquickborderimage.cpp92
-rw-r--r--src/quick/items/qquickborderimage_p.h1
-rw-r--r--src/quick/items/qquickdrag.cpp6
-rw-r--r--src/quick/items/qquickdrag_p.h8
-rw-r--r--src/quick/items/qquickdroparea.cpp8
-rw-r--r--src/quick/items/qquickdroparea_p.h3
-rw-r--r--src/quick/items/qquickevents.cpp188
-rw-r--r--src/quick/items/qquickevents_p_p.h118
-rw-r--r--src/quick/items/qquickflickable.cpp14
-rw-r--r--src/quick/items/qquickflickable_p.h1
-rw-r--r--src/quick/items/qquickflickable_p_p.h3
-rw-r--r--src/quick/items/qquickflipable_p.h1
-rw-r--r--src/quick/items/qquickfocusscope_p.h1
-rw-r--r--src/quick/items/qquickframebufferobject.cpp30
-rw-r--r--src/quick/items/qquickframebufferobject.h3
-rw-r--r--src/quick/items/qquickgenericshadereffect.cpp3
-rw-r--r--src/quick/items/qquickgraphicsinfo_p.h7
-rw-r--r--src/quick/items/qquickgridview.cpp8
-rw-r--r--src/quick/items/qquickgridview_p.h3
-rw-r--r--src/quick/items/qquickimage.cpp62
-rw-r--r--src/quick/items/qquickimage_p.h2
-rw-r--r--src/quick/items/qquickimage_p_p.h13
-rw-r--r--src/quick/items/qquickimagebase.cpp182
-rw-r--r--src/quick/items/qquickimagebase_p.h26
-rw-r--r--src/quick/items/qquickimagebase_p_p.h2
-rw-r--r--src/quick/items/qquickitem.cpp429
-rw-r--r--src/quick/items/qquickitem.h2
-rw-r--r--src/quick/items/qquickitem_p.h33
-rw-r--r--src/quick/items/qquickitemanimation.cpp2
-rw-r--r--src/quick/items/qquickitemanimation_p.h3
-rw-r--r--src/quick/items/qquickitemgrabresult.cpp2
-rw-r--r--src/quick/items/qquickitemgrabresult.h8
-rw-r--r--src/quick/items/qquickitemsmodule.cpp327
-rw-r--r--src/quick/items/qquickitemsmodule_p.h22
-rw-r--r--src/quick/items/qquickitemview.cpp91
-rw-r--r--src/quick/items/qquickitemview_p.h16
-rw-r--r--src/quick/items/qquickitemview_p_p.h17
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp2
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h5
-rw-r--r--src/quick/items/qquicklistview.cpp156
-rw-r--r--src/quick/items/qquicklistview_p.h6
-rw-r--r--src/quick/items/qquickloader.cpp6
-rw-r--r--src/quick/items/qquickloader_p.h1
-rw-r--r--src/quick/items/qquickmousearea.cpp22
-rw-r--r--src/quick/items/qquickmousearea_p.h1
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp44
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h11
-rw-r--r--src/quick/items/qquickopenglinfo_p.h7
-rw-r--r--src/quick/items/qquickopenglshadereffectnode.cpp2
-rw-r--r--src/quick/items/qquickpainteditem.cpp1
-rw-r--r--src/quick/items/qquickpainteditem.h3
-rw-r--r--src/quick/items/qquickpathview.cpp12
-rw-r--r--src/quick/items/qquickpathview_p.h3
-rw-r--r--src/quick/items/qquickpincharea.cpp8
-rw-r--r--src/quick/items/qquickpincharea_p.h3
-rw-r--r--src/quick/items/qquickpositioners.cpp8
-rw-r--r--src/quick/items/qquickpositioners_p.h11
-rw-r--r--src/quick/items/qquickrectangle.cpp2
-rw-r--r--src/quick/items/qquickrectangle_p.h4
-rw-r--r--src/quick/items/qquickrepeater.cpp10
-rw-r--r--src/quick/items/qquickrepeater_p.h1
-rw-r--r--src/quick/items/qquickscalegrid_p_p.h1
-rw-r--r--src/quick/items/qquickscreen.cpp3
-rw-r--r--src/quick/items/qquickscreen_p.h17
-rw-r--r--src/quick/items/qquickshadereffect_p.h1
-rw-r--r--src/quick/items/qquickshadereffectmesh_p.h10
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h1
-rw-r--r--src/quick/items/qquicksprite_p.h1
-rw-r--r--src/quick/items/qquickspriteengine_p.h16
-rw-r--r--src/quick/items/qquickspritesequence.cpp4
-rw-r--r--src/quick/items/qquickspritesequence_p.h1
-rw-r--r--src/quick/items/qquickstateoperations.cpp94
-rw-r--r--src/quick/items/qquickstateoperations_p.h3
-rw-r--r--src/quick/items/qquicktableview.cpp118
-rw-r--r--src/quick/items/qquicktableview_p.h9
-rw-r--r--src/quick/items/qquicktableview_p_p.h16
-rw-r--r--src/quick/items/qquicktext.cpp102
-rw-r--r--src/quick/items/qquicktext_p.h15
-rw-r--r--src/quick/items/qquicktext_p_p.h2
-rw-r--r--src/quick/items/qquicktextcontrol.cpp19
-rw-r--r--src/quick/items/qquicktextcontrol_p.h3
-rw-r--r--src/quick/items/qquicktextdocument.h1
-rw-r--r--src/quick/items/qquicktextedit.cpp6
-rw-r--r--src/quick/items/qquicktextedit_p.h1
-rw-r--r--src/quick/items/qquicktextinput.cpp8
-rw-r--r--src/quick/items/qquicktextinput_p.h1
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp2
-rw-r--r--src/quick/items/qquicktranslate_p.h5
-rw-r--r--src/quick/items/qquickview.cpp20
-rw-r--r--src/quick/items/qquickwindow.cpp266
-rw-r--r--src/quick/items/qquickwindow.h8
-rw-r--r--src/quick/items/qquickwindow_p.h40
-rw-r--r--src/quick/items/qquickwindowmodule.cpp23
-rw-r--r--src/quick/items/qquickwindowmodule_p.h8
-rw-r--r--src/quick/qtquick.tracepoints48
-rw-r--r--src/quick/qtquick2.cpp13
-rw-r--r--src/quick/qtquickglobal_p.h2
-rw-r--r--src/quick/quick.pro9
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp43
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp12
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp21
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer.h4
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp133
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h109
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterial.cpp1
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp4
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp21
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer.cpp11
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp6
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode_p.h9
-rw-r--r--src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.cpp58
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.h6
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp9
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp3
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp1
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp13
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp66
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h5
-rw-r--r--src/quick/scenegraph/qsgrhilayer.cpp2
-rw-r--r--src/quick/scenegraph/qsgrhishadereffectnode.cpp4
-rw-r--r--src/quick/scenegraph/qsgrhisupport.cpp78
-rw-r--r--src/quick/scenegraph/qsgrhisupport_p.h3
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp123
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp20
-rw-r--r--src/quick/scenegraph/scenegraph.pri2
-rw-r--r--src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsbbin1873 -> 1469 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsbbin1754 -> 1344 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsbbin1753 -> 1351 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsbbin1280 -> 845 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsbbin2209 -> 1783 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsbbin2209 -> 1802 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsbbin2210 -> 1780 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsbbin2319 -> 1867 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsbbin2340 -> 1930 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsbbin2334 -> 1858 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsbbin1883 -> 1488 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsbbin2048 -> 1692 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsbbin1883 -> 1479 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/flatcolor.frag.qsbbin1149 -> 864 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/flatcolor.vert.qsbbin1597 -> 1284 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsbbin3314 -> 2848 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsbbin3675 -> 3282 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsbbin3304 -> 2863 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsbbin2411 -> 1971 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsbbin3028 -> 2614 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsbbin2412 -> 1979 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsbbin1173 -> 927 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsbbin1791 -> 1469 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsbbin2549 -> 2107 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsbbin3029 -> 2623 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsbbin1859 -> 1402 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/shadereffect.frag.qsbbin1622 -> 1247 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/shadereffect.vert.qsbbin1860 -> 1501 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsbbin838 -> 672 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsbbin3682 -> 3320 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsbbin1299 -> 1038 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsbbin4350 -> 3954 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/sprite.frag.qsbbin1908 -> 1498 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/sprite.vert.qsbbin2437 -> 2087 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/stencilclip.frag.qsbbin853 -> 715 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/stencilclip.vert.qsbbin1510 -> 1230 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext.frag.qsbbin2210 -> 1740 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext.vert.qsbbin2618 -> 2175 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsbbin1631 -> 1158 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/textmask.frag.qsbbin1873 -> 1469 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/textmask.vert.qsbbin2307 -> 1933 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/texture.frag.qsbbin1618 -> 1242 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/texture.vert.qsbbin1865 -> 1516 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsbbin851 -> 672 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsbbin1837 -> 1507 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/visualization.frag.qsbbin1877 -> 1504 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/visualization.vert.qsbbin2099 -> 1704 bytes
-rw-r--r--src/quick/scenegraph/util/qsgengine.cpp5
-rw-r--r--src/quick/scenegraph/util/qsgengine.h5
-rw-r--r--src/quick/scenegraph/util/qsgengine_p.h2
-rw-r--r--src/quick/scenegraph/util/qsgopenglatlastexture.cpp5
-rw-r--r--src/quick/scenegraph/util/qsgplaintexture.cpp19
-rw-r--r--src/quick/scenegraph/util/qsgrhiatlastexture.cpp6
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.cpp4
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.h7
-rw-r--r--src/quick/util/qquickanimation.cpp109
-rw-r--r--src/quick/util/qquickanimation_p.h15
-rw-r--r--src/quick/util/qquickanimation_p_p.h5
-rw-r--r--src/quick/util/qquickanimationcontroller_p.h1
-rw-r--r--src/quick/util/qquickanimator_p.h16
-rw-r--r--src/quick/util/qquickanimatorjob.cpp4
-rw-r--r--src/quick/util/qquickapplication_p.h3
-rw-r--r--src/quick/util/qquickbehavior.cpp76
-rw-r--r--src/quick/util/qquickbehavior_p.h5
-rw-r--r--src/quick/util/qquickfontloader_p.h1
-rw-r--r--src/quick/util/qquickfontmetrics_p.h2
-rw-r--r--src/quick/util/qquickforeignutils_p.h (renamed from src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp)132
-rw-r--r--src/quick/util/qquickglobal.cpp62
-rw-r--r--src/quick/util/qquickimageprovider.cpp38
-rw-r--r--src/quick/util/qquickpath.cpp229
-rw-r--r--src/quick/util/qquickpath_p.h123
-rw-r--r--src/quick/util/qquickpath_p_p.h1
-rw-r--r--src/quick/util/qquickpathinterpolator_p.h1
-rw-r--r--src/quick/util/qquickpixmapcache.cpp147
-rw-r--r--src/quick/util/qquickpixmapcache_p.h18
-rw-r--r--src/quick/util/qquickpropertychanges_p.h7
-rw-r--r--src/quick/util/qquickshortcut.cpp6
-rw-r--r--src/quick/util/qquickshortcut_p.h3
-rw-r--r--src/quick/util/qquicksmoothedanimation.cpp2
-rw-r--r--src/quick/util/qquicksmoothedanimation_p.h1
-rw-r--r--src/quick/util/qquickspringanimation.cpp2
-rw-r--r--src/quick/util/qquickspringanimation_p.h1
-rw-r--r--src/quick/util/qquickstate.cpp10
-rw-r--r--src/quick/util/qquickstate_p.h2
-rw-r--r--src/quick/util/qquickstate_p_p.h17
-rw-r--r--src/quick/util/qquickstatechangescript_p.h1
-rw-r--r--src/quick/util/qquickstategroup.cpp36
-rw-r--r--src/quick/util/qquickstategroup_p.h1
-rw-r--r--src/quick/util/qquickstyledtext.cpp20
-rw-r--r--src/quick/util/qquicksystempalette_p.h1
-rw-r--r--src/quick/util/qquicktextmetrics_p.h2
-rw-r--r--src/quick/util/qquicktimeline.cpp2
-rw-r--r--src/quick/util/qquicktimeline_p_p.h3
-rw-r--r--src/quick/util/qquicktransition_p.h1
-rw-r--r--src/quick/util/qquickutilmodule.cpp143
-rw-r--r--src/quick/util/qquickvalidator_p.h2
-rw-r--r--src/quick/util/qquickvaluetypes.cpp43
-rw-r--r--src/quick/util/qquickvaluetypes_p.h56
-rw-r--r--src/quick/util/util.pri7
-rw-r--r--src/quickshapes/qquickshape.cpp22
-rw-r--r--src/quickshapes/qquickshape_p.h14
-rw-r--r--src/quickshapes/qquickshape_p_p.h2
-rw-r--r--src/quickshapes/qquickshapegenericrenderer.cpp6
-rw-r--r--src/quickshapes/qquickshapesglobal_p.h1
-rw-r--r--src/quickshapes/qquickshapesoftwarerenderer.cpp2
-rw-r--r--src/quickshapes/quickshapes.pro6
-rw-r--r--src/quickshapes/shaders_ng/conicalgradient.frag.qsbbin2228 -> 1843 bytes
-rw-r--r--src/quickshapes/shaders_ng/conicalgradient.vert.qsbbin1994 -> 1662 bytes
-rw-r--r--src/quickshapes/shaders_ng/lineargradient.frag.qsbbin1762 -> 1363 bytes
-rw-r--r--src/quickshapes/shaders_ng/lineargradient.vert.qsbbin2225 -> 1869 bytes
-rw-r--r--src/quickshapes/shaders_ng/radialgradient.frag.qsbbin2931 -> 2539 bytes
-rw-r--r--src/quickshapes/shaders_ng/radialgradient.vert.qsbbin2115 -> 1779 bytes
-rw-r--r--src/quickwidgets/qquickwidget.cpp58
-rw-r--r--src/quickwidgets/qquickwidget_p.h2
-rw-r--r--src/src.pro6
691 files changed, 16723 insertions, 16275 deletions
diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h
index 632d1fdbc4..ba57564a1d 100644
--- a/src/3rdparty/masm/assembler/LinkBuffer.h
+++ b/src/3rdparty/masm/assembler/LinkBuffer.h
@@ -209,9 +209,9 @@ public:
// complete generation of the code. Alternatively, call
// finalizeCodeWithoutDisassembly() directly if you have your own way of
// displaying disassembly.
-
+
inline CodeRef finalizeCodeWithoutDisassembly();
- inline CodeRef finalizeCodeWithDisassembly(const char *jitKind, const char* format, ...) WTF_ATTRIBUTE_PRINTF(3, 4);
+ inline CodeRef finalizeCodeWithDisassembly(const char *jitKind, const char* func);
CodePtr trampolineAt(Label label)
{
@@ -267,9 +267,9 @@ protected:
#endif
};
-#define FINALIZE_CODE_IF(condition, linkBufferReference, jitKind, dataLogFArgumentsForHeading) \
+#define FINALIZE_CODE_IF(condition, linkBufferReference, jitKind, func) \
(UNLIKELY((condition)) \
- ? ((linkBufferReference).finalizeCodeWithDisassembly (jitKind, dataLogFArgumentsForHeading)) \
+ ? ((linkBufferReference).finalizeCodeWithDisassembly (jitKind, func)) \
: (linkBufferReference).finalizeCodeWithoutDisassembly())
// Use this to finalize code, like so:
@@ -288,11 +288,11 @@ protected:
// Note that the dataLogFArgumentsForHeading are only evaluated when showDisassembly
// is true, so you can hide expensive disassembly-only computations inside there.
-#define FINALIZE_CODE(linkBufferReference, jitKind, dataLogFArgumentsForHeading) \
- FINALIZE_CODE_IF(Options::showDisassembly(), linkBufferReference, jitKind, dataLogFArgumentsForHeading)
+#define FINALIZE_CODE(linkBufferReference, jitKind, func) \
+ FINALIZE_CODE_IF(Options::showDisassembly(), linkBufferReference, jitKind, func)
-#define FINALIZE_DFG_CODE(linkBufferReference, jitKind, dataLogFArgumentsForHeading) \
- FINALIZE_CODE_IF((Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, jitKind, dataLogFArgumentsForHeading)
+#define FINALIZE_DFG_CODE(linkBufferReference, jitKind, func) \
+ FINALIZE_CODE_IF((Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, jitKind, func)
template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
@@ -304,23 +304,19 @@ inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::Code
}
template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
-inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::CodeRef LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::finalizeCodeWithDisassembly(const char *jitKind, const char* format, ...)
+inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::CodeRef LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::finalizeCodeWithDisassembly(const char *jitKind, const char* func)
{
ASSERT(Options::showDisassembly() || Options::showDFGDisassembly());
CodeRef result = finalizeCodeWithoutDisassembly();
- dataLogF("Generated %s code for ", jitKind);
- va_list argList;
- va_start(argList, format);
- WTF::dataLogFV(format, argList);
- va_end(argList);
+ dataLogF("Generated %s code for function %s:", jitKind, func);
dataLogF(
#if OS(WINDOWS)
- ": Code at [0x%p, 0x%p):",
+ " Code at [0x%p, 0x%p):",
#else
- ": Code at [%p, %p):",
+ " Code at [%p, %p):",
#endif
result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());
disassemble(result.code(), m_size, " ", WTF::dataFile());
diff --git a/src/imports/folderlistmodel/folderlistmodel.pro b/src/imports/folderlistmodel/folderlistmodel.pro
index 54ef107e45..fd05653879 100644
--- a/src/imports/folderlistmodel/folderlistmodel.pro
+++ b/src/imports/folderlistmodel/folderlistmodel.pro
@@ -11,4 +11,5 @@ HEADERS += qquickfolderlistmodel.h \
fileproperty_p.h \
fileinfothread_p.h
+CONFIG += qmltypes install_qmltypes
load(qml_plugin)
diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp
index 31cd793737..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,23 +53,18 @@ 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"));
- qmlRegisterType<QQuickFolderListModel>(uri,1,0,"FolderListModel");
- qmlRegisterType<QQuickFolderListModel>(uri,2,0,"FolderListModel");
- qmlRegisterType<QQuickFolderListModel,1>(uri,2,1,"FolderListModel");
- qmlRegisterType<QQuickFolderListModel,2>(uri,2,2,"FolderListModel");
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
-
- // revision in Qt 5.11: added status property
- qmlRegisterType<QQuickFolderListModel,11>(uri, 2, 11, "FolderListModel");
- // revision in Qt 5.12: added sortCaseSensitive property
- qmlRegisterType<QQuickFolderListModel,12>(uri, 2, 12, "FolderListModel");
+ // Major version 1 only has a single revision, 0.
+ qmlRegisterType<QQuickFolderListModel>(uri, 1, 0, "FolderListModel");
}
};
//![class decl]
diff --git a/src/imports/folderlistmodel/plugins.qmltypes b/src/imports/folderlistmodel/plugins.qmltypes
deleted file mode 100644
index 7c53c99665..0000000000
--- a/src/imports/folderlistmodel/plugins.qmltypes
+++ /dev/null
@@ -1,351 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt.labs.folderlistmodel 2.14'
-
-Module {
- dependencies: ["QtQuick 2.0"]
- Component {
- name: "QAbstractItemModel"
- prototype: "QObject"
- Enum {
- name: "LayoutChangeHint"
- values: {
- "NoLayoutChangeHint": 0,
- "VerticalSortHint": 1,
- "HorizontalSortHint": 2
- }
- }
- Enum {
- name: "CheckIndexOption"
- values: {
- "NoOption": 0,
- "IndexIsValid": 1,
- "DoNotUseParent": 2,
- "ParentIsInvalid": 4
- }
- }
- Signal {
- name: "dataChanged"
- Parameter { name: "topLeft"; type: "QModelIndex" }
- Parameter { name: "bottomRight"; type: "QModelIndex" }
- Parameter { name: "roles"; type: "QVector<int>" }
- }
- Signal {
- name: "dataChanged"
- Parameter { name: "topLeft"; type: "QModelIndex" }
- Parameter { name: "bottomRight"; type: "QModelIndex" }
- }
- Signal {
- name: "headerDataChanged"
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "layoutChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
- }
- Signal {
- name: "layoutChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- }
- Signal { name: "layoutChanged" }
- Signal {
- name: "layoutAboutToBeChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
- }
- Signal {
- name: "layoutAboutToBeChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- }
- Signal { name: "layoutAboutToBeChanged" }
- Signal {
- name: "rowsAboutToBeInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsAboutToBeRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal { name: "modelAboutToBeReset" }
- Signal { name: "modelReset" }
- Signal {
- name: "rowsAboutToBeMoved"
- Parameter { name: "sourceParent"; type: "QModelIndex" }
- Parameter { name: "sourceStart"; type: "int" }
- Parameter { name: "sourceEnd"; type: "int" }
- Parameter { name: "destinationParent"; type: "QModelIndex" }
- Parameter { name: "destinationRow"; type: "int" }
- }
- Signal {
- name: "rowsMoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- Parameter { name: "destination"; type: "QModelIndex" }
- Parameter { name: "row"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeMoved"
- Parameter { name: "sourceParent"; type: "QModelIndex" }
- Parameter { name: "sourceStart"; type: "int" }
- Parameter { name: "sourceEnd"; type: "int" }
- Parameter { name: "destinationParent"; type: "QModelIndex" }
- Parameter { name: "destinationColumn"; type: "int" }
- }
- Signal {
- name: "columnsMoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- Parameter { name: "destination"; type: "QModelIndex" }
- Parameter { name: "column"; type: "int" }
- }
- Method { name: "submit"; type: "bool" }
- Method { name: "revert" }
- Method {
- name: "hasIndex"
- type: "bool"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "hasIndex"
- type: "bool"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- }
- Method {
- name: "index"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "index"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- }
- Method {
- name: "parent"
- type: "QModelIndex"
- Parameter { name: "child"; type: "QModelIndex" }
- }
- Method {
- name: "sibling"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "idx"; type: "QModelIndex" }
- }
- Method {
- name: "rowCount"
- type: "int"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "rowCount"; type: "int" }
- Method {
- name: "columnCount"
- type: "int"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "columnCount"; type: "int" }
- Method {
- name: "hasChildren"
- type: "bool"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "hasChildren"; type: "bool" }
- Method {
- name: "data"
- type: "QVariant"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "data"
- type: "QVariant"
- Parameter { name: "index"; type: "QModelIndex" }
- }
- Method {
- name: "setData"
- type: "bool"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "setData"
- type: "bool"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "value"; type: "QVariant" }
- }
- Method {
- name: "headerData"
- type: "QVariant"
- Parameter { name: "section"; type: "int" }
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "headerData"
- type: "QVariant"
- Parameter { name: "section"; type: "int" }
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- }
- Method {
- name: "fetchMore"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "canFetchMore"
- type: "bool"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "flags"
- type: "Qt::ItemFlags"
- Parameter { name: "index"; type: "QModelIndex" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "hits"; type: "int" }
- Parameter { name: "flags"; type: "Qt::MatchFlags" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "hits"; type: "int" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- }
- }
- Component { name: "QAbstractListModel"; prototype: "QAbstractItemModel" }
- Component {
- name: "QQuickFolderListModel"
- prototype: "QAbstractListModel"
- exports: [
- "Qt.labs.folderlistmodel/FolderListModel 1.0",
- "Qt.labs.folderlistmodel/FolderListModel 2.0",
- "Qt.labs.folderlistmodel/FolderListModel 2.1",
- "Qt.labs.folderlistmodel/FolderListModel 2.11",
- "Qt.labs.folderlistmodel/FolderListModel 2.12",
- "Qt.labs.folderlistmodel/FolderListModel 2.2"
- ]
- exportMetaObjectRevisions: [0, 0, 1, 11, 12, 2]
- Enum {
- name: "SortField"
- values: {
- "Unsorted": 0,
- "Name": 1,
- "Time": 2,
- "Size": 3,
- "Type": 4
- }
- }
- Enum {
- name: "Status"
- values: {
- "Null": 0,
- "Ready": 1,
- "Loading": 2
- }
- }
- Property { name: "folder"; type: "QUrl" }
- Property { name: "rootFolder"; type: "QUrl" }
- Property { name: "parentFolder"; type: "QUrl"; isReadonly: true }
- Property { name: "nameFilters"; type: "QStringList" }
- Property { name: "sortField"; type: "SortField" }
- Property { name: "sortReversed"; type: "bool" }
- Property { name: "showFiles"; revision: 1; type: "bool" }
- Property { name: "showDirs"; type: "bool" }
- Property { name: "showDirsFirst"; type: "bool" }
- Property { name: "showDotAndDotDot"; type: "bool" }
- Property { name: "showHidden"; revision: 1; type: "bool" }
- Property { name: "showOnlyReadable"; type: "bool" }
- Property { name: "caseSensitive"; revision: 2; type: "bool" }
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "status"; revision: 11; type: "Status"; isReadonly: true }
- Property { name: "sortCaseSensitive"; revision: 12; type: "bool" }
- Signal { name: "rowCountChanged" }
- Signal { name: "countChanged"; revision: 1 }
- Signal { name: "statusChanged"; revision: 11 }
- Method {
- name: "isFolder"
- type: "bool"
- Parameter { name: "index"; type: "int" }
- }
- Method {
- name: "get"
- type: "QVariant"
- Parameter { name: "idx"; type: "int" }
- Parameter { name: "property"; type: "string" }
- }
- Method {
- name: "indexOf"
- type: "int"
- Parameter { name: "file"; type: "QUrl" }
- }
- }
-}
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
index f5acfd86b7..44f0a49d76 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
@@ -107,7 +107,7 @@ void QQuickFolderListModelPrivate::updateSorting()
{
Q_Q(QQuickFolderListModel);
- QDir::SortFlags flags = nullptr;
+ QDir::SortFlags flags;
switch (sortField) {
case QQuickFolderListModel::Unsorted:
@@ -255,7 +255,8 @@ QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path)
\list
\li \c fileName
\li \c filePath
- \li \c fileURL (since Qt 5.2)
+ \li \c fileURL (since Qt 5.2; deprecated since Qt 5.15)
+ \li \c fileUrl (since Qt 5.15)
\li \c fileBaseName
\li \c fileSuffix
\li \c fileSize
@@ -334,7 +335,8 @@ QQuickFolderListModel::QQuickFolderListModel(QObject *parent)
d->roleNames[FileLastModifiedRole] = "fileModified";
d->roleNames[FileLastReadRole] = "fileAccessed";
d->roleNames[FileIsDirRole] = "fileIsDir";
- d->roleNames[FileUrlRole] = "fileURL";
+ d->roleNames[FileUrlRole] = "fileUrl";
+ d->roleNames[FileURLRole] = "fileURL";
d->init();
}
@@ -377,6 +379,7 @@ QVariant QQuickFolderListModel::data(const QModelIndex &index, int role) const
rv = d->data.at(index.row()).isDir();
break;
case FileUrlRole:
+ case FileURLRole:
rv = QUrl::fromLocalFile(d->data.at(index.row()).filePath());
break;
default:
@@ -886,7 +889,8 @@ void QQuickFolderListModel::setSortCaseSensitive(bool on)
\list
\li \c fileName
\li \c filePath
- \li \c fileURL (since Qt 5.2)
+ \li \c fileURL (since Qt 5.2; deprecated since Qt 5.15)
+ \li \c fileUrl (since Qt 5.15)
\li \c fileBaseName
\li \c fileSuffix
\li \c fileSize
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h
index d93e7daf3f..772976d65a 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.h
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h
@@ -79,6 +79,7 @@ class QQuickFolderListModel : public QAbstractListModel, public QQmlParserStatus
Q_PROPERTY(bool sortCaseSensitive READ sortCaseSensitive WRITE setSortCaseSensitive REVISION 12)
//![class props]
+ QML_NAMED_ELEMENT(FolderListModel)
//![abslistmodel]
public:
QQuickFolderListModel(QObject *parent = nullptr);
@@ -93,7 +94,8 @@ public:
FileLastModifiedRole = Qt::UserRole + 6,
FileLastReadRole = Qt::UserRole +7,
FileIsDirRole = Qt::UserRole + 8,
- FileUrlRole = Qt::UserRole + 9
+ FileUrlRole = Qt::UserRole + 9,
+ FileURLRole = Qt::UserRole + 10
};
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
diff --git a/src/imports/labsanimation/labsanimation.pro b/src/imports/labsanimation/labsanimation.pro
index 64e076401f..f64ae775c6 100644
--- a/src/imports/labsanimation/labsanimation.pro
+++ b/src/imports/labsanimation/labsanimation.pro
@@ -4,8 +4,13 @@ TARGETPATH = Qt/labs/animation
IMPORT_VERSION = 1.0
SOURCES += \
+ qquickboundaryrule.cpp \
plugin.cpp
+HEADERS += \
+ qquickboundaryrule_p.h
+
QT = qml-private quick-private
+CONFIG += qmltypes install_qmltypes
load(qml_plugin)
diff --git a/src/imports/labsanimation/plugin.cpp b/src/imports/labsanimation/plugin.cpp
index d8c0c071ca..9c985f0dcf 100644
--- a/src/imports/labsanimation/plugin.cpp
+++ b/src/imports/labsanimation/plugin.cpp
@@ -40,7 +40,9 @@
#include <QtQml/qqmlextensionplugin.h>
#include <QtQml/qqml.h>
-#include <private/qquickboundaryrule_p.h>
+#include "qquickboundaryrule_p.h"
+
+extern void qml_register_types_Qt_labs_animation();
QT_BEGIN_NAMESPACE
@@ -61,17 +63,15 @@ QT_BEGIN_NAMESPACE
*/
//![class decl]
-class QtLabsAnimationPlugin : public QQmlExtensionPlugin
+class QtLabsAnimationPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtLabsAnimationPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
+ QtLabsAnimationPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.animation"));
- qmlRegisterType<QQuickBoundaryRule>(uri, 1, 0, "BoundaryRule");
- qmlRegisterModule(uri, 1, 0);
+ volatile auto registration = &qml_register_types_Qt_labs_animation;
+ Q_UNUSED(registration);
}
};
//![class decl]
diff --git a/src/imports/labsanimation/plugins.qmltypes b/src/imports/labsanimation/plugins.qmltypes
deleted file mode 100644
index 2ecc5e6f5d..0000000000
--- a/src/imports/labsanimation/plugins.qmltypes
+++ /dev/null
@@ -1,36 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt.labs.animation 1.0'
-
-Module {
- dependencies: []
- Component {
- name: "QQuickBoundaryRule"
- prototype: "QObject"
- exports: ["Qt.labs.animation/BoundaryRule 1.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "OvershootFilter"
- values: {
- "None": 0,
- "Peak": 1
- }
- }
- Property { name: "enabled"; type: "bool" }
- Property { name: "minimum"; type: "double" }
- Property { name: "minimumOvershoot"; type: "double" }
- Property { name: "maximum"; type: "double" }
- Property { name: "maximumOvershoot"; type: "double" }
- Property { name: "overshootScale"; type: "double" }
- Property { name: "currentOvershoot"; type: "double"; isReadonly: true }
- Property { name: "peakOvershoot"; type: "double"; isReadonly: true }
- Property { name: "overshootFilter"; type: "OvershootFilter" }
- Property { name: "easing"; type: "QEasingCurve" }
- Property { name: "returnDuration"; type: "int" }
- Method { name: "returnToBounds"; type: "bool" }
- }
-}
diff --git a/src/quick/util/qquickboundaryrule.cpp b/src/imports/labsanimation/qquickboundaryrule.cpp
index 3558c8bfa0..3558c8bfa0 100644
--- a/src/quick/util/qquickboundaryrule.cpp
+++ b/src/imports/labsanimation/qquickboundaryrule.cpp
diff --git a/src/quick/util/qquickboundaryrule_p.h b/src/imports/labsanimation/qquickboundaryrule_p.h
index 3325b675c5..1681558304 100644
--- a/src/quick/util/qquickboundaryrule_p.h
+++ b/src/imports/labsanimation/qquickboundaryrule_p.h
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class QQuickAbstractAnimation;
class QQuickBoundaryRulePrivate;
-class Q_QUICK_PRIVATE_EXPORT QQuickBoundaryRule : public QObject, public QQmlPropertyValueInterceptor
+class QQuickBoundaryRule : public QObject, public QQmlPropertyValueInterceptor
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickBoundaryRule)
@@ -77,6 +77,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBoundaryRule : public QObject, public QQmlPro
Q_PROPERTY(OvershootFilter overshootFilter READ overshootFilter WRITE setOvershootFilter NOTIFY overshootFilterChanged)
Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
Q_PROPERTY(int returnDuration READ returnDuration WRITE setReturnDuration NOTIFY returnDurationChanged)
+ QML_NAMED_ELEMENT(BoundaryRule)
public:
enum OvershootFilter {
diff --git a/src/imports/labsmodels/labsmodels.pro b/src/imports/labsmodels/labsmodels.pro
index 5ef2ad76f6..13468348cb 100644
--- a/src/imports/labsmodels/labsmodels.pro
+++ b/src/imports/labsmodels/labsmodels.pro
@@ -3,9 +3,28 @@ TARGET = labsmodelsplugin
TARGETPATH = Qt/labs/qmlmodels
IMPORT_VERSION = 1.0
+QT = qml-private qmlmodels-private
+
SOURCES += \
plugin.cpp
-QT = qml-private qmlmodels-private
+qtConfig(qml-table-model) {
+ SOURCES += \
+ $$PWD/qqmltablemodel.cpp \
+ $$PWD/qqmltablemodelcolumn.cpp
+
+ HEADERS += \
+ $$PWD/qqmltablemodel_p.h \
+ $$PWD/qqmltablemodelcolumn_p.h
+}
+
+qtConfig(qml-delegate-model) {
+ SOURCES += \
+ qqmldelegatecomponent.cpp
+
+ HEADERS += \
+ qqmldelegatecomponent_p.h
+}
+CONFIG += qmltypes install_qmltypes
load(qml_plugin)
diff --git a/src/imports/labsmodels/plugin.cpp b/src/imports/labsmodels/plugin.cpp
index 697235e1ca..ab5e0023a6 100644
--- a/src/imports/labsmodels/plugin.cpp
+++ b/src/imports/labsmodels/plugin.cpp
@@ -42,6 +42,16 @@
#include <private/qqmlmodelsmodule_p.h>
+#if QT_CONFIG(qml_table_model)
+#include "qqmltablemodel_p.h"
+#include "qqmltablemodelcolumn_p.h"
+#endif
+#if QT_CONFIG(qml_delegate_model)
+#include "qqmldelegatecomponent_p.h"
+#endif
+
+extern void qml_register_types_Qt_labs_qmlmodels();
+
QT_BEGIN_NAMESPACE
/*!
@@ -61,18 +71,15 @@ QT_BEGIN_NAMESPACE
*/
//![class decl]
-class QtQmlLabsModelsPlugin : public QQmlExtensionPlugin
+class QtQmlLabsModelsPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQmlLabsModelsPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
+ QtQmlLabsModelsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.qmlmodels"));
- QQmlModelsModule::defineLabsModule();
-
- qmlRegisterModule(uri, 1, 0);
+ volatile auto registration = &qml_register_types_Qt_labs_qmlmodels;
+ Q_UNUSED(registration);
}
};
//![class decl]
diff --git a/src/imports/labsmodels/plugins.qmltypes b/src/imports/labsmodels/plugins.qmltypes
deleted file mode 100644
index f2a5752422..0000000000
--- a/src/imports/labsmodels/plugins.qmltypes
+++ /dev/null
@@ -1,414 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt.labs.qmlmodels 1.0'
-
-Module {
- dependencies: []
- Component {
- name: "QAbstractItemModel"
- prototype: "QObject"
- Enum {
- name: "LayoutChangeHint"
- values: {
- "NoLayoutChangeHint": 0,
- "VerticalSortHint": 1,
- "HorizontalSortHint": 2
- }
- }
- Enum {
- name: "CheckIndexOption"
- values: {
- "NoOption": 0,
- "IndexIsValid": 1,
- "DoNotUseParent": 2,
- "ParentIsInvalid": 4
- }
- }
- Signal {
- name: "dataChanged"
- Parameter { name: "topLeft"; type: "QModelIndex" }
- Parameter { name: "bottomRight"; type: "QModelIndex" }
- Parameter { name: "roles"; type: "QVector<int>" }
- }
- Signal {
- name: "dataChanged"
- Parameter { name: "topLeft"; type: "QModelIndex" }
- Parameter { name: "bottomRight"; type: "QModelIndex" }
- }
- Signal {
- name: "headerDataChanged"
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "layoutChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
- }
- Signal {
- name: "layoutChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- }
- Signal { name: "layoutChanged" }
- Signal {
- name: "layoutAboutToBeChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
- }
- Signal {
- name: "layoutAboutToBeChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- }
- Signal { name: "layoutAboutToBeChanged" }
- Signal {
- name: "rowsAboutToBeInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsAboutToBeRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal { name: "modelAboutToBeReset" }
- Signal { name: "modelReset" }
- Signal {
- name: "rowsAboutToBeMoved"
- Parameter { name: "sourceParent"; type: "QModelIndex" }
- Parameter { name: "sourceStart"; type: "int" }
- Parameter { name: "sourceEnd"; type: "int" }
- Parameter { name: "destinationParent"; type: "QModelIndex" }
- Parameter { name: "destinationRow"; type: "int" }
- }
- Signal {
- name: "rowsMoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- Parameter { name: "destination"; type: "QModelIndex" }
- Parameter { name: "row"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeMoved"
- Parameter { name: "sourceParent"; type: "QModelIndex" }
- Parameter { name: "sourceStart"; type: "int" }
- Parameter { name: "sourceEnd"; type: "int" }
- Parameter { name: "destinationParent"; type: "QModelIndex" }
- Parameter { name: "destinationColumn"; type: "int" }
- }
- Signal {
- name: "columnsMoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- Parameter { name: "destination"; type: "QModelIndex" }
- Parameter { name: "column"; type: "int" }
- }
- Method { name: "submit"; type: "bool" }
- Method { name: "revert" }
- Method {
- name: "hasIndex"
- type: "bool"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "hasIndex"
- type: "bool"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- }
- Method {
- name: "index"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "index"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- }
- Method {
- name: "parent"
- type: "QModelIndex"
- Parameter { name: "child"; type: "QModelIndex" }
- }
- Method {
- name: "sibling"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "idx"; type: "QModelIndex" }
- }
- Method {
- name: "rowCount"
- type: "int"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "rowCount"; type: "int" }
- Method {
- name: "columnCount"
- type: "int"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "columnCount"; type: "int" }
- Method {
- name: "hasChildren"
- type: "bool"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "hasChildren"; type: "bool" }
- Method {
- name: "data"
- type: "QVariant"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "data"
- type: "QVariant"
- Parameter { name: "index"; type: "QModelIndex" }
- }
- Method {
- name: "setData"
- type: "bool"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "setData"
- type: "bool"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "value"; type: "QVariant" }
- }
- Method {
- name: "headerData"
- type: "QVariant"
- Parameter { name: "section"; type: "int" }
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "headerData"
- type: "QVariant"
- Parameter { name: "section"; type: "int" }
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- }
- Method {
- name: "fetchMore"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "canFetchMore"
- type: "bool"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "flags"
- type: "Qt::ItemFlags"
- Parameter { name: "index"; type: "QModelIndex" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "hits"; type: "int" }
- Parameter { name: "flags"; type: "Qt::MatchFlags" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "hits"; type: "int" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- }
- }
- Component { name: "QAbstractTableModel"; prototype: "QAbstractItemModel" }
- Component {
- name: "QQmlAbstractDelegateComponent"
- prototype: "QQmlComponent"
- exports: ["Qt.labs.qmlmodels/AbstractDelegateComponent 1.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Signal { name: "delegateChanged" }
- }
- Component {
- name: "QQmlDelegateChoice"
- defaultProperty: "delegate"
- prototype: "QObject"
- exports: ["Qt.labs.qmlmodels/DelegateChoice 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "roleValue"; type: "QVariant" }
- Property { name: "row"; type: "int" }
- Property { name: "index"; type: "int" }
- Property { name: "column"; type: "int" }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Signal { name: "changed" }
- }
- Component {
- name: "QQmlDelegateChooser"
- defaultProperty: "choices"
- prototype: "QQmlAbstractDelegateComponent"
- exports: ["Qt.labs.qmlmodels/DelegateChooser 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "role"; type: "string" }
- Property { name: "choices"; type: "QQmlDelegateChoice"; isList: true; isReadonly: true }
- }
- Component {
- name: "QQmlTableModel"
- defaultProperty: "columns"
- prototype: "QAbstractTableModel"
- exports: ["Qt.labs.qmlmodels/TableModel 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "columnCount"; type: "int"; isReadonly: true }
- Property { name: "rowCount"; type: "int"; isReadonly: true }
- Property { name: "rows"; type: "QVariant" }
- Property { name: "columns"; type: "QQmlTableModelColumn"; isList: true; isReadonly: true }
- Method {
- name: "appendRow"
- Parameter { name: "row"; type: "QVariant" }
- }
- Method { name: "clear" }
- Method {
- name: "getRow"
- type: "QVariant"
- Parameter { name: "rowIndex"; type: "int" }
- }
- Method {
- name: "insertRow"
- Parameter { name: "rowIndex"; type: "int" }
- Parameter { name: "row"; type: "QVariant" }
- }
- Method {
- name: "moveRow"
- Parameter { name: "fromRowIndex"; type: "int" }
- Parameter { name: "toRowIndex"; type: "int" }
- Parameter { name: "rows"; type: "int" }
- }
- Method {
- name: "moveRow"
- Parameter { name: "fromRowIndex"; type: "int" }
- Parameter { name: "toRowIndex"; type: "int" }
- }
- Method {
- name: "removeRow"
- Parameter { name: "rowIndex"; type: "int" }
- Parameter { name: "rows"; type: "int" }
- }
- Method {
- name: "removeRow"
- Parameter { name: "rowIndex"; type: "int" }
- }
- Method {
- name: "setRow"
- Parameter { name: "rowIndex"; type: "int" }
- Parameter { name: "row"; type: "QVariant" }
- }
- Method {
- name: "data"
- type: "QVariant"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "role"; type: "string" }
- }
- Method {
- name: "setData"
- type: "bool"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "role"; type: "string" }
- Parameter { name: "value"; type: "QVariant" }
- }
- }
- Component {
- name: "QQmlTableModelColumn"
- prototype: "QObject"
- exports: ["Qt.labs.qmlmodels/TableModelColumn 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "display"; type: "QJSValue" }
- Property { name: "setDisplay"; type: "QJSValue" }
- Property { name: "decoration"; type: "QJSValue" }
- Property { name: "setDecoration"; type: "QJSValue" }
- Property { name: "edit"; type: "QJSValue" }
- Property { name: "setEdit"; type: "QJSValue" }
- Property { name: "toolTip"; type: "QJSValue" }
- Property { name: "setToolTip"; type: "QJSValue" }
- Property { name: "statusTip"; type: "QJSValue" }
- Property { name: "setStatusTip"; type: "QJSValue" }
- Property { name: "whatsThis"; type: "QJSValue" }
- Property { name: "setWhatsThis"; type: "QJSValue" }
- Property { name: "font"; type: "QJSValue" }
- Property { name: "setFont"; type: "QJSValue" }
- Property { name: "textAlignment"; type: "QJSValue" }
- Property { name: "setTextAlignment"; type: "QJSValue" }
- Property { name: "background"; type: "QJSValue" }
- Property { name: "setBackground"; type: "QJSValue" }
- Property { name: "foreground"; type: "QJSValue" }
- Property { name: "setForeground"; type: "QJSValue" }
- Property { name: "checkState"; type: "QJSValue" }
- Property { name: "setCheckState"; type: "QJSValue" }
- Property { name: "accessibleText"; type: "QJSValue" }
- Property { name: "setAccessibleText"; type: "QJSValue" }
- Property { name: "accessibleDescription"; type: "QJSValue" }
- Property { name: "setAccessibleDescription"; type: "QJSValue" }
- Property { name: "sizeHint"; type: "QJSValue" }
- Property { name: "setSizeHint"; type: "QJSValue" }
- Signal { name: "indexChanged" }
- }
-}
diff --git a/src/qmlmodels/qqmldelegatecomponent.cpp b/src/imports/labsmodels/qqmldelegatecomponent.cpp
index ccd54bccec..b8eb8049b3 100644
--- a/src/qmlmodels/qqmldelegatecomponent.cpp
+++ b/src/imports/labsmodels/qqmldelegatecomponent.cpp
@@ -42,22 +42,6 @@
QT_BEGIN_NAMESPACE
-QQmlAbstractDelegateComponent::QQmlAbstractDelegateComponent(QObject *parent)
- : QQmlComponent(parent)
-{
-}
-
-QQmlAbstractDelegateComponent::~QQmlAbstractDelegateComponent()
-{
-}
-
-QVariant QQmlAbstractDelegateComponent::value(QQmlAdaptorModel *adaptorModel, int row, int column, const QString &role) const
-{
- if (!adaptorModel)
- return QVariant();
- return adaptorModel->value(adaptorModel->indexAt(row, column), role);
-}
-
/*!
\qmltype DelegateChoice
\instantiates QQmlDelegateChoice
@@ -234,7 +218,7 @@ bool QQmlDelegateChoice::match(int row, int column, const QVariant &value) const
/*!
\qmlproperty string QtQml.Models::DelegateChooser::role
- This property holds the role used to determine the delegate for a given model item.
+ This property holds the role or the property name used to determine the delegate for a given model item.
\sa DelegateChoice
*/
@@ -266,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)
@@ -298,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;
@@ -305,9 +311,15 @@ QQmlComponent *QQmlDelegateChooser::delegate(QQmlAdaptorModel *adaptorModel, int
v = value(adaptorModel, row, column, m_role);
if (!v.isValid()) { // check if the row only has modelData, for example if the row is a QVariantMap
v = value(adaptorModel, row, column, QStringLiteral("modelData"));
- if (v.isValid())
- v = v.toMap().value(m_role);
+
+ if (v.isValid()) {
+ if (v.canConvert(QMetaType::QVariantMap))
+ v = v.toMap().value(m_role);
+ else if (v.canConvert(QMetaType::QObjectStar))
+ v = v.value<QObject*>()->property(m_role.toUtf8());
+ }
}
+
// loop through choices, finding first one that fits
for (int i = 0; i < m_choices.count(); ++i) {
const QQmlDelegateChoice *choice = m_choices.at(i);
diff --git a/src/qmlmodels/qqmldelegatecomponent_p.h b/src/imports/labsmodels/qqmldelegatecomponent_p.h
index 1d20f0327b..8473831b1d 100644
--- a/src/qmlmodels/qqmldelegatecomponent_p.h
+++ b/src/imports/labsmodels/qqmldelegatecomponent_p.h
@@ -51,37 +51,15 @@
// We mean it.
//
-#include <private/qtqmlmodelsglobal_p.h>
-#include <qqmlcomponent.h>
+#include <QtQmlModels/private/qtqmlmodelsglobal_p.h>
+#include <QtQmlModels/private/qqmlabstractdelegatecomponent_p.h>
+#include <QtQml/qqmlcomponent.h>
QT_REQUIRE_CONFIG(qml_delegate_model);
QT_BEGIN_NAMESPACE
-// TODO: consider making QQmlAbstractDelegateComponent public API
-class QQmlAbstractDelegateComponentPrivate;
-class QQmlAdaptorModel;
-class Q_QMLMODELS_PRIVATE_EXPORT QQmlAbstractDelegateComponent : public QQmlComponent
-{
- Q_OBJECT
-public:
- QQmlAbstractDelegateComponent(QObject *parent = nullptr);
- ~QQmlAbstractDelegateComponent() override;
-
- virtual QQmlComponent *delegate(QQmlAdaptorModel *adaptorModel, int row, int column = 0) const = 0;
-
-signals:
- void delegateChanged();
-
-protected:
- QVariant value(QQmlAdaptorModel *adaptorModel,int row, int column, const QString &role) const;
-
-private:
- Q_DECLARE_PRIVATE(QQmlAbstractDelegateComponent)
- Q_DISABLE_COPY(QQmlAbstractDelegateComponent)
-};
-
-class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateChoice : public QObject
+class QQmlDelegateChoice : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariant roleValue READ roleValue WRITE setRoleValue NOTIFY roleValueChanged)
@@ -90,6 +68,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateChoice : public QObject
Q_PROPERTY(int column READ column WRITE setColumn NOTIFY columnChanged)
Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_CLASSINFO("DefaultProperty", "delegate")
+ QML_NAMED_ELEMENT(DelegateChoice)
public:
QVariant roleValue() const;
void setRoleValue(const QVariant &roleValue);
@@ -120,12 +99,13 @@ private:
QQmlComponent *m_delegate = nullptr;
};
-class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateChooser : public QQmlAbstractDelegateComponent
+class QQmlDelegateChooser : public QQmlAbstractDelegateComponent
{
Q_OBJECT
Q_PROPERTY(QString role READ role WRITE setRole NOTIFY roleChanged)
Q_PROPERTY(QQmlListProperty<QQmlDelegateChoice> choices READ choices CONSTANT)
Q_CLASSINFO("DefaultProperty", "choices")
+ QML_NAMED_ELEMENT(DelegateChooser)
public:
QString role() const { return m_role; }
@@ -136,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/qmlmodels/qqmltablemodel.cpp b/src/imports/labsmodels/qqmltablemodel.cpp
index fab20f7410..5a2d68780c 100644
--- a/src/qmlmodels/qqmltablemodel.cpp
+++ b/src/imports/labsmodels/qqmltablemodel.cpp
@@ -271,7 +271,7 @@ QQmlTableModel::ColumnRoleMetadata QQmlTableModel::fetchColumnRoleData(const QSt
if (columnRoleGetter.isString()) {
// The role is set as a string, so we assume the row is a simple object.
- if (firstRow.type() != QVariant::Map) {
+ if (firstRow.userType() != QMetaType::QVariantMap) {
qmlWarning(this).quote() << "expected row for role "
<< roleNameKey << " of TableModelColumn at index "
<< columnIndex << " to be a simple object, but it's "
@@ -284,7 +284,7 @@ QQmlTableModel::ColumnRoleMetadata QQmlTableModel::fetchColumnRoleData(const QSt
roleData.isStringRole = true;
roleData.name = rolePropertyName;
- roleData.type = roleProperty.type();
+ roleData.type = roleProperty.userType();
roleData.typeName = QString::fromLatin1(roleProperty.typeName());
} else if (columnRoleGetter.isCallable()) {
// The role is provided via a function, which means the row is complex and
@@ -296,7 +296,7 @@ QQmlTableModel::ColumnRoleMetadata QQmlTableModel::fetchColumnRoleData(const QSt
// We don't know the property name since it's provided through the function.
// roleData.name = ???
roleData.isStringRole = false;
- roleData.type = cellData.type();
+ roleData.type = cellData.userType();
roleData.typeName = QString::fromLatin1(cellData.typeName());
} else {
// Invalid role.
@@ -326,7 +326,7 @@ void QQmlTableModel::fetchColumnMetadata()
for (const int builtInRoleKey : builtInRoleKeys) {
const QString builtInRoleName = supportedRoleNames.value(builtInRoleKey);
ColumnRoleMetadata roleData = fetchColumnRoleData(builtInRoleName, column, columnIndex);
- if (roleData.type == QVariant::Invalid) {
+ if (roleData.type == QMetaType::UnknownType) {
// This built-in role was not specified in this column.
continue;
}
@@ -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)
@@ -847,7 +862,7 @@ bool QQmlTableModel::setData(const QModelIndex &index, const QVariant &value, in
// If the value set is not of the expected type, we can try to convert it automatically.
const ColumnRoleMetadata roleData = columnMetadata.roles.value(roleName);
QVariant effectiveValue = value;
- if (value.type() != roleData.type) {
+ if (value.userType() != roleData.type) {
if (!value.canConvert(int(roleData.type))) {
qmlWarning(this).nospace() << "setData(): the value " << value
<< " set at row " << row << " column " << column << " with role " << roleName
@@ -933,7 +948,7 @@ QQmlTableModel::ColumnRoleMetadata::ColumnRoleMetadata()
}
QQmlTableModel::ColumnRoleMetadata::ColumnRoleMetadata(
- bool isStringRole, const QString &name, QVariant::Type type, const QString &typeName) :
+ bool isStringRole, const QString &name, int type, const QString &typeName) :
isStringRole(isStringRole),
name(name),
type(type),
@@ -995,7 +1010,7 @@ bool QQmlTableModel::validateNewRow(const char *functionName, const QVariant &ro
const QVariant rowAsVariant = operation == SetRowsOperation
? row : row.value<QJSValue>().toVariant();
- if (rowAsVariant.type() != QVariant::Map) {
+ if (rowAsVariant.userType() != QMetaType::QVariantMap) {
qmlWarning(this) << functionName << ": row manipulation functions "
<< "do not support complex rows (row index: " << rowIndex << ")";
return false;
@@ -1029,7 +1044,7 @@ bool QQmlTableModel::validateNewRow(const char *functionName, const QVariant &ro
const QVariant rolePropertyValue = rowAsMap.value(roleData.name);
- if (rolePropertyValue.type() != roleData.type) {
+ if (rolePropertyValue.userType() != roleData.type) {
if (!rolePropertyValue.canConvert(int(roleData.type))) {
qmlWarning(this).quote() << functionName << ": expected the property named "
<< roleData.name << " to be of type " << roleData.typeName
diff --git a/src/qmlmodels/qqmltablemodel_p.h b/src/imports/labsmodels/qqmltablemodel_p.h
index b3c0cc2848..75e2768849 100644
--- a/src/qmlmodels/qqmltablemodel_p.h
+++ b/src/imports/labsmodels/qqmltablemodel_p.h
@@ -51,11 +51,12 @@
// We mean it.
//
+#include "qqmltablemodelcolumn_p.h"
+
#include <QtCore/QObject>
#include <QtCore/QAbstractTableModel>
#include <QtQml/qqml.h>
#include <QtQmlModels/private/qtqmlmodelsglobal_p.h>
-#include <QtQmlModels/private/qqmltablemodelcolumn_p.h>
#include <QtQml/QJSValue>
#include <QtQml/QQmlListProperty>
@@ -63,7 +64,7 @@ QT_REQUIRE_CONFIG(qml_table_model);
QT_BEGIN_NAMESPACE
-class Q_QMLMODELS_PRIVATE_EXPORT QQmlTableModel : public QAbstractTableModel, public QQmlParserStatus
+class QQmlTableModel : public QAbstractTableModel, public QQmlParserStatus
{
Q_OBJECT
Q_PROPERTY(int columnCount READ columnCount NOTIFY columnCountChanged FINAL)
@@ -72,6 +73,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlTableModel : public QAbstractTableModel, pu
Q_PROPERTY(QQmlListProperty<QQmlTableModelColumn> columns READ columns CONSTANT FINAL)
Q_INTERFACES(QQmlParserStatus)
Q_CLASSINFO("DefaultProperty", "columns")
+ QML_NAMED_ELEMENT(TableModel)
public:
QQmlTableModel(QObject *parent = nullptr);
@@ -94,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;
@@ -114,14 +118,14 @@ private:
{
public:
ColumnRoleMetadata();
- ColumnRoleMetadata(bool isStringRole, const QString &name, QVariant::Type type, const QString &typeName);
+ ColumnRoleMetadata(bool isStringRole, const QString &name, int type, const QString &typeName);
bool isValid() const;
// If this is false, it's a function role.
bool isStringRole = false;
QString name;
- QVariant::Type type = QVariant::Invalid;
+ int type = QMetaType::UnknownType;
QString typeName;
};
diff --git a/src/qmlmodels/qqmltablemodelcolumn.cpp b/src/imports/labsmodels/qqmltablemodelcolumn.cpp
index 93da0642de..93da0642de 100644
--- a/src/qmlmodels/qqmltablemodelcolumn.cpp
+++ b/src/imports/labsmodels/qqmltablemodelcolumn.cpp
diff --git a/src/qmlmodels/qqmltablemodelcolumn_p.h b/src/imports/labsmodels/qqmltablemodelcolumn_p.h
index 0b6478ce38..a18f21ab4f 100644
--- a/src/qmlmodels/qqmltablemodelcolumn_p.h
+++ b/src/imports/labsmodels/qqmltablemodelcolumn_p.h
@@ -60,7 +60,7 @@ QT_REQUIRE_CONFIG(qml_table_model);
QT_BEGIN_NAMESPACE
-class Q_QMLMODELS_PRIVATE_EXPORT QQmlTableModelColumn : public QObject
+class QQmlTableModelColumn : public QObject
{
Q_OBJECT
Q_PROPERTY(QJSValue display READ display WRITE setDisplay NOTIFY displayChanged FINAL)
@@ -96,6 +96,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlTableModelColumn : public QObject
Q_PROPERTY(QJSValue sizeHint READ sizeHint WRITE setSizeHint NOTIFY sizeHintChanged FINAL)
Q_PROPERTY(QJSValue setSizeHint READ getSetSizeHint WRITE setSetSizeHint NOTIFY setSizeHintChanged FINAL)
+ QML_NAMED_ELEMENT(TableModelColumn)
public:
QQmlTableModelColumn(QObject *parent = nullptr);
diff --git a/src/imports/layouts/layouts.pro b/src/imports/layouts/layouts.pro
index addf396746..ea7940e4ad 100644
--- a/src/imports/layouts/layouts.pro
+++ b/src/imports/layouts/layouts.pro
@@ -19,4 +19,6 @@ HEADERS += \
qquickgridlayoutengine_p.h \
qquicklayoutstyleinfo_p.h
+CONFIG += qmltypes install_qmltypes
+
load(qml_plugin)
diff --git a/src/imports/layouts/plugin.cpp b/src/imports/layouts/plugin.cpp
index d28109c3cf..af270c1732 100644
--- a/src/imports/layouts/plugin.cpp
+++ b/src/imports/layouts/plugin.cpp
@@ -42,33 +42,20 @@
#include "qquicklinearlayout_p.h"
#include "qquickstacklayout_p.h"
+extern void qml_register_types_QtQuick_Layouts();
+
QT_BEGIN_NAMESPACE
//![class decl]
-class QtQuickLayoutsPlugin : public QQmlExtensionPlugin
+class QtQuickLayoutsPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQuickLayoutsPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent)
- {
- }
- void registerTypes(const char *uri) override
+ QtQuickLayoutsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Layouts"));
-
- qmlRegisterType<QQuickRowLayout>(uri, 1, 0, "RowLayout");
- qmlRegisterType<QQuickColumnLayout>(uri, 1, 0, "ColumnLayout");
- qmlRegisterType<QQuickGridLayout>(uri, 1, 0, "GridLayout");
- qmlRegisterType<QQuickStackLayout>(uri, 1, 3, "StackLayout");
- qmlRegisterUncreatableType<QQuickLayout>(uri, 1, 0, "Layout",
- QStringLiteral("Do not create objects of type Layout"));
- qmlRegisterUncreatableType<QQuickLayout>(uri, 1, 2, "Layout",
- QStringLiteral("Do not create objects of type Layout"));
- qmlRegisterRevision<QQuickGridLayoutBase, 1>(uri, 1, 1);
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 1, QT_VERSION_MINOR);
+ volatile auto registration = &qml_register_types_QtQuick_Layouts;
+ Q_UNUSED(registration);
}
};
//![class decl]
diff --git a/src/imports/layouts/plugins.qmltypes b/src/imports/layouts/plugins.qmltypes
deleted file mode 100644
index 6015164511..0000000000
--- a/src/imports/layouts/plugins.qmltypes
+++ /dev/null
@@ -1,102 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Layouts 1.14'
-
-Module {
- dependencies: ["QtQuick 2.0"]
- Component {
- name: "QQuickColumnLayout"
- defaultProperty: "data"
- prototype: "QQuickLinearLayout"
- exports: ["QtQuick.Layouts/ColumnLayout 1.0"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickGridLayout"
- defaultProperty: "data"
- prototype: "QQuickGridLayoutBase"
- exports: ["QtQuick.Layouts/GridLayout 1.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Flow"
- values: {
- "LeftToRight": 0,
- "TopToBottom": 1
- }
- }
- Property { name: "columnSpacing"; type: "double" }
- Property { name: "rowSpacing"; type: "double" }
- Property { name: "columns"; type: "int" }
- Property { name: "rows"; type: "int" }
- Property { name: "flow"; type: "Flow" }
- }
- Component {
- name: "QQuickGridLayoutBase"
- defaultProperty: "data"
- prototype: "QQuickLayout"
- Property { name: "layoutDirection"; revision: 1; type: "Qt::LayoutDirection" }
- Signal { name: "layoutDirectionChanged"; revision: 1 }
- }
- Component {
- name: "QQuickLayout"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick.Layouts/Layout 1.0", "QtQuick.Layouts/Layout 1.2"]
- isCreatable: false
- exportMetaObjectRevisions: [0, 0]
- attachedType: "QQuickLayoutAttached"
- }
- Component {
- name: "QQuickLayoutAttached"
- prototype: "QObject"
- Property { name: "minimumWidth"; type: "double" }
- Property { name: "minimumHeight"; type: "double" }
- Property { name: "preferredWidth"; type: "double" }
- Property { name: "preferredHeight"; type: "double" }
- Property { name: "maximumWidth"; type: "double" }
- Property { name: "maximumHeight"; type: "double" }
- Property { name: "fillHeight"; type: "bool" }
- Property { name: "fillWidth"; type: "bool" }
- Property { name: "row"; type: "int" }
- Property { name: "column"; type: "int" }
- Property { name: "rowSpan"; type: "int" }
- Property { name: "columnSpan"; type: "int" }
- Property { name: "alignment"; type: "Qt::Alignment" }
- Property { name: "margins"; type: "double" }
- Property { name: "leftMargin"; type: "double" }
- Property { name: "topMargin"; type: "double" }
- Property { name: "rightMargin"; type: "double" }
- Property { name: "bottomMargin"; type: "double" }
- }
- Component {
- name: "QQuickLinearLayout"
- defaultProperty: "data"
- prototype: "QQuickGridLayoutBase"
- Property { name: "spacing"; type: "double" }
- }
- Component {
- name: "QQuickRowLayout"
- defaultProperty: "data"
- prototype: "QQuickLinearLayout"
- exports: ["QtQuick.Layouts/RowLayout 1.0"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickStackLayout"
- defaultProperty: "data"
- prototype: "QQuickLayout"
- exports: ["QtQuick.Layouts/StackLayout 1.3"]
- exportMetaObjectRevisions: [0]
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "currentIndex"; type: "int" }
- Method {
- name: "itemAt"
- type: "QQuickItem*"
- Parameter { name: "index"; type: "int" }
- }
- }
-}
diff --git a/src/imports/layouts/qquickgridlayoutengine.cpp b/src/imports/layouts/qquickgridlayoutengine.cpp
index 6004bb92ca..5275d70c39 100644
--- a/src/imports/layouts/qquickgridlayoutengine.cpp
+++ b/src/imports/layouts/qquickgridlayoutengine.cpp
@@ -55,7 +55,7 @@ Qt::Alignment QQuickGridLayoutEngine::alignment(QQuickItem *quickItem) const
{
if (QGridLayoutItem *item = findLayoutItem(quickItem))
return item->alignment();
- return nullptr;
+ return {};
}
QT_END_NAMESPACE
diff --git a/src/imports/layouts/qquickgridlayoutengine_p.h b/src/imports/layouts/qquickgridlayoutengine_p.h
index 2810e2e5d0..c53be89477 100644
--- a/src/imports/layouts/qquickgridlayoutengine_p.h
+++ b/src/imports/layouts/qquickgridlayoutengine_p.h
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
class QQuickGridLayoutItem : public QGridLayoutItem {
public:
QQuickGridLayoutItem(QQuickItem *item, int row, int column,
- int rowSpan = 1, int columnSpan = 1, Qt::Alignment alignment = 0)
+ int rowSpan = 1, int columnSpan = 1, Qt::Alignment alignment = { })
: QGridLayoutItem(row, column, rowSpan, columnSpan, alignment), m_item(item), sizeHintCacheDirty(true), useFallbackToWidthOrHeight(true) {}
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp
index 17d37b5c4e..33c27bd928 100644
--- a/src/imports/layouts/qquicklayout.cpp
+++ b/src/imports/layouts/qquicklayout.cpp
@@ -117,8 +117,7 @@ QQuickLayoutAttached::QQuickLayoutAttached(QObject *parent)
m_isLeftMarginSet(false),
m_isTopMarginSet(false),
m_isRightMarginSet(false),
- m_isBottomMarginSet(false),
- m_alignment(nullptr)
+ m_isBottomMarginSet(false)
{
}
diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h
index d2421667be..3322d03636 100644
--- a/src/imports/layouts/qquicklayout_p.h
+++ b/src/imports/layouts/qquicklayout_p.h
@@ -61,6 +61,10 @@ class QQuickLayout : public QQuickItem, public QQuickItemChangeListener
{
Q_OBJECT
+ QML_NAMED_ELEMENT(Layout)
+ QML_UNCREATABLE("Do not create objects of type Layout.")
+ QML_ATTACHED(QQuickLayoutAttached)
+
public:
enum SizeHint {
MinimumSize = 0,
@@ -333,6 +337,5 @@ inline QQuickLayoutAttached *attachedLayoutObject(QQuickItem *item, bool create
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickLayout)
-QML_DECLARE_TYPEINFO(QQuickLayout, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKLAYOUT_P_H
diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp
index 911793d748..1004ed8593 100644
--- a/src/imports/layouts/qquicklinearlayout.cpp
+++ b/src/imports/layouts/qquicklinearlayout.cpp
@@ -675,7 +675,7 @@ void QQuickGridLayout::insertLayoutItems()
if (shouldIgnoreItem(child, info, sizeHints))
continue;
- Qt::Alignment alignment = nullptr;
+ Qt::Alignment alignment;
int row = -1;
int column = -1;
int span[2] = {1,1};
@@ -864,7 +864,7 @@ void QQuickLinearLayout::insertLayoutItems()
if (shouldIgnoreItem(child, info, sizeHints))
continue;
- Qt::Alignment alignment = nullptr;
+ Qt::Alignment alignment;
if (info)
alignment = info->alignment();
diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h
index 866d0884a2..f36f99741d 100644
--- a/src/imports/layouts/qquicklinearlayout_p.h
+++ b/src/imports/layouts/qquicklinearlayout_p.h
@@ -57,6 +57,8 @@ class QQuickGridLayoutBase : public QQuickLayout
Q_OBJECT
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged REVISION 1)
+ QML_ANONYMOUS
+ QML_ADDED_IN_MINOR_VERSION(1)
public:
@@ -142,6 +144,7 @@ class QQuickGridLayout : public QQuickGridLayoutBase
Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged)
Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
+ QML_NAMED_ELEMENT(GridLayout)
public:
explicit QQuickGridLayout(QQuickItem *parent = 0);
qreal columnSpacing() const;
@@ -225,6 +228,7 @@ public:
class QQuickRowLayout : public QQuickLinearLayout
{
Q_OBJECT
+ QML_NAMED_ELEMENT(RowLayout)
public:
explicit QQuickRowLayout(QQuickItem *parent = 0)
@@ -240,6 +244,7 @@ public:
class QQuickColumnLayout : public QQuickLinearLayout
{
Q_OBJECT
+ QML_NAMED_ELEMENT(ColumnLayout)
public:
explicit QQuickColumnLayout(QQuickItem *parent = 0)
diff --git a/src/imports/layouts/qquickstacklayout_p.h b/src/imports/layouts/qquickstacklayout_p.h
index 46181c6f50..537d54900f 100644
--- a/src/imports/layouts/qquickstacklayout_p.h
+++ b/src/imports/layouts/qquickstacklayout_p.h
@@ -51,6 +51,8 @@ class QQuickStackLayout : public QQuickLayout
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+ QML_NAMED_ELEMENT(StackLayout)
+ QML_ADDED_IN_MINOR_VERSION(3)
public:
explicit QQuickStackLayout(QQuickItem *parent = 0);
diff --git a/src/imports/localstorage/localstorage.pro b/src/imports/localstorage/localstorage.pro
index 5c8177e238..a95fa04401 100644
--- a/src/imports/localstorage/localstorage.pro
+++ b/src/imports/localstorage/localstorage.pro
@@ -5,8 +5,14 @@ IMPORT_VERSION = 2.$$QT_MINOR_VERSION
QT = sql qml-private core-private
-SOURCES += plugin.cpp
+SOURCES += \
+ plugin.cpp \
+ qquicklocalstorage.cpp
+
+HEADERS += \
+ qquicklocalstorage_p.h
load(qml_plugin)
+CONFIG += qmltypes install_qmltypes
OTHER_FILES += localstorage.json
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index 9004d1ee6f..e488b3d43c 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -36,797 +36,26 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <QStringList>
-#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
-#include <private/qqmlengine_p.h>
-#include <QDebug>
-#include <QtSql/qsqldatabase.h>
-#include <QtSql/qsqlquery.h>
-#include <QtSql/qsqlerror.h>
-#include <QtSql/qsqlrecord.h>
-#include <QtSql/qsqlfield.h>
-#include <QtCore/qstandardpaths.h>
-#include <QtCore/qstack.h>
-#include <QtCore/qcryptographichash.h>
-#include <QtCore/qsettings.h>
-#include <QtCore/qdir.h>
-#include <private/qv4sqlerrors_p.h>
-#include <private/qv4engine_p.h>
-#include <private/qv4object_p.h>
-#include <private/qv4functionobject_p.h>
-#include <private/qv4objectproto_p.h>
-#include <private/qv4scopedvalue_p.h>
-#include <private/qv4jscall_p.h>
-#include <private/qv4objectiterator_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#define V4THROW_SQL(error, desc) { \
- QV4::ScopedString v(scope, scope.engine->newString(desc)); \
- QV4::ScopedObject ex(scope, scope.engine->newErrorObject(v)); \
- ex->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("code"))).getPointer(), QV4::ScopedValue(scope, Value::fromInt32(error))); \
- scope.engine->throwError(ex); \
- RETURN_UNDEFINED(); \
-}
-
-#define V4THROW_SQL2(error, desc) { \
- QV4::ScopedString v(scope, scope.engine->newString(desc)); \
- QV4::ScopedObject ex(scope, scope.engine->newErrorObject(v)); \
- ex->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("code"))).getPointer(), QV4::ScopedValue(scope, Value::fromInt32(error))); \
- args->setReturnValue(scope.engine->throwError(ex)); \
- return; \
-}
-
-#define V4THROW_REFERENCE(string) { \
- QV4::ScopedString v(scope, scope.engine->newString(string)); \
- scope.engine->throwReferenceError(v); \
- RETURN_UNDEFINED(); \
-}
-
-
-class QQmlSqlDatabaseData : public QV4::ExecutionEngine::Deletable
-{
-public:
- QQmlSqlDatabaseData(QV4::ExecutionEngine *engine);
- ~QQmlSqlDatabaseData() override;
-
- QV4::PersistentValue databaseProto;
- QV4::PersistentValue queryProto;
- QV4::PersistentValue rowsProto;
-};
-
-V4_DEFINE_EXTENSION(QQmlSqlDatabaseData, databaseData)
-
-namespace QV4 {
-
-namespace Heap {
- struct QQmlSqlDatabaseWrapper : public Object {
- enum Type { Database, Query, Rows };
- void init()
- {
- Object::init();
- type = Database;
- database = new QSqlDatabase;
- version = new QString;
- sqlQuery = new QSqlQuery;
- }
-
- void destroy() {
- delete database;
- delete version;
- delete sqlQuery;
- Object::destroy();
- }
-
- Type type;
- QSqlDatabase *database;
-
- QString *version; // type == Database
-
- bool inTransaction; // type == Query
- bool readonly; // type == Query
-
- QSqlQuery *sqlQuery; // type == Rows
- bool forwardOnly; // type == Rows
- };
-}
-
-class QQmlSqlDatabaseWrapper : public Object
-{
-public:
- V4_OBJECT2(QQmlSqlDatabaseWrapper, Object)
- V4_NEEDS_DESTROY
-
- static Heap::QQmlSqlDatabaseWrapper *create(QV4::ExecutionEngine *engine)
- {
- return engine->memoryManager->allocate<QQmlSqlDatabaseWrapper>();
- }
-
- ~QQmlSqlDatabaseWrapper() {
- }
-
- static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
-};
-
-}
-
-using namespace QV4;
-
-DEFINE_OBJECT_VTABLE(QV4::QQmlSqlDatabaseWrapper);
-
-
-
-static ReturnedValue qmlsqldatabase_version(const FunctionObject *b, const Value *thisObject, const QV4::Value *, int)
-{
- Scope scope(b);
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
- if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
- V4THROW_REFERENCE("Not a SQLDatabase object");
-
- RETURN_RESULT(Encode(scope.engine->newString(*r->d()->version)));
-}
-
-static ReturnedValue qmlsqldatabase_rows_length(const FunctionObject *b, const Value *thisObject, const QV4::Value *, int)
-{
- Scope scope(b);
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
- if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
- V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
-
- int s = r->d()->sqlQuery->size();
- if (s < 0) {
- // Inefficient
- if (r->d()->sqlQuery->last()) {
- s = r->d()->sqlQuery->at() + 1;
- } else {
- s = 0;
- }
- }
- RETURN_RESULT(Encode(s));
-}
-
-static ReturnedValue qmlsqldatabase_rows_forwardOnly(const FunctionObject *b, const Value *thisObject, const QV4::Value *, int)
-{
- Scope scope(b);
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
- if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
- V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
- RETURN_RESULT(Encode(r->d()->sqlQuery->isForwardOnly()));
-}
-
-static ReturnedValue qmlsqldatabase_rows_setForwardOnly(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
-{
- Scope scope(b);
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
- if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
- V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
- if (argc < 1)
- RETURN_RESULT(scope.engine->throwTypeError());
-
- r->d()->sqlQuery->setForwardOnly(argv[0].toBoolean());
- RETURN_UNDEFINED();
-}
-
-QQmlSqlDatabaseData::~QQmlSqlDatabaseData()
-{
-}
-
-static ReturnedValue qmlsqldatabase_rows_index(const QQmlSqlDatabaseWrapper *r, ExecutionEngine *v4, quint32 index, bool *hasProperty = nullptr)
-{
- Scope scope(v4);
-
- if (r->d()->sqlQuery->at() == (int)index || r->d()->sqlQuery->seek(index)) {
- QSqlRecord record = r->d()->sqlQuery->record();
- // XXX optimize
- ScopedObject row(scope, v4->newObject());
- for (int ii = 0; ii < record.count(); ++ii) {
- QVariant v = record.value(ii);
- ScopedString s(scope, v4->newIdentifier(record.fieldName(ii)));
- ScopedValue val(scope, v.isNull() ? Encode::null() : v4->fromVariant(v));
- row->put(s.getPointer(), val);
- }
- if (hasProperty)
- *hasProperty = true;
- return row.asReturnedValue();
- } else {
- if (hasProperty)
- *hasProperty = false;
- return Encode::undefined();
- }
-}
-
-ReturnedValue QQmlSqlDatabaseWrapper::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
-{
- if (!id.isArrayIndex())
- return Object::virtualGet(m, id, receiver, hasProperty);
-
- uint index = id.asArrayIndex();
- Q_ASSERT(m->as<QQmlSqlDatabaseWrapper>());
- const QQmlSqlDatabaseWrapper *r = static_cast<const QQmlSqlDatabaseWrapper *>(m);
- if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
- return Object::virtualGet(m, id, receiver, hasProperty);
-
- return qmlsqldatabase_rows_index(r, r->engine(), index, hasProperty);
-}
-
-static ReturnedValue qmlsqldatabase_rows_item(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
-{
- Scope scope(b);
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
- if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
- V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
-
- RETURN_RESULT(qmlsqldatabase_rows_index(r, scope.engine, argc ? argv[0].toUInt32() : 0));
-}
-
-static QVariant toSqlVariant(QV4::ExecutionEngine *engine, const QV4::ScopedValue &value)
-{
- // toVariant() maps a null JS value to QVariant(VoidStar), but the SQL module
- // expects a null variant. (this is because of QTBUG-40880)
- if (value->isNull())
- return QVariant();
- return engine->toVariant(value, /*typehint*/-1);
-}
-
-static ReturnedValue qmlsqldatabase_executeSql(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
-{
- Scope scope(b);
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
- if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Query)
- V4THROW_REFERENCE("Not a SQLDatabase::Query object");
-
- if (!r->d()->inTransaction)
- V4THROW_SQL(SQLEXCEPTION_DATABASE_ERR,QQmlEngine::tr("executeSql called outside transaction()"));
-
- QSqlDatabase db = *r->d()->database;
-
- QString sql = argc ? argv[0].toQString() : QString();
-
- if (r->d()->readonly && !sql.startsWith(QLatin1String("SELECT"),Qt::CaseInsensitive)) {
- V4THROW_SQL(SQLEXCEPTION_SYNTAX_ERR, QQmlEngine::tr("Read-only Transaction"));
- }
-
- QSqlQuery query(db);
- bool err = false;
-
- ScopedValue result(scope, Value::undefinedValue());
-
- if (query.prepare(sql)) {
- if (argc > 1) {
- ScopedValue values(scope, argv[1]);
- if (values->as<ArrayObject>()) {
- ScopedArrayObject array(scope, values);
- quint32 size = array->getLength();
- QV4::ScopedValue v(scope);
- for (quint32 ii = 0; ii < size; ++ii) {
- query.bindValue(ii, toSqlVariant(scope.engine, (v = array->get(ii))));
- }
- } else if (values->as<Object>()) {
- ScopedObject object(scope, values);
- ObjectIterator it(scope, object, ObjectIterator::EnumerableOnly);
- ScopedValue key(scope);
- QV4::ScopedValue val(scope);
- while (1) {
- key = it.nextPropertyName(val);
- if (key->isNull())
- break;
- QVariant v = toSqlVariant(scope.engine, val);
- if (key->isString()) {
- query.bindValue(key->stringValue()->toQString(), v);
- } else {
- Q_ASSERT(key->isInteger());
- query.bindValue(key->integerValue(), v);
- }
- }
- } else {
- query.bindValue(0, toSqlVariant(scope.engine, values));
- }
- }
- if (query.exec()) {
- QV4::Scoped<QQmlSqlDatabaseWrapper> rows(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
- QV4::ScopedObject p(scope, databaseData(scope.engine)->rowsProto.value());
- rows->setPrototypeUnchecked(p.getPointer());
- rows->d()->type = Heap::QQmlSqlDatabaseWrapper::Rows;
- *rows->d()->database = db;
- *rows->d()->sqlQuery = query;
-
- ScopedObject resultObject(scope, scope.engine->newObject());
- result = resultObject.asReturnedValue();
- // XXX optimize
- ScopedString s(scope);
- ScopedValue v(scope);
- resultObject->put((s = scope.engine->newIdentifier("rowsAffected")).getPointer(), (v = Value::fromInt32(query.numRowsAffected())));
- resultObject->put((s = scope.engine->newIdentifier("insertId")).getPointer(), (v = scope.engine->newString(query.lastInsertId().toString())));
- resultObject->put((s = scope.engine->newIdentifier("rows")).getPointer(), rows);
- } else {
- err = true;
- }
- } else {
- err = true;
- }
- if (err)
- V4THROW_SQL(SQLEXCEPTION_DATABASE_ERR,query.lastError().text());
-
- RETURN_RESULT(result->asReturnedValue());
-}
-
-struct TransactionRollback {
- QSqlDatabase *db;
- bool *inTransactionFlag;
-
- TransactionRollback(QSqlDatabase *database, bool *transactionFlag)
- : db(database)
- , inTransactionFlag(transactionFlag)
- {
- if (inTransactionFlag)
- *inTransactionFlag = true;
- }
-
- ~TransactionRollback()
- {
- if (inTransactionFlag)
- *inTransactionFlag = false;
- if (db)
- db->rollback();
- }
-
- void clear() {
- db = nullptr;
- if (inTransactionFlag)
- *inTransactionFlag = false;
- inTransactionFlag = nullptr;
- }
-};
-
-
-static ReturnedValue qmlsqldatabase_changeVersion(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
-{
- Scope scope(b);
- if (argc < 2)
- RETURN_UNDEFINED();
-
- Scoped<QQmlSqlDatabaseWrapper> r(scope, *thisObject);
- if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
- V4THROW_REFERENCE("Not a SQLDatabase object");
-
- QSqlDatabase db = *r->d()->database;
- QString from_version = argv[0].toQString();
- QString to_version = argv[1].toQString();
- ScopedFunctionObject callback(scope, argc > 2 ? argv[2] : Value::undefinedValue());
-
- if (from_version != *r->d()->version)
- V4THROW_SQL(SQLEXCEPTION_VERSION_ERR, QQmlEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(*r->d()->version));
-
- bool ok = true;
- if (!!callback) {
- Scoped<QQmlSqlDatabaseWrapper> query(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
- ScopedObject p(scope, databaseData(scope.engine)->queryProto.value());
- query->setPrototypeUnchecked(p.getPointer());
- query->d()->type = Heap::QQmlSqlDatabaseWrapper::Query;
- *query->d()->database = db;
- *query->d()->version = *r->d()->version;
-
- ok = false;
- db.transaction();
-
- JSCallData jsCall(scope, 1);
- *jsCall->thisObject = scope.engine->globalObject;
- jsCall->args[0] = query;
-
- TransactionRollback rollbackOnException(&db, &query->d()->inTransaction);
- callback->call(jsCall);
- rollbackOnException.clear();
- if (!db.commit()) {
- db.rollback();
- V4THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR,QQmlEngine::tr("SQL transaction failed"));
- } else {
- ok = true;
- }
- }
-
- if (ok) {
- Scoped<QQmlSqlDatabaseWrapper> w(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
- ScopedObject p(scope, databaseData(scope.engine)->databaseProto.value());
- w->setPrototypeUnchecked(p.getPointer());
- w->d()->type = Heap::QQmlSqlDatabaseWrapper::Database;
- *w->d()->database = db;
- *w->d()->version = to_version;
-#if QT_CONFIG(settings)
- const QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(scope.engine->qmlEngine());
- QSettings ini(enginePrivate->offlineStorageDatabaseDirectory() + db.connectionName() + QLatin1String(".ini"), QSettings::IniFormat);
- ini.setValue(QLatin1String("Version"), to_version);
-#endif
- RETURN_RESULT(w.asReturnedValue());
- }
-
- RETURN_UNDEFINED();
-}
-
-static ReturnedValue qmlsqldatabase_transaction_shared(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc, bool readOnly)
-{
- Scope scope(b);
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
- if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
- V4THROW_REFERENCE("Not a SQLDatabase object");
-
- const FunctionObject *callback = argc ? argv[0].as<FunctionObject>() : nullptr;
- if (!callback)
- V4THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR, QQmlEngine::tr("transaction: missing callback"));
-
- QSqlDatabase db = *r->d()->database;
-
- Scoped<QQmlSqlDatabaseWrapper> w(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
- QV4::ScopedObject p(scope, databaseData(scope.engine)->queryProto.value());
- w->setPrototypeUnchecked(p.getPointer());
- w->d()->type = Heap::QQmlSqlDatabaseWrapper::Query;
- *w->d()->database = db;
- *w->d()->version = *r->d()->version;
- w->d()->readonly = readOnly;
- db.transaction();
- if (callback) {
- JSCallData jsCall(scope, 1);
- *jsCall->thisObject = scope.engine->globalObject;
- jsCall->args[0] = w;
- TransactionRollback rollbackOnException(&db, &w->d()->inTransaction);
- callback->call(jsCall);
- rollbackOnException.clear();
+#include "qquicklocalstorage_p.h"
- if (!db.commit())
- db.rollback();
- }
-
- RETURN_UNDEFINED();
-}
-
-static ReturnedValue qmlsqldatabase_transaction(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
-{
- return qmlsqldatabase_transaction_shared(f, thisObject, argv, argc, false);
-}
-
-static ReturnedValue qmlsqldatabase_read_transaction(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
-{
- return qmlsqldatabase_transaction_shared(f, thisObject, argv, argc, true);
-}
-
-QQmlSqlDatabaseData::QQmlSqlDatabaseData(ExecutionEngine *v4)
-{
- Scope scope(v4);
- {
- ScopedObject proto(scope, v4->newObject());
- proto->defineDefaultProperty(QStringLiteral("transaction"), qmlsqldatabase_transaction);
- proto->defineDefaultProperty(QStringLiteral("readTransaction"), qmlsqldatabase_read_transaction);
- proto->defineAccessorProperty(QStringLiteral("version"), qmlsqldatabase_version, nullptr);
- proto->defineDefaultProperty(QStringLiteral("changeVersion"), qmlsqldatabase_changeVersion);
- databaseProto = proto;
- }
-
- {
- ScopedObject proto(scope, v4->newObject());
- proto->defineDefaultProperty(QStringLiteral("executeSql"), qmlsqldatabase_executeSql);
- queryProto = proto;
- }
- {
- ScopedObject proto(scope, v4->newObject());
- proto->defineDefaultProperty(QStringLiteral("item"), qmlsqldatabase_rows_item);
- proto->defineAccessorProperty(QStringLiteral("length"), qmlsqldatabase_rows_length, nullptr);
- proto->defineAccessorProperty(QStringLiteral("forwardOnly"),
- qmlsqldatabase_rows_forwardOnly, qmlsqldatabase_rows_setForwardOnly);
- rowsProto = proto;
- }
-}
-
-/*
-HTML5 "spec" says "rs.rows[n]", but WebKit only impelments "rs.rows.item(n)". We do both (and property iterator).
-We add a "forwardOnly" property that stops Qt caching results (code promises to only go forward
-through the data.
-*/
-
-
-/*!
- \qmlmodule QtQuick.LocalStorage 2.\QtMinorVersion
- \title Qt Quick Local Storage QML Types
- \ingroup qmlmodules
- \brief Provides a JavaScript object singleton type for accessing a local
- SQLite database
-
- This is a singleton type for reading and writing to SQLite databases.
-
-
- \section1 Methods
-
- \list
- \li object \b{\l{#openDatabaseSync}{openDatabaseSync}}(string name, string version, string description, int estimated_size, jsobject callback(db))
- \endlist
-
-
- \section1 Detailed Description
-
- To use the types in this module, import the module and call the
- relevant functions using the \c LocalStorage type:
-
- \qml \QtMinorVersion
- import QtQuick 2.\1
- import QtQuick.LocalStorage 2.\1
-
- Item {
- Component.onCompleted: {
- var db = LocalStorage.openDatabaseSync(...)
- }
- }
- \endqml
-
-
-These databases are user-specific and QML-specific, but accessible to all QML applications.
-They are stored in the \c Databases subdirectory
-of QQmlEngine::offlineStoragePath(), currently as SQLite databases.
-
-Database connections are automatically closed during Javascript garbage collection.
-
-The API can be used from JavaScript functions in your QML:
-
-\snippet qml/localstorage/hello.qml 0
-
-The API conforms to the Synchronous API of the HTML5 Web Database API,
-\link http://www.w3.org/TR/2009/WD-webdatabase-20091029/ W3C Working Draft 29 October 2009\endlink.
-
-The \l{Qt Quick Examples - Local Storage}{SQL Local Storage example} demonstrates the basics of
-using the Offline Storage API.
-
-\section3 Open or Create a Database
-
-\qml \QtMinorVersion
-import QtQuick.LocalStorage 2.\1 as Sql
-
-db = Sql.openDatabaseSync(identifier, version, description, estimated_size, callback(db))
-\endqml
-
-The above code returns the database identified by \e identifier. If the database does not already exist, it
-is created, and the function \e callback is called with the database as a parameter. \e identifier is the
-name of the physical file (with or without full path) containing the database. \e description and
-\e estimated_size are written to the INI file (described below), but are currently unused.
-
-May throw exception with code property SQLException.DATABASE_ERR, or SQLException.VERSION_ERR.
-
-When a database is first created, an INI file is also created specifying its characteristics:
-
-\table
-\header \li \b {Key} \li \b {Value}
-\row \li Identifier \li The name of the database passed to \c openDatabase()
-\row \li Version \li The version of the database passed to \c openDatabase()
-\row \li Description \li The description of the database passed to \c openDatabase()
-\row \li EstimatedSize \li The estimated size (in bytes) of the database passed to \c openDatabase()
-\row \li Driver \li Currently "QSQLITE"
-\endtable
-
-This data can be used by application tools.
-
-\section3 db.changeVersion(from, to, callback(tx))
-
-This method allows you to perform a \e{Scheme Upgrade}. If it succeeds it returns a new
-database object of version \e to. Otherwise it returns \e undefined.
-
-If the current version of \e db is not \e from, then an exception is thrown.
-
-Otherwise, a database transaction is created and passed to \e callback. In this function,
-you can call \e executeSql on \e tx to upgrade the database.
-
-May throw exception with code property SQLException.DATABASE_ERR or SQLException.UNKNOWN_ERR.
-
-See example below.
-
-\badcode
- var db = LocalStorage.openDatabaseSync("ActivityTrackDB", "", "Database tracking sports activities", 1000000);
- if (db.version == "0.1") {
- db.changeVersion("0.1", "0.2", function(tx) {
- tx.executeSql("INSERT INTO trip_log VALUES(?, ?, ?)",
- [ "01/10/2016","Sylling - Vikersund", "53" ]);
- }
- });
-\endcode
-
-\section3 db.transaction(callback(tx))
-
-This method creates a read/write transaction and passed to \e callback. In this function,
-you can call \e executeSql on \e tx to read and modify the database.
-
-If the callback throws exceptions, the transaction is rolled back.
-Below you will find an example of a database transaction which catches exceptions.
-
-
-\quotefromfile localstorage/localstorage/Database.js
-\skipuntil dbInit()
-\printto dbGetHandle
-
-In the example you can see an \c insert statement where values are assigned to the fields,
-and the record is written into the table. That is an \c insert statement with a syntax that is usual
-for a relational database. It is however also possible to work with JSON objects and
-store them in a table.
-
-Let's suppose a simple example where we store trips in JSON format using \c date as the unique key.
-An example of a table that could be used for that purpose:
-
-\badcode
- create table trip_log(date text, data text)
-\endcode
-
-The assignment of values to a JSON object:
-
-\badcode
- var obj = {description = "Vikersund - Noresund", distance = "60"}
-\endcode
-
-In that case, the data could be saved in the following way:
-
-\badcode
- db.transaction(function(tx) {
- result = tx.executeSQL("insert into trip_log values (?,?)",
- ["01/11/2016", JSON.stringify(obj)])
-
-\endcode
-
-\section3 db.readTransaction(callback(tx))
-
-This method creates a read-only transaction and passed to \e callback. In this function,
-you can call \e executeSql on \e tx to read the database (with \c select statements).
-
-\section3 results = tx.executeSql(statement, values)
-
-This method executes an SQL \e statement, binding the list of \e values to SQL positional parameters ("?").
-
-It returns a results object, with the following properties:
-
-\table
-\header \li \b {Type} \li \b {Property} \li \b {Value} \li \b {Applicability}
-\row \li int \li rows.length \li The number of rows in the result \li SELECT
-\row \li var \li rows.item(i) \li Function that returns row \e i of the result \li SELECT
-\row \li int \li rowsAffected \li The number of rows affected by a modification \li UPDATE, DELETE
-\row \li string \li insertId \li The id of the row inserted \li INSERT
-\endtable
-
-May throw exception with code property SQLException.DATABASE_ERR, SQLException.SYNTAX_ERR, or SQLException.UNKNOWN_ERR.
-
-See below for an example:
-
-\quotefromfile localstorage/localstorage/Database.js
-\skipto dbReadAll()
-\printto dbUpdate(Pdate
-
-\section1 Method Documentation
-
-\target openDatabaseSync
-\code
-object openDatabaseSync(string name, string version, string description, int estimated_size, jsobject callback(db))
-\endcode
-
-Opens or creates a local storage sql database by the given parameters.
-
-\list
-\li \c name is the database name
-\li \c version is the database version
-\li \c description is the database display name
-\li \c estimated_size is the database's estimated size, in bytes
-\li \c callback is an optional parameter, which is invoked if the database has not yet been created.
-\endlist
-
-Returns the created database object.
-
-*/
-class QQuickLocalStorage : public QObject
-{
- Q_OBJECT
-public:
- QQuickLocalStorage(QObject *parent=nullptr) : QObject(parent)
- {
- }
- ~QQuickLocalStorage() override {
- }
-
- Q_INVOKABLE void openDatabaseSync(QQmlV4Function* args);
-};
-
-void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
-{
-#if QT_CONFIG(settings)
- QV4::Scope scope(args->v4engine());
- if (scope.engine->qmlEngine()->offlineStoragePath().isEmpty())
- V4THROW_SQL2(SQLEXCEPTION_DATABASE_ERR, QQmlEngine::tr("SQL: can't create database, offline storage is disabled."));
-
- QV4::ScopedValue v(scope);
- QString dbname = (v = (*args)[0])->toQStringNoThrow();
- QString dbversion = (v = (*args)[1])->toQStringNoThrow();
- QString dbdescription = (v = (*args)[2])->toQStringNoThrow();
- int dbestimatedsize = (v = (*args)[3])->toInt32();
- FunctionObject *dbcreationCallback = (v = (*args)[4])->as<FunctionObject>();
- QString basename = args->v4engine()->qmlEngine()->offlineStorageDatabaseFilePath(dbname);
- QFileInfo dbFile(basename);
- if (!QDir().mkpath(dbFile.dir().absolutePath())) {
- const QString message = QQmlEngine::tr("LocalStorage: can't create path %1").
- arg(QDir::toNativeSeparators(dbFile.dir().absolutePath()));
- V4THROW_SQL2(SQLEXCEPTION_DATABASE_ERR, message);
- }
- QString dbid = dbFile.fileName();
- bool created = false;
- QString version = dbversion;
- QSqlDatabase database;
-
- {
- QSettings ini(basename+QLatin1String(".ini"),QSettings::IniFormat);
-
- if (QSqlDatabase::connectionNames().contains(dbid)) {
- database = QSqlDatabase::database(dbid);
- version = ini.value(QLatin1String("Version")).toString();
- if (version != dbversion && !dbversion.isEmpty() && !version.isEmpty())
- V4THROW_SQL2(SQLEXCEPTION_VERSION_ERR, QQmlEngine::tr("SQL: database version mismatch"));
- } else {
- created = !QFile::exists(basename+QLatin1String(".sqlite"));
- if (created) {
- ini.setValue(QLatin1String("Name"), dbname);
- if (dbcreationCallback)
- version = QString();
- ini.setValue(QLatin1String("Version"), version);
- ini.setValue(QLatin1String("Description"), dbdescription);
- ini.setValue(QLatin1String("EstimatedSize"), dbestimatedsize);
- ini.setValue(QLatin1String("Driver"), QLatin1String("QSQLITE"));
- } else {
- if (!dbversion.isEmpty() && ini.value(QLatin1String("Version")) != dbversion) {
- // Incompatible
- V4THROW_SQL2(SQLEXCEPTION_VERSION_ERR,QQmlEngine::tr("SQL: database version mismatch"));
- }
- version = ini.value(QLatin1String("Version")).toString();
- }
- database = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), dbid);
- database.setDatabaseName(basename+QLatin1String(".sqlite"));
- }
- if (!database.isOpen())
- database.open();
- }
-
- QV4::Scoped<QQmlSqlDatabaseWrapper> db(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
- QV4::ScopedObject p(scope, databaseData(scope.engine)->databaseProto.value());
- db->setPrototypeUnchecked(p.getPointer());
- *db->d()->database = database;
- *db->d()->version = version;
-
- if (created && dbcreationCallback) {
- JSCallData jsCall(scope, 1);
- *jsCall->thisObject = scope.engine->globalObject;
- jsCall->args[0] = db;
- dbcreationCallback->call(jsCall);
- }
-
- args->setReturnValue(db.asReturnedValue());
-#else
- Q_UNUSED(args)
-#endif // settings
-}
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
-static QObject *module_api_factory(QQmlEngine *engine, QJSEngine *scriptEngine)
-{
- Q_UNUSED(engine)
- Q_UNUSED(scriptEngine)
- QQuickLocalStorage *api = new QQuickLocalStorage();
+extern void qml_register_types_QtQuick_LocalStorage();
- return api;
-}
+QT_BEGIN_NAMESPACE
-class QQmlLocalStoragePlugin : public QQmlExtensionPlugin
+class QQmlLocalStoragePlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QQmlLocalStoragePlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent)
+ QQmlLocalStoragePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- }
- void registerTypes(const char *uri) override
- {
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.LocalStorage"));
- qmlRegisterSingletonType<QQuickLocalStorage>(uri, 2, 0, "LocalStorage", module_api_factory);
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
+ volatile auto registration = &qml_register_types_QtQuick_LocalStorage;
+ Q_UNUSED(registration);
}
};
diff --git a/src/imports/localstorage/plugins.qmltypes b/src/imports/localstorage/plugins.qmltypes
deleted file mode 100644
index 6ed334cc9d..0000000000
--- a/src/imports/localstorage/plugins.qmltypes
+++ /dev/null
@@ -1,23 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.LocalStorage 2.14'
-
-Module {
- dependencies: []
- Component {
- name: "QQuickLocalStorage"
- prototype: "QObject"
- exports: ["QtQuick.LocalStorage/LocalStorage 2.0"]
- isCreatable: false
- isSingleton: true
- exportMetaObjectRevisions: [0]
- Method {
- name: "openDatabaseSync"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- }
-}
diff --git a/src/imports/localstorage/qquicklocalstorage.cpp b/src/imports/localstorage/qquicklocalstorage.cpp
new file mode 100644
index 0000000000..333e697e3c
--- /dev/null
+++ b/src/imports/localstorage/qquicklocalstorage.cpp
@@ -0,0 +1,792 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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: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 "qquicklocalstorage_p.h"
+
+#include <QtQml/private/qqmlengine_p.h>
+#include <QtQml/private/qv4global_p.h>
+#include <QtQml/private/qv4scopedvalue_p.h>
+#include <QtQml/private/qv4object_p.h>
+#include <QtQml/private/qv4sqlerrors_p.h>
+#include <QtQml/private/qv4jscall_p.h>
+#include <QtQml/private/qv4objectiterator_p.h>
+
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qdir.h>
+
+#include <QtSql/qsqldatabase.h>
+#include <QtSql/qsqlquery.h>
+#include <QtSql/qsqlrecord.h>
+#include <QtSql/qsqlerror.h>
+
+#if QT_CONFIG(settings)
+#include <QtCore/qsettings.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#define V4THROW_SQL(error, desc) { \
+ QV4::ScopedString v(scope, scope.engine->newString(desc)); \
+ QV4::ScopedObject ex(scope, scope.engine->newErrorObject(v)); \
+ ex->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("code"))).getPointer(), QV4::ScopedValue(scope, Value::fromInt32(error))); \
+ scope.engine->throwError(ex); \
+ RETURN_UNDEFINED(); \
+}
+
+#define V4THROW_SQL2(error, desc) { \
+ QV4::ScopedString v(scope, scope.engine->newString(desc)); \
+ QV4::ScopedObject ex(scope, scope.engine->newErrorObject(v)); \
+ ex->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("code"))).getPointer(), QV4::ScopedValue(scope, Value::fromInt32(error))); \
+ args->setReturnValue(scope.engine->throwError(ex)); \
+ return; \
+}
+
+#define V4THROW_REFERENCE(string) { \
+ QV4::ScopedString v(scope, scope.engine->newString(string)); \
+ scope.engine->throwReferenceError(v); \
+ RETURN_UNDEFINED(); \
+}
+
+
+class QQmlSqlDatabaseData : public QV4::ExecutionEngine::Deletable
+{
+public:
+ QQmlSqlDatabaseData(QV4::ExecutionEngine *engine);
+ ~QQmlSqlDatabaseData() override;
+
+ QV4::PersistentValue databaseProto;
+ QV4::PersistentValue queryProto;
+ QV4::PersistentValue rowsProto;
+};
+
+V4_DEFINE_EXTENSION(QQmlSqlDatabaseData, databaseData)
+
+namespace QV4 {
+
+namespace Heap {
+ struct QQmlSqlDatabaseWrapper : public Object {
+ enum Type { Database, Query, Rows };
+ void init()
+ {
+ Object::init();
+ type = Database;
+ database = new QSqlDatabase;
+ version = new QString;
+ sqlQuery = new QSqlQuery;
+ }
+
+ void destroy() {
+ delete database;
+ delete version;
+ delete sqlQuery;
+ Object::destroy();
+ }
+
+ Type type;
+ QSqlDatabase *database;
+
+ QString *version; // type == Database
+
+ bool inTransaction; // type == Query
+ bool readonly; // type == Query
+
+ QSqlQuery *sqlQuery; // type == Rows
+ bool forwardOnly; // type == Rows
+ };
+}
+
+class QQmlSqlDatabaseWrapper : public Object
+{
+public:
+ V4_OBJECT2(QQmlSqlDatabaseWrapper, Object)
+ V4_NEEDS_DESTROY
+
+ static Heap::QQmlSqlDatabaseWrapper *create(QV4::ExecutionEngine *engine)
+ {
+ return engine->memoryManager->allocate<QQmlSqlDatabaseWrapper>();
+ }
+
+ ~QQmlSqlDatabaseWrapper() {
+ }
+
+ static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
+};
+
+}
+
+using namespace QV4;
+
+DEFINE_OBJECT_VTABLE(QV4::QQmlSqlDatabaseWrapper);
+
+
+
+static ReturnedValue qmlsqldatabase_version(const FunctionObject *b, const Value *thisObject, const QV4::Value *, int)
+{
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
+ if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
+ V4THROW_REFERENCE("Not a SQLDatabase object");
+
+ RETURN_RESULT(Encode(scope.engine->newString(*r->d()->version)));
+}
+
+static ReturnedValue qmlsqldatabase_rows_length(const FunctionObject *b, const Value *thisObject, const QV4::Value *, int)
+{
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
+ if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
+ V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
+
+ int s = r->d()->sqlQuery->size();
+ if (s < 0) {
+ // Inefficient
+ if (r->d()->sqlQuery->last()) {
+ s = r->d()->sqlQuery->at() + 1;
+ } else {
+ s = 0;
+ }
+ }
+ RETURN_RESULT(Encode(s));
+}
+
+static ReturnedValue qmlsqldatabase_rows_forwardOnly(const FunctionObject *b, const Value *thisObject, const QV4::Value *, int)
+{
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
+ if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
+ V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
+ RETURN_RESULT(Encode(r->d()->sqlQuery->isForwardOnly()));
+}
+
+static ReturnedValue qmlsqldatabase_rows_setForwardOnly(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
+ if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
+ V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
+ if (argc < 1)
+ RETURN_RESULT(scope.engine->throwTypeError());
+
+ r->d()->sqlQuery->setForwardOnly(argv[0].toBoolean());
+ RETURN_UNDEFINED();
+}
+
+QQmlSqlDatabaseData::~QQmlSqlDatabaseData()
+{
+}
+
+static ReturnedValue qmlsqldatabase_rows_index(const QQmlSqlDatabaseWrapper *r, ExecutionEngine *v4, quint32 index, bool *hasProperty = nullptr)
+{
+ Scope scope(v4);
+
+ if (r->d()->sqlQuery->at() == (int)index || r->d()->sqlQuery->seek(index)) {
+ QSqlRecord record = r->d()->sqlQuery->record();
+ // XXX optimize
+ ScopedObject row(scope, v4->newObject());
+ for (int ii = 0; ii < record.count(); ++ii) {
+ QVariant v = record.value(ii);
+ ScopedString s(scope, v4->newIdentifier(record.fieldName(ii)));
+ ScopedValue val(scope, v.isNull() ? Encode::null() : v4->fromVariant(v));
+ row->put(s.getPointer(), val);
+ }
+ if (hasProperty)
+ *hasProperty = true;
+ return row.asReturnedValue();
+ } else {
+ if (hasProperty)
+ *hasProperty = false;
+ return Encode::undefined();
+ }
+}
+
+ReturnedValue QQmlSqlDatabaseWrapper::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
+{
+ if (!id.isArrayIndex())
+ return Object::virtualGet(m, id, receiver, hasProperty);
+
+ uint index = id.asArrayIndex();
+ Q_ASSERT(m->as<QQmlSqlDatabaseWrapper>());
+ const QQmlSqlDatabaseWrapper *r = static_cast<const QQmlSqlDatabaseWrapper *>(m);
+ if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
+ return Object::virtualGet(m, id, receiver, hasProperty);
+
+ return qmlsqldatabase_rows_index(r, r->engine(), index, hasProperty);
+}
+
+static ReturnedValue qmlsqldatabase_rows_item(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
+ if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
+ V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
+
+ RETURN_RESULT(qmlsqldatabase_rows_index(r, scope.engine, argc ? argv[0].toUInt32() : 0));
+}
+
+static QVariant toSqlVariant(QV4::ExecutionEngine *engine, const QV4::ScopedValue &value)
+{
+ // toVariant() maps a null JS value to QVariant(VoidStar), but the SQL module
+ // expects a null variant. (this is because of QTBUG-40880)
+ if (value->isNull())
+ return QVariant();
+ return engine->toVariant(value, /*typehint*/-1);
+}
+
+static ReturnedValue qmlsqldatabase_executeSql(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
+ if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Query)
+ V4THROW_REFERENCE("Not a SQLDatabase::Query object");
+
+ if (!r->d()->inTransaction)
+ V4THROW_SQL(SQLEXCEPTION_DATABASE_ERR,QQmlEngine::tr("executeSql called outside transaction()"));
+
+ QSqlDatabase db = *r->d()->database;
+
+ QString sql = argc ? argv[0].toQString() : QString();
+
+ if (r->d()->readonly && !sql.startsWith(QLatin1String("SELECT"),Qt::CaseInsensitive)) {
+ V4THROW_SQL(SQLEXCEPTION_SYNTAX_ERR, QQmlEngine::tr("Read-only Transaction"));
+ }
+
+ QSqlQuery query(db);
+ bool err = false;
+
+ ScopedValue result(scope, Value::undefinedValue());
+
+ if (query.prepare(sql)) {
+ if (argc > 1) {
+ ScopedValue values(scope, argv[1]);
+ if (values->as<ArrayObject>()) {
+ ScopedArrayObject array(scope, values);
+ quint32 size = array->getLength();
+ QV4::ScopedValue v(scope);
+ for (quint32 ii = 0; ii < size; ++ii) {
+ query.bindValue(ii, toSqlVariant(scope.engine, (v = array->get(ii))));
+ }
+ } else if (values->as<Object>()) {
+ ScopedObject object(scope, values);
+ ObjectIterator it(scope, object, ObjectIterator::EnumerableOnly);
+ ScopedValue key(scope);
+ QV4::ScopedValue val(scope);
+ while (1) {
+ key = it.nextPropertyName(val);
+ if (key->isNull())
+ break;
+ QVariant v = toSqlVariant(scope.engine, val);
+ if (key->isString()) {
+ query.bindValue(key->stringValue()->toQString(), v);
+ } else {
+ Q_ASSERT(key->isInteger());
+ query.bindValue(key->integerValue(), v);
+ }
+ }
+ } else {
+ query.bindValue(0, toSqlVariant(scope.engine, values));
+ }
+ }
+ if (query.exec()) {
+ QV4::Scoped<QQmlSqlDatabaseWrapper> rows(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
+ QV4::ScopedObject p(scope, databaseData(scope.engine)->rowsProto.value());
+ rows->setPrototypeUnchecked(p.getPointer());
+ rows->d()->type = Heap::QQmlSqlDatabaseWrapper::Rows;
+ *rows->d()->database = db;
+ *rows->d()->sqlQuery = query;
+
+ ScopedObject resultObject(scope, scope.engine->newObject());
+ result = resultObject.asReturnedValue();
+ // XXX optimize
+ ScopedString s(scope);
+ ScopedValue v(scope);
+ resultObject->put((s = scope.engine->newIdentifier("rowsAffected")).getPointer(), (v = Value::fromInt32(query.numRowsAffected())));
+ resultObject->put((s = scope.engine->newIdentifier("insertId")).getPointer(), (v = scope.engine->newString(query.lastInsertId().toString())));
+ resultObject->put((s = scope.engine->newIdentifier("rows")).getPointer(), rows);
+ } else {
+ err = true;
+ }
+ } else {
+ err = true;
+ }
+ if (err)
+ V4THROW_SQL(SQLEXCEPTION_DATABASE_ERR,query.lastError().text());
+
+ RETURN_RESULT(result->asReturnedValue());
+}
+
+struct TransactionRollback {
+ QSqlDatabase *db;
+ bool *inTransactionFlag;
+
+ TransactionRollback(QSqlDatabase *database, bool *transactionFlag)
+ : db(database)
+ , inTransactionFlag(transactionFlag)
+ {
+ if (inTransactionFlag)
+ *inTransactionFlag = true;
+ }
+
+ ~TransactionRollback()
+ {
+ if (inTransactionFlag)
+ *inTransactionFlag = false;
+ if (db)
+ db->rollback();
+ }
+
+ void clear() {
+ db = nullptr;
+ if (inTransactionFlag)
+ *inTransactionFlag = false;
+ inTransactionFlag = nullptr;
+ }
+};
+
+
+static ReturnedValue qmlsqldatabase_changeVersion(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ if (argc < 2)
+ RETURN_UNDEFINED();
+
+ Scoped<QQmlSqlDatabaseWrapper> r(scope, *thisObject);
+ if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
+ V4THROW_REFERENCE("Not a SQLDatabase object");
+
+ QSqlDatabase db = *r->d()->database;
+ QString from_version = argv[0].toQString();
+ QString to_version = argv[1].toQString();
+ ScopedFunctionObject callback(scope, argc > 2 ? argv[2] : Value::undefinedValue());
+
+ if (from_version != *r->d()->version)
+ V4THROW_SQL(SQLEXCEPTION_VERSION_ERR, QQmlEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(*r->d()->version));
+
+ bool ok = true;
+ if (!!callback) {
+ Scoped<QQmlSqlDatabaseWrapper> query(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
+ ScopedObject p(scope, databaseData(scope.engine)->queryProto.value());
+ query->setPrototypeUnchecked(p.getPointer());
+ query->d()->type = Heap::QQmlSqlDatabaseWrapper::Query;
+ *query->d()->database = db;
+ *query->d()->version = *r->d()->version;
+
+ ok = false;
+ db.transaction();
+
+ JSCallData jsCall(scope, 1);
+ *jsCall->thisObject = scope.engine->globalObject;
+ jsCall->args[0] = query;
+
+ TransactionRollback rollbackOnException(&db, &query->d()->inTransaction);
+ callback->call(jsCall);
+ rollbackOnException.clear();
+ if (!db.commit()) {
+ db.rollback();
+ V4THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR,QQmlEngine::tr("SQL transaction failed"));
+ } else {
+ ok = true;
+ }
+ }
+
+ if (ok) {
+ Scoped<QQmlSqlDatabaseWrapper> w(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
+ ScopedObject p(scope, databaseData(scope.engine)->databaseProto.value());
+ w->setPrototypeUnchecked(p.getPointer());
+ w->d()->type = Heap::QQmlSqlDatabaseWrapper::Database;
+ *w->d()->database = db;
+ *w->d()->version = to_version;
+#if QT_CONFIG(settings)
+ const QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(scope.engine->qmlEngine());
+ QSettings ini(enginePrivate->offlineStorageDatabaseDirectory() + db.connectionName() + QLatin1String(".ini"), QSettings::IniFormat);
+ ini.setValue(QLatin1String("Version"), to_version);
+#endif
+ RETURN_RESULT(w.asReturnedValue());
+ }
+
+ RETURN_UNDEFINED();
+}
+
+static ReturnedValue qmlsqldatabase_transaction_shared(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc, bool readOnly)
+{
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
+ if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
+ V4THROW_REFERENCE("Not a SQLDatabase object");
+
+ const FunctionObject *callback = argc ? argv[0].as<FunctionObject>() : nullptr;
+ if (!callback)
+ V4THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR, QQmlEngine::tr("transaction: missing callback"));
+
+ QSqlDatabase db = *r->d()->database;
+
+ Scoped<QQmlSqlDatabaseWrapper> w(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
+ QV4::ScopedObject p(scope, databaseData(scope.engine)->queryProto.value());
+ w->setPrototypeUnchecked(p.getPointer());
+ w->d()->type = Heap::QQmlSqlDatabaseWrapper::Query;
+ *w->d()->database = db;
+ *w->d()->version = *r->d()->version;
+ w->d()->readonly = readOnly;
+
+ db.transaction();
+ if (callback) {
+ JSCallData jsCall(scope, 1);
+ *jsCall->thisObject = scope.engine->globalObject;
+ jsCall->args[0] = w;
+ TransactionRollback rollbackOnException(&db, &w->d()->inTransaction);
+ callback->call(jsCall);
+ rollbackOnException.clear();
+
+ if (!db.commit())
+ db.rollback();
+ }
+
+ RETURN_UNDEFINED();
+}
+
+static ReturnedValue qmlsqldatabase_transaction(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
+{
+ return qmlsqldatabase_transaction_shared(f, thisObject, argv, argc, false);
+}
+
+static ReturnedValue qmlsqldatabase_read_transaction(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
+{
+ return qmlsqldatabase_transaction_shared(f, thisObject, argv, argc, true);
+}
+
+QQmlSqlDatabaseData::QQmlSqlDatabaseData(ExecutionEngine *v4)
+{
+ Scope scope(v4);
+ {
+ ScopedObject proto(scope, v4->newObject());
+ proto->defineDefaultProperty(QStringLiteral("transaction"), qmlsqldatabase_transaction);
+ proto->defineDefaultProperty(QStringLiteral("readTransaction"), qmlsqldatabase_read_transaction);
+ proto->defineAccessorProperty(QStringLiteral("version"), qmlsqldatabase_version, nullptr);
+ proto->defineDefaultProperty(QStringLiteral("changeVersion"), qmlsqldatabase_changeVersion);
+ databaseProto = proto;
+ }
+
+ {
+ ScopedObject proto(scope, v4->newObject());
+ proto->defineDefaultProperty(QStringLiteral("executeSql"), qmlsqldatabase_executeSql);
+ queryProto = proto;
+ }
+ {
+ ScopedObject proto(scope, v4->newObject());
+ proto->defineDefaultProperty(QStringLiteral("item"), qmlsqldatabase_rows_item);
+ proto->defineAccessorProperty(QStringLiteral("length"), qmlsqldatabase_rows_length, nullptr);
+ proto->defineAccessorProperty(QStringLiteral("forwardOnly"),
+ qmlsqldatabase_rows_forwardOnly, qmlsqldatabase_rows_setForwardOnly);
+ rowsProto = proto;
+ }
+}
+
+/*
+HTML5 "spec" says "rs.rows[n]", but WebKit only impelments "rs.rows.item(n)". We do both (and property iterator).
+We add a "forwardOnly" property that stops Qt caching results (code promises to only go forward
+through the data.
+*/
+
+
+/*!
+ \qmlmodule QtQuick.LocalStorage 2.\QtMinorVersion
+ \title Qt Quick Local Storage QML Types
+ \ingroup qmlmodules
+ \brief Provides a JavaScript object singleton type for accessing a local
+ SQLite database
+
+ This is a singleton type for reading and writing to SQLite databases.
+
+
+ \section1 Methods
+
+ \list
+ \li object \b{\l{#openDatabaseSync}{openDatabaseSync}}(string name, string version, string description, int estimated_size, jsobject callback(db))
+ \endlist
+
+
+ \section1 Detailed Description
+
+ To use the types in this module, import the module and call the
+ relevant functions using the \c LocalStorage type:
+
+ \qml \QtMinorVersion
+ import QtQuick 2.\1
+ import QtQuick.LocalStorage 2.\1
+
+ Item {
+ Component.onCompleted: {
+ var db = LocalStorage.openDatabaseSync(...)
+ }
+ }
+ \endqml
+
+
+These databases are user-specific and QML-specific, but accessible to all QML applications.
+They are stored in the \c Databases subdirectory
+of QQmlEngine::offlineStoragePath(), currently as SQLite databases.
+
+Database connections are automatically closed during Javascript garbage collection.
+
+The API can be used from JavaScript functions in your QML:
+
+\snippet qml/localstorage/hello.qml 0
+
+The API conforms to the Synchronous API of the HTML5 Web Database API,
+\link http://www.w3.org/TR/2009/WD-webdatabase-20091029/ W3C Working Draft 29 October 2009\endlink.
+
+The \l{Qt Quick Examples - Local Storage}{SQL Local Storage example} demonstrates the basics of
+using the Offline Storage API.
+
+\section3 Open or Create a Database
+
+\qml \QtMinorVersion
+import QtQuick.LocalStorage 2.\1 as Sql
+
+db = Sql.openDatabaseSync(identifier, version, description, estimated_size, callback(db))
+\endqml
+
+The above code returns the database identified by \e identifier. If the database does not already exist, it
+is created, and the function \e callback is called with the database as a parameter. \e identifier is the
+name of the physical file (with or without full path) containing the database. \e description and
+\e estimated_size are written to the INI file (described below), but are currently unused.
+
+May throw exception with code property SQLException.DATABASE_ERR, or SQLException.VERSION_ERR.
+
+When a database is first created, an INI file is also created specifying its characteristics:
+
+\table
+\header \li \b {Key} \li \b {Value}
+\row \li Identifier \li The name of the database passed to \c openDatabase()
+\row \li Version \li The version of the database passed to \c openDatabase()
+\row \li Description \li The description of the database passed to \c openDatabase()
+\row \li EstimatedSize \li The estimated size (in bytes) of the database passed to \c openDatabase()
+\row \li Driver \li Currently "QSQLITE"
+\endtable
+
+This data can be used by application tools.
+
+\section3 db.changeVersion(from, to, callback(tx))
+
+This method allows you to perform a \e{Scheme Upgrade}. If it succeeds it returns a new
+database object of version \e to. Otherwise it returns \e undefined.
+
+If the current version of \e db is not \e from, then an exception is thrown.
+
+Otherwise, a database transaction is created and passed to \e callback. In this function,
+you can call \e executeSql on \e tx to upgrade the database.
+
+May throw exception with code property SQLException.DATABASE_ERR or SQLException.UNKNOWN_ERR.
+
+See example below.
+
+\badcode
+ var db = LocalStorage.openDatabaseSync("ActivityTrackDB", "", "Database tracking sports activities", 1000000);
+ if (db.version == "0.1") {
+ db.changeVersion("0.1", "0.2", function(tx) {
+ tx.executeSql("INSERT INTO trip_log VALUES(?, ?, ?)",
+ [ "01/10/2016","Sylling - Vikersund", "53" ]);
+ }
+ });
+\endcode
+
+\section3 db.transaction(callback(tx))
+
+This method creates a read/write transaction and passed to \e callback. In this function,
+you can call \e executeSql on \e tx to read and modify the database.
+
+If the callback throws exceptions, the transaction is rolled back.
+Below you will find an example of a database transaction which catches exceptions.
+
+
+\quotefromfile localstorage/localstorage/Database.js
+\skipuntil dbInit()
+\printto dbGetHandle
+
+In the example you can see an \c insert statement where values are assigned to the fields,
+and the record is written into the table. That is an \c insert statement with a syntax that is usual
+for a relational database. It is however also possible to work with JSON objects and
+store them in a table.
+
+Let's suppose a simple example where we store trips in JSON format using \c date as the unique key.
+An example of a table that could be used for that purpose:
+
+\badcode
+ create table trip_log(date text, data text)
+\endcode
+
+The assignment of values to a JSON object:
+
+\badcode
+ var obj = {description = "Vikersund - Noresund", distance = "60"}
+\endcode
+
+In that case, the data could be saved in the following way:
+
+\badcode
+ db.transaction(function(tx) {
+ result = tx.executeSQL("insert into trip_log values (?,?)",
+ ["01/11/2016", JSON.stringify(obj)])
+
+\endcode
+
+\section3 db.readTransaction(callback(tx))
+
+This method creates a read-only transaction and passed to \e callback. In this function,
+you can call \e executeSql on \e tx to read the database (with \c select statements).
+
+\section3 results = tx.executeSql(statement, values)
+
+This method executes an SQL \e statement, binding the list of \e values to SQL positional parameters ("?").
+
+It returns a results object, with the following properties:
+
+\table
+\header \li \b {Type} \li \b {Property} \li \b {Value} \li \b {Applicability}
+\row \li int \li rows.length \li The number of rows in the result \li SELECT
+\row \li var \li rows.item(i) \li Function that returns row \e i of the result \li SELECT
+\row \li int \li rowsAffected \li The number of rows affected by a modification \li UPDATE, DELETE
+\row \li string \li insertId \li The id of the row inserted \li INSERT
+\endtable
+
+May throw exception with code property SQLException.DATABASE_ERR, SQLException.SYNTAX_ERR, or SQLException.UNKNOWN_ERR.
+
+See below for an example:
+
+\quotefromfile localstorage/localstorage/Database.js
+\skipto dbReadAll()
+\printto dbUpdate(Pdate
+
+\section1 Method Documentation
+
+\target openDatabaseSync
+\code
+object openDatabaseSync(string name, string version, string description, int estimated_size, jsobject callback(db))
+\endcode
+
+Opens or creates a local storage sql database by the given parameters.
+
+\list
+\li \c name is the database name
+\li \c version is the database version
+\li \c description is the database display name
+\li \c estimated_size is the database's estimated size, in bytes
+\li \c callback is an optional parameter, which is invoked if the database has not yet been created.
+\endlist
+
+Returns the created database object.
+
+*/
+
+void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
+{
+#if QT_CONFIG(settings)
+ QV4::Scope scope(args->v4engine());
+ if (scope.engine->qmlEngine()->offlineStoragePath().isEmpty())
+ V4THROW_SQL2(SQLEXCEPTION_DATABASE_ERR, QQmlEngine::tr("SQL: can't create database, offline storage is disabled."));
+
+ QV4::ScopedValue v(scope);
+ QString dbname = (v = (*args)[0])->toQStringNoThrow();
+ QString dbversion = (v = (*args)[1])->toQStringNoThrow();
+ QString dbdescription = (v = (*args)[2])->toQStringNoThrow();
+ int dbestimatedsize = (v = (*args)[3])->toInt32();
+ FunctionObject *dbcreationCallback = (v = (*args)[4])->as<FunctionObject>();
+ QString basename = args->v4engine()->qmlEngine()->offlineStorageDatabaseFilePath(dbname);
+ QFileInfo dbFile(basename);
+ if (!QDir().mkpath(dbFile.dir().absolutePath())) {
+ const QString message = QQmlEngine::tr("LocalStorage: can't create path %1").
+ arg(QDir::toNativeSeparators(dbFile.dir().absolutePath()));
+ V4THROW_SQL2(SQLEXCEPTION_DATABASE_ERR, message);
+ }
+ QString dbid = dbFile.fileName();
+ bool created = false;
+ QString version = dbversion;
+ QSqlDatabase database;
+
+ {
+ QSettings ini(basename+QLatin1String(".ini"),QSettings::IniFormat);
+
+ if (QSqlDatabase::connectionNames().contains(dbid)) {
+ database = QSqlDatabase::database(dbid);
+ version = ini.value(QLatin1String("Version")).toString();
+ if (version != dbversion && !dbversion.isEmpty() && !version.isEmpty())
+ V4THROW_SQL2(SQLEXCEPTION_VERSION_ERR, QQmlEngine::tr("SQL: database version mismatch"));
+ } else {
+ created = !QFile::exists(basename+QLatin1String(".sqlite"));
+ if (created) {
+ ini.setValue(QLatin1String("Name"), dbname);
+ if (dbcreationCallback)
+ version = QString();
+ ini.setValue(QLatin1String("Version"), version);
+ ini.setValue(QLatin1String("Description"), dbdescription);
+ ini.setValue(QLatin1String("EstimatedSize"), dbestimatedsize);
+ ini.setValue(QLatin1String("Driver"), QLatin1String("QSQLITE"));
+ } else {
+ if (!dbversion.isEmpty() && ini.value(QLatin1String("Version")) != dbversion) {
+ // Incompatible
+ V4THROW_SQL2(SQLEXCEPTION_VERSION_ERR,QQmlEngine::tr("SQL: database version mismatch"));
+ }
+ version = ini.value(QLatin1String("Version")).toString();
+ }
+ database = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), dbid);
+ database.setDatabaseName(basename+QLatin1String(".sqlite"));
+ }
+ if (!database.isOpen())
+ database.open();
+ }
+
+ QV4::Scoped<QQmlSqlDatabaseWrapper> db(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
+ QV4::ScopedObject p(scope, databaseData(scope.engine)->databaseProto.value());
+ db->setPrototypeUnchecked(p.getPointer());
+ *db->d()->database = database;
+ *db->d()->version = version;
+
+ if (created && dbcreationCallback) {
+ JSCallData jsCall(scope, 1);
+ *jsCall->thisObject = scope.engine->globalObject;
+ jsCall->args[0] = db;
+ dbcreationCallback->call(jsCall);
+ }
+
+ args->setReturnValue(db.asReturnedValue());
+#else
+ Q_UNUSED(args)
+#endif // settings
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h b/src/imports/localstorage/qquicklocalstorage_p.h
index e811109a94..d2ebc85ce9 100644
--- a/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h
+++ b/src/imports/localstorage/qquicklocalstorage_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtQuick module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QSGRHINATIVETEXTUREIMPORTER_P_H
-#define QSGRHINATIVETEXTUREIMPORTER_P_H
+#ifndef QQUICKLOCALSTORAGE_P_H
+#define QQUICKLOCALSTORAGE_P_H
//
// W A R N I N G
@@ -51,20 +51,25 @@
// We mean it.
//
-#include <QtQuick/private/qtquickglobal_p.h>
+#include <QtCore/qobject.h>
+#include <QtQml/qqml.h>
+#include <QtQml/private/qv4engine_p.h>
QT_BEGIN_NAMESPACE
-class QRhi;
-class QRhiTexture;
-
-class QSGRhiNativeTextureImporter
+class QQuickLocalStorage : public QObject
{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(LocalStorage)
+ QML_SINGLETON
+
public:
- static void buildWrapper(QRhi *rhi, QRhiTexture *t,
- const void *nativeObjectPtr, int nativeLayout);
+ QQuickLocalStorage(QObject *parent = nullptr) : QObject(parent) {}
+ ~QQuickLocalStorage() override = default;
+
+ Q_INVOKABLE void openDatabaseSync(QQmlV4Function* args);
};
QT_END_NAMESPACE
-#endif // QSGRHINATIVETEXTUREIMPORTER_P_H
+#endif // QQUICKLOCALSTORAGE_P_H
diff --git a/src/imports/models/plugin.cpp b/src/imports/models/plugin.cpp
index 319321013e..c15866cf05 100644
--- a/src/imports/models/plugin.cpp
+++ b/src/imports/models/plugin.cpp
@@ -37,10 +37,8 @@
**
****************************************************************************/
+#include <QtQmlModels/private/qtqmlmodelsglobal_p.h>
#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
-
-#include <private/qqmlmodelsmodule_p.h>
QT_BEGIN_NAMESPACE
@@ -81,19 +79,15 @@ QT_BEGIN_NAMESPACE
//![class decl]
-class QtQmlModelsPlugin : public QQmlExtensionPlugin
+class QtQmlModelsPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQmlModelsPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
+ QtQmlModelsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQml.Models"));
- QQmlModelsModule::defineModule();
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
+ volatile auto registration = &qml_register_types_QtQml_Models;
+ Q_UNUSED(registration);
}
};
//![class decl]
diff --git a/src/imports/models/plugins.qmltypes b/src/imports/models/plugins.qmltypes
deleted file mode 100644
index 58122b9b45..0000000000
--- a/src/imports/models/plugins.qmltypes
+++ /dev/null
@@ -1,710 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.Models 2.14'
-
-Module {
- dependencies: []
- Component {
- name: "QAbstractItemModel"
- prototype: "QObject"
- Enum {
- name: "LayoutChangeHint"
- values: {
- "NoLayoutChangeHint": 0,
- "VerticalSortHint": 1,
- "HorizontalSortHint": 2
- }
- }
- Enum {
- name: "CheckIndexOption"
- values: {
- "NoOption": 0,
- "IndexIsValid": 1,
- "DoNotUseParent": 2,
- "ParentIsInvalid": 4
- }
- }
- Signal {
- name: "dataChanged"
- Parameter { name: "topLeft"; type: "QModelIndex" }
- Parameter { name: "bottomRight"; type: "QModelIndex" }
- Parameter { name: "roles"; type: "QVector<int>" }
- }
- Signal {
- name: "dataChanged"
- Parameter { name: "topLeft"; type: "QModelIndex" }
- Parameter { name: "bottomRight"; type: "QModelIndex" }
- }
- Signal {
- name: "headerDataChanged"
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "layoutChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
- }
- Signal {
- name: "layoutChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- }
- Signal { name: "layoutChanged" }
- Signal {
- name: "layoutAboutToBeChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
- }
- Signal {
- name: "layoutAboutToBeChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- }
- Signal { name: "layoutAboutToBeChanged" }
- Signal {
- name: "rowsAboutToBeInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsAboutToBeRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal { name: "modelAboutToBeReset" }
- Signal { name: "modelReset" }
- Signal {
- name: "rowsAboutToBeMoved"
- Parameter { name: "sourceParent"; type: "QModelIndex" }
- Parameter { name: "sourceStart"; type: "int" }
- Parameter { name: "sourceEnd"; type: "int" }
- Parameter { name: "destinationParent"; type: "QModelIndex" }
- Parameter { name: "destinationRow"; type: "int" }
- }
- Signal {
- name: "rowsMoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- Parameter { name: "destination"; type: "QModelIndex" }
- Parameter { name: "row"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeMoved"
- Parameter { name: "sourceParent"; type: "QModelIndex" }
- Parameter { name: "sourceStart"; type: "int" }
- Parameter { name: "sourceEnd"; type: "int" }
- Parameter { name: "destinationParent"; type: "QModelIndex" }
- Parameter { name: "destinationColumn"; type: "int" }
- }
- Signal {
- name: "columnsMoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- Parameter { name: "destination"; type: "QModelIndex" }
- Parameter { name: "column"; type: "int" }
- }
- Method { name: "submit"; type: "bool" }
- Method { name: "revert" }
- Method {
- name: "hasIndex"
- type: "bool"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "hasIndex"
- type: "bool"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- }
- Method {
- name: "index"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "index"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- }
- Method {
- name: "parent"
- type: "QModelIndex"
- Parameter { name: "child"; type: "QModelIndex" }
- }
- Method {
- name: "sibling"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "idx"; type: "QModelIndex" }
- }
- Method {
- name: "rowCount"
- type: "int"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "rowCount"; type: "int" }
- Method {
- name: "columnCount"
- type: "int"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "columnCount"; type: "int" }
- Method {
- name: "hasChildren"
- type: "bool"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "hasChildren"; type: "bool" }
- Method {
- name: "data"
- type: "QVariant"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "data"
- type: "QVariant"
- Parameter { name: "index"; type: "QModelIndex" }
- }
- Method {
- name: "setData"
- type: "bool"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "setData"
- type: "bool"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "value"; type: "QVariant" }
- }
- Method {
- name: "headerData"
- type: "QVariant"
- Parameter { name: "section"; type: "int" }
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "headerData"
- type: "QVariant"
- Parameter { name: "section"; type: "int" }
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- }
- Method {
- name: "fetchMore"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "canFetchMore"
- type: "bool"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "flags"
- type: "Qt::ItemFlags"
- Parameter { name: "index"; type: "QModelIndex" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "hits"; type: "int" }
- Parameter { name: "flags"; type: "Qt::MatchFlags" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "hits"; type: "int" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- }
- }
- Component { name: "QAbstractListModel"; prototype: "QAbstractItemModel" }
- Component {
- name: "QItemSelectionModel"
- prototype: "QObject"
- exports: ["QtQml.Models/ItemSelectionModel 2.2"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "SelectionFlags"
- values: {
- "NoUpdate": 0,
- "Clear": 1,
- "Select": 2,
- "Deselect": 4,
- "Toggle": 8,
- "Current": 16,
- "Rows": 32,
- "Columns": 64,
- "SelectCurrent": 18,
- "ToggleCurrent": 24,
- "ClearAndSelect": 3
- }
- }
- Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
- Property { name: "hasSelection"; type: "bool"; isReadonly: true }
- Property { name: "currentIndex"; type: "QModelIndex"; isReadonly: true }
- Property { name: "selection"; type: "QItemSelection"; isReadonly: true }
- Property { name: "selectedIndexes"; type: "QModelIndexList"; isReadonly: true }
- Signal {
- name: "selectionChanged"
- Parameter { name: "selected"; type: "QItemSelection" }
- Parameter { name: "deselected"; type: "QItemSelection" }
- }
- Signal {
- name: "currentChanged"
- Parameter { name: "current"; type: "QModelIndex" }
- Parameter { name: "previous"; type: "QModelIndex" }
- }
- Signal {
- name: "currentRowChanged"
- Parameter { name: "current"; type: "QModelIndex" }
- Parameter { name: "previous"; type: "QModelIndex" }
- }
- Signal {
- name: "currentColumnChanged"
- Parameter { name: "current"; type: "QModelIndex" }
- Parameter { name: "previous"; type: "QModelIndex" }
- }
- Signal {
- name: "modelChanged"
- Parameter { name: "model"; type: "QAbstractItemModel"; isPointer: true }
- }
- Method {
- name: "setCurrentIndex"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "command"; type: "QItemSelectionModel::SelectionFlags" }
- }
- Method {
- name: "select"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "command"; type: "QItemSelectionModel::SelectionFlags" }
- }
- Method {
- name: "select"
- Parameter { name: "selection"; type: "QItemSelection" }
- Parameter { name: "command"; type: "QItemSelectionModel::SelectionFlags" }
- }
- Method { name: "clear" }
- Method { name: "reset" }
- Method { name: "clearSelection" }
- Method { name: "clearCurrentIndex" }
- Method {
- name: "isSelected"
- type: "bool"
- Parameter { name: "index"; type: "QModelIndex" }
- }
- Method {
- name: "isRowSelected"
- type: "bool"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "isColumnSelected"
- type: "bool"
- Parameter { name: "column"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "rowIntersectsSelection"
- type: "bool"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "columnIntersectsSelection"
- type: "bool"
- Parameter { name: "column"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "selectedRows"
- type: "QModelIndexList"
- Parameter { name: "column"; type: "int" }
- }
- Method { name: "selectedRows"; type: "QModelIndexList" }
- Method {
- name: "selectedColumns"
- type: "QModelIndexList"
- Parameter { name: "row"; type: "int" }
- }
- Method { name: "selectedColumns"; type: "QModelIndexList" }
- }
- Component {
- name: "QQmlDelegateModel"
- defaultProperty: "delegate"
- prototype: "QQmlInstanceModel"
- exports: ["QtQml.Models/DelegateModel 2.1"]
- exportMetaObjectRevisions: [0]
- attachedType: "QQmlDelegateModelAttached"
- Property { name: "model"; type: "QVariant" }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "filterOnGroup"; type: "string" }
- Property { name: "items"; type: "QQmlDelegateModelGroup"; isReadonly: true; isPointer: true }
- Property {
- name: "persistedItems"
- type: "QQmlDelegateModelGroup"
- isReadonly: true
- isPointer: true
- }
- Property { name: "groups"; type: "QQmlDelegateModelGroup"; isList: true; isReadonly: true }
- Property { name: "parts"; type: "QObject"; isReadonly: true; isPointer: true }
- Property { name: "rootIndex"; type: "QVariant" }
- Signal { name: "filterGroupChanged" }
- Signal { name: "defaultGroupsChanged" }
- Method {
- name: "modelIndex"
- type: "QVariant"
- Parameter { name: "idx"; type: "int" }
- }
- Method { name: "parentModelIndex"; type: "QVariant" }
- }
- Component {
- name: "QQmlDelegateModelAttached"
- prototype: "QObject"
- Property { name: "model"; type: "QQmlDelegateModel"; isReadonly: true; isPointer: true }
- Property { name: "groups"; type: "QStringList" }
- Property { name: "isUnresolved"; type: "bool"; isReadonly: true }
- Signal { name: "unresolvedChanged" }
- }
- Component {
- name: "QQmlDelegateModelGroup"
- prototype: "QObject"
- exports: ["QtQml.Models/DelegateModelGroup 2.1"]
- exportMetaObjectRevisions: [0]
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "name"; type: "string" }
- Property { name: "includeByDefault"; type: "bool" }
- Signal { name: "defaultIncludeChanged" }
- Signal {
- name: "changed"
- Parameter { name: "removed"; type: "QJSValue" }
- Parameter { name: "inserted"; type: "QJSValue" }
- }
- Method {
- name: "insert"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "create"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "resolve"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "remove"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "addGroups"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "removeGroups"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "setGroups"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "move"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "get"
- type: "QJSValue"
- Parameter { name: "index"; type: "int" }
- }
- }
- Component { name: "QQmlDelegateModelParts"; prototype: "QObject" }
- Component {
- name: "QQmlInstanceModel"
- prototype: "QObject"
- Property { name: "count"; type: "int"; isReadonly: true }
- Signal {
- name: "modelUpdated"
- Parameter { name: "changeSet"; type: "QQmlChangeSet" }
- Parameter { name: "reset"; type: "bool" }
- }
- Signal {
- name: "createdItem"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "initItem"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "destroyingItem"
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- }
- Component {
- name: "QQmlInstantiator"
- defaultProperty: "delegate"
- prototype: "QObject"
- exports: ["QtQml.Models/Instantiator 2.14"]
- exportMetaObjectRevisions: [0]
- Property { name: "active"; type: "bool" }
- Property { name: "asynchronous"; type: "bool" }
- Property { name: "model"; type: "QVariant" }
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "object"; type: "QObject"; isReadonly: true; isPointer: true }
- Signal {
- name: "objectAdded"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "objectRemoved"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Method {
- name: "objectAt"
- type: "QObject*"
- Parameter { name: "index"; type: "int" }
- }
- }
- Component {
- name: "QQmlListElement"
- prototype: "QObject"
- exports: ["QtQml.Models/ListElement 2.1"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQmlListModel"
- prototype: "QAbstractListModel"
- exports: ["QtQml.Models/ListModel 2.1"]
- exportMetaObjectRevisions: [0]
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "dynamicRoles"; type: "bool" }
- Property { name: "agent"; revision: 14; type: "QObject"; isReadonly: true; isPointer: true }
- Method { name: "clear" }
- Method {
- name: "remove"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "append"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "insert"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "get"
- type: "QJSValue"
- Parameter { name: "index"; type: "int" }
- }
- Method {
- name: "set"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "value"; type: "QJSValue" }
- }
- Method {
- name: "setProperty"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "property"; type: "string" }
- Parameter { name: "value"; type: "QVariant" }
- }
- Method {
- name: "move"
- Parameter { name: "from"; type: "int" }
- Parameter { name: "to"; type: "int" }
- Parameter { name: "count"; type: "int" }
- }
- Method { name: "sync" }
- }
- Component {
- name: "QQmlListModelWorkerAgent"
- prototype: "QObject"
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
- Signal {
- name: "engineChanged"
- Parameter { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
- }
- Method { name: "addref" }
- Method { name: "release" }
- Method { name: "clear" }
- Method {
- name: "remove"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "append"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "insert"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "get"
- type: "QJSValue"
- Parameter { name: "index"; type: "int" }
- }
- Method {
- name: "set"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "value"; type: "QJSValue" }
- }
- Method {
- name: "setProperty"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "property"; type: "string" }
- Parameter { name: "value"; type: "QVariant" }
- }
- Method {
- name: "move"
- Parameter { name: "from"; type: "int" }
- Parameter { name: "to"; type: "int" }
- Parameter { name: "count"; type: "int" }
- }
- Method { name: "sync" }
- }
- Component {
- name: "QQmlObjectModel"
- defaultProperty: "children"
- prototype: "QQmlInstanceModel"
- exports: [
- "QtQml.Models/ObjectModel 2.1",
- "QtQml.Models/ObjectModel 2.3"
- ]
- exportMetaObjectRevisions: [0, 3]
- attachedType: "QQmlObjectModelAttached"
- Property { name: "children"; type: "QObject"; isList: true; isReadonly: true }
- Method { name: "clear"; revision: 3 }
- Method {
- name: "get"
- revision: 3
- type: "QObject*"
- Parameter { name: "index"; type: "int" }
- }
- Method {
- name: "append"
- revision: 3
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Method {
- name: "insert"
- revision: 3
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Method {
- name: "move"
- revision: 3
- Parameter { name: "from"; type: "int" }
- Parameter { name: "to"; type: "int" }
- Parameter { name: "n"; type: "int" }
- }
- Method {
- name: "move"
- revision: 3
- Parameter { name: "from"; type: "int" }
- Parameter { name: "to"; type: "int" }
- }
- Method {
- name: "remove"
- revision: 3
- Parameter { name: "index"; type: "int" }
- Parameter { name: "n"; type: "int" }
- }
- Method {
- name: "remove"
- revision: 3
- Parameter { name: "index"; type: "int" }
- }
- }
- Component {
- name: "QQmlObjectModelAttached"
- prototype: "QObject"
- Property { name: "index"; type: "int"; isReadonly: true }
- }
- Component {
- name: "QQuickPackage"
- defaultProperty: "data"
- prototype: "QObject"
- exports: ["QtQml.Models/Package 2.14"]
- exportMetaObjectRevisions: [0]
- attachedType: "QQuickPackageAttached"
- Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
- }
- Component {
- name: "QQuickPackageAttached"
- prototype: "QObject"
- Property { name: "name"; type: "string" }
- }
-}
diff --git a/src/imports/particles/plugin.cpp b/src/imports/particles/plugin.cpp
index 26fd979133..6629a660af 100644
--- a/src/imports/particles/plugin.cpp
+++ b/src/imports/particles/plugin.cpp
@@ -50,14 +50,16 @@ 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_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Particles"));
+ Q_UNUSED(uri);
QQuickParticlesModule::defineModule();
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
}
};
//![class decl]
diff --git a/src/imports/particles/plugins.qmltypes b/src/imports/particles/plugins.qmltypes
deleted file mode 100644
index 0a5e124c3c..0000000000
--- a/src/imports/particles/plugins.qmltypes
+++ /dev/null
@@ -1,1257 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Particles 2.14'
-
-Module {
- dependencies: ["QtQuick 2.0"]
- Component {
- name: "QQuickAgeAffector"
- defaultProperty: "data"
- prototype: "QQuickParticleAffector"
- exports: ["QtQuick.Particles/Age 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "lifeLeft"; type: "int" }
- Property { name: "advancePosition"; type: "bool" }
- Signal {
- name: "lifeLeftChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "advancePositionChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setLifeLeft"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setAdvancePosition"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickAngleDirection"
- prototype: "QQuickDirection"
- exports: ["QtQuick.Particles/AngleDirection 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "angle"; type: "double" }
- Property { name: "magnitude"; type: "double" }
- Property { name: "angleVariation"; type: "double" }
- Property { name: "magnitudeVariation"; type: "double" }
- Signal {
- name: "angleChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "magnitudeChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "angleVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "magnitudeVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setAngle"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setMagnitude"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setAngleVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setMagnitudeVariation"
- Parameter { name: "arg"; type: "double" }
- }
- }
- Component {
- name: "QQuickAttractorAffector"
- defaultProperty: "data"
- prototype: "QQuickParticleAffector"
- exports: ["QtQuick.Particles/Attractor 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Proportion"
- values: {
- "Constant": 0,
- "Linear": 1,
- "Quadratic": 2,
- "InverseLinear": 3,
- "InverseQuadratic": 4
- }
- }
- Enum {
- name: "AffectableParameters"
- values: {
- "Position": 0,
- "Velocity": 1,
- "Acceleration": 2
- }
- }
- Property { name: "strength"; type: "double" }
- Property { name: "pointX"; type: "double" }
- Property { name: "pointY"; type: "double" }
- Property { name: "affectedParameter"; type: "AffectableParameters" }
- Property { name: "proportionalToDistance"; type: "Proportion" }
- Signal {
- name: "strengthChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "pointXChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "pointYChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "affectedParameterChanged"
- Parameter { name: "arg"; type: "AffectableParameters" }
- }
- Signal {
- name: "proportionalToDistanceChanged"
- Parameter { name: "arg"; type: "Proportion" }
- }
- Method {
- name: "setStrength"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setPointX"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setPointY"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setAffectedParameter"
- Parameter { name: "arg"; type: "AffectableParameters" }
- }
- Method {
- name: "setProportionalToDistance"
- Parameter { name: "arg"; type: "Proportion" }
- }
- }
- Component {
- name: "QQuickCumulativeDirection"
- defaultProperty: "directions"
- prototype: "QQuickDirection"
- exports: ["QtQuick.Particles/CumulativeDirection 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "directions"; type: "QQuickDirection"; isList: true; isReadonly: true }
- }
- Component {
- name: "QQuickCustomAffector"
- defaultProperty: "data"
- prototype: "QQuickParticleAffector"
- exports: ["QtQuick.Particles/Affector 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "relative"; type: "bool" }
- Property { name: "position"; type: "QQuickDirection"; isPointer: true }
- Property { name: "velocity"; type: "QQuickDirection"; isPointer: true }
- Property { name: "acceleration"; type: "QQuickDirection"; isPointer: true }
- Signal {
- name: "affectParticles"
- Parameter { name: "particles"; type: "QJSValue" }
- Parameter { name: "dt"; type: "double" }
- }
- Signal {
- name: "positionChanged"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Signal {
- name: "velocityChanged"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Signal {
- name: "accelerationChanged"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Signal {
- name: "relativeChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setPosition"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Method {
- name: "setVelocity"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Method {
- name: "setAcceleration"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Method {
- name: "setRelative"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickCustomParticle"
- defaultProperty: "data"
- prototype: "QQuickParticlePainter"
- exports: ["QtQuick.Particles/CustomParticle 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "fragmentShader"; type: "QByteArray" }
- Property { name: "vertexShader"; type: "QByteArray" }
- }
- Component {
- name: "QQuickDirection"
- prototype: "QObject"
- exports: ["QtQuick.Particles/NullVector 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickEllipseExtruder"
- prototype: "QQuickParticleExtruder"
- exports: ["QtQuick.Particles/EllipseShape 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "fill"; type: "bool" }
- Signal {
- name: "fillChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setFill"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickFrictionAffector"
- defaultProperty: "data"
- prototype: "QQuickParticleAffector"
- exports: ["QtQuick.Particles/Friction 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "factor"; type: "double" }
- Property { name: "threshold"; type: "double" }
- Signal {
- name: "factorChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "thresholdChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setFactor"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setThreshold"
- Parameter { name: "arg"; type: "double" }
- }
- }
- Component {
- name: "QQuickGravityAffector"
- defaultProperty: "data"
- prototype: "QQuickParticleAffector"
- exports: ["QtQuick.Particles/Gravity 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "magnitude"; type: "double" }
- Property { name: "acceleration"; type: "double" }
- Property { name: "angle"; type: "double" }
- Signal {
- name: "magnitudeChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "angleChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setMagnitude"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setAcceleration"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setAngle"
- Parameter { name: "arg"; type: "double" }
- }
- }
- Component {
- name: "QQuickGroupGoalAffector"
- defaultProperty: "data"
- prototype: "QQuickParticleAffector"
- exports: ["QtQuick.Particles/GroupGoal 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "goalState"; type: "string" }
- Property { name: "jump"; type: "bool" }
- Signal {
- name: "goalStateChanged"
- Parameter { name: "arg"; type: "string" }
- }
- Signal {
- name: "jumpChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setGoalState"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setJump"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickImageParticle"
- defaultProperty: "data"
- prototype: "QQuickParticlePainter"
- exports: ["QtQuick.Particles/ImageParticle 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Status"
- values: {
- "Null": 0,
- "Ready": 1,
- "Loading": 2,
- "Error": 3
- }
- }
- Enum {
- name: "EntryEffect"
- values: {
- "None": 0,
- "Fade": 1,
- "Scale": 2
- }
- }
- Property { name: "source"; type: "QUrl" }
- Property { name: "sprites"; type: "QQuickSprite"; isList: true; isReadonly: true }
- Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "colorTable"; type: "QUrl" }
- Property { name: "sizeTable"; type: "QUrl" }
- Property { name: "opacityTable"; type: "QUrl" }
- Property { name: "color"; type: "QColor" }
- Property { name: "colorVariation"; type: "double" }
- Property { name: "redVariation"; type: "double" }
- Property { name: "greenVariation"; type: "double" }
- Property { name: "blueVariation"; type: "double" }
- Property { name: "alpha"; type: "double" }
- Property { name: "alphaVariation"; type: "double" }
- Property { name: "rotation"; type: "double" }
- Property { name: "rotationVariation"; type: "double" }
- Property { name: "rotationVelocity"; type: "double" }
- Property { name: "rotationVelocityVariation"; type: "double" }
- Property { name: "autoRotation"; type: "bool" }
- Property { name: "xVector"; type: "QQuickDirection"; isPointer: true }
- Property { name: "yVector"; type: "QQuickDirection"; isPointer: true }
- Property { name: "spritesInterpolate"; type: "bool" }
- Property { name: "entryEffect"; type: "EntryEffect" }
- Signal { name: "imageChanged" }
- Signal { name: "colortableChanged" }
- Signal { name: "sizetableChanged" }
- Signal { name: "opacitytableChanged" }
- Signal {
- name: "alphaVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "alphaChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "redVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "greenVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "blueVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "rotationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "rotationVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "rotationVelocityChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "rotationVelocityVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "autoRotationChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "xVectorChanged"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Signal {
- name: "yVectorChanged"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Signal {
- name: "spritesInterpolateChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "bypassOptimizationsChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "entryEffectChanged"
- Parameter { name: "arg"; type: "EntryEffect" }
- }
- Signal {
- name: "statusChanged"
- Parameter { name: "arg"; type: "Status" }
- }
- Method {
- name: "reloadColor"
- Parameter { name: "c"; type: "Color4ub" }
- Parameter { name: "d"; type: "QQuickParticleData"; isPointer: true }
- }
- Method {
- name: "setAlphaVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setAlpha"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setRedVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setGreenVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setBlueVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setRotation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setRotationVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setRotationVelocity"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setRotationVelocityVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setAutoRotation"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setXVector"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Method {
- name: "setYVector"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Method {
- name: "setSpritesInterpolate"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setBypassOptimizations"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setEntryEffect"
- Parameter { name: "arg"; type: "EntryEffect" }
- }
- }
- Component {
- name: "QQuickItemParticle"
- defaultProperty: "data"
- prototype: "QQuickParticlePainter"
- exports: ["QtQuick.Particles/ItemParticle 2.0"]
- exportMetaObjectRevisions: [0]
- attachedType: "QQuickItemParticleAttached"
- Property { name: "fade"; type: "bool" }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Signal {
- name: "delegateChanged"
- Parameter { name: "arg"; type: "QQmlComponent"; isPointer: true }
- }
- Method {
- name: "freeze"
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- }
- Method {
- name: "unfreeze"
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- }
- Method {
- name: "take"
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- Parameter { name: "prioritize"; type: "bool" }
- }
- Method {
- name: "take"
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- }
- Method {
- name: "give"
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- }
- Method {
- name: "setFade"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setDelegate"
- Parameter { name: "arg"; type: "QQmlComponent"; isPointer: true }
- }
- }
- Component {
- name: "QQuickItemParticleAttached"
- prototype: "QObject"
- Property { name: "particle"; type: "QQuickItemParticle"; isReadonly: true; isPointer: true }
- Signal { name: "detached" }
- Signal { name: "attached" }
- }
- Component {
- name: "QQuickLineExtruder"
- prototype: "QQuickParticleExtruder"
- exports: ["QtQuick.Particles/LineShape 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "mirrored"; type: "bool" }
- Signal {
- name: "mirroredChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setMirrored"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickMaskExtruder"
- prototype: "QQuickParticleExtruder"
- exports: ["QtQuick.Particles/MaskShape 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "source"; type: "QUrl" }
- Signal {
- name: "sourceChanged"
- Parameter { name: "arg"; type: "QUrl" }
- }
- Method {
- name: "setSource"
- Parameter { name: "arg"; type: "QUrl" }
- }
- }
- Component {
- name: "QQuickParticleAffector"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick.Particles/ParticleAffector 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "system"; type: "QQuickParticleSystem"; isPointer: true }
- Property { name: "groups"; type: "QStringList" }
- Property { name: "whenCollidingWith"; type: "QStringList" }
- Property { name: "enabled"; type: "bool" }
- Property { name: "once"; type: "bool" }
- Property { name: "shape"; type: "QQuickParticleExtruder"; isPointer: true }
- Signal {
- name: "systemChanged"
- Parameter { name: "arg"; type: "QQuickParticleSystem"; isPointer: true }
- }
- Signal {
- name: "groupsChanged"
- Parameter { name: "arg"; type: "QStringList" }
- }
- Signal {
- name: "enabledChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "onceChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "shapeChanged"
- Parameter { name: "arg"; type: "QQuickParticleExtruder"; isPointer: true }
- }
- Signal {
- name: "affected"
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- Signal {
- name: "whenCollidingWithChanged"
- Parameter { name: "arg"; type: "QStringList" }
- }
- Method {
- name: "setSystem"
- Parameter { name: "arg"; type: "QQuickParticleSystem"; isPointer: true }
- }
- Method {
- name: "setGroups"
- Parameter { name: "arg"; type: "QStringList" }
- }
- Method {
- name: "setEnabled"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setOnceOff"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setShape"
- Parameter { name: "arg"; type: "QQuickParticleExtruder"; isPointer: true }
- }
- Method {
- name: "setWhenCollidingWith"
- Parameter { name: "arg"; type: "QStringList" }
- }
- Method { name: "updateOffsets" }
- }
- Component {
- name: "QQuickParticleEmitter"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick.Particles/Emitter 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Lifetime"
- values: {
- "InfiniteLife": 600000
- }
- }
- Property { name: "system"; type: "QQuickParticleSystem"; isPointer: true }
- Property { name: "group"; type: "string" }
- Property { name: "shape"; type: "QQuickParticleExtruder"; isPointer: true }
- Property { name: "enabled"; type: "bool" }
- Property { name: "startTime"; type: "int" }
- Property { name: "emitRate"; type: "double" }
- Property { name: "lifeSpan"; type: "int" }
- Property { name: "lifeSpanVariation"; type: "int" }
- Property { name: "maximumEmitted"; type: "int" }
- Property { name: "size"; type: "double" }
- Property { name: "endSize"; type: "double" }
- Property { name: "sizeVariation"; type: "double" }
- Property { name: "velocity"; type: "QQuickDirection"; isPointer: true }
- Property { name: "acceleration"; type: "QQuickDirection"; isPointer: true }
- Property { name: "velocityFromMovement"; type: "double" }
- Signal {
- name: "emitParticles"
- Parameter { name: "particles"; type: "QJSValue" }
- }
- Signal {
- name: "particlesPerSecondChanged"
- Parameter { type: "double" }
- }
- Signal {
- name: "particleDurationChanged"
- Parameter { type: "int" }
- }
- Signal {
- name: "enabledChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "systemChanged"
- Parameter { name: "arg"; type: "QQuickParticleSystem"; isPointer: true }
- }
- Signal {
- name: "groupChanged"
- Parameter { name: "arg"; type: "string" }
- }
- Signal {
- name: "particleDurationVariationChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "extruderChanged"
- Parameter { name: "arg"; type: "QQuickParticleExtruder"; isPointer: true }
- }
- Signal {
- name: "particleSizeChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "particleEndSizeChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "particleSizeVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "velocityChanged"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Signal {
- name: "accelerationChanged"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Signal {
- name: "maximumEmittedChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal { name: "particleCountChanged" }
- Signal {
- name: "startTimeChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "pulse"
- Parameter { name: "milliseconds"; type: "int" }
- }
- Method {
- name: "burst"
- Parameter { name: "num"; type: "int" }
- }
- Method {
- name: "burst"
- Parameter { name: "num"; type: "int" }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- Method {
- name: "setEnabled"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setParticlesPerSecond"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setParticleDuration"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setSystem"
- Parameter { name: "arg"; type: "QQuickParticleSystem"; isPointer: true }
- }
- Method {
- name: "setGroup"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setParticleDurationVariation"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setExtruder"
- Parameter { name: "arg"; type: "QQuickParticleExtruder"; isPointer: true }
- }
- Method {
- name: "setParticleSize"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setParticleEndSize"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setParticleSizeVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setVelocity"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Method {
- name: "setAcceleration"
- Parameter { name: "arg"; type: "QQuickDirection"; isPointer: true }
- }
- Method {
- name: "setMaxParticleCount"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setStartTime"
- Parameter { name: "arg"; type: "int" }
- }
- Method { name: "reset" }
- }
- Component {
- name: "QQuickParticleExtruder"
- prototype: "QObject"
- exports: ["QtQuick.Particles/ParticleExtruder 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickParticleGroup"
- defaultProperty: "particleChildren"
- prototype: "QQuickStochasticState"
- exports: ["QtQuick.Particles/ParticleGroup 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "system"; type: "QQuickParticleSystem"; isPointer: true }
- Property { name: "particleChildren"; type: "QObject"; isList: true; isReadonly: true }
- Signal {
- name: "maximumAliveChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "systemChanged"
- Parameter { name: "arg"; type: "QQuickParticleSystem"; isPointer: true }
- }
- Method {
- name: "setMaximumAlive"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setSystem"
- Parameter { name: "arg"; type: "QQuickParticleSystem"; isPointer: true }
- }
- Method {
- name: "delayRedirect"
- Parameter { name: "obj"; type: "QObject"; isPointer: true }
- }
- }
- Component {
- name: "QQuickParticlePainter"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick.Particles/ParticlePainter 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "system"; type: "QQuickParticleSystem"; isPointer: true }
- Property { name: "groups"; type: "QStringList" }
- Signal { name: "countChanged" }
- Signal {
- name: "systemChanged"
- Parameter { name: "arg"; type: "QQuickParticleSystem"; isPointer: true }
- }
- Signal {
- name: "groupsChanged"
- Parameter { name: "arg"; type: "QStringList" }
- }
- Method {
- name: "setSystem"
- Parameter { name: "arg"; type: "QQuickParticleSystem"; isPointer: true }
- }
- Method {
- name: "setGroups"
- Parameter { name: "arg"; type: "QStringList" }
- }
- Method {
- name: "calcSystemOffset"
- Parameter { name: "resetPending"; type: "bool" }
- }
- Method { name: "calcSystemOffset" }
- }
- Component {
- name: "QQuickParticleSystem"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick.Particles/ParticleSystem 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "running"; type: "bool" }
- Property { name: "paused"; type: "bool" }
- Property { name: "empty"; type: "bool"; isReadonly: true }
- Signal { name: "systemInitialized" }
- Signal {
- name: "runningChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "pausedChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "emptyChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method { name: "start" }
- Method { name: "stop" }
- Method { name: "restart" }
- Method { name: "pause" }
- Method { name: "resume" }
- Method { name: "reset" }
- Method {
- name: "setRunning"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setPaused"
- Parameter { name: "arg"; type: "bool" }
- }
- Method { name: "duration"; type: "int" }
- }
- Component {
- name: "QQuickPointDirection"
- prototype: "QQuickDirection"
- exports: ["QtQuick.Particles/PointDirection 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "x"; type: "double" }
- Property { name: "y"; type: "double" }
- Property { name: "xVariation"; type: "double" }
- Property { name: "yVariation"; type: "double" }
- Signal {
- name: "xChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "yChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "xVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "yVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setX"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setY"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setXVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setYVariation"
- Parameter { name: "arg"; type: "double" }
- }
- }
- Component {
- name: "QQuickRectangleExtruder"
- prototype: "QQuickParticleExtruder"
- exports: ["QtQuick.Particles/RectangleShape 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "fill"; type: "bool" }
- Signal {
- name: "fillChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setFill"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickSpriteGoalAffector"
- defaultProperty: "data"
- prototype: "QQuickParticleAffector"
- exports: ["QtQuick.Particles/SpriteGoal 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "goalState"; type: "string" }
- Property { name: "jump"; type: "bool" }
- Property { name: "systemStates"; type: "bool" }
- Signal {
- name: "goalStateChanged"
- Parameter { name: "arg"; type: "string" }
- }
- Signal {
- name: "jumpChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "systemStatesChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setGoalState"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setJump"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setSystemStates"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickStochasticState"
- prototype: "QObject"
- Property { name: "duration"; type: "int" }
- Property { name: "durationVariation"; type: "int" }
- Property { name: "randomStart"; type: "bool" }
- Property { name: "to"; type: "QVariantMap" }
- Property { name: "name"; type: "string" }
- Signal {
- name: "durationChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "nameChanged"
- Parameter { name: "arg"; type: "string" }
- }
- Signal {
- name: "toChanged"
- Parameter { name: "arg"; type: "QVariantMap" }
- }
- Signal {
- name: "durationVariationChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal { name: "entered" }
- Signal {
- name: "randomStartChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setDuration"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setName"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setTo"
- Parameter { name: "arg"; type: "QVariantMap" }
- }
- Method {
- name: "setDurationVariation"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setRandomStart"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickTargetDirection"
- prototype: "QQuickDirection"
- exports: ["QtQuick.Particles/TargetDirection 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "targetX"; type: "double" }
- Property { name: "targetY"; type: "double" }
- Property { name: "targetItem"; type: "QQuickItem"; isPointer: true }
- Property { name: "targetVariation"; type: "double" }
- Property { name: "proportionalMagnitude"; type: "bool" }
- Property { name: "magnitude"; type: "double" }
- Property { name: "magnitudeVariation"; type: "double" }
- Signal {
- name: "targetXChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "targetYChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "targetVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "magnitudeChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "proprotionalMagnitudeChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "magnitudeVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "targetItemChanged"
- Parameter { name: "arg"; type: "QQuickItem"; isPointer: true }
- }
- Method {
- name: "setTargetX"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setTargetY"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setTargetVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setMagnitude"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setProportionalMagnitude"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setMagnitudeVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setTargetItem"
- Parameter { name: "arg"; type: "QQuickItem"; isPointer: true }
- }
- }
- Component {
- name: "QQuickTrailEmitter"
- defaultProperty: "data"
- prototype: "QQuickParticleEmitter"
- exports: ["QtQuick.Particles/TrailEmitter 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "EmitSize"
- values: {
- "ParticleSize": -2
- }
- }
- Property { name: "follow"; type: "string" }
- Property { name: "emitRatePerParticle"; type: "int" }
- Property { name: "emitShape"; type: "QQuickParticleExtruder"; isPointer: true }
- Property { name: "emitHeight"; type: "double" }
- Property { name: "emitWidth"; type: "double" }
- Signal {
- name: "emitFollowParticles"
- Parameter { name: "particles"; type: "QJSValue" }
- Parameter { name: "followed"; type: "QJSValue" }
- }
- Signal {
- name: "particlesPerParticlePerSecondChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "emitterXVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "emitterYVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "followChanged"
- Parameter { name: "arg"; type: "string" }
- }
- Signal {
- name: "emissionShapeChanged"
- Parameter { name: "arg"; type: "QQuickParticleExtruder"; isPointer: true }
- }
- Method {
- name: "setParticlesPerParticlePerSecond"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setEmitterXVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setEmitterYVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setFollow"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setEmissionShape"
- Parameter { name: "arg"; type: "QQuickParticleExtruder"; isPointer: true }
- }
- }
- Component {
- name: "QQuickTurbulenceAffector"
- defaultProperty: "data"
- prototype: "QQuickParticleAffector"
- exports: ["QtQuick.Particles/Turbulence 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "strength"; type: "double" }
- Property { name: "noiseSource"; type: "QUrl" }
- Signal {
- name: "strengthChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "noiseSourceChanged"
- Parameter { name: "arg"; type: "QUrl" }
- }
- Method {
- name: "setStrength"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setNoiseSource"
- Parameter { name: "arg"; type: "QUrl" }
- }
- }
- Component {
- name: "QQuickWanderAffector"
- defaultProperty: "data"
- prototype: "QQuickParticleAffector"
- exports: ["QtQuick.Particles/Wander 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "AffectableParameters"
- values: {
- "Position": 0,
- "Velocity": 1,
- "Acceleration": 2
- }
- }
- Property { name: "pace"; type: "double" }
- Property { name: "xVariance"; type: "double" }
- Property { name: "yVariance"; type: "double" }
- Property { name: "affectedParameter"; type: "AffectableParameters" }
- Signal {
- name: "xVarianceChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "yVarianceChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "paceChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "affectedParameterChanged"
- Parameter { name: "arg"; type: "AffectableParameters" }
- }
- Method {
- name: "setXVariance"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setYVariance"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setPace"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setAffectedParameter"
- Parameter { name: "arg"; type: "AffectableParameters" }
- }
- }
-}
diff --git a/src/imports/qtqml/plugin.cpp b/src/imports/qtqml/plugin.cpp
index 7595d6d65b..854ef6d2e6 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>
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QtQmlModels/private/qqmlmodelsmodule_p.h>
@@ -65,25 +63,33 @@ QT_BEGIN_NAMESPACE
*/
//![class decl]
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
class QtQmlPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
- QtQmlPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
+ QtQmlPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent)
{
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQml"));
- QQmlEnginePrivate::defineModule();
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- QQmlModelsModule::registerQmlTypes();
-#endif
+ volatile auto registration = &qml_register_types_QtQml;
+ Q_UNUSED(registration);
+ }
- // Auto-increment the import to stay in sync with ALL future QtQml minor versions from 5.11 onward
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
+ void registerTypes(const char *) override { QQmlModelsModule::registerQmlTypes(); }
+};
+#else
+class QtQmlPlugin : public QQmlEngineExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
+public:
+ QtQmlPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQml;
+ Q_UNUSED(registration);
}
};
+#endif
//![class decl]
QT_END_NAMESPACE
diff --git a/src/imports/qtqml/plugins.qmltypes b/src/imports/qtqml/plugins.qmltypes
deleted file mode 100644
index 7bccfea26a..0000000000
--- a/src/imports/qtqml/plugins.qmltypes
+++ /dev/null
@@ -1,245 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml 2.14'
-
-Module {
- dependencies: []
- Component {
- name: "QObject"
- exports: ["QtQml/QtObject 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "objectName"; type: "string" }
- Signal {
- name: "objectNameChanged"
- Parameter { name: "objectName"; type: "string" }
- }
- Method { name: "toString" }
- Method { name: "destroy" }
- Method {
- name: "destroy"
- Parameter { name: "delay"; type: "int" }
- }
- }
- Component {
- name: "QQmlBind"
- prototype: "QObject"
- exports: [
- "QtQml/Binding 2.0",
- "QtQml/Binding 2.14",
- "QtQml/Binding 2.8"
- ]
- exportMetaObjectRevisions: [0, 14, 8]
- Enum {
- name: "RestorationMode"
- values: {
- "RestoreNone": 0,
- "RestoreBinding": 1,
- "RestoreValue": 2,
- "RestoreBindingOrValue": 3
- }
- }
- Property { name: "target"; type: "QObject"; isPointer: true }
- Property { name: "property"; type: "string" }
- Property { name: "value"; type: "QVariant" }
- Property { name: "when"; type: "bool" }
- Property { name: "delayed"; revision: 8; type: "bool" }
- Property { name: "restoreMode"; revision: 14; type: "RestorationMode" }
- }
- Component {
- name: "QQmlComponent"
- prototype: "QObject"
- exports: ["QtQml/Component 2.0"]
- exportMetaObjectRevisions: [0]
- attachedType: "QQmlComponentAttached"
- Enum {
- name: "CompilationMode"
- values: {
- "PreferSynchronous": 0,
- "Asynchronous": 1
- }
- }
- Enum {
- name: "Status"
- values: {
- "Null": 0,
- "Ready": 1,
- "Loading": 2,
- "Error": 3
- }
- }
- Property { name: "progress"; type: "double"; isReadonly: true }
- Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "url"; type: "QUrl"; isReadonly: true }
- Signal {
- name: "statusChanged"
- Parameter { type: "QQmlComponent::Status" }
- }
- Signal {
- name: "progressChanged"
- Parameter { type: "double" }
- }
- Method {
- name: "loadUrl"
- Parameter { name: "url"; type: "QUrl" }
- }
- Method {
- name: "loadUrl"
- Parameter { name: "url"; type: "QUrl" }
- Parameter { name: "mode"; type: "CompilationMode" }
- }
- Method {
- name: "setData"
- Parameter { type: "QByteArray" }
- Parameter { name: "baseUrl"; type: "QUrl" }
- }
- Method { name: "errorString"; type: "string" }
- }
- Component {
- name: "QQmlComponentAttached"
- prototype: "QObject"
- Signal { name: "completed" }
- Signal { name: "destruction" }
- }
- Component {
- name: "QQmlConnections"
- prototype: "QObject"
- exports: ["QtQml/Connections 2.0", "QtQml/Connections 2.3"]
- exportMetaObjectRevisions: [0, 3]
- Property { name: "target"; type: "QObject"; isPointer: true }
- Property { name: "enabled"; revision: 3; type: "bool" }
- Property { name: "ignoreUnknownSignals"; type: "bool" }
- Signal { name: "enabledChanged"; revision: 3 }
- }
- Component {
- name: "QQmlInstanceModel"
- prototype: "QObject"
- Property { name: "count"; type: "int"; isReadonly: true }
- Signal {
- name: "modelUpdated"
- Parameter { name: "changeSet"; type: "QQmlChangeSet" }
- Parameter { name: "reset"; type: "bool" }
- }
- Signal {
- name: "createdItem"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "initItem"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "destroyingItem"
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- }
- Component {
- name: "QQmlInstantiator"
- defaultProperty: "delegate"
- prototype: "QObject"
- exports: ["QtQml/Instantiator 2.1"]
- exportMetaObjectRevisions: [0]
- Property { name: "active"; type: "bool" }
- Property { name: "asynchronous"; type: "bool" }
- Property { name: "model"; type: "QVariant" }
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "object"; type: "QObject"; isReadonly: true; isPointer: true }
- Signal {
- name: "objectAdded"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "objectRemoved"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Method {
- name: "objectAt"
- type: "QObject*"
- Parameter { name: "index"; type: "int" }
- }
- }
- Component {
- name: "QQmlLocale"
- exports: ["QtQml/Locale 2.2"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "MeasurementSystem"
- values: {
- "MetricSystem": 0,
- "ImperialSystem": 1,
- "ImperialUSSystem": 1,
- "ImperialUKSystem": 2
- }
- }
- Enum {
- name: "FormatType"
- values: {
- "LongFormat": 0,
- "ShortFormat": 1,
- "NarrowFormat": 2
- }
- }
- Enum {
- name: "CurrencySymbolFormat"
- values: {
- "CurrencyIsoCode": 0,
- "CurrencySymbol": 1,
- "CurrencyDisplayName": 2
- }
- }
- Enum {
- name: "DayOfWeek"
- values: {
- "Sunday": 0,
- "Monday": 1,
- "Tuesday": 2,
- "Wednesday": 3,
- "Thursday": 4,
- "Friday": 5,
- "Saturday": 6
- }
- }
- }
- Component {
- name: "QQmlLoggingCategory"
- prototype: "QObject"
- exports: ["QtQml/LoggingCategory 2.12", "QtQml/LoggingCategory 2.8"]
- exportMetaObjectRevisions: [12, 0]
- Enum {
- name: "DefaultLogLevel"
- values: {
- "Debug": 0,
- "Info": 4,
- "Warning": 1,
- "Critical": 2,
- "Fatal": 3
- }
- }
- Property { name: "name"; type: "string" }
- Property { name: "defaultLogLevel"; revision: 12; type: "DefaultLogLevel" }
- }
- Component {
- name: "QQmlTimer"
- prototype: "QObject"
- exports: ["QtQml/Timer 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "interval"; type: "int" }
- Property { name: "running"; type: "bool" }
- Property { name: "repeat"; type: "bool" }
- Property { name: "triggeredOnStart"; type: "bool" }
- Property { name: "parent"; type: "QObject"; isReadonly: true; isPointer: true }
- Signal { name: "triggered" }
- Method { name: "start" }
- Method { name: "stop" }
- Method { name: "restart" }
- }
-}
diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp
index efa05c349c..20bc4a3cc0 100644
--- a/src/imports/qtquick2/plugin.cpp
+++ b/src/imports/qtquick2/plugin.cpp
@@ -57,7 +57,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"));
@@ -71,9 +76,6 @@ public:
#endif
#endif
QQmlQtQuick2Module::defineModule();
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule("QtQuick", 2, QT_VERSION_MINOR);
}
~QtQuick2Plugin() override
diff --git a/src/imports/qtquick2/plugins.qmltypes b/src/imports/qtquick2/plugins.qmltypes
deleted file mode 100644
index fffe03ad73..0000000000
--- a/src/imports/qtquick2/plugins.qmltypes
+++ /dev/null
@@ -1,5709 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick 2.14'
-
-Module {
- dependencies: []
- Component {
- name: "QAbstractItemModel"
- prototype: "QObject"
- Enum {
- name: "LayoutChangeHint"
- values: {
- "NoLayoutChangeHint": 0,
- "VerticalSortHint": 1,
- "HorizontalSortHint": 2
- }
- }
- Enum {
- name: "CheckIndexOption"
- values: {
- "NoOption": 0,
- "IndexIsValid": 1,
- "DoNotUseParent": 2,
- "ParentIsInvalid": 4
- }
- }
- Signal {
- name: "dataChanged"
- Parameter { name: "topLeft"; type: "QModelIndex" }
- Parameter { name: "bottomRight"; type: "QModelIndex" }
- Parameter { name: "roles"; type: "QVector<int>" }
- }
- Signal {
- name: "dataChanged"
- Parameter { name: "topLeft"; type: "QModelIndex" }
- Parameter { name: "bottomRight"; type: "QModelIndex" }
- }
- Signal {
- name: "headerDataChanged"
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "layoutChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
- }
- Signal {
- name: "layoutChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- }
- Signal { name: "layoutChanged" }
- Signal {
- name: "layoutAboutToBeChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" }
- }
- Signal {
- name: "layoutAboutToBeChanged"
- Parameter { name: "parents"; type: "QList<QPersistentModelIndex>" }
- }
- Signal { name: "layoutAboutToBeChanged" }
- Signal {
- name: "rowsAboutToBeInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsAboutToBeRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "rowsRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsInserted"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal {
- name: "columnsRemoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "first"; type: "int" }
- Parameter { name: "last"; type: "int" }
- }
- Signal { name: "modelAboutToBeReset" }
- Signal { name: "modelReset" }
- Signal {
- name: "rowsAboutToBeMoved"
- Parameter { name: "sourceParent"; type: "QModelIndex" }
- Parameter { name: "sourceStart"; type: "int" }
- Parameter { name: "sourceEnd"; type: "int" }
- Parameter { name: "destinationParent"; type: "QModelIndex" }
- Parameter { name: "destinationRow"; type: "int" }
- }
- Signal {
- name: "rowsMoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- Parameter { name: "destination"; type: "QModelIndex" }
- Parameter { name: "row"; type: "int" }
- }
- Signal {
- name: "columnsAboutToBeMoved"
- Parameter { name: "sourceParent"; type: "QModelIndex" }
- Parameter { name: "sourceStart"; type: "int" }
- Parameter { name: "sourceEnd"; type: "int" }
- Parameter { name: "destinationParent"; type: "QModelIndex" }
- Parameter { name: "destinationColumn"; type: "int" }
- }
- Signal {
- name: "columnsMoved"
- Parameter { name: "parent"; type: "QModelIndex" }
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- Parameter { name: "destination"; type: "QModelIndex" }
- Parameter { name: "column"; type: "int" }
- }
- Method { name: "submit"; type: "bool" }
- Method { name: "revert" }
- Method {
- name: "hasIndex"
- type: "bool"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "hasIndex"
- type: "bool"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- }
- Method {
- name: "index"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "index"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- }
- Method {
- name: "parent"
- type: "QModelIndex"
- Parameter { name: "child"; type: "QModelIndex" }
- }
- Method {
- name: "sibling"
- type: "QModelIndex"
- Parameter { name: "row"; type: "int" }
- Parameter { name: "column"; type: "int" }
- Parameter { name: "idx"; type: "QModelIndex" }
- }
- Method {
- name: "rowCount"
- type: "int"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "rowCount"; type: "int" }
- Method {
- name: "columnCount"
- type: "int"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "columnCount"; type: "int" }
- Method {
- name: "hasChildren"
- type: "bool"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method { name: "hasChildren"; type: "bool" }
- Method {
- name: "data"
- type: "QVariant"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "data"
- type: "QVariant"
- Parameter { name: "index"; type: "QModelIndex" }
- }
- Method {
- name: "setData"
- type: "bool"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "setData"
- type: "bool"
- Parameter { name: "index"; type: "QModelIndex" }
- Parameter { name: "value"; type: "QVariant" }
- }
- Method {
- name: "headerData"
- type: "QVariant"
- Parameter { name: "section"; type: "int" }
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- Parameter { name: "role"; type: "int" }
- }
- Method {
- name: "headerData"
- type: "QVariant"
- Parameter { name: "section"; type: "int" }
- Parameter { name: "orientation"; type: "Qt::Orientation" }
- }
- Method {
- name: "fetchMore"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "canFetchMore"
- type: "bool"
- Parameter { name: "parent"; type: "QModelIndex" }
- }
- Method {
- name: "flags"
- type: "Qt::ItemFlags"
- Parameter { name: "index"; type: "QModelIndex" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "hits"; type: "int" }
- Parameter { name: "flags"; type: "Qt::MatchFlags" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- Parameter { name: "hits"; type: "int" }
- }
- Method {
- name: "match"
- type: "QModelIndexList"
- Parameter { name: "start"; type: "QModelIndex" }
- Parameter { name: "role"; type: "int" }
- Parameter { name: "value"; type: "QVariant" }
- }
- }
- Component { name: "QAbstractListModel"; prototype: "QAbstractItemModel" }
- Component {
- name: "QDoubleValidator"
- prototype: "QValidator"
- Enum {
- name: "Notation"
- values: {
- "StandardNotation": 0,
- "ScientificNotation": 1
- }
- }
- Property { name: "bottom"; type: "double" }
- Property { name: "top"; type: "double" }
- Property { name: "decimals"; type: "int" }
- Property { name: "notation"; type: "Notation" }
- Signal {
- name: "bottomChanged"
- Parameter { name: "bottom"; type: "double" }
- }
- Signal {
- name: "topChanged"
- Parameter { name: "top"; type: "double" }
- }
- Signal {
- name: "decimalsChanged"
- Parameter { name: "decimals"; type: "int" }
- }
- Signal {
- name: "notationChanged"
- Parameter { name: "notation"; type: "QDoubleValidator::Notation" }
- }
- }
- Component {
- name: "QInputMethod"
- prototype: "QObject"
- exports: ["QtQuick/InputMethod 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Action"
- values: {
- "Click": 0,
- "ContextMenu": 1
- }
- }
- Property { name: "cursorRectangle"; type: "QRectF"; isReadonly: true }
- Property { name: "anchorRectangle"; type: "QRectF"; isReadonly: true }
- Property { name: "keyboardRectangle"; type: "QRectF"; isReadonly: true }
- Property { name: "inputItemClipRectangle"; type: "QRectF"; isReadonly: true }
- Property { name: "visible"; type: "bool"; isReadonly: true }
- Property { name: "animating"; type: "bool"; isReadonly: true }
- Property { name: "locale"; type: "QLocale"; isReadonly: true }
- Property { name: "inputDirection"; type: "Qt::LayoutDirection"; isReadonly: true }
- Signal {
- name: "inputDirectionChanged"
- Parameter { name: "newDirection"; type: "Qt::LayoutDirection" }
- }
- Method { name: "show" }
- Method { name: "hide" }
- Method {
- name: "update"
- Parameter { name: "queries"; type: "Qt::InputMethodQueries" }
- }
- Method { name: "reset" }
- Method { name: "commit" }
- Method {
- name: "invokeAction"
- Parameter { name: "a"; type: "Action" }
- Parameter { name: "cursorPosition"; type: "int" }
- }
- }
- Component {
- name: "QIntValidator"
- prototype: "QValidator"
- Property { name: "bottom"; type: "int" }
- Property { name: "top"; type: "int" }
- Signal {
- name: "bottomChanged"
- Parameter { name: "bottom"; type: "int" }
- }
- Signal {
- name: "topChanged"
- Parameter { name: "top"; type: "int" }
- }
- }
- Component {
- name: "QKeySequence"
- exports: ["QtQuick/StandardKey 2.2"]
- isCreatable: false
- exportMetaObjectRevisions: [2]
- Enum {
- name: "StandardKey"
- values: {
- "UnknownKey": 0,
- "HelpContents": 1,
- "WhatsThis": 2,
- "Open": 3,
- "Close": 4,
- "Save": 5,
- "New": 6,
- "Delete": 7,
- "Cut": 8,
- "Copy": 9,
- "Paste": 10,
- "Undo": 11,
- "Redo": 12,
- "Back": 13,
- "Forward": 14,
- "Refresh": 15,
- "ZoomIn": 16,
- "ZoomOut": 17,
- "Print": 18,
- "AddTab": 19,
- "NextChild": 20,
- "PreviousChild": 21,
- "Find": 22,
- "FindNext": 23,
- "FindPrevious": 24,
- "Replace": 25,
- "SelectAll": 26,
- "Bold": 27,
- "Italic": 28,
- "Underline": 29,
- "MoveToNextChar": 30,
- "MoveToPreviousChar": 31,
- "MoveToNextWord": 32,
- "MoveToPreviousWord": 33,
- "MoveToNextLine": 34,
- "MoveToPreviousLine": 35,
- "MoveToNextPage": 36,
- "MoveToPreviousPage": 37,
- "MoveToStartOfLine": 38,
- "MoveToEndOfLine": 39,
- "MoveToStartOfBlock": 40,
- "MoveToEndOfBlock": 41,
- "MoveToStartOfDocument": 42,
- "MoveToEndOfDocument": 43,
- "SelectNextChar": 44,
- "SelectPreviousChar": 45,
- "SelectNextWord": 46,
- "SelectPreviousWord": 47,
- "SelectNextLine": 48,
- "SelectPreviousLine": 49,
- "SelectNextPage": 50,
- "SelectPreviousPage": 51,
- "SelectStartOfLine": 52,
- "SelectEndOfLine": 53,
- "SelectStartOfBlock": 54,
- "SelectEndOfBlock": 55,
- "SelectStartOfDocument": 56,
- "SelectEndOfDocument": 57,
- "DeleteStartOfWord": 58,
- "DeleteEndOfWord": 59,
- "DeleteEndOfLine": 60,
- "InsertParagraphSeparator": 61,
- "InsertLineSeparator": 62,
- "SaveAs": 63,
- "Preferences": 64,
- "Quit": 65,
- "FullScreen": 66,
- "Deselect": 67,
- "DeleteCompleteLine": 68,
- "Backspace": 69,
- "Cancel": 70
- }
- }
- }
- Component {
- name: "QObject"
- exports: ["QtQuick/QtObject 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "objectName"; type: "string" }
- Signal {
- name: "objectNameChanged"
- Parameter { name: "objectName"; type: "string" }
- }
- Method { name: "toString" }
- Method { name: "destroy" }
- Method {
- name: "destroy"
- Parameter { name: "delay"; type: "int" }
- }
- }
- Component {
- name: "QPointingDeviceUniqueId"
- exports: ["QtQuick/PointingDeviceUniqueId 2.9"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "numericId"; type: "qlonglong"; isReadonly: true }
- }
- Component {
- name: "QQmlApplication"
- prototype: "QObject"
- Property { name: "arguments"; type: "QStringList"; isReadonly: true }
- Property { name: "name"; type: "string" }
- Property { name: "version"; type: "string" }
- Property { name: "organization"; type: "string" }
- Property { name: "domain"; type: "string" }
- Signal { name: "aboutToQuit" }
- Method {
- name: "setName"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setVersion"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setOrganization"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setDomain"
- Parameter { name: "arg"; type: "string" }
- }
- }
- Component {
- name: "QQmlBind"
- prototype: "QObject"
- exports: ["QtQuick/Binding 2.0", "QtQuick/Binding 2.8"]
- exportMetaObjectRevisions: [0, 8]
- Enum {
- name: "RestorationMode"
- values: {
- "RestoreNone": 0,
- "RestoreBinding": 1,
- "RestoreValue": 2,
- "RestoreBindingOrValue": 3
- }
- }
- Property { name: "target"; type: "QObject"; isPointer: true }
- Property { name: "property"; type: "string" }
- Property { name: "value"; type: "QVariant" }
- Property { name: "when"; type: "bool" }
- Property { name: "delayed"; revision: 8; type: "bool" }
- Property { name: "restoreMode"; revision: 14; type: "RestorationMode" }
- }
- Component {
- name: "QQmlComponent"
- prototype: "QObject"
- exports: ["QtQuick/Component 2.0"]
- exportMetaObjectRevisions: [0]
- attachedType: "QQmlComponentAttached"
- Enum {
- name: "CompilationMode"
- values: {
- "PreferSynchronous": 0,
- "Asynchronous": 1
- }
- }
- Enum {
- name: "Status"
- values: {
- "Null": 0,
- "Ready": 1,
- "Loading": 2,
- "Error": 3
- }
- }
- Property { name: "progress"; type: "double"; isReadonly: true }
- Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "url"; type: "QUrl"; isReadonly: true }
- Signal {
- name: "statusChanged"
- Parameter { type: "QQmlComponent::Status" }
- }
- Signal {
- name: "progressChanged"
- Parameter { type: "double" }
- }
- Method {
- name: "loadUrl"
- Parameter { name: "url"; type: "QUrl" }
- }
- Method {
- name: "loadUrl"
- Parameter { name: "url"; type: "QUrl" }
- Parameter { name: "mode"; type: "CompilationMode" }
- }
- Method {
- name: "setData"
- Parameter { type: "QByteArray" }
- Parameter { name: "baseUrl"; type: "QUrl" }
- }
- Method { name: "errorString"; type: "string" }
- }
- Component {
- name: "QQmlComponentAttached"
- prototype: "QObject"
- Signal { name: "completed" }
- Signal { name: "destruction" }
- }
- Component {
- name: "QQmlConnections"
- prototype: "QObject"
- exports: ["QtQuick/Connections 2.0", "QtQuick/Connections 2.7"]
- exportMetaObjectRevisions: [0, 3]
- Property { name: "target"; type: "QObject"; isPointer: true }
- Property { name: "enabled"; revision: 3; type: "bool" }
- Property { name: "ignoreUnknownSignals"; type: "bool" }
- Signal { name: "enabledChanged"; revision: 3 }
- }
- Component {
- name: "QQmlDelegateModel"
- defaultProperty: "delegate"
- prototype: "QQmlInstanceModel"
- exports: ["QtQuick/VisualDataModel 2.0"]
- exportMetaObjectRevisions: [0]
- attachedType: "QQmlDelegateModelAttached"
- Property { name: "model"; type: "QVariant" }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "filterOnGroup"; type: "string" }
- Property { name: "items"; type: "QQmlDelegateModelGroup"; isReadonly: true; isPointer: true }
- Property {
- name: "persistedItems"
- type: "QQmlDelegateModelGroup"
- isReadonly: true
- isPointer: true
- }
- Property { name: "groups"; type: "QQmlDelegateModelGroup"; isList: true; isReadonly: true }
- Property { name: "parts"; type: "QObject"; isReadonly: true; isPointer: true }
- Property { name: "rootIndex"; type: "QVariant" }
- Signal { name: "filterGroupChanged" }
- Signal { name: "defaultGroupsChanged" }
- Method {
- name: "modelIndex"
- type: "QVariant"
- Parameter { name: "idx"; type: "int" }
- }
- Method { name: "parentModelIndex"; type: "QVariant" }
- }
- Component {
- name: "QQmlDelegateModelAttached"
- prototype: "QObject"
- Property { name: "model"; type: "QQmlDelegateModel"; isReadonly: true; isPointer: true }
- Property { name: "groups"; type: "QStringList" }
- Property { name: "isUnresolved"; type: "bool"; isReadonly: true }
- Signal { name: "unresolvedChanged" }
- }
- Component {
- name: "QQmlDelegateModelGroup"
- prototype: "QObject"
- exports: ["QtQuick/VisualDataGroup 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "name"; type: "string" }
- Property { name: "includeByDefault"; type: "bool" }
- Signal { name: "defaultIncludeChanged" }
- Signal {
- name: "changed"
- Parameter { name: "removed"; type: "QJSValue" }
- Parameter { name: "inserted"; type: "QJSValue" }
- }
- Method {
- name: "insert"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "create"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "resolve"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "remove"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "addGroups"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "removeGroups"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "setGroups"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "move"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "get"
- type: "QJSValue"
- Parameter { name: "index"; type: "int" }
- }
- }
- Component { name: "QQmlDelegateModelParts"; prototype: "QObject" }
- Component {
- name: "QQmlEasingValueType"
- exports: ["QtQuick/Easing 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Type"
- values: {
- "Linear": 0,
- "InQuad": 1,
- "OutQuad": 2,
- "InOutQuad": 3,
- "OutInQuad": 4,
- "InCubic": 5,
- "OutCubic": 6,
- "InOutCubic": 7,
- "OutInCubic": 8,
- "InQuart": 9,
- "OutQuart": 10,
- "InOutQuart": 11,
- "OutInQuart": 12,
- "InQuint": 13,
- "OutQuint": 14,
- "InOutQuint": 15,
- "OutInQuint": 16,
- "InSine": 17,
- "OutSine": 18,
- "InOutSine": 19,
- "OutInSine": 20,
- "InExpo": 21,
- "OutExpo": 22,
- "InOutExpo": 23,
- "OutInExpo": 24,
- "InCirc": 25,
- "OutCirc": 26,
- "InOutCirc": 27,
- "OutInCirc": 28,
- "InElastic": 29,
- "OutElastic": 30,
- "InOutElastic": 31,
- "OutInElastic": 32,
- "InBack": 33,
- "OutBack": 34,
- "InOutBack": 35,
- "OutInBack": 36,
- "InBounce": 37,
- "OutBounce": 38,
- "InOutBounce": 39,
- "OutInBounce": 40,
- "InCurve": 41,
- "OutCurve": 42,
- "SineCurve": 43,
- "CosineCurve": 44,
- "Bezier": 45
- }
- }
- Property { name: "type"; type: "Type" }
- Property { name: "amplitude"; type: "double" }
- Property { name: "overshoot"; type: "double" }
- Property { name: "period"; type: "double" }
- Property { name: "bezierCurve"; type: "QVariantList" }
- }
- Component {
- name: "QQmlInstanceModel"
- prototype: "QObject"
- Property { name: "count"; type: "int"; isReadonly: true }
- Signal {
- name: "modelUpdated"
- Parameter { name: "changeSet"; type: "QQmlChangeSet" }
- Parameter { name: "reset"; type: "bool" }
- }
- Signal {
- name: "createdItem"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "initItem"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "destroyingItem"
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- }
- Component {
- name: "QQmlInstantiator"
- defaultProperty: "delegate"
- prototype: "QObject"
- exports: ["QtQuick/Instantiator 2.1"]
- exportMetaObjectRevisions: [0]
- Property { name: "active"; type: "bool" }
- Property { name: "asynchronous"; type: "bool" }
- Property { name: "model"; type: "QVariant" }
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "object"; type: "QObject"; isReadonly: true; isPointer: true }
- Signal {
- name: "objectAdded"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "objectRemoved"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Method {
- name: "objectAt"
- type: "QObject*"
- Parameter { name: "index"; type: "int" }
- }
- }
- Component {
- name: "QQmlListElement"
- prototype: "QObject"
- exports: ["QtQuick/ListElement 2.0"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQmlListModel"
- prototype: "QAbstractListModel"
- exports: ["QtQuick/ListModel 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "dynamicRoles"; type: "bool" }
- Property { name: "agent"; revision: 14; type: "QObject"; isReadonly: true; isPointer: true }
- Method { name: "clear" }
- Method {
- name: "remove"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "append"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "insert"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "get"
- type: "QJSValue"
- Parameter { name: "index"; type: "int" }
- }
- Method {
- name: "set"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "value"; type: "QJSValue" }
- }
- Method {
- name: "setProperty"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "property"; type: "string" }
- Parameter { name: "value"; type: "QVariant" }
- }
- Method {
- name: "move"
- Parameter { name: "from"; type: "int" }
- Parameter { name: "to"; type: "int" }
- Parameter { name: "count"; type: "int" }
- }
- Method { name: "sync" }
- }
- Component {
- name: "QQmlListModelWorkerAgent"
- prototype: "QObject"
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
- Signal {
- name: "engineChanged"
- Parameter { name: "engine"; type: "QV4::ExecutionEngine"; isPointer: true }
- }
- Method { name: "addref" }
- Method { name: "release" }
- Method { name: "clear" }
- Method {
- name: "remove"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "append"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "insert"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "get"
- type: "QJSValue"
- Parameter { name: "index"; type: "int" }
- }
- Method {
- name: "set"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "value"; type: "QJSValue" }
- }
- Method {
- name: "setProperty"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "property"; type: "string" }
- Parameter { name: "value"; type: "QVariant" }
- }
- Method {
- name: "move"
- Parameter { name: "from"; type: "int" }
- Parameter { name: "to"; type: "int" }
- Parameter { name: "count"; type: "int" }
- }
- Method { name: "sync" }
- }
- Component {
- name: "QQmlLocale"
- exports: ["QtQuick/Locale 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "MeasurementSystem"
- values: {
- "MetricSystem": 0,
- "ImperialSystem": 1,
- "ImperialUSSystem": 1,
- "ImperialUKSystem": 2
- }
- }
- Enum {
- name: "FormatType"
- values: {
- "LongFormat": 0,
- "ShortFormat": 1,
- "NarrowFormat": 2
- }
- }
- Enum {
- name: "CurrencySymbolFormat"
- values: {
- "CurrencyIsoCode": 0,
- "CurrencySymbol": 1,
- "CurrencyDisplayName": 2
- }
- }
- Enum {
- name: "DayOfWeek"
- values: {
- "Sunday": 0,
- "Monday": 1,
- "Tuesday": 2,
- "Wednesday": 3,
- "Thursday": 4,
- "Friday": 5,
- "Saturday": 6
- }
- }
- }
- Component {
- name: "QQmlLoggingCategory"
- prototype: "QObject"
- exports: [
- "QtQuick/LoggingCategory 2.12",
- "QtQuick/LoggingCategory 2.8"
- ]
- exportMetaObjectRevisions: [12, 0]
- Enum {
- name: "DefaultLogLevel"
- values: {
- "Debug": 0,
- "Info": 4,
- "Warning": 1,
- "Critical": 2,
- "Fatal": 3
- }
- }
- Property { name: "name"; type: "string" }
- Property { name: "defaultLogLevel"; revision: 12; type: "DefaultLogLevel" }
- }
- Component {
- name: "QQmlObjectModel"
- defaultProperty: "children"
- prototype: "QQmlInstanceModel"
- exports: ["QtQuick/VisualItemModel 2.0"]
- exportMetaObjectRevisions: [0]
- attachedType: "QQmlObjectModelAttached"
- Property { name: "children"; type: "QObject"; isList: true; isReadonly: true }
- Method { name: "clear"; revision: 3 }
- Method {
- name: "get"
- revision: 3
- type: "QObject*"
- Parameter { name: "index"; type: "int" }
- }
- Method {
- name: "append"
- revision: 3
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Method {
- name: "insert"
- revision: 3
- Parameter { name: "index"; type: "int" }
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Method {
- name: "move"
- revision: 3
- Parameter { name: "from"; type: "int" }
- Parameter { name: "to"; type: "int" }
- Parameter { name: "n"; type: "int" }
- }
- Method {
- name: "move"
- revision: 3
- Parameter { name: "from"; type: "int" }
- Parameter { name: "to"; type: "int" }
- }
- Method {
- name: "remove"
- revision: 3
- Parameter { name: "index"; type: "int" }
- Parameter { name: "n"; type: "int" }
- }
- Method {
- name: "remove"
- revision: 3
- Parameter { name: "index"; type: "int" }
- }
- }
- Component {
- name: "QQmlObjectModelAttached"
- prototype: "QObject"
- Property { name: "index"; type: "int"; isReadonly: true }
- }
- Component {
- name: "QQmlTimer"
- prototype: "QObject"
- exports: ["QtQuick/Timer 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "interval"; type: "int" }
- Property { name: "running"; type: "bool" }
- Property { name: "repeat"; type: "bool" }
- Property { name: "triggeredOnStart"; type: "bool" }
- Property { name: "parent"; type: "QObject"; isReadonly: true; isPointer: true }
- Signal { name: "triggered" }
- Method { name: "start" }
- Method { name: "stop" }
- Method { name: "restart" }
- }
- Component {
- name: "QQuickAbstractAnimation"
- prototype: "QObject"
- exports: ["QtQuick/Animation 2.0", "QtQuick/Animation 2.12"]
- isCreatable: false
- exportMetaObjectRevisions: [0, 12]
- Enum {
- name: "Loops"
- values: {
- "Infinite": -2
- }
- }
- Property { name: "running"; type: "bool" }
- Property { name: "paused"; type: "bool" }
- Property { name: "alwaysRunToEnd"; type: "bool" }
- Property { name: "loops"; type: "int" }
- Signal { name: "started" }
- Signal { name: "stopped" }
- Signal {
- name: "runningChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "pausedChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "alwaysRunToEndChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "loopCountChanged"
- Parameter { type: "int" }
- }
- Signal { name: "finished"; revision: 12 }
- Method { name: "restart" }
- Method { name: "start" }
- Method { name: "pause" }
- Method { name: "resume" }
- Method { name: "stop" }
- Method { name: "complete" }
- }
- Component {
- name: "QQuickAccessibleAttached"
- prototype: "QObject"
- exports: ["QtQuick/Accessible 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "role"; type: "QAccessible::Role" }
- Property { name: "name"; type: "string" }
- Property { name: "description"; type: "string" }
- Property { name: "ignored"; type: "bool" }
- Property { name: "checkable"; type: "bool" }
- Property { name: "checked"; type: "bool" }
- Property { name: "editable"; type: "bool" }
- Property { name: "focusable"; type: "bool" }
- Property { name: "focused"; type: "bool" }
- Property { name: "multiLine"; type: "bool" }
- Property { name: "readOnly"; type: "bool" }
- Property { name: "selected"; type: "bool" }
- Property { name: "selectable"; type: "bool" }
- Property { name: "pressed"; type: "bool" }
- Property { name: "checkStateMixed"; type: "bool" }
- Property { name: "defaultButton"; type: "bool" }
- Property { name: "passwordEdit"; type: "bool" }
- Property { name: "selectableText"; type: "bool" }
- Property { name: "searchEdit"; type: "bool" }
- Signal {
- name: "checkableChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "checkedChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "editableChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "focusableChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "focusedChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "multiLineChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "readOnlyChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "selectedChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "selectableChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "pressedChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "checkStateMixedChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "defaultButtonChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "passwordEditChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "selectableTextChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "searchEditChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal { name: "pressAction" }
- Signal { name: "toggleAction" }
- Signal { name: "increaseAction" }
- Signal { name: "decreaseAction" }
- Signal { name: "scrollUpAction" }
- Signal { name: "scrollDownAction" }
- Signal { name: "scrollLeftAction" }
- Signal { name: "scrollRightAction" }
- Signal { name: "previousPageAction" }
- Signal { name: "nextPageAction" }
- Method { name: "valueChanged" }
- Method { name: "cursorPositionChanged" }
- Method {
- name: "setIgnored"
- Parameter { name: "ignored"; type: "bool" }
- }
- }
- Component {
- name: "QQuickAnchorAnimation"
- prototype: "QQuickAbstractAnimation"
- exports: ["QtQuick/AnchorAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "targets"; type: "QQuickItem"; isList: true; isReadonly: true }
- Property { name: "duration"; type: "int" }
- Property { name: "easing"; type: "QEasingCurve" }
- Signal {
- name: "durationChanged"
- Parameter { type: "int" }
- }
- Signal {
- name: "easingChanged"
- Parameter { type: "QEasingCurve" }
- }
- }
- Component {
- name: "QQuickAnchorChanges"
- prototype: "QQuickStateOperation"
- exports: ["QtQuick/AnchorChanges 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "target"; type: "QQuickItem"; isPointer: true }
- Property { name: "anchors"; type: "QQuickAnchorSet"; isReadonly: true; isPointer: true }
- }
- Component {
- name: "QQuickAnchorSet"
- prototype: "QObject"
- Property { name: "left"; type: "QQmlScriptString" }
- Property { name: "right"; type: "QQmlScriptString" }
- Property { name: "horizontalCenter"; type: "QQmlScriptString" }
- Property { name: "top"; type: "QQmlScriptString" }
- Property { name: "bottom"; type: "QQmlScriptString" }
- Property { name: "verticalCenter"; type: "QQmlScriptString" }
- Property { name: "baseline"; type: "QQmlScriptString" }
- }
- Component {
- name: "QQuickAnchors"
- prototype: "QObject"
- Enum {
- name: "Anchors"
- values: {
- "InvalidAnchor": 0,
- "LeftAnchor": 1,
- "RightAnchor": 2,
- "TopAnchor": 4,
- "BottomAnchor": 8,
- "HCenterAnchor": 16,
- "VCenterAnchor": 32,
- "BaselineAnchor": 64,
- "Horizontal_Mask": 19,
- "Vertical_Mask": 108
- }
- }
- Property { name: "left"; type: "QQuickAnchorLine" }
- Property { name: "right"; type: "QQuickAnchorLine" }
- Property { name: "horizontalCenter"; type: "QQuickAnchorLine" }
- Property { name: "top"; type: "QQuickAnchorLine" }
- Property { name: "bottom"; type: "QQuickAnchorLine" }
- Property { name: "verticalCenter"; type: "QQuickAnchorLine" }
- Property { name: "baseline"; type: "QQuickAnchorLine" }
- Property { name: "margins"; type: "double" }
- Property { name: "leftMargin"; type: "double" }
- Property { name: "rightMargin"; type: "double" }
- Property { name: "horizontalCenterOffset"; type: "double" }
- Property { name: "topMargin"; type: "double" }
- Property { name: "bottomMargin"; type: "double" }
- Property { name: "verticalCenterOffset"; type: "double" }
- Property { name: "baselineOffset"; type: "double" }
- Property { name: "fill"; type: "QQuickItem"; isPointer: true }
- Property { name: "centerIn"; type: "QQuickItem"; isPointer: true }
- Property { name: "alignWhenCentered"; type: "bool" }
- Signal { name: "centerAlignedChanged" }
- }
- Component {
- name: "QQuickAnimatedImage"
- defaultProperty: "data"
- prototype: "QQuickImage"
- exports: ["QtQuick/AnimatedImage 2.0", "QtQuick/AnimatedImage 2.11"]
- exportMetaObjectRevisions: [0, 11]
- Property { name: "playing"; type: "bool" }
- Property { name: "paused"; type: "bool" }
- Property { name: "currentFrame"; type: "int" }
- Property { name: "frameCount"; type: "int"; isReadonly: true }
- Property { name: "speed"; revision: 11; type: "double" }
- Property { name: "sourceSize"; type: "QSize"; isReadonly: true }
- Signal { name: "frameChanged" }
- Signal { name: "speedChanged"; revision: 11 }
- }
- Component {
- name: "QQuickAnimatedSprite"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick/AnimatedSprite 2.0", "QtQuick/AnimatedSprite 2.12"]
- exportMetaObjectRevisions: [0, 12]
- Enum {
- name: "LoopParameters"
- values: {
- "Infinite": -1
- }
- }
- Property { name: "running"; type: "bool" }
- Property { name: "interpolate"; type: "bool" }
- Property { name: "source"; type: "QUrl" }
- Property { name: "reverse"; type: "bool" }
- Property { name: "frameSync"; type: "bool" }
- Property { name: "frameCount"; type: "int" }
- Property { name: "frameHeight"; type: "int" }
- Property { name: "frameWidth"; type: "int" }
- Property { name: "frameX"; type: "int" }
- Property { name: "frameY"; type: "int" }
- Property { name: "frameRate"; type: "double" }
- Property { name: "frameDuration"; type: "int" }
- Property { name: "loops"; type: "int" }
- Property { name: "paused"; type: "bool" }
- Property { name: "currentFrame"; type: "int" }
- Signal {
- name: "pausedChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "runningChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "interpolateChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "sourceChanged"
- Parameter { name: "arg"; type: "QUrl" }
- }
- Signal {
- name: "reverseChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "frameSyncChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "frameCountChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameHeightChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameWidthChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameXChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameYChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameRateChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "frameDurationChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "loopsChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "currentFrameChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal { name: "finished"; revision: 12 }
- Method { name: "start" }
- Method { name: "stop" }
- Method { name: "restart" }
- Method {
- name: "advance"
- Parameter { name: "frames"; type: "int" }
- }
- Method { name: "advance" }
- Method { name: "pause" }
- Method { name: "resume" }
- Method {
- name: "setRunning"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setPaused"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setInterpolate"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setSource"
- Parameter { name: "arg"; type: "QUrl" }
- }
- Method {
- name: "setReverse"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setFrameSync"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setFrameCount"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameHeight"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameWidth"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameX"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameY"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameRate"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setFrameDuration"
- Parameter { name: "arg"; type: "int" }
- }
- Method { name: "resetFrameRate" }
- Method { name: "resetFrameDuration" }
- Method {
- name: "setLoops"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setCurrentFrame"
- Parameter { name: "arg"; type: "int" }
- }
- }
- Component {
- name: "QQuickAnimationController"
- defaultProperty: "animation"
- prototype: "QObject"
- exports: ["QtQuick/AnimationController 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "progress"; type: "double" }
- Property { name: "animation"; type: "QQuickAbstractAnimation"; isPointer: true }
- Method { name: "reload" }
- Method { name: "completeToBeginning" }
- Method { name: "completeToEnd" }
- }
- Component {
- name: "QQuickAnimationGroup"
- defaultProperty: "animations"
- prototype: "QQuickAbstractAnimation"
- Property { name: "animations"; type: "QQuickAbstractAnimation"; isList: true; isReadonly: true }
- }
- Component {
- name: "QQuickAnimator"
- prototype: "QQuickAbstractAnimation"
- exports: ["QtQuick/Animator 2.2"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "target"; type: "QQuickItem"; isPointer: true }
- Property { name: "easing"; type: "QEasingCurve" }
- Property { name: "duration"; type: "int" }
- Property { name: "to"; type: "double" }
- Property { name: "from"; type: "double" }
- Signal {
- name: "targetItemChanged"
- Parameter { type: "QQuickItem"; isPointer: true }
- }
- Signal {
- name: "durationChanged"
- Parameter { name: "duration"; type: "int" }
- }
- Signal {
- name: "easingChanged"
- Parameter { name: "curve"; type: "QEasingCurve" }
- }
- Signal {
- name: "toChanged"
- Parameter { name: "to"; type: "double" }
- }
- Signal {
- name: "fromChanged"
- Parameter { name: "from"; type: "double" }
- }
- }
- Component {
- name: "QQuickApplication"
- prototype: "QQmlApplication"
- exports: ["QtQuick/Application 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "active"; type: "bool"; isReadonly: true }
- Property { name: "layoutDirection"; type: "Qt::LayoutDirection"; isReadonly: true }
- Property { name: "supportsMultipleWindows"; type: "bool"; isReadonly: true }
- Property { name: "state"; type: "Qt::ApplicationState"; isReadonly: true }
- Property { name: "font"; type: "QFont"; isReadonly: true }
- Property { name: "displayName"; type: "string" }
- Property { name: "screens"; type: "QQuickScreenInfo"; isList: true; isReadonly: true }
- Signal {
- name: "stateChanged"
- Parameter { name: "state"; type: "Qt::ApplicationState" }
- }
- }
- Component {
- name: "QQuickBasePositioner"
- defaultProperty: "data"
- prototype: "QQuickImplicitSizeItem"
- exports: [
- "QtQuick/Positioner 2.0",
- "QtQuick/Positioner 2.6",
- "QtQuick/Positioner 2.9"
- ]
- isCreatable: false
- exportMetaObjectRevisions: [0, 6, 9]
- attachedType: "QQuickPositionerAttached"
- Property { name: "spacing"; type: "double" }
- Property { name: "populate"; type: "QQuickTransition"; isPointer: true }
- Property { name: "move"; type: "QQuickTransition"; isPointer: true }
- Property { name: "add"; type: "QQuickTransition"; isPointer: true }
- Property { name: "padding"; revision: 6; type: "double" }
- Property { name: "topPadding"; revision: 6; type: "double" }
- Property { name: "leftPadding"; revision: 6; type: "double" }
- Property { name: "rightPadding"; revision: 6; type: "double" }
- Property { name: "bottomPadding"; revision: 6; type: "double" }
- Signal { name: "paddingChanged"; revision: 6 }
- Signal { name: "topPaddingChanged"; revision: 6 }
- Signal { name: "leftPaddingChanged"; revision: 6 }
- Signal { name: "rightPaddingChanged"; revision: 6 }
- Signal { name: "bottomPaddingChanged"; revision: 6 }
- Signal { name: "positioningComplete"; revision: 9 }
- Method { name: "forceLayout"; revision: 9 }
- }
- Component {
- name: "QQuickBehavior"
- defaultProperty: "animation"
- prototype: "QObject"
- exports: ["QtQuick/Behavior 2.0", "QtQuick/Behavior 2.13"]
- exportMetaObjectRevisions: [0, 13]
- Property { name: "animation"; type: "QQuickAbstractAnimation"; isPointer: true }
- Property { name: "enabled"; type: "bool" }
- Property { name: "targetValue"; revision: 13; type: "QVariant"; isReadonly: true }
- }
- Component {
- name: "QQuickBorderImage"
- defaultProperty: "data"
- prototype: "QQuickImageBase"
- exports: ["QtQuick/BorderImage 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "TileMode"
- values: {
- "Stretch": 0,
- "Repeat": 1,
- "Round": 2
- }
- }
- Property { name: "border"; type: "QQuickScaleGrid"; isReadonly: true; isPointer: true }
- Property { name: "horizontalTileMode"; type: "TileMode" }
- Property { name: "verticalTileMode"; type: "TileMode" }
- Property { name: "sourceSize"; type: "QSize"; isReadonly: true }
- }
- Component {
- name: "QQuickBorderImageMesh"
- prototype: "QQuickShaderEffectMesh"
- exports: ["QtQuick/BorderImageMesh 2.8"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "TileMode"
- values: {
- "Stretch": 0,
- "Repeat": 1,
- "Round": 2
- }
- }
- Property { name: "border"; type: "QQuickScaleGrid"; isReadonly: true; isPointer: true }
- Property { name: "size"; type: "QSize" }
- Property { name: "horizontalTileMode"; type: "TileMode" }
- Property { name: "verticalTileMode"; type: "TileMode" }
- }
- Component {
- name: "QQuickCanvasItem"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick/Canvas 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "RenderTarget"
- values: {
- "Image": 0,
- "FramebufferObject": 1
- }
- }
- Enum {
- name: "RenderStrategy"
- values: {
- "Immediate": 0,
- "Threaded": 1,
- "Cooperative": 2
- }
- }
- Property { name: "available"; type: "bool"; isReadonly: true }
- Property { name: "contextType"; type: "string" }
- Property { name: "context"; type: "QJSValue"; isReadonly: true }
- Property { name: "canvasSize"; type: "QSizeF" }
- Property { name: "tileSize"; type: "QSize" }
- Property { name: "canvasWindow"; type: "QRectF" }
- Property { name: "renderTarget"; type: "RenderTarget" }
- Property { name: "renderStrategy"; type: "RenderStrategy" }
- Signal {
- name: "paint"
- Parameter { name: "region"; type: "QRect" }
- }
- Signal { name: "painted" }
- Signal { name: "imageLoaded" }
- Method {
- name: "loadImage"
- Parameter { name: "url"; type: "QUrl" }
- }
- Method {
- name: "unloadImage"
- Parameter { name: "url"; type: "QUrl" }
- }
- Method {
- name: "isImageLoaded"
- type: "bool"
- Parameter { name: "url"; type: "QUrl" }
- }
- Method {
- name: "isImageLoading"
- type: "bool"
- Parameter { name: "url"; type: "QUrl" }
- }
- Method {
- name: "isImageError"
- type: "bool"
- Parameter { name: "url"; type: "QUrl" }
- }
- Method {
- name: "getContext"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "requestAnimationFrame"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "cancelRequestAnimationFrame"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method { name: "requestPaint" }
- Method {
- name: "markDirty"
- Parameter { name: "dirtyRect"; type: "QRectF" }
- }
- Method { name: "markDirty" }
- Method {
- name: "save"
- type: "bool"
- Parameter { name: "filename"; type: "string" }
- }
- Method {
- name: "toDataURL"
- type: "string"
- Parameter { name: "type"; type: "string" }
- }
- Method { name: "toDataURL"; type: "string" }
- }
- Component {
- name: "QQuickCloseEvent"
- prototype: "QObject"
- Property { name: "accepted"; type: "bool" }
- }
- Component {
- name: "QQuickColorAnimation"
- prototype: "QQuickPropertyAnimation"
- exports: ["QtQuick/ColorAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "from"; type: "QColor" }
- Property { name: "to"; type: "QColor" }
- }
- Component {
- name: "QQuickColumn"
- defaultProperty: "data"
- prototype: "QQuickBasePositioner"
- exports: ["QtQuick/Column 2.0", "QtQuick/Column 2.6"]
- exportMetaObjectRevisions: [0, 6]
- }
- Component {
- name: "QQuickCurve"
- prototype: "QQuickPathElement"
- Property { name: "x"; type: "double" }
- Property { name: "y"; type: "double" }
- Property { name: "relativeX"; type: "double" }
- Property { name: "relativeY"; type: "double" }
- }
- Component {
- name: "QQuickDoubleValidator"
- prototype: "QDoubleValidator"
- exports: ["QtQuick/DoubleValidator 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "locale"; type: "string" }
- Signal { name: "localeNameChanged" }
- }
- Component {
- name: "QQuickDrag"
- prototype: "QObject"
- exports: ["QtQuick/Drag 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- attachedType: "QQuickDragAttached"
- Enum {
- name: "DragType"
- values: {
- "None": 0,
- "Automatic": 1,
- "Internal": 2
- }
- }
- Enum {
- name: "Axis"
- values: {
- "XAxis": 1,
- "YAxis": 2,
- "XAndYAxis": 3,
- "XandYAxis": 3
- }
- }
- Property { name: "target"; type: "QQuickItem"; isPointer: true }
- Property { name: "axis"; type: "Axis" }
- Property { name: "minimumX"; type: "double" }
- Property { name: "maximumX"; type: "double" }
- Property { name: "minimumY"; type: "double" }
- Property { name: "maximumY"; type: "double" }
- Property { name: "active"; type: "bool"; isReadonly: true }
- Property { name: "filterChildren"; type: "bool" }
- Property { name: "smoothed"; type: "bool" }
- Property { name: "threshold"; type: "double" }
- }
- Component {
- name: "QQuickDragAttached"
- prototype: "QObject"
- Property { name: "active"; type: "bool" }
- Property { name: "source"; type: "QObject"; isPointer: true }
- Property { name: "target"; type: "QObject"; isReadonly: true; isPointer: true }
- Property { name: "hotSpot"; type: "QPointF" }
- Property { name: "imageSource"; type: "QUrl" }
- Property { name: "keys"; type: "QStringList" }
- Property { name: "mimeData"; type: "QVariantMap" }
- Property { name: "supportedActions"; type: "Qt::DropActions" }
- Property { name: "proposedAction"; type: "Qt::DropAction" }
- Property { name: "dragType"; type: "QQuickDrag::DragType" }
- Signal { name: "dragStarted" }
- Signal {
- name: "dragFinished"
- Parameter { name: "dropAction"; type: "Qt::DropAction" }
- }
- Method {
- name: "start"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "startDrag"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method { name: "cancel" }
- Method { name: "drop"; type: "int" }
- }
- Component {
- name: "QQuickDragAxis"
- prototype: "QObject"
- exports: ["QtQuick/DragAxis 2.12"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "minimum"; type: "double" }
- Property { name: "maximum"; type: "double" }
- Property { name: "enabled"; type: "bool" }
- }
- Component {
- name: "QQuickDragHandler"
- prototype: "QQuickMultiPointHandler"
- exports: ["QtQuick/DragHandler 2.12", "QtQuick/DragHandler 2.14"]
- exportMetaObjectRevisions: [0, 14]
- Enum {
- name: "SnapMode"
- values: {
- "NoSnap": 0,
- "SnapAuto": 1,
- "SnapIfPressedOutsideTarget": 2,
- "SnapAlways": 3
- }
- }
- Property { name: "xAxis"; type: "QQuickDragAxis"; isReadonly: true; isPointer: true }
- Property { name: "yAxis"; type: "QQuickDragAxis"; isReadonly: true; isPointer: true }
- Property { name: "translation"; type: "QVector2D"; isReadonly: true }
- Property { name: "snapMode"; revision: 14; type: "SnapMode" }
- Signal { name: "snapModeChanged"; revision: 14 }
- }
- Component {
- name: "QQuickDropArea"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick/DropArea 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "containsDrag"; type: "bool"; isReadonly: true }
- Property { name: "keys"; type: "QStringList" }
- Property { name: "drag"; type: "QQuickDropAreaDrag"; isReadonly: true; isPointer: true }
- Signal { name: "sourceChanged" }
- Signal {
- name: "entered"
- Parameter { name: "drag"; type: "QQuickDropEvent"; isPointer: true }
- }
- Signal { name: "exited" }
- Signal {
- name: "positionChanged"
- Parameter { name: "drag"; type: "QQuickDropEvent"; isPointer: true }
- }
- Signal {
- name: "dropped"
- Parameter { name: "drop"; type: "QQuickDropEvent"; isPointer: true }
- }
- }
- Component {
- name: "QQuickDropAreaDrag"
- prototype: "QObject"
- Property { name: "x"; type: "double"; isReadonly: true }
- Property { name: "y"; type: "double"; isReadonly: true }
- Property { name: "source"; type: "QObject"; isReadonly: true; isPointer: true }
- Signal { name: "positionChanged" }
- }
- Component {
- name: "QQuickDropEvent"
- prototype: "QObject"
- Property { name: "x"; type: "double"; isReadonly: true }
- Property { name: "y"; type: "double"; isReadonly: true }
- Property { name: "source"; type: "QObject"; isReadonly: true; isPointer: true }
- Property { name: "keys"; type: "QStringList"; isReadonly: true }
- Property { name: "supportedActions"; type: "Qt::DropActions"; isReadonly: true }
- Property { name: "proposedAction"; type: "Qt::DropActions"; isReadonly: true }
- Property { name: "action"; type: "Qt::DropAction" }
- Property { name: "accepted"; type: "bool" }
- Property { name: "hasColor"; type: "bool"; isReadonly: true }
- Property { name: "hasHtml"; type: "bool"; isReadonly: true }
- Property { name: "hasText"; type: "bool"; isReadonly: true }
- Property { name: "hasUrls"; type: "bool"; isReadonly: true }
- Property { name: "colorData"; type: "QVariant"; isReadonly: true }
- Property { name: "html"; type: "string"; isReadonly: true }
- Property { name: "text"; type: "string"; isReadonly: true }
- Property { name: "urls"; type: "QList<QUrl>"; isReadonly: true }
- Property { name: "formats"; type: "QStringList"; isReadonly: true }
- Method {
- name: "getDataAsString"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "getDataAsArrayBuffer"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "acceptProposedAction"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "accept"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- }
- Component {
- name: "QQuickEnterKeyAttached"
- prototype: "QObject"
- exports: ["QtQuick/EnterKey 2.6"]
- isCreatable: false
- exportMetaObjectRevisions: [6]
- Property { name: "type"; type: "Qt::EnterKeyType" }
- }
- Component {
- name: "QQuickEventPoint"
- prototype: "QObject"
- exports: ["QtQuick/EventPoint 2.12"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "States"
- values: {
- "Pressed": 1,
- "Updated": 2,
- "Stationary": 4,
- "Released": 8
- }
- }
- Enum {
- name: "GrabTransition"
- values: {
- "GrabPassive": 1,
- "UngrabPassive": 2,
- "CancelGrabPassive": 3,
- "OverrideGrabPassive": 4,
- "GrabExclusive": 16,
- "UngrabExclusive": 32,
- "CancelGrabExclusive": 48
- }
- }
- Property { name: "event"; type: "QQuickPointerEvent"; isReadonly: true; isPointer: true }
- Property { name: "position"; type: "QPointF"; isReadonly: true }
- Property { name: "scenePosition"; type: "QPointF"; isReadonly: true }
- Property { name: "scenePressPosition"; type: "QPointF"; isReadonly: true }
- Property { name: "sceneGrabPosition"; type: "QPointF"; isReadonly: true }
- Property { name: "state"; type: "State"; isReadonly: true }
- Property { name: "pointId"; type: "int"; isReadonly: true }
- Property { name: "timeHeld"; type: "double"; isReadonly: true }
- Property { name: "velocity"; type: "QVector2D"; isReadonly: true }
- Property { name: "accepted"; type: "bool" }
- Property { name: "exclusiveGrabber"; type: "QObject"; isPointer: true }
- }
- Component {
- name: "QQuickEventTouchPoint"
- prototype: "QQuickEventPoint"
- exports: ["QtQuick/EventTouchPoint 2.12"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "rotation"; type: "double"; isReadonly: true }
- Property { name: "pressure"; type: "double"; isReadonly: true }
- Property { name: "ellipseDiameters"; type: "QSizeF"; isReadonly: true }
- Property { name: "uniqueId"; type: "QPointingDeviceUniqueId"; isReadonly: true }
- }
- Component {
- name: "QQuickFlickable"
- defaultProperty: "flickableData"
- prototype: "QQuickItem"
- exports: [
- "QtQuick/Flickable 2.0",
- "QtQuick/Flickable 2.10",
- "QtQuick/Flickable 2.12",
- "QtQuick/Flickable 2.9"
- ]
- exportMetaObjectRevisions: [0, 10, 12, 9]
- Enum {
- name: "BoundsBehavior"
- values: {
- "StopAtBounds": 0,
- "DragOverBounds": 1,
- "OvershootBounds": 2,
- "DragAndOvershootBounds": 3
- }
- }
- Enum {
- name: "BoundsMovement"
- values: {
- "FollowBoundsBehavior": 1
- }
- }
- Enum {
- name: "FlickableDirection"
- values: {
- "AutoFlickDirection": 0,
- "HorizontalFlick": 1,
- "VerticalFlick": 2,
- "HorizontalAndVerticalFlick": 3,
- "AutoFlickIfNeeded": 12
- }
- }
- Property { name: "contentWidth"; type: "double" }
- Property { name: "contentHeight"; type: "double" }
- Property { name: "contentX"; type: "double" }
- Property { name: "contentY"; type: "double" }
- Property { name: "contentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "topMargin"; type: "double" }
- Property { name: "bottomMargin"; type: "double" }
- Property { name: "originY"; type: "double"; isReadonly: true }
- Property { name: "leftMargin"; type: "double" }
- Property { name: "rightMargin"; type: "double" }
- Property { name: "originX"; type: "double"; isReadonly: true }
- Property { name: "horizontalVelocity"; type: "double"; isReadonly: true }
- Property { name: "verticalVelocity"; type: "double"; isReadonly: true }
- Property { name: "boundsBehavior"; type: "BoundsBehavior" }
- Property { name: "boundsMovement"; revision: 10; type: "BoundsMovement" }
- Property { name: "rebound"; type: "QQuickTransition"; isPointer: true }
- Property { name: "maximumFlickVelocity"; type: "double" }
- Property { name: "flickDeceleration"; type: "double" }
- Property { name: "moving"; type: "bool"; isReadonly: true }
- Property { name: "movingHorizontally"; type: "bool"; isReadonly: true }
- Property { name: "movingVertically"; type: "bool"; isReadonly: true }
- Property { name: "flicking"; type: "bool"; isReadonly: true }
- Property { name: "flickingHorizontally"; type: "bool"; isReadonly: true }
- Property { name: "flickingVertically"; type: "bool"; isReadonly: true }
- Property { name: "dragging"; type: "bool"; isReadonly: true }
- Property { name: "draggingHorizontally"; type: "bool"; isReadonly: true }
- Property { name: "draggingVertically"; type: "bool"; isReadonly: true }
- Property { name: "flickableDirection"; type: "FlickableDirection" }
- Property { name: "interactive"; type: "bool" }
- Property { name: "pressDelay"; type: "int" }
- Property { name: "atXEnd"; type: "bool"; isReadonly: true }
- Property { name: "atYEnd"; type: "bool"; isReadonly: true }
- Property { name: "atXBeginning"; type: "bool"; isReadonly: true }
- Property { name: "atYBeginning"; type: "bool"; isReadonly: true }
- Property {
- name: "visibleArea"
- type: "QQuickFlickableVisibleArea"
- isReadonly: true
- isPointer: true
- }
- Property { name: "pixelAligned"; type: "bool" }
- Property { name: "synchronousDrag"; revision: 12; type: "bool" }
- Property { name: "horizontalOvershoot"; revision: 9; type: "double"; isReadonly: true }
- Property { name: "verticalOvershoot"; revision: 9; type: "double"; isReadonly: true }
- Property { name: "flickableData"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "flickableChildren"; type: "QQuickItem"; isList: true; isReadonly: true }
- Signal { name: "isAtBoundaryChanged" }
- Signal { name: "boundsMovementChanged"; revision: 10 }
- Signal { name: "movementStarted" }
- Signal { name: "movementEnded" }
- Signal { name: "flickStarted" }
- Signal { name: "flickEnded" }
- Signal { name: "dragStarted" }
- Signal { name: "dragEnded" }
- Signal { name: "synchronousDragChanged"; revision: 12 }
- Signal { name: "horizontalOvershootChanged"; revision: 9 }
- Signal { name: "verticalOvershootChanged"; revision: 9 }
- Method {
- name: "resizeContent"
- Parameter { name: "w"; type: "double" }
- Parameter { name: "h"; type: "double" }
- Parameter { name: "center"; type: "QPointF" }
- }
- Method { name: "returnToBounds" }
- Method {
- name: "flick"
- Parameter { name: "xVelocity"; type: "double" }
- Parameter { name: "yVelocity"; type: "double" }
- }
- Method { name: "cancelFlick" }
- }
- Component {
- name: "QQuickFlickableVisibleArea"
- prototype: "QObject"
- Property { name: "xPosition"; type: "double"; isReadonly: true }
- Property { name: "yPosition"; type: "double"; isReadonly: true }
- Property { name: "widthRatio"; type: "double"; isReadonly: true }
- Property { name: "heightRatio"; type: "double"; isReadonly: true }
- Signal {
- name: "xPositionChanged"
- Parameter { name: "xPosition"; type: "double" }
- }
- Signal {
- name: "yPositionChanged"
- Parameter { name: "yPosition"; type: "double" }
- }
- Signal {
- name: "widthRatioChanged"
- Parameter { name: "widthRatio"; type: "double" }
- }
- Signal {
- name: "heightRatioChanged"
- Parameter { name: "heightRatio"; type: "double" }
- }
- }
- Component {
- name: "QQuickFlipable"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick/Flipable 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Side"
- values: {
- "Front": 0,
- "Back": 1
- }
- }
- Property { name: "front"; type: "QQuickItem"; isPointer: true }
- Property { name: "back"; type: "QQuickItem"; isPointer: true }
- Property { name: "side"; type: "Side"; isReadonly: true }
- }
- Component {
- name: "QQuickFlow"
- defaultProperty: "data"
- prototype: "QQuickBasePositioner"
- exports: ["QtQuick/Flow 2.0", "QtQuick/Flow 2.6"]
- exportMetaObjectRevisions: [0, 6]
- Enum {
- name: "Flow"
- values: {
- "LeftToRight": 0,
- "TopToBottom": 1
- }
- }
- Property { name: "flow"; type: "Flow" }
- Property { name: "layoutDirection"; type: "Qt::LayoutDirection" }
- Property { name: "effectiveLayoutDirection"; type: "Qt::LayoutDirection"; isReadonly: true }
- }
- Component {
- name: "QQuickFocusScope"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick/FocusScope 2.0"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickFontLoader"
- prototype: "QObject"
- exports: ["QtQuick/FontLoader 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Status"
- values: {
- "Null": 0,
- "Ready": 1,
- "Loading": 2,
- "Error": 3
- }
- }
- Property { name: "source"; type: "QUrl" }
- Property { name: "name"; type: "string" }
- Property { name: "status"; type: "Status"; isReadonly: true }
- }
- Component {
- name: "QQuickFontMetrics"
- prototype: "QObject"
- exports: ["QtQuick/FontMetrics 2.4"]
- exportMetaObjectRevisions: [0]
- Property { name: "font"; type: "QFont" }
- Property { name: "ascent"; type: "double"; isReadonly: true }
- Property { name: "descent"; type: "double"; isReadonly: true }
- Property { name: "height"; type: "double"; isReadonly: true }
- Property { name: "leading"; type: "double"; isReadonly: true }
- Property { name: "lineSpacing"; type: "double"; isReadonly: true }
- Property { name: "minimumLeftBearing"; type: "double"; isReadonly: true }
- Property { name: "minimumRightBearing"; type: "double"; isReadonly: true }
- Property { name: "maximumCharacterWidth"; type: "double"; isReadonly: true }
- Property { name: "xHeight"; type: "double"; isReadonly: true }
- Property { name: "averageCharacterWidth"; type: "double"; isReadonly: true }
- Property { name: "underlinePosition"; type: "double"; isReadonly: true }
- Property { name: "overlinePosition"; type: "double"; isReadonly: true }
- Property { name: "strikeOutPosition"; type: "double"; isReadonly: true }
- Property { name: "lineWidth"; type: "double"; isReadonly: true }
- Signal {
- name: "fontChanged"
- Parameter { name: "font"; type: "QFont" }
- }
- Method {
- name: "advanceWidth"
- type: "double"
- Parameter { name: "text"; type: "string" }
- }
- Method {
- name: "boundingRect"
- type: "QRectF"
- Parameter { name: "text"; type: "string" }
- }
- Method {
- name: "tightBoundingRect"
- type: "QRectF"
- Parameter { name: "text"; type: "string" }
- }
- Method {
- name: "elidedText"
- type: "string"
- Parameter { name: "text"; type: "string" }
- Parameter { name: "mode"; type: "Qt::TextElideMode" }
- Parameter { name: "width"; type: "double" }
- Parameter { name: "flags"; type: "int" }
- }
- Method {
- name: "elidedText"
- type: "string"
- Parameter { name: "text"; type: "string" }
- Parameter { name: "mode"; type: "Qt::TextElideMode" }
- Parameter { name: "width"; type: "double" }
- }
- }
- Component {
- name: "QQuickFontValueType"
- exports: ["QtQuick/Font 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "FontWeight"
- values: {
- "Thin": 0,
- "ExtraLight": 12,
- "Light": 25,
- "Normal": 50,
- "Medium": 57,
- "DemiBold": 63,
- "Bold": 75,
- "ExtraBold": 81,
- "Black": 87
- }
- }
- Enum {
- name: "Capitalization"
- values: {
- "MixedCase": 0,
- "AllUppercase": 1,
- "AllLowercase": 2,
- "SmallCaps": 3,
- "Capitalize": 4
- }
- }
- Enum {
- name: "HintingPreference"
- values: {
- "PreferDefaultHinting": 0,
- "PreferNoHinting": 1,
- "PreferVerticalHinting": 2,
- "PreferFullHinting": 3
- }
- }
- Property { name: "family"; type: "string" }
- Property { name: "styleName"; type: "string" }
- Property { name: "bold"; type: "bool" }
- Property { name: "weight"; type: "FontWeight" }
- Property { name: "italic"; type: "bool" }
- Property { name: "underline"; type: "bool" }
- Property { name: "overline"; type: "bool" }
- Property { name: "strikeout"; type: "bool" }
- Property { name: "pointSize"; type: "double" }
- Property { name: "pixelSize"; type: "int" }
- Property { name: "capitalization"; type: "Capitalization" }
- Property { name: "letterSpacing"; type: "double" }
- Property { name: "wordSpacing"; type: "double" }
- Property { name: "hintingPreference"; type: "HintingPreference" }
- Property { name: "kerning"; type: "bool" }
- Property { name: "preferShaping"; type: "bool" }
- Method { name: "toString"; type: "string" }
- }
- Component {
- name: "QQuickGrabGestureEvent"
- prototype: "QObject"
- exports: ["QtQuick/GestureEvent 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "touchPoints"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "dragThreshold"; type: "double"; isReadonly: true }
- Method { name: "grab" }
- }
- Component {
- name: "QQuickGradient"
- defaultProperty: "stops"
- prototype: "QObject"
- exports: ["QtQuick/Gradient 2.0", "QtQuick/Gradient 2.12"]
- exportMetaObjectRevisions: [0, 12]
- Enum {
- name: "Orientation"
- values: {
- "Vertical": 2,
- "Horizontal": 1
- }
- }
- Property { name: "stops"; type: "QQuickGradientStop"; isList: true; isReadonly: true }
- Property { name: "orientation"; revision: 12; type: "Orientation" }
- Signal { name: "updated" }
- }
- Component {
- name: "QQuickGradientStop"
- prototype: "QObject"
- exports: ["QtQuick/GradientStop 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "position"; type: "double" }
- Property { name: "color"; type: "QColor" }
- }
- Component {
- name: "QQuickGraphicsInfo"
- prototype: "QObject"
- exports: ["QtQuick/GraphicsInfo 2.8"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "GraphicsApi"
- values: {
- "Unknown": 0,
- "Software": 1,
- "OpenGL": 2,
- "Direct3D12": 3,
- "OpenVG": 4,
- "OpenGLRhi": 5,
- "Direct3D11Rhi": 6,
- "VulkanRhi": 7,
- "MetalRhi": 8,
- "NullRhi": 9
- }
- }
- Enum {
- name: "ShaderType"
- values: {
- "UnknownShadingLanguage": 0,
- "GLSL": 1,
- "HLSL": 2,
- "RhiShader": 3
- }
- }
- Enum {
- name: "ShaderCompilationType"
- values: {
- "RuntimeCompilation": 1,
- "OfflineCompilation": 2
- }
- }
- Enum {
- name: "ShaderSourceType"
- values: {
- "ShaderSourceString": 1,
- "ShaderSourceFile": 2,
- "ShaderByteCode": 4
- }
- }
- Enum {
- name: "OpenGLContextProfile"
- values: {
- "OpenGLNoProfile": 0,
- "OpenGLCoreProfile": 1,
- "OpenGLCompatibilityProfile": 2
- }
- }
- Enum {
- name: "RenderableType"
- values: {
- "SurfaceFormatUnspecified": 0,
- "SurfaceFormatOpenGL": 1,
- "SurfaceFormatOpenGLES": 2
- }
- }
- Property { name: "api"; type: "GraphicsApi"; isReadonly: true }
- Property { name: "shaderType"; type: "ShaderType"; isReadonly: true }
- Property { name: "shaderCompilationType"; type: "ShaderCompilationType"; isReadonly: true }
- Property { name: "shaderSourceType"; type: "ShaderSourceType"; isReadonly: true }
- Property { name: "majorVersion"; type: "int"; isReadonly: true }
- Property { name: "minorVersion"; type: "int"; isReadonly: true }
- Property { name: "profile"; type: "OpenGLContextProfile"; isReadonly: true }
- Property { name: "renderableType"; type: "RenderableType"; isReadonly: true }
- }
- Component {
- name: "QQuickGrid"
- defaultProperty: "data"
- prototype: "QQuickBasePositioner"
- exports: ["QtQuick/Grid 2.0", "QtQuick/Grid 2.1", "QtQuick/Grid 2.6"]
- exportMetaObjectRevisions: [0, 1, 6]
- Enum {
- name: "Flow"
- values: {
- "LeftToRight": 0,
- "TopToBottom": 1
- }
- }
- Enum {
- name: "HAlignment"
- values: {
- "AlignLeft": 1,
- "AlignRight": 2,
- "AlignHCenter": 4
- }
- }
- Enum {
- name: "VAlignment"
- values: {
- "AlignTop": 32,
- "AlignBottom": 64,
- "AlignVCenter": 128
- }
- }
- Property { name: "rows"; type: "int" }
- Property { name: "columns"; type: "int" }
- Property { name: "rowSpacing"; type: "double" }
- Property { name: "columnSpacing"; type: "double" }
- Property { name: "flow"; type: "Flow" }
- Property { name: "layoutDirection"; type: "Qt::LayoutDirection" }
- Property { name: "effectiveLayoutDirection"; type: "Qt::LayoutDirection"; isReadonly: true }
- Property { name: "horizontalItemAlignment"; revision: 1; type: "HAlignment" }
- Property {
- name: "effectiveHorizontalItemAlignment"
- revision: 1
- type: "HAlignment"
- isReadonly: true
- }
- Property { name: "verticalItemAlignment"; revision: 1; type: "VAlignment" }
- Signal {
- name: "horizontalAlignmentChanged"
- revision: 1
- Parameter { name: "alignment"; type: "HAlignment" }
- }
- Signal {
- name: "effectiveHorizontalAlignmentChanged"
- revision: 1
- Parameter { name: "alignment"; type: "HAlignment" }
- }
- Signal {
- name: "verticalAlignmentChanged"
- revision: 1
- Parameter { name: "alignment"; type: "VAlignment" }
- }
- }
- Component {
- name: "QQuickGridMesh"
- prototype: "QQuickShaderEffectMesh"
- exports: ["QtQuick/GridMesh 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "resolution"; type: "QSize" }
- }
- Component {
- name: "QQuickGridView"
- defaultProperty: "data"
- prototype: "QQuickItemView"
- exports: [
- "QtQuick/GridView 2.0",
- "QtQuick/GridView 2.1",
- "QtQuick/GridView 2.13",
- "QtQuick/GridView 2.7"
- ]
- exportMetaObjectRevisions: [0, 1, 13, 7]
- attachedType: "QQuickGridViewAttached"
- Enum {
- name: "Flow"
- values: {
- "FlowLeftToRight": 0,
- "FlowTopToBottom": 2
- }
- }
- Enum {
- name: "SnapMode"
- values: {
- "NoSnap": 0,
- "SnapToRow": 1,
- "SnapOneRow": 2
- }
- }
- Property { name: "flow"; type: "Flow" }
- Property { name: "cellWidth"; type: "double" }
- Property { name: "cellHeight"; type: "double" }
- Property { name: "snapMode"; type: "SnapMode" }
- Signal { name: "highlightMoveDurationChanged" }
- Method { name: "moveCurrentIndexUp" }
- Method { name: "moveCurrentIndexDown" }
- Method { name: "moveCurrentIndexLeft" }
- Method { name: "moveCurrentIndexRight" }
- }
- Component { name: "QQuickGridViewAttached"; prototype: "QQuickItemViewAttached" }
- Component {
- name: "QQuickHoverHandler"
- prototype: "QQuickSinglePointHandler"
- exports: ["QtQuick/HoverHandler 2.12"]
- exportMetaObjectRevisions: [0]
- Property { name: "hovered"; type: "bool"; isReadonly: true }
- }
- Component {
- name: "QQuickImage"
- defaultProperty: "data"
- prototype: "QQuickImageBase"
- exports: [
- "QtQuick/Image 2.0",
- "QtQuick/Image 2.14",
- "QtQuick/Image 2.3",
- "QtQuick/Image 2.5"
- ]
- exportMetaObjectRevisions: [0, 14, 3, 5]
- Enum {
- name: "HAlignment"
- values: {
- "AlignLeft": 1,
- "AlignRight": 2,
- "AlignHCenter": 4
- }
- }
- Enum {
- name: "VAlignment"
- values: {
- "AlignTop": 32,
- "AlignBottom": 64,
- "AlignVCenter": 128
- }
- }
- Enum {
- name: "FillMode"
- values: {
- "Stretch": 0,
- "PreserveAspectFit": 1,
- "PreserveAspectCrop": 2,
- "Tile": 3,
- "TileVertically": 4,
- "TileHorizontally": 5,
- "Pad": 6
- }
- }
- Property { name: "fillMode"; type: "FillMode" }
- Property { name: "paintedWidth"; type: "double"; isReadonly: true }
- Property { name: "paintedHeight"; type: "double"; isReadonly: true }
- Property { name: "horizontalAlignment"; type: "HAlignment" }
- Property { name: "verticalAlignment"; type: "VAlignment" }
- Property { name: "mipmap"; revision: 3; type: "bool" }
- Property { name: "autoTransform"; revision: 5; type: "bool" }
- Signal { name: "paintedGeometryChanged" }
- Signal {
- name: "horizontalAlignmentChanged"
- Parameter { name: "alignment"; type: "HAlignment" }
- }
- Signal {
- name: "verticalAlignmentChanged"
- Parameter { name: "alignment"; type: "VAlignment" }
- }
- Signal {
- name: "mipmapChanged"
- revision: 3
- Parameter { type: "bool" }
- }
- Signal { name: "autoTransformChanged"; revision: 5 }
- }
- Component {
- name: "QQuickImageBase"
- defaultProperty: "data"
- prototype: "QQuickImplicitSizeItem"
- exports: ["QtQuick/ImageBase 2.14"]
- isCreatable: false
- exportMetaObjectRevisions: [14]
- Enum {
- name: "Status"
- values: {
- "Null": 0,
- "Ready": 1,
- "Loading": 2,
- "Error": 3
- }
- }
- Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "source"; type: "QUrl" }
- Property { name: "progress"; type: "double"; isReadonly: true }
- Property { name: "asynchronous"; type: "bool" }
- Property { name: "cache"; type: "bool" }
- Property { name: "sourceSize"; type: "QSize" }
- Property { name: "mirror"; type: "bool" }
- Property { name: "currentFrame"; revision: 14; type: "int" }
- Property { name: "frameCount"; revision: 14; type: "int"; isReadonly: true }
- Signal {
- name: "sourceChanged"
- Parameter { type: "QUrl" }
- }
- Signal {
- name: "statusChanged"
- Parameter { type: "QQuickImageBase::Status" }
- }
- Signal {
- name: "progressChanged"
- Parameter { name: "progress"; type: "double" }
- }
- Signal { name: "currentFrameChanged"; revision: 14 }
- Signal { name: "frameCountChanged"; revision: 14 }
- }
- Component {
- name: "QQuickImplicitSizeItem"
- defaultProperty: "data"
- prototype: "QQuickItem"
- Property { name: "implicitWidth"; type: "double"; isReadonly: true }
- Property { name: "implicitHeight"; type: "double"; isReadonly: true }
- }
- Component {
- name: "QQuickIntValidator"
- prototype: "QIntValidator"
- exports: ["QtQuick/IntValidator 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "locale"; type: "string" }
- Signal { name: "localeNameChanged" }
- }
- Component {
- name: "QQuickItem"
- defaultProperty: "data"
- prototype: "QObject"
- exports: [
- "QtQuick/Item 2.0",
- "QtQuick/Item 2.1",
- "QtQuick/Item 2.11",
- "QtQuick/Item 2.4",
- "QtQuick/Item 2.7"
- ]
- exportMetaObjectRevisions: [0, 1, 11, 4, 7]
- Enum {
- name: "Flags"
- values: {
- "ItemClipsChildrenToShape": 1,
- "ItemAcceptsInputMethod": 2,
- "ItemIsFocusScope": 4,
- "ItemHasContents": 8,
- "ItemAcceptsDrops": 16
- }
- }
- Enum {
- name: "TransformOrigin"
- values: {
- "TopLeft": 0,
- "Top": 1,
- "TopRight": 2,
- "Left": 3,
- "Center": 4,
- "Right": 5,
- "BottomLeft": 6,
- "Bottom": 7,
- "BottomRight": 8
- }
- }
- Property { name: "parent"; type: "QQuickItem"; isPointer: true }
- Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "resources"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "children"; type: "QQuickItem"; isList: true; isReadonly: true }
- Property { name: "x"; type: "double" }
- Property { name: "y"; type: "double" }
- Property { name: "z"; type: "double" }
- Property { name: "width"; type: "double" }
- Property { name: "height"; type: "double" }
- Property { name: "opacity"; type: "double" }
- Property { name: "enabled"; type: "bool" }
- Property { name: "visible"; type: "bool" }
- Property { name: "visibleChildren"; type: "QQuickItem"; isList: true; isReadonly: true }
- Property { name: "states"; type: "QQuickState"; isList: true; isReadonly: true }
- Property { name: "transitions"; type: "QQuickTransition"; isList: true; isReadonly: true }
- Property { name: "state"; type: "string" }
- Property { name: "childrenRect"; type: "QRectF"; isReadonly: true }
- Property { name: "anchors"; type: "QQuickAnchors"; isReadonly: true; isPointer: true }
- Property { name: "left"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "right"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "horizontalCenter"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "top"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "bottom"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "verticalCenter"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "baseline"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "baselineOffset"; type: "double" }
- Property { name: "clip"; type: "bool" }
- Property { name: "focus"; type: "bool" }
- Property { name: "activeFocus"; type: "bool"; isReadonly: true }
- Property { name: "activeFocusOnTab"; revision: 1; type: "bool" }
- Property { name: "rotation"; type: "double" }
- Property { name: "scale"; type: "double" }
- Property { name: "transformOrigin"; type: "TransformOrigin" }
- Property { name: "transformOriginPoint"; type: "QPointF"; isReadonly: true }
- Property { name: "transform"; type: "QQuickTransform"; isList: true; isReadonly: true }
- Property { name: "smooth"; type: "bool" }
- Property { name: "antialiasing"; type: "bool" }
- Property { name: "implicitWidth"; type: "double" }
- Property { name: "implicitHeight"; type: "double" }
- Property { name: "containmentMask"; revision: 11; type: "QObject"; isPointer: true }
- Property { name: "layer"; type: "QQuickItemLayer"; isReadonly: true; isPointer: true }
- Signal {
- name: "childrenRectChanged"
- Parameter { type: "QRectF" }
- }
- Signal {
- name: "baselineOffsetChanged"
- Parameter { type: "double" }
- }
- Signal {
- name: "stateChanged"
- Parameter { type: "string" }
- }
- Signal {
- name: "focusChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "activeFocusChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "activeFocusOnTabChanged"
- revision: 1
- Parameter { type: "bool" }
- }
- Signal {
- name: "parentChanged"
- Parameter { type: "QQuickItem"; isPointer: true }
- }
- Signal {
- name: "transformOriginChanged"
- Parameter { type: "TransformOrigin" }
- }
- Signal {
- name: "smoothChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "antialiasingChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "clipChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "windowChanged"
- revision: 1
- Parameter { name: "window"; type: "QQuickWindow"; isPointer: true }
- }
- Signal { name: "containmentMaskChanged"; revision: 11 }
- Method { name: "update" }
- Method {
- name: "grabToImage"
- revision: 4
- type: "bool"
- Parameter { name: "callback"; type: "QJSValue" }
- Parameter { name: "targetSize"; type: "QSize" }
- }
- Method {
- name: "grabToImage"
- revision: 4
- type: "bool"
- Parameter { name: "callback"; type: "QJSValue" }
- }
- Method {
- name: "contains"
- type: "bool"
- Parameter { name: "point"; type: "QPointF" }
- }
- Method {
- name: "mapFromItem"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "mapToItem"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "mapFromGlobal"
- revision: 7
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "mapToGlobal"
- revision: 7
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method { name: "forceActiveFocus" }
- Method {
- name: "forceActiveFocus"
- Parameter { name: "reason"; type: "Qt::FocusReason" }
- }
- Method {
- name: "nextItemInFocusChain"
- revision: 1
- type: "QQuickItem*"
- Parameter { name: "forward"; type: "bool" }
- }
- Method { name: "nextItemInFocusChain"; revision: 1; type: "QQuickItem*" }
- Method {
- name: "childAt"
- type: "QQuickItem*"
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- }
- Component {
- name: "QQuickItemGrabResult"
- prototype: "QObject"
- Property { name: "image"; type: "QImage"; isReadonly: true }
- Property { name: "url"; type: "QUrl"; isReadonly: true }
- Signal { name: "ready" }
- Method {
- name: "saveToFile"
- type: "bool"
- Parameter { name: "fileName"; type: "string" }
- }
- Method {
- name: "saveToFile"
- type: "bool"
- Parameter { name: "fileName"; type: "string" }
- }
- }
- Component {
- name: "QQuickItemLayer"
- prototype: "QObject"
- Property { name: "enabled"; type: "bool" }
- Property { name: "textureSize"; type: "QSize" }
- Property { name: "sourceRect"; type: "QRectF" }
- Property { name: "mipmap"; type: "bool" }
- Property { name: "smooth"; type: "bool" }
- Property { name: "wrapMode"; type: "QQuickShaderEffectSource::WrapMode" }
- Property { name: "format"; type: "QQuickShaderEffectSource::Format" }
- Property { name: "samplerName"; type: "QByteArray" }
- Property { name: "effect"; type: "QQmlComponent"; isPointer: true }
- Property { name: "textureMirroring"; type: "QQuickShaderEffectSource::TextureMirroring" }
- Property { name: "samples"; type: "int" }
- Signal {
- name: "enabledChanged"
- Parameter { name: "enabled"; type: "bool" }
- }
- Signal {
- name: "sizeChanged"
- Parameter { name: "size"; type: "QSize" }
- }
- Signal {
- name: "mipmapChanged"
- Parameter { name: "mipmap"; type: "bool" }
- }
- Signal {
- name: "wrapModeChanged"
- Parameter { name: "mode"; type: "QQuickShaderEffectSource::WrapMode" }
- }
- Signal {
- name: "nameChanged"
- Parameter { name: "name"; type: "QByteArray" }
- }
- Signal {
- name: "effectChanged"
- Parameter { name: "component"; type: "QQmlComponent"; isPointer: true }
- }
- Signal {
- name: "smoothChanged"
- Parameter { name: "smooth"; type: "bool" }
- }
- Signal {
- name: "formatChanged"
- Parameter { name: "format"; type: "QQuickShaderEffectSource::Format" }
- }
- Signal {
- name: "sourceRectChanged"
- Parameter { name: "sourceRect"; type: "QRectF" }
- }
- Signal {
- name: "textureMirroringChanged"
- Parameter { name: "mirroring"; type: "QQuickShaderEffectSource::TextureMirroring" }
- }
- Signal {
- name: "samplesChanged"
- Parameter { name: "count"; type: "int" }
- }
- }
- Component {
- name: "QQuickItemView"
- defaultProperty: "flickableData"
- prototype: "QQuickFlickable"
- exports: [
- "QtQuick/ItemView 2.1",
- "QtQuick/ItemView 2.13",
- "QtQuick/ItemView 2.3",
- "QtQuick/ItemView 2.7"
- ]
- isCreatable: false
- exportMetaObjectRevisions: [1, 13, 3, 7]
- Enum {
- name: "LayoutDirection"
- values: {
- "LeftToRight": 0,
- "RightToLeft": 1,
- "VerticalTopToBottom": 2,
- "VerticalBottomToTop": 3
- }
- }
- Enum {
- name: "VerticalLayoutDirection"
- values: {
- "TopToBottom": 2,
- "BottomToTop": 3
- }
- }
- Enum {
- name: "HighlightRangeMode"
- values: {
- "NoHighlightRange": 0,
- "ApplyRange": 1,
- "StrictlyEnforceRange": 2
- }
- }
- Enum {
- name: "PositionMode"
- values: {
- "Beginning": 0,
- "Center": 1,
- "End": 2,
- "Visible": 3,
- "Contain": 4,
- "SnapPosition": 5
- }
- }
- Property { name: "model"; type: "QVariant" }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "currentIndex"; type: "int" }
- Property { name: "currentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "keyNavigationWraps"; type: "bool" }
- Property { name: "keyNavigationEnabled"; revision: 7; type: "bool" }
- Property { name: "cacheBuffer"; type: "int" }
- Property { name: "displayMarginBeginning"; revision: 3; type: "int" }
- Property { name: "displayMarginEnd"; revision: 3; type: "int" }
- Property { name: "layoutDirection"; type: "Qt::LayoutDirection" }
- Property { name: "effectiveLayoutDirection"; type: "Qt::LayoutDirection"; isReadonly: true }
- Property { name: "verticalLayoutDirection"; type: "VerticalLayoutDirection" }
- Property { name: "header"; type: "QQmlComponent"; isPointer: true }
- Property { name: "headerItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "footer"; type: "QQmlComponent"; isPointer: true }
- Property { name: "footerItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "populate"; type: "QQuickTransition"; isPointer: true }
- Property { name: "add"; type: "QQuickTransition"; isPointer: true }
- Property { name: "addDisplaced"; type: "QQuickTransition"; isPointer: true }
- Property { name: "move"; type: "QQuickTransition"; isPointer: true }
- Property { name: "moveDisplaced"; type: "QQuickTransition"; isPointer: true }
- Property { name: "remove"; type: "QQuickTransition"; isPointer: true }
- Property { name: "removeDisplaced"; type: "QQuickTransition"; isPointer: true }
- Property { name: "displaced"; type: "QQuickTransition"; isPointer: true }
- Property { name: "highlight"; type: "QQmlComponent"; isPointer: true }
- Property { name: "highlightItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "highlightFollowsCurrentItem"; type: "bool" }
- Property { name: "highlightRangeMode"; type: "HighlightRangeMode" }
- Property { name: "preferredHighlightBegin"; type: "double" }
- Property { name: "preferredHighlightEnd"; type: "double" }
- Property { name: "highlightMoveDuration"; type: "int" }
- Signal { name: "keyNavigationEnabledChanged"; revision: 7 }
- Signal { name: "populateTransitionChanged" }
- Signal { name: "addTransitionChanged" }
- Signal { name: "addDisplacedTransitionChanged" }
- Signal { name: "moveTransitionChanged" }
- Signal { name: "moveDisplacedTransitionChanged" }
- Signal { name: "removeTransitionChanged" }
- Signal { name: "removeDisplacedTransitionChanged" }
- Signal { name: "displacedTransitionChanged" }
- Method {
- name: "positionViewAtIndex"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "mode"; type: "int" }
- }
- Method {
- name: "indexAt"
- type: "int"
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- Method {
- name: "itemAt"
- type: "QQuickItem*"
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- Method {
- name: "itemAtIndex"
- revision: 13
- type: "QQuickItem*"
- Parameter { name: "index"; type: "int" }
- }
- Method { name: "positionViewAtBeginning" }
- Method { name: "positionViewAtEnd" }
- Method { name: "forceLayout"; revision: 1 }
- }
- Component {
- name: "QQuickItemViewAttached"
- prototype: "QObject"
- Property { name: "view"; type: "QQuickItemView"; isReadonly: true; isPointer: true }
- Property { name: "isCurrentItem"; type: "bool"; isReadonly: true }
- Property { name: "delayRemove"; type: "bool" }
- Property { name: "section"; type: "string"; isReadonly: true }
- Property { name: "previousSection"; type: "string"; isReadonly: true }
- Property { name: "nextSection"; type: "string"; isReadonly: true }
- Signal { name: "currentItemChanged" }
- Signal { name: "add" }
- Signal { name: "remove" }
- Signal { name: "prevSectionChanged" }
- }
- Component {
- name: "QQuickKeyEvent"
- prototype: "QObject"
- Property { name: "key"; type: "int"; isReadonly: true }
- Property { name: "text"; type: "string"; isReadonly: true }
- Property { name: "modifiers"; type: "int"; isReadonly: true }
- Property { name: "isAutoRepeat"; type: "bool"; isReadonly: true }
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "nativeScanCode"; type: "uint"; isReadonly: true }
- Property { name: "accepted"; type: "bool" }
- Method {
- name: "matches"
- revision: 2
- type: "bool"
- Parameter { name: "key"; type: "QKeySequence::StandardKey" }
- }
- }
- Component {
- name: "QQuickKeyNavigationAttached"
- prototype: "QObject"
- exports: ["QtQuick/KeyNavigation 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Priority"
- values: {
- "BeforeItem": 0,
- "AfterItem": 1
- }
- }
- Property { name: "left"; type: "QQuickItem"; isPointer: true }
- Property { name: "right"; type: "QQuickItem"; isPointer: true }
- Property { name: "up"; type: "QQuickItem"; isPointer: true }
- Property { name: "down"; type: "QQuickItem"; isPointer: true }
- Property { name: "tab"; type: "QQuickItem"; isPointer: true }
- Property { name: "backtab"; type: "QQuickItem"; isPointer: true }
- Property { name: "priority"; type: "Priority" }
- }
- Component {
- name: "QQuickKeysAttached"
- prototype: "QObject"
- exports: ["QtQuick/Keys 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Priority"
- values: {
- "BeforeItem": 0,
- "AfterItem": 1
- }
- }
- Property { name: "enabled"; type: "bool" }
- Property { name: "forwardTo"; type: "QQuickItem"; isList: true; isReadonly: true }
- Property { name: "priority"; type: "Priority" }
- Signal {
- name: "pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "released"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "shortcutOverride"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "digit0Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "digit1Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "digit2Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "digit3Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "digit4Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "digit5Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "digit6Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "digit7Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "digit8Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "digit9Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "leftPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "rightPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "upPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "downPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "tabPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "backtabPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "asteriskPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "numberSignPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "escapePressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "returnPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "enterPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "deletePressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "spacePressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "backPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "cancelPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "selectPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "yesPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "noPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "context1Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "context2Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "context3Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "context4Pressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "callPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "hangupPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "flipPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "menuPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "volumeUpPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- Signal {
- name: "volumeDownPressed"
- Parameter { name: "event"; type: "QQuickKeyEvent"; isPointer: true }
- }
- }
- Component {
- name: "QQuickLayoutMirroringAttached"
- prototype: "QObject"
- exports: ["QtQuick/LayoutMirroring 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "enabled"; type: "bool" }
- Property { name: "childrenInherit"; type: "bool" }
- }
- Component {
- name: "QQuickListView"
- defaultProperty: "data"
- prototype: "QQuickItemView"
- exports: [
- "QtQuick/ListView 2.0",
- "QtQuick/ListView 2.1",
- "QtQuick/ListView 2.4",
- "QtQuick/ListView 2.7"
- ]
- exportMetaObjectRevisions: [0, 1, 4, 7]
- attachedType: "QQuickListViewAttached"
- Enum {
- name: "Orientation"
- values: {
- "Horizontal": 1,
- "Vertical": 2
- }
- }
- Enum {
- name: "SnapMode"
- values: {
- "NoSnap": 0,
- "SnapToItem": 1,
- "SnapOneItem": 2
- }
- }
- Enum {
- name: "HeaderPositioning"
- values: {
- "InlineHeader": 0,
- "OverlayHeader": 1,
- "PullBackHeader": 2
- }
- }
- Enum {
- name: "FooterPositioning"
- values: {
- "InlineFooter": 0,
- "OverlayFooter": 1,
- "PullBackFooter": 2
- }
- }
- Property { name: "highlightMoveVelocity"; type: "double" }
- Property { name: "highlightResizeVelocity"; type: "double" }
- Property { name: "highlightResizeDuration"; type: "int" }
- Property { name: "spacing"; type: "double" }
- Property { name: "orientation"; type: "Orientation" }
- Property { name: "section"; type: "QQuickViewSection"; isReadonly: true; isPointer: true }
- Property { name: "currentSection"; type: "string"; isReadonly: true }
- Property { name: "snapMode"; type: "SnapMode" }
- Property { name: "headerPositioning"; revision: 4; type: "HeaderPositioning" }
- Property { name: "footerPositioning"; revision: 4; type: "FooterPositioning" }
- Signal { name: "headerPositioningChanged"; revision: 4 }
- Signal { name: "footerPositioningChanged"; revision: 4 }
- Method { name: "incrementCurrentIndex" }
- Method { name: "decrementCurrentIndex" }
- }
- Component { name: "QQuickListViewAttached"; prototype: "QQuickItemViewAttached" }
- Component {
- name: "QQuickLoader"
- defaultProperty: "data"
- prototype: "QQuickImplicitSizeItem"
- exports: ["QtQuick/Loader 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Status"
- values: {
- "Null": 0,
- "Ready": 1,
- "Loading": 2,
- "Error": 3
- }
- }
- Property { name: "active"; type: "bool" }
- Property { name: "source"; type: "QUrl" }
- Property { name: "sourceComponent"; type: "QQmlComponent"; isPointer: true }
- Property { name: "item"; type: "QObject"; isReadonly: true; isPointer: true }
- Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "progress"; type: "double"; isReadonly: true }
- Property { name: "asynchronous"; type: "bool" }
- Signal { name: "loaded" }
- Method {
- name: "setSource"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- }
- Component {
- name: "QQuickMatrix4x4"
- prototype: "QQuickTransform"
- exports: ["QtQuick/Matrix4x4 2.3"]
- exportMetaObjectRevisions: [0]
- Property { name: "matrix"; type: "QMatrix4x4" }
- }
- Component {
- name: "QQuickMouseArea"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: [
- "QtQuick/MouseArea 2.0",
- "QtQuick/MouseArea 2.4",
- "QtQuick/MouseArea 2.5",
- "QtQuick/MouseArea 2.9"
- ]
- exportMetaObjectRevisions: [0, 4, 5, 9]
- Property { name: "mouseX"; type: "double"; isReadonly: true }
- Property { name: "mouseY"; type: "double"; isReadonly: true }
- Property { name: "containsMouse"; type: "bool"; isReadonly: true }
- Property { name: "pressed"; type: "bool"; isReadonly: true }
- Property { name: "enabled"; type: "bool" }
- Property { name: "scrollGestureEnabled"; revision: 5; type: "bool" }
- Property { name: "pressedButtons"; type: "Qt::MouseButtons"; isReadonly: true }
- Property { name: "acceptedButtons"; type: "Qt::MouseButtons" }
- Property { name: "hoverEnabled"; type: "bool" }
- Property { name: "drag"; type: "QQuickDrag"; isReadonly: true; isPointer: true }
- Property { name: "preventStealing"; type: "bool" }
- Property { name: "propagateComposedEvents"; type: "bool" }
- Property { name: "cursorShape"; type: "Qt::CursorShape" }
- Property { name: "containsPress"; revision: 4; type: "bool"; isReadonly: true }
- Property { name: "pressAndHoldInterval"; revision: 9; type: "int" }
- Signal { name: "hoveredChanged" }
- Signal { name: "scrollGestureEnabledChanged"; revision: 5 }
- Signal {
- name: "positionChanged"
- Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true }
- }
- Signal {
- name: "mouseXChanged"
- Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true }
- }
- Signal {
- name: "mouseYChanged"
- Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true }
- }
- Signal {
- name: "pressed"
- Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true }
- }
- Signal {
- name: "pressAndHold"
- Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true }
- }
- Signal {
- name: "released"
- Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true }
- }
- Signal {
- name: "clicked"
- Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true }
- }
- Signal {
- name: "doubleClicked"
- Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true }
- }
- Signal {
- name: "wheel"
- Parameter { name: "wheel"; type: "QQuickWheelEvent"; isPointer: true }
- }
- Signal { name: "entered" }
- Signal { name: "exited" }
- Signal { name: "canceled" }
- Signal { name: "containsPressChanged"; revision: 4 }
- Signal { name: "pressAndHoldIntervalChanged"; revision: 9 }
- }
- Component {
- name: "QQuickMouseEvent"
- prototype: "QObject"
- Property { name: "x"; type: "double"; isReadonly: true }
- Property { name: "y"; type: "double"; isReadonly: true }
- Property { name: "button"; type: "int"; isReadonly: true }
- Property { name: "buttons"; type: "int"; isReadonly: true }
- Property { name: "modifiers"; type: "int"; isReadonly: true }
- Property { name: "source"; revision: 7; type: "int"; isReadonly: true }
- Property { name: "wasHeld"; type: "bool"; isReadonly: true }
- Property { name: "isClick"; type: "bool"; isReadonly: true }
- Property { name: "accepted"; type: "bool" }
- Property { name: "flags"; revision: 11; type: "int"; isReadonly: true }
- }
- Component {
- name: "QQuickMultiPointHandler"
- prototype: "QQuickPointerDeviceHandler"
- Property { name: "minimumPointCount"; type: "int" }
- Property { name: "maximumPointCount"; type: "int" }
- Property { name: "centroid"; type: "QQuickHandlerPoint"; isReadonly: true }
- }
- Component {
- name: "QQuickMultiPointTouchArea"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick/MultiPointTouchArea 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "touchPoints"; type: "QQuickTouchPoint"; isList: true; isReadonly: true }
- Property { name: "minimumTouchPoints"; type: "int" }
- Property { name: "maximumTouchPoints"; type: "int" }
- Property { name: "mouseEnabled"; type: "bool" }
- Signal {
- name: "pressed"
- Parameter { name: "touchPoints"; type: "QList<QObject*>" }
- }
- Signal {
- name: "updated"
- Parameter { name: "touchPoints"; type: "QList<QObject*>" }
- }
- Signal {
- name: "released"
- Parameter { name: "touchPoints"; type: "QList<QObject*>" }
- }
- Signal {
- name: "canceled"
- Parameter { name: "touchPoints"; type: "QList<QObject*>" }
- }
- Signal {
- name: "gestureStarted"
- Parameter { name: "gesture"; type: "QQuickGrabGestureEvent"; isPointer: true }
- }
- Signal {
- name: "touchUpdated"
- Parameter { name: "touchPoints"; type: "QList<QObject*>" }
- }
- }
- Component {
- name: "QQuickNumberAnimation"
- prototype: "QQuickPropertyAnimation"
- exports: ["QtQuick/NumberAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "from"; type: "double" }
- Property { name: "to"; type: "double" }
- }
- Component {
- name: "QQuickOpacityAnimator"
- prototype: "QQuickAnimator"
- exports: ["QtQuick/OpacityAnimator 2.2"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickOpenGLInfo"
- prototype: "QObject"
- exports: ["QtQuick/OpenGLInfo 2.4"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "ContextProfile"
- values: {
- "NoProfile": 0,
- "CoreProfile": 1,
- "CompatibilityProfile": 2
- }
- }
- Enum {
- name: "RenderableType"
- values: {
- "Unspecified": 0,
- "OpenGL": 1,
- "OpenGLES": 2
- }
- }
- Property { name: "majorVersion"; type: "int"; isReadonly: true }
- Property { name: "minorVersion"; type: "int"; isReadonly: true }
- Property { name: "profile"; type: "ContextProfile"; isReadonly: true }
- Property { name: "renderableType"; type: "RenderableType"; isReadonly: true }
- }
- Component {
- name: "QQuickPackage"
- defaultProperty: "data"
- prototype: "QObject"
- exports: ["QtQuick/Package 2.0"]
- exportMetaObjectRevisions: [0]
- attachedType: "QQuickPackageAttached"
- Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
- }
- Component {
- name: "QQuickPackageAttached"
- prototype: "QObject"
- Property { name: "name"; type: "string" }
- }
- Component {
- name: "QQuickPaintedItem"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick/PaintedItem 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "RenderTarget"
- values: {
- "Image": 0,
- "FramebufferObject": 1,
- "InvertedYFramebufferObject": 2
- }
- }
- Enum {
- name: "PerformanceHints"
- values: {
- "FastFBOResizing": 1
- }
- }
- Property { name: "contentsSize"; type: "QSize" }
- Property { name: "fillColor"; type: "QColor" }
- Property { name: "contentsScale"; type: "double" }
- Property { name: "renderTarget"; type: "RenderTarget" }
- Property { name: "textureSize"; type: "QSize" }
- }
- Component {
- name: "QQuickParallelAnimation"
- defaultProperty: "animations"
- prototype: "QQuickAnimationGroup"
- exports: ["QtQuick/ParallelAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickParentAnimation"
- defaultProperty: "animations"
- prototype: "QQuickAnimationGroup"
- exports: ["QtQuick/ParentAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "target"; type: "QQuickItem"; isPointer: true }
- Property { name: "newParent"; type: "QQuickItem"; isPointer: true }
- Property { name: "via"; type: "QQuickItem"; isPointer: true }
- }
- Component {
- name: "QQuickParentChange"
- prototype: "QQuickStateOperation"
- exports: ["QtQuick/ParentChange 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "target"; type: "QQuickItem"; isPointer: true }
- Property { name: "parent"; type: "QQuickItem"; isPointer: true }
- Property { name: "x"; type: "QQmlScriptString" }
- Property { name: "y"; type: "QQmlScriptString" }
- Property { name: "width"; type: "QQmlScriptString" }
- Property { name: "height"; type: "QQmlScriptString" }
- Property { name: "scale"; type: "QQmlScriptString" }
- Property { name: "rotation"; type: "QQmlScriptString" }
- }
- Component {
- name: "QQuickPath"
- defaultProperty: "pathElements"
- prototype: "QObject"
- exports: ["QtQuick/Path 2.0", "QtQuick/Path 2.14"]
- exportMetaObjectRevisions: [0, 14]
- Property { name: "pathElements"; type: "QQuickPathElement"; isList: true; isReadonly: true }
- Property { name: "startX"; type: "double" }
- Property { name: "startY"; type: "double" }
- Property { name: "closed"; type: "bool"; isReadonly: true }
- Property { name: "scale"; revision: 14; type: "QSizeF" }
- Signal { name: "changed" }
- Signal { name: "scaleChanged"; revision: 14 }
- Method {
- name: "pointAtPercent"
- revision: 14
- type: "QPointF"
- Parameter { name: "t"; type: "double" }
- }
- }
- Component {
- name: "QQuickPathAngleArc"
- prototype: "QQuickCurve"
- exports: ["QtQuick/PathAngleArc 2.11"]
- exportMetaObjectRevisions: [0]
- Property { name: "centerX"; type: "double" }
- Property { name: "centerY"; type: "double" }
- Property { name: "radiusX"; type: "double" }
- Property { name: "radiusY"; type: "double" }
- Property { name: "startAngle"; type: "double" }
- Property { name: "sweepAngle"; type: "double" }
- Property { name: "moveToStart"; type: "bool" }
- }
- Component {
- name: "QQuickPathAnimation"
- prototype: "QQuickAbstractAnimation"
- exports: ["QtQuick/PathAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Orientation"
- values: {
- "Fixed": 0,
- "RightFirst": 1,
- "LeftFirst": 2,
- "BottomFirst": 3,
- "TopFirst": 4
- }
- }
- Property { name: "duration"; type: "int" }
- Property { name: "easing"; type: "QEasingCurve" }
- Property { name: "path"; type: "QQuickPath"; isPointer: true }
- Property { name: "target"; type: "QQuickItem"; isPointer: true }
- Property { name: "orientation"; type: "Orientation" }
- Property { name: "anchorPoint"; type: "QPointF" }
- Property { name: "orientationEntryDuration"; type: "int" }
- Property { name: "orientationExitDuration"; type: "int" }
- Property { name: "endRotation"; type: "double" }
- Signal {
- name: "durationChanged"
- Parameter { type: "int" }
- }
- Signal {
- name: "easingChanged"
- Parameter { type: "QEasingCurve" }
- }
- Signal {
- name: "orientationChanged"
- Parameter { type: "Orientation" }
- }
- Signal {
- name: "anchorPointChanged"
- Parameter { type: "QPointF" }
- }
- Signal {
- name: "orientationEntryDurationChanged"
- Parameter { type: "double" }
- }
- Signal {
- name: "orientationExitDurationChanged"
- Parameter { type: "double" }
- }
- Signal {
- name: "endRotationChanged"
- Parameter { type: "double" }
- }
- }
- Component {
- name: "QQuickPathArc"
- prototype: "QQuickCurve"
- exports: ["QtQuick/PathArc 2.0", "QtQuick/PathArc 2.9"]
- exportMetaObjectRevisions: [0, 9]
- Enum {
- name: "ArcDirection"
- values: {
- "Clockwise": 0,
- "Counterclockwise": 1
- }
- }
- Property { name: "radiusX"; type: "double" }
- Property { name: "radiusY"; type: "double" }
- Property { name: "useLargeArc"; type: "bool" }
- Property { name: "direction"; type: "ArcDirection" }
- Property { name: "xAxisRotation"; revision: 9; type: "double" }
- Signal { name: "xAxisRotationChanged"; revision: 9 }
- }
- Component {
- name: "QQuickPathAttribute"
- prototype: "QQuickPathElement"
- exports: ["QtQuick/PathAttribute 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "name"; type: "string" }
- Property { name: "value"; type: "double" }
- }
- Component {
- name: "QQuickPathCatmullRomCurve"
- prototype: "QQuickCurve"
- exports: ["QtQuick/PathCurve 2.0"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickPathCubic"
- prototype: "QQuickCurve"
- exports: ["QtQuick/PathCubic 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "control1X"; type: "double" }
- Property { name: "control1Y"; type: "double" }
- Property { name: "control2X"; type: "double" }
- Property { name: "control2Y"; type: "double" }
- Property { name: "relativeControl1X"; type: "double" }
- Property { name: "relativeControl1Y"; type: "double" }
- Property { name: "relativeControl2X"; type: "double" }
- Property { name: "relativeControl2Y"; type: "double" }
- }
- Component {
- name: "QQuickPathElement"
- prototype: "QObject"
- Signal { name: "changed" }
- }
- Component {
- name: "QQuickPathInterpolator"
- prototype: "QObject"
- exports: ["QtQuick/PathInterpolator 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "path"; type: "QQuickPath"; isPointer: true }
- Property { name: "progress"; type: "double" }
- Property { name: "x"; type: "double"; isReadonly: true }
- Property { name: "y"; type: "double"; isReadonly: true }
- Property { name: "angle"; type: "double"; isReadonly: true }
- }
- Component {
- name: "QQuickPathLine"
- prototype: "QQuickCurve"
- exports: ["QtQuick/PathLine 2.0"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickPathMove"
- prototype: "QQuickCurve"
- exports: ["QtQuick/PathMove 2.9"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickPathMultiline"
- prototype: "QQuickCurve"
- exports: ["QtQuick/PathMultiline 2.14"]
- exportMetaObjectRevisions: [0]
- Property { name: "start"; type: "QPointF"; isReadonly: true }
- Property { name: "paths"; type: "QVariant" }
- }
- Component {
- name: "QQuickPathPercent"
- prototype: "QQuickPathElement"
- exports: ["QtQuick/PathPercent 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "value"; type: "double" }
- }
- Component {
- name: "QQuickPathPolyline"
- prototype: "QQuickCurve"
- exports: ["QtQuick/PathPolyline 2.14"]
- exportMetaObjectRevisions: [0]
- Property { name: "start"; type: "QPointF"; isReadonly: true }
- Property { name: "path"; type: "QVariant" }
- }
- Component {
- name: "QQuickPathQuad"
- prototype: "QQuickCurve"
- exports: ["QtQuick/PathQuad 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "controlX"; type: "double" }
- Property { name: "controlY"; type: "double" }
- Property { name: "relativeControlX"; type: "double" }
- Property { name: "relativeControlY"; type: "double" }
- }
- Component {
- name: "QQuickPathSvg"
- prototype: "QQuickCurve"
- exports: ["QtQuick/PathSvg 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "path"; type: "string" }
- }
- Component {
- name: "QQuickPathView"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: [
- "QtQuick/PathView 2.0",
- "QtQuick/PathView 2.13",
- "QtQuick/PathView 2.7"
- ]
- exportMetaObjectRevisions: [0, 13, 7]
- attachedType: "QQuickPathViewAttached"
- Enum {
- name: "HighlightRangeMode"
- values: {
- "NoHighlightRange": 0,
- "ApplyRange": 1,
- "StrictlyEnforceRange": 2
- }
- }
- Enum {
- name: "SnapMode"
- values: {
- "NoSnap": 0,
- "SnapToItem": 1,
- "SnapOneItem": 2
- }
- }
- Enum {
- name: "MovementDirection"
- values: {
- "Shortest": 0,
- "Negative": 1,
- "Positive": 2
- }
- }
- Enum {
- name: "PositionMode"
- values: {
- "Beginning": 0,
- "Center": 1,
- "End": 2,
- "Contain": 4,
- "SnapPosition": 5
- }
- }
- Property { name: "model"; type: "QVariant" }
- Property { name: "path"; type: "QQuickPath"; isPointer: true }
- Property { name: "currentIndex"; type: "int" }
- Property { name: "currentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "offset"; type: "double" }
- Property { name: "highlight"; type: "QQmlComponent"; isPointer: true }
- Property { name: "highlightItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "preferredHighlightBegin"; type: "double" }
- Property { name: "preferredHighlightEnd"; type: "double" }
- Property { name: "highlightRangeMode"; type: "HighlightRangeMode" }
- Property { name: "highlightMoveDuration"; type: "int" }
- Property { name: "dragMargin"; type: "double" }
- Property { name: "maximumFlickVelocity"; type: "double" }
- Property { name: "flickDeceleration"; type: "double" }
- Property { name: "interactive"; type: "bool" }
- Property { name: "moving"; type: "bool"; isReadonly: true }
- Property { name: "flicking"; type: "bool"; isReadonly: true }
- Property { name: "dragging"; type: "bool"; isReadonly: true }
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "pathItemCount"; type: "int" }
- Property { name: "snapMode"; type: "SnapMode" }
- Property { name: "movementDirection"; revision: 7; type: "MovementDirection" }
- Property { name: "cacheItemCount"; type: "int" }
- Signal { name: "snapPositionChanged" }
- Signal { name: "movementStarted" }
- Signal { name: "movementEnded" }
- Signal { name: "movementDirectionChanged"; revision: 7 }
- Signal { name: "flickStarted" }
- Signal { name: "flickEnded" }
- Signal { name: "dragStarted" }
- Signal { name: "dragEnded" }
- Method { name: "incrementCurrentIndex" }
- Method { name: "decrementCurrentIndex" }
- Method {
- name: "positionViewAtIndex"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "mode"; type: "int" }
- }
- Method {
- name: "indexAt"
- type: "int"
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- Method {
- name: "itemAt"
- type: "QQuickItem*"
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- Method {
- name: "itemAtIndex"
- revision: 13
- type: "QQuickItem*"
- Parameter { name: "index"; type: "int" }
- }
- }
- Component {
- name: "QQuickPathViewAttached"
- prototype: "QObject"
- Property { name: "view"; type: "QQuickPathView"; isReadonly: true; isPointer: true }
- Property { name: "isCurrentItem"; type: "bool"; isReadonly: true }
- Property { name: "onPath"; type: "bool"; isReadonly: true }
- Signal { name: "currentItemChanged" }
- Signal { name: "pathChanged" }
- }
- Component {
- name: "QQuickPauseAnimation"
- prototype: "QQuickAbstractAnimation"
- exports: ["QtQuick/PauseAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "duration"; type: "int" }
- Signal {
- name: "durationChanged"
- Parameter { type: "int" }
- }
- }
- Component {
- name: "QQuickPen"
- prototype: "QObject"
- Property { name: "width"; type: "double" }
- Property { name: "color"; type: "QColor" }
- Property { name: "pixelAligned"; type: "bool" }
- Signal { name: "penChanged" }
- }
- Component {
- name: "QQuickPinch"
- prototype: "QObject"
- exports: ["QtQuick/Pinch 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Axis"
- values: {
- "NoDrag": 0,
- "XAxis": 1,
- "YAxis": 2,
- "XAndYAxis": 3,
- "XandYAxis": 3
- }
- }
- Property { name: "target"; type: "QQuickItem"; isPointer: true }
- Property { name: "minimumScale"; type: "double" }
- Property { name: "maximumScale"; type: "double" }
- Property { name: "minimumRotation"; type: "double" }
- Property { name: "maximumRotation"; type: "double" }
- Property { name: "dragAxis"; type: "Axis" }
- Property { name: "minimumX"; type: "double" }
- Property { name: "maximumX"; type: "double" }
- Property { name: "minimumY"; type: "double" }
- Property { name: "maximumY"; type: "double" }
- Property { name: "active"; type: "bool"; isReadonly: true }
- }
- Component {
- name: "QQuickPinchArea"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick/PinchArea 2.0", "QtQuick/PinchArea 2.5"]
- exportMetaObjectRevisions: [0, 5]
- Property { name: "enabled"; type: "bool" }
- Property { name: "pinch"; type: "QQuickPinch"; isReadonly: true; isPointer: true }
- Signal {
- name: "pinchStarted"
- Parameter { name: "pinch"; type: "QQuickPinchEvent"; isPointer: true }
- }
- Signal {
- name: "pinchUpdated"
- Parameter { name: "pinch"; type: "QQuickPinchEvent"; isPointer: true }
- }
- Signal {
- name: "pinchFinished"
- Parameter { name: "pinch"; type: "QQuickPinchEvent"; isPointer: true }
- }
- Signal {
- name: "smartZoom"
- revision: 5
- Parameter { name: "pinch"; type: "QQuickPinchEvent"; isPointer: true }
- }
- }
- Component {
- name: "QQuickPinchEvent"
- prototype: "QObject"
- Property { name: "center"; type: "QPointF"; isReadonly: true }
- Property { name: "startCenter"; type: "QPointF"; isReadonly: true }
- Property { name: "previousCenter"; type: "QPointF"; isReadonly: true }
- Property { name: "scale"; type: "double"; isReadonly: true }
- Property { name: "previousScale"; type: "double"; isReadonly: true }
- Property { name: "angle"; type: "double"; isReadonly: true }
- Property { name: "previousAngle"; type: "double"; isReadonly: true }
- Property { name: "rotation"; type: "double"; isReadonly: true }
- Property { name: "point1"; type: "QPointF"; isReadonly: true }
- Property { name: "startPoint1"; type: "QPointF"; isReadonly: true }
- Property { name: "point2"; type: "QPointF"; isReadonly: true }
- Property { name: "startPoint2"; type: "QPointF"; isReadonly: true }
- Property { name: "pointCount"; type: "int"; isReadonly: true }
- Property { name: "accepted"; type: "bool" }
- }
- Component {
- name: "QQuickPinchHandler"
- prototype: "QQuickMultiPointHandler"
- exports: ["QtQuick/PinchHandler 2.12"]
- exportMetaObjectRevisions: [0]
- Property { name: "minimumScale"; type: "double" }
- Property { name: "maximumScale"; type: "double" }
- Property { name: "minimumRotation"; type: "double" }
- Property { name: "maximumRotation"; type: "double" }
- Property { name: "scale"; type: "double"; isReadonly: true }
- Property { name: "activeScale"; type: "double"; isReadonly: true }
- Property { name: "rotation"; type: "double"; isReadonly: true }
- Property { name: "translation"; type: "QVector2D"; isReadonly: true }
- Property { name: "minimumX"; type: "double" }
- Property { name: "maximumX"; type: "double" }
- Property { name: "minimumY"; type: "double" }
- Property { name: "maximumY"; type: "double" }
- Property { name: "xAxis"; type: "QQuickDragAxis"; isReadonly: true; isPointer: true }
- Property { name: "yAxis"; type: "QQuickDragAxis"; isReadonly: true; isPointer: true }
- Signal { name: "updated" }
- }
- Component {
- name: "QQuickPointHandler"
- prototype: "QQuickSinglePointHandler"
- exports: ["QtQuick/PointHandler 2.12"]
- exportMetaObjectRevisions: [0]
- Property { name: "translation"; type: "QVector2D"; isReadonly: true }
- }
- Component {
- name: "QQuickPointerDevice"
- prototype: "QObject"
- exports: ["QtQuick/PointerDevice 2.12"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "DeviceTypes"
- values: {
- "UnknownDevice": 0,
- "Mouse": 1,
- "TouchScreen": 2,
- "TouchPad": 4,
- "Puck": 8,
- "Stylus": 16,
- "Airbrush": 32,
- "AllDevices": 32767
- }
- }
- Enum {
- name: "PointerTypes"
- values: {
- "GenericPointer": 1,
- "Finger": 2,
- "Pen": 4,
- "Eraser": 8,
- "Cursor": 16,
- "AllPointerTypes": 32767
- }
- }
- Enum {
- name: "Capabilities"
- values: {
- "Position": 1,
- "Area": 2,
- "Pressure": 4,
- "Velocity": 8,
- "MouseEmulation": 64,
- "Scroll": 256,
- "Hover": 512,
- "Rotation": 1024,
- "XTilt": 2048,
- "YTilt": 4096
- }
- }
- Property { name: "type"; type: "DeviceType"; isReadonly: true }
- Property { name: "pointerType"; type: "PointerType"; isReadonly: true }
- Property { name: "capabilities"; type: "Capabilities"; isReadonly: true }
- Property { name: "maximumTouchPoints"; type: "int"; isReadonly: true }
- Property { name: "buttonCount"; type: "int"; isReadonly: true }
- Property { name: "name"; type: "string"; isReadonly: true }
- Property { name: "uniqueId"; type: "QPointingDeviceUniqueId"; isReadonly: true }
- }
- Component {
- name: "QQuickPointerDeviceHandler"
- prototype: "QQuickPointerHandler"
- Property { name: "acceptedDevices"; type: "QQuickPointerDevice::DeviceTypes" }
- Property { name: "acceptedPointerTypes"; type: "QQuickPointerDevice::PointerTypes" }
- Property { name: "acceptedButtons"; type: "Qt::MouseButtons" }
- Property { name: "acceptedModifiers"; type: "Qt::KeyboardModifiers" }
- Method {
- name: "setAcceptedDevices"
- Parameter { name: "acceptedDevices"; type: "QQuickPointerDevice::DeviceTypes" }
- }
- Method {
- name: "setAcceptedPointerTypes"
- Parameter { name: "acceptedPointerTypes"; type: "QQuickPointerDevice::PointerTypes" }
- }
- Method {
- name: "setAcceptedButtons"
- Parameter { name: "buttons"; type: "Qt::MouseButtons" }
- }
- Method {
- name: "setAcceptedModifiers"
- Parameter { name: "acceptedModifiers"; type: "Qt::KeyboardModifiers" }
- }
- }
- Component {
- name: "QQuickPointerEvent"
- prototype: "QObject"
- exports: ["QtQuick/PointerEvent 2.12"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "device"; type: "QQuickPointerDevice"; isReadonly: true; isPointer: true }
- Property { name: "modifiers"; type: "Qt::KeyboardModifiers"; isReadonly: true }
- Property { name: "button"; type: "Qt::MouseButtons"; isReadonly: true }
- Property { name: "buttons"; type: "Qt::MouseButtons"; isReadonly: true }
- }
- Component {
- name: "QQuickPointerHandler"
- prototype: "QObject"
- exports: ["QtQuick/PointerHandler 2.12"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "GrabPermissions"
- values: {
- "TakeOverForbidden": 0,
- "CanTakeOverFromHandlersOfSameType": 1,
- "CanTakeOverFromHandlersOfDifferentType": 2,
- "CanTakeOverFromItems": 4,
- "CanTakeOverFromAnything": 15,
- "ApprovesTakeOverByHandlersOfSameType": 16,
- "ApprovesTakeOverByHandlersOfDifferentType": 32,
- "ApprovesTakeOverByItems": 64,
- "ApprovesCancellation": 128,
- "ApprovesTakeOverByAnything": 240
- }
- }
- Property { name: "enabled"; type: "bool" }
- Property { name: "active"; type: "bool"; isReadonly: true }
- Property { name: "target"; type: "QQuickItem"; isPointer: true }
- Property { name: "parent"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "grabPermissions"; type: "GrabPermissions" }
- Property { name: "margin"; type: "double" }
- Signal {
- name: "grabChanged"
- Parameter { name: "transition"; type: "QQuickEventPoint::GrabTransition" }
- Parameter { name: "point"; type: "QQuickEventPoint"; isPointer: true }
- }
- Signal { name: "grabPermissionChanged" }
- Signal {
- name: "canceled"
- Parameter { name: "point"; type: "QQuickEventPoint"; isPointer: true }
- }
- }
- Component {
- name: "QQuickPointerMouseEvent"
- prototype: "QQuickSinglePointEvent"
- exports: ["QtQuick/PointerMouseEvent 2.12"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickPointerTouchEvent"
- prototype: "QQuickPointerEvent"
- exports: ["QtQuick/PointerTouchEvent 2.12"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickPositionerAttached"
- prototype: "QObject"
- Property { name: "index"; type: "int"; isReadonly: true }
- Property { name: "isFirstItem"; type: "bool"; isReadonly: true }
- Property { name: "isLastItem"; type: "bool"; isReadonly: true }
- }
- Component {
- name: "QQuickPropertyAction"
- prototype: "QQuickAbstractAnimation"
- exports: ["QtQuick/PropertyAction 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "target"; type: "QObject"; isPointer: true }
- Property { name: "property"; type: "string" }
- Property { name: "properties"; type: "string" }
- Property { name: "targets"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "exclude"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "value"; type: "QVariant" }
- Signal {
- name: "valueChanged"
- Parameter { type: "QVariant" }
- }
- Signal {
- name: "propertiesChanged"
- Parameter { type: "string" }
- }
- }
- Component {
- name: "QQuickPropertyAnimation"
- prototype: "QQuickAbstractAnimation"
- exports: ["QtQuick/PropertyAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "duration"; type: "int" }
- Property { name: "from"; type: "QVariant" }
- Property { name: "to"; type: "QVariant" }
- Property { name: "easing"; type: "QEasingCurve" }
- Property { name: "target"; type: "QObject"; isPointer: true }
- Property { name: "property"; type: "string" }
- Property { name: "properties"; type: "string" }
- Property { name: "targets"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "exclude"; type: "QObject"; isList: true; isReadonly: true }
- Signal {
- name: "durationChanged"
- Parameter { type: "int" }
- }
- Signal {
- name: "easingChanged"
- Parameter { type: "QEasingCurve" }
- }
- Signal {
- name: "propertiesChanged"
- Parameter { type: "string" }
- }
- }
- Component {
- name: "QQuickPropertyChanges"
- prototype: "QQuickStateOperation"
- exports: ["QtQuick/PropertyChanges 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "target"; type: "QObject"; isPointer: true }
- Property { name: "restoreEntryValues"; type: "bool" }
- Property { name: "explicit"; type: "bool" }
- }
- Component {
- name: "QQuickRectangle"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick/Rectangle 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "color"; type: "QColor" }
- Property { name: "gradient"; type: "QJSValue" }
- Property { name: "border"; type: "QQuickPen"; isReadonly: true; isPointer: true }
- Property { name: "radius"; type: "double" }
- }
- Component {
- name: "QQuickRepeater"
- defaultProperty: "delegate"
- prototype: "QQuickItem"
- exports: ["QtQuick/Repeater 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "model"; type: "QVariant" }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "count"; type: "int"; isReadonly: true }
- Signal {
- name: "itemAdded"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- }
- Signal {
- name: "itemRemoved"
- Parameter { name: "index"; type: "int" }
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- }
- Method {
- name: "itemAt"
- type: "QQuickItem*"
- Parameter { name: "index"; type: "int" }
- }
- }
- Component {
- name: "QQuickRotation"
- prototype: "QQuickTransform"
- exports: ["QtQuick/Rotation 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "origin"; type: "QVector3D" }
- Property { name: "angle"; type: "double" }
- Property { name: "axis"; type: "QVector3D" }
- }
- Component {
- name: "QQuickRotationAnimation"
- prototype: "QQuickPropertyAnimation"
- exports: ["QtQuick/RotationAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "RotationDirection"
- values: {
- "Numerical": 0,
- "Shortest": 1,
- "Clockwise": 2,
- "Counterclockwise": 3
- }
- }
- Property { name: "from"; type: "double" }
- Property { name: "to"; type: "double" }
- Property { name: "direction"; type: "RotationDirection" }
- }
- Component {
- name: "QQuickRotationAnimator"
- prototype: "QQuickAnimator"
- exports: ["QtQuick/RotationAnimator 2.2"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "RotationDirection"
- values: {
- "Numerical": 0,
- "Shortest": 1,
- "Clockwise": 2,
- "Counterclockwise": 3
- }
- }
- Property { name: "direction"; type: "RotationDirection" }
- Signal {
- name: "directionChanged"
- Parameter { name: "dir"; type: "RotationDirection" }
- }
- }
- Component {
- name: "QQuickRow"
- defaultProperty: "data"
- prototype: "QQuickBasePositioner"
- exports: ["QtQuick/Row 2.0", "QtQuick/Row 2.6"]
- exportMetaObjectRevisions: [0, 6]
- Property { name: "layoutDirection"; type: "Qt::LayoutDirection" }
- Property { name: "effectiveLayoutDirection"; type: "Qt::LayoutDirection"; isReadonly: true }
- }
- Component {
- name: "QQuickScale"
- prototype: "QQuickTransform"
- exports: ["QtQuick/Scale 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "origin"; type: "QVector3D" }
- Property { name: "xScale"; type: "double" }
- Property { name: "yScale"; type: "double" }
- Property { name: "zScale"; type: "double" }
- Signal { name: "scaleChanged" }
- }
- Component {
- name: "QQuickScaleAnimator"
- prototype: "QQuickAnimator"
- exports: ["QtQuick/ScaleAnimator 2.2"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickScaleGrid"
- prototype: "QObject"
- Property { name: "left"; type: "int" }
- Property { name: "top"; type: "int" }
- Property { name: "right"; type: "int" }
- Property { name: "bottom"; type: "int" }
- Signal { name: "borderChanged" }
- Signal { name: "leftBorderChanged" }
- Signal { name: "topBorderChanged" }
- Signal { name: "rightBorderChanged" }
- Signal { name: "bottomBorderChanged" }
- }
- Component {
- name: "QQuickScriptAction"
- prototype: "QQuickAbstractAnimation"
- exports: ["QtQuick/ScriptAction 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "script"; type: "QQmlScriptString" }
- Property { name: "scriptName"; type: "string" }
- }
- Component {
- name: "QQuickSequentialAnimation"
- defaultProperty: "animations"
- prototype: "QQuickAnimationGroup"
- exports: ["QtQuick/SequentialAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickShaderEffect"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick/ShaderEffect 2.0", "QtQuick/ShaderEffect 2.4"]
- exportMetaObjectRevisions: [0, 4]
- Enum {
- name: "CullMode"
- values: {
- "NoCulling": 0,
- "BackFaceCulling": 1,
- "FrontFaceCulling": 2
- }
- }
- Enum {
- name: "Status"
- values: {
- "Compiled": 0,
- "Uncompiled": 1,
- "Error": 2
- }
- }
- Property { name: "fragmentShader"; type: "QByteArray" }
- Property { name: "vertexShader"; type: "QByteArray" }
- Property { name: "blending"; type: "bool" }
- Property { name: "mesh"; type: "QVariant" }
- Property { name: "cullMode"; type: "CullMode" }
- Property { name: "log"; type: "string"; isReadonly: true }
- Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "supportsAtlasTextures"; revision: 4; type: "bool" }
- }
- Component {
- name: "QQuickShaderEffectMesh"
- prototype: "QObject"
- exports: ["QtQuick/ShaderEffectMesh 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Signal { name: "geometryChanged" }
- }
- Component {
- name: "QQuickShaderEffectSource"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: [
- "QtQuick/ShaderEffectSource 2.0",
- "QtQuick/ShaderEffectSource 2.6",
- "QtQuick/ShaderEffectSource 2.9"
- ]
- exportMetaObjectRevisions: [0, 6, 9]
- Enum {
- name: "WrapMode"
- values: {
- "ClampToEdge": 0,
- "RepeatHorizontally": 1,
- "RepeatVertically": 2,
- "Repeat": 3
- }
- }
- Enum {
- name: "Format"
- values: {
- "Alpha": 6406,
- "RGB": 6407,
- "RGBA": 6408
- }
- }
- Enum {
- name: "TextureMirroring"
- values: {
- "NoMirroring": 0,
- "MirrorHorizontally": 1,
- "MirrorVertically": 2
- }
- }
- Property { name: "wrapMode"; type: "WrapMode" }
- Property { name: "sourceItem"; type: "QQuickItem"; isPointer: true }
- Property { name: "sourceRect"; type: "QRectF" }
- Property { name: "textureSize"; type: "QSize" }
- Property { name: "format"; type: "Format" }
- Property { name: "live"; type: "bool" }
- Property { name: "hideSource"; type: "bool" }
- Property { name: "mipmap"; type: "bool" }
- Property { name: "recursive"; type: "bool" }
- Property { name: "textureMirroring"; revision: 6; type: "TextureMirroring" }
- Property { name: "samples"; revision: 9; type: "int" }
- Signal { name: "scheduledUpdateCompleted" }
- Method { name: "scheduleUpdate" }
- }
- Component {
- name: "QQuickShortcut"
- prototype: "QObject"
- exports: [
- "QtQuick/Shortcut 2.5",
- "QtQuick/Shortcut 2.6",
- "QtQuick/Shortcut 2.9"
- ]
- exportMetaObjectRevisions: [0, 6, 9]
- Property { name: "sequence"; type: "QVariant" }
- Property { name: "sequences"; revision: 9; type: "QVariantList" }
- Property { name: "nativeText"; revision: 6; type: "string"; isReadonly: true }
- Property { name: "portableText"; revision: 6; type: "string"; isReadonly: true }
- Property { name: "enabled"; type: "bool" }
- Property { name: "autoRepeat"; type: "bool" }
- Property { name: "context"; type: "Qt::ShortcutContext" }
- Signal { name: "sequencesChanged"; revision: 9 }
- Signal { name: "activated" }
- Signal { name: "activatedAmbiguously" }
- }
- Component { name: "QQuickSinglePointEvent"; prototype: "QQuickPointerEvent" }
- Component {
- name: "QQuickSinglePointHandler"
- prototype: "QQuickPointerDeviceHandler"
- Property { name: "point"; type: "QQuickHandlerPoint"; isReadonly: true }
- }
- Component {
- name: "QQuickSmoothedAnimation"
- prototype: "QQuickNumberAnimation"
- exports: ["QtQuick/SmoothedAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "ReversingMode"
- values: {
- "Eased": 0,
- "Immediate": 1,
- "Sync": 2
- }
- }
- Property { name: "velocity"; type: "double" }
- Property { name: "reversingMode"; type: "ReversingMode" }
- Property { name: "maximumEasingTime"; type: "double" }
- }
- Component {
- name: "QQuickSpringAnimation"
- prototype: "QQuickNumberAnimation"
- exports: ["QtQuick/SpringAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "velocity"; type: "double" }
- Property { name: "spring"; type: "double" }
- Property { name: "damping"; type: "double" }
- Property { name: "epsilon"; type: "double" }
- Property { name: "modulus"; type: "double" }
- Property { name: "mass"; type: "double" }
- Signal { name: "syncChanged" }
- }
- Component {
- name: "QQuickSprite"
- prototype: "QQuickStochasticState"
- exports: ["QtQuick/Sprite 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "source"; type: "QUrl" }
- Property { name: "reverse"; type: "bool" }
- Property { name: "frameSync"; type: "bool" }
- Property { name: "frames"; type: "int" }
- Property { name: "frameCount"; type: "int" }
- Property { name: "frameHeight"; type: "int" }
- Property { name: "frameWidth"; type: "int" }
- Property { name: "frameX"; type: "int" }
- Property { name: "frameY"; type: "int" }
- Property { name: "frameRate"; type: "double" }
- Property { name: "frameRateVariation"; type: "double" }
- Property { name: "frameDuration"; type: "int" }
- Property { name: "frameDurationVariation"; type: "int" }
- Signal {
- name: "sourceChanged"
- Parameter { name: "arg"; type: "QUrl" }
- }
- Signal {
- name: "frameHeightChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameWidthChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "reverseChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "frameCountChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameXChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameYChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameRateChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "frameRateVariationChanged"
- Parameter { name: "arg"; type: "double" }
- }
- Signal {
- name: "frameDurationChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameDurationVariationChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "frameSyncChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setSource"
- Parameter { name: "arg"; type: "QUrl" }
- }
- Method {
- name: "setFrameHeight"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameWidth"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setReverse"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setFrames"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameCount"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameX"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameY"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameRate"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setFrameRateVariation"
- Parameter { name: "arg"; type: "double" }
- }
- Method {
- name: "setFrameDuration"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameDurationVariation"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setFrameSync"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickSpriteSequence"
- defaultProperty: "sprites"
- prototype: "QQuickItem"
- exports: ["QtQuick/SpriteSequence 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "running"; type: "bool" }
- Property { name: "interpolate"; type: "bool" }
- Property { name: "goalSprite"; type: "string" }
- Property { name: "currentSprite"; type: "string"; isReadonly: true }
- Property { name: "sprites"; type: "QQuickSprite"; isList: true; isReadonly: true }
- Signal {
- name: "runningChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "interpolateChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "goalSpriteChanged"
- Parameter { name: "arg"; type: "string" }
- }
- Signal {
- name: "currentSpriteChanged"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "jumpTo"
- Parameter { name: "sprite"; type: "string" }
- }
- Method {
- name: "setGoalSprite"
- Parameter { name: "sprite"; type: "string" }
- }
- Method {
- name: "setRunning"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setInterpolate"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickState"
- defaultProperty: "changes"
- prototype: "QObject"
- exports: ["QtQuick/State 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "name"; type: "string" }
- Property { name: "when"; type: "bool" }
- Property { name: "extend"; type: "string" }
- Property { name: "changes"; type: "QQuickStateOperation"; isList: true; isReadonly: true }
- Signal { name: "completed" }
- }
- Component {
- name: "QQuickStateChangeScript"
- prototype: "QQuickStateOperation"
- exports: ["QtQuick/StateChangeScript 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "script"; type: "QQmlScriptString" }
- Property { name: "name"; type: "string" }
- }
- Component {
- name: "QQuickStateGroup"
- prototype: "QObject"
- exports: ["QtQuick/StateGroup 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "state"; type: "string" }
- Property { name: "states"; type: "QQuickState"; isList: true; isReadonly: true }
- Property { name: "transitions"; type: "QQuickTransition"; isList: true; isReadonly: true }
- Signal {
- name: "stateChanged"
- Parameter { type: "string" }
- }
- }
- Component { name: "QQuickStateOperation"; prototype: "QObject" }
- Component {
- name: "QQuickStochasticState"
- prototype: "QObject"
- Property { name: "duration"; type: "int" }
- Property { name: "durationVariation"; type: "int" }
- Property { name: "randomStart"; type: "bool" }
- Property { name: "to"; type: "QVariantMap" }
- Property { name: "name"; type: "string" }
- Signal {
- name: "durationChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "nameChanged"
- Parameter { name: "arg"; type: "string" }
- }
- Signal {
- name: "toChanged"
- Parameter { name: "arg"; type: "QVariantMap" }
- }
- Signal {
- name: "durationVariationChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal { name: "entered" }
- Signal {
- name: "randomStartChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setDuration"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setName"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setTo"
- Parameter { name: "arg"; type: "QVariantMap" }
- }
- Method {
- name: "setDurationVariation"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setRandomStart"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickSystemPalette"
- prototype: "QObject"
- exports: ["QtQuick/SystemPalette 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "ColorGroup"
- values: {
- "Active": 0,
- "Inactive": 2,
- "Disabled": 1
- }
- }
- Property { name: "colorGroup"; type: "QQuickSystemPalette::ColorGroup" }
- Property { name: "window"; type: "QColor"; isReadonly: true }
- Property { name: "windowText"; type: "QColor"; isReadonly: true }
- Property { name: "base"; type: "QColor"; isReadonly: true }
- Property { name: "text"; type: "QColor"; isReadonly: true }
- Property { name: "alternateBase"; type: "QColor"; isReadonly: true }
- Property { name: "button"; type: "QColor"; isReadonly: true }
- Property { name: "buttonText"; type: "QColor"; isReadonly: true }
- Property { name: "light"; type: "QColor"; isReadonly: true }
- Property { name: "midlight"; type: "QColor"; isReadonly: true }
- Property { name: "dark"; type: "QColor"; isReadonly: true }
- Property { name: "mid"; type: "QColor"; isReadonly: true }
- Property { name: "shadow"; type: "QColor"; isReadonly: true }
- Property { name: "highlight"; type: "QColor"; isReadonly: true }
- Property { name: "highlightedText"; type: "QColor"; isReadonly: true }
- Signal { name: "paletteChanged" }
- }
- Component {
- name: "QQuickTableView"
- defaultProperty: "flickableData"
- prototype: "QQuickFlickable"
- exports: ["QtQuick/TableView 2.12", "QtQuick/TableView 2.14"]
- exportMetaObjectRevisions: [0, 14]
- attachedType: "QQuickTableViewAttached"
- Property { name: "rows"; type: "int"; isReadonly: true }
- Property { name: "columns"; type: "int"; isReadonly: true }
- Property { name: "rowSpacing"; type: "double" }
- Property { name: "columnSpacing"; type: "double" }
- Property { name: "rowHeightProvider"; type: "QJSValue" }
- Property { name: "columnWidthProvider"; type: "QJSValue" }
- Property { name: "model"; type: "QVariant" }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "reuseItems"; type: "bool" }
- Property { name: "contentWidth"; type: "double" }
- Property { name: "contentHeight"; type: "double" }
- Property { name: "syncView"; revision: 14; type: "QQuickTableView"; isPointer: true }
- Property { name: "syncDirection"; revision: 14; type: "Qt::Orientations" }
- Signal { name: "syncViewChanged"; revision: 14 }
- Signal { name: "syncDirectionChanged"; revision: 14 }
- Method { name: "forceLayout" }
- }
- Component {
- name: "QQuickTableViewAttached"
- prototype: "QObject"
- Property { name: "view"; type: "QQuickTableView"; isReadonly: true; isPointer: true }
- Signal { name: "pooled" }
- Signal { name: "reused" }
- }
- Component {
- name: "QQuickTapHandler"
- prototype: "QQuickSinglePointHandler"
- exports: ["QtQuick/TapHandler 2.12"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "GesturePolicy"
- values: {
- "DragThreshold": 0,
- "WithinBounds": 1,
- "ReleaseWithinBounds": 2
- }
- }
- Property { name: "pressed"; type: "bool"; isReadonly: true }
- Property { name: "tapCount"; type: "int"; isReadonly: true }
- Property { name: "timeHeld"; type: "double"; isReadonly: true }
- Property { name: "longPressThreshold"; type: "double" }
- Property { name: "gesturePolicy"; type: "GesturePolicy" }
- Signal {
- name: "tapped"
- Parameter { name: "eventPoint"; type: "QQuickEventPoint"; isPointer: true }
- }
- Signal {
- name: "singleTapped"
- Parameter { name: "eventPoint"; type: "QQuickEventPoint"; isPointer: true }
- }
- Signal {
- name: "doubleTapped"
- Parameter { name: "eventPoint"; type: "QQuickEventPoint"; isPointer: true }
- }
- Signal { name: "longPressed" }
- }
- Component {
- name: "QQuickText"
- defaultProperty: "data"
- prototype: "QQuickImplicitSizeItem"
- exports: [
- "QtQuick/Text 2.0",
- "QtQuick/Text 2.10",
- "QtQuick/Text 2.12",
- "QtQuick/Text 2.2",
- "QtQuick/Text 2.3",
- "QtQuick/Text 2.6",
- "QtQuick/Text 2.9"
- ]
- exportMetaObjectRevisions: [0, 10, 12, 2, 3, 6, 9]
- Enum {
- name: "HAlignment"
- values: {
- "AlignLeft": 1,
- "AlignRight": 2,
- "AlignHCenter": 4,
- "AlignJustify": 8
- }
- }
- Enum {
- name: "VAlignment"
- values: {
- "AlignTop": 32,
- "AlignBottom": 64,
- "AlignVCenter": 128
- }
- }
- Enum {
- name: "TextStyle"
- values: {
- "Normal": 0,
- "Outline": 1,
- "Raised": 2,
- "Sunken": 3
- }
- }
- Enum {
- name: "TextFormat"
- values: {
- "PlainText": 0,
- "RichText": 1,
- "MarkdownText": 3,
- "AutoText": 2,
- "StyledText": 4
- }
- }
- Enum {
- name: "TextElideMode"
- values: {
- "ElideLeft": 0,
- "ElideRight": 1,
- "ElideMiddle": 2,
- "ElideNone": 3
- }
- }
- Enum {
- name: "WrapMode"
- values: {
- "NoWrap": 0,
- "WordWrap": 1,
- "WrapAnywhere": 3,
- "WrapAtWordBoundaryOrAnywhere": 4,
- "Wrap": 4
- }
- }
- Enum {
- name: "RenderType"
- values: {
- "QtRendering": 0,
- "NativeRendering": 1
- }
- }
- Enum {
- name: "LineHeightMode"
- values: {
- "ProportionalHeight": 0,
- "FixedHeight": 1
- }
- }
- Enum {
- name: "FontSizeMode"
- values: {
- "FixedSize": 0,
- "HorizontalFit": 1,
- "VerticalFit": 2,
- "Fit": 3
- }
- }
- Property { name: "text"; type: "string" }
- Property { name: "font"; type: "QFont" }
- Property { name: "color"; type: "QColor" }
- Property { name: "linkColor"; type: "QColor" }
- Property { name: "style"; type: "TextStyle" }
- Property { name: "styleColor"; type: "QColor" }
- Property { name: "horizontalAlignment"; type: "HAlignment" }
- Property { name: "effectiveHorizontalAlignment"; type: "HAlignment"; isReadonly: true }
- Property { name: "verticalAlignment"; type: "VAlignment" }
- Property { name: "wrapMode"; type: "WrapMode" }
- Property { name: "lineCount"; type: "int"; isReadonly: true }
- Property { name: "truncated"; type: "bool"; isReadonly: true }
- Property { name: "maximumLineCount"; type: "int" }
- Property { name: "textFormat"; type: "TextFormat" }
- Property { name: "elide"; type: "TextElideMode" }
- Property { name: "contentWidth"; type: "double"; isReadonly: true }
- Property { name: "contentHeight"; type: "double"; isReadonly: true }
- Property { name: "paintedWidth"; type: "double"; isReadonly: true }
- Property { name: "paintedHeight"; type: "double"; isReadonly: true }
- Property { name: "lineHeight"; type: "double" }
- Property { name: "lineHeightMode"; type: "LineHeightMode" }
- Property { name: "baseUrl"; type: "QUrl" }
- Property { name: "minimumPixelSize"; type: "int" }
- Property { name: "minimumPointSize"; type: "int" }
- Property { name: "fontSizeMode"; type: "FontSizeMode" }
- Property { name: "renderType"; type: "RenderType" }
- Property { name: "hoveredLink"; revision: 2; type: "string"; isReadonly: true }
- Property { name: "padding"; revision: 6; type: "double" }
- Property { name: "topPadding"; revision: 6; type: "double" }
- Property { name: "leftPadding"; revision: 6; type: "double" }
- Property { name: "rightPadding"; revision: 6; type: "double" }
- Property { name: "bottomPadding"; revision: 6; type: "double" }
- Property { name: "fontInfo"; revision: 9; type: "QJSValue"; isReadonly: true }
- Property { name: "advance"; revision: 10; type: "QSizeF"; isReadonly: true }
- Signal {
- name: "textChanged"
- Parameter { name: "text"; type: "string" }
- }
- Signal {
- name: "linkActivated"
- Parameter { name: "link"; type: "string" }
- }
- Signal {
- name: "linkHovered"
- revision: 2
- Parameter { name: "link"; type: "string" }
- }
- Signal {
- name: "fontChanged"
- Parameter { name: "font"; type: "QFont" }
- }
- Signal {
- name: "styleChanged"
- Parameter { name: "style"; type: "QQuickText::TextStyle" }
- }
- Signal {
- name: "horizontalAlignmentChanged"
- Parameter { name: "alignment"; type: "QQuickText::HAlignment" }
- }
- Signal {
- name: "verticalAlignmentChanged"
- Parameter { name: "alignment"; type: "QQuickText::VAlignment" }
- }
- Signal {
- name: "textFormatChanged"
- Parameter { name: "textFormat"; type: "QQuickText::TextFormat" }
- }
- Signal {
- name: "elideModeChanged"
- Parameter { name: "mode"; type: "QQuickText::TextElideMode" }
- }
- Signal { name: "contentSizeChanged" }
- Signal {
- name: "contentWidthChanged"
- Parameter { name: "contentWidth"; type: "double" }
- }
- Signal {
- name: "contentHeightChanged"
- Parameter { name: "contentHeight"; type: "double" }
- }
- Signal {
- name: "lineHeightChanged"
- Parameter { name: "lineHeight"; type: "double" }
- }
- Signal {
- name: "lineHeightModeChanged"
- Parameter { name: "mode"; type: "LineHeightMode" }
- }
- Signal {
- name: "lineLaidOut"
- Parameter { name: "line"; type: "QQuickTextLine"; isPointer: true }
- }
- Signal { name: "paddingChanged"; revision: 6 }
- Signal { name: "topPaddingChanged"; revision: 6 }
- Signal { name: "leftPaddingChanged"; revision: 6 }
- Signal { name: "rightPaddingChanged"; revision: 6 }
- Signal { name: "bottomPaddingChanged"; revision: 6 }
- Signal { name: "fontInfoChanged"; revision: 9 }
- Method { name: "doLayout" }
- Method { name: "forceLayout"; revision: 9 }
- Method {
- name: "linkAt"
- revision: 3
- type: "string"
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- }
- Component { name: "QQuickTextDocument"; prototype: "QObject" }
- Component {
- name: "QQuickTextEdit"
- defaultProperty: "data"
- prototype: "QQuickImplicitSizeItem"
- exports: [
- "QtQuick/TextEdit 2.0",
- "QtQuick/TextEdit 2.1",
- "QtQuick/TextEdit 2.10",
- "QtQuick/TextEdit 2.2",
- "QtQuick/TextEdit 2.3",
- "QtQuick/TextEdit 2.6",
- "QtQuick/TextEdit 2.7"
- ]
- exportMetaObjectRevisions: [0, 1, 10, 2, 3, 6, 7]
- Enum {
- name: "HAlignment"
- values: {
- "AlignLeft": 1,
- "AlignRight": 2,
- "AlignHCenter": 4,
- "AlignJustify": 8
- }
- }
- Enum {
- name: "VAlignment"
- values: {
- "AlignTop": 32,
- "AlignBottom": 64,
- "AlignVCenter": 128
- }
- }
- Enum {
- name: "TextFormat"
- values: {
- "PlainText": 0,
- "RichText": 1,
- "AutoText": 2,
- "MarkdownText": 3
- }
- }
- Enum {
- name: "WrapMode"
- values: {
- "NoWrap": 0,
- "WordWrap": 1,
- "WrapAnywhere": 3,
- "WrapAtWordBoundaryOrAnywhere": 4,
- "Wrap": 4
- }
- }
- Enum {
- name: "SelectionMode"
- values: {
- "SelectCharacters": 0,
- "SelectWords": 1
- }
- }
- Enum {
- name: "RenderType"
- values: {
- "QtRendering": 0,
- "NativeRendering": 1
- }
- }
- Property { name: "text"; type: "string" }
- Property { name: "color"; type: "QColor" }
- Property { name: "selectionColor"; type: "QColor" }
- Property { name: "selectedTextColor"; type: "QColor" }
- Property { name: "font"; type: "QFont" }
- Property { name: "horizontalAlignment"; type: "HAlignment" }
- Property { name: "effectiveHorizontalAlignment"; type: "HAlignment"; isReadonly: true }
- Property { name: "verticalAlignment"; type: "VAlignment" }
- Property { name: "wrapMode"; type: "WrapMode" }
- Property { name: "lineCount"; type: "int"; isReadonly: true }
- Property { name: "length"; type: "int"; isReadonly: true }
- Property { name: "contentWidth"; type: "double"; isReadonly: true }
- Property { name: "contentHeight"; type: "double"; isReadonly: true }
- Property { name: "paintedWidth"; type: "double"; isReadonly: true }
- Property { name: "paintedHeight"; type: "double"; isReadonly: true }
- Property { name: "textFormat"; type: "TextFormat" }
- Property { name: "readOnly"; type: "bool" }
- Property { name: "cursorVisible"; type: "bool" }
- Property { name: "cursorPosition"; type: "int" }
- Property { name: "cursorRectangle"; type: "QRectF"; isReadonly: true }
- Property { name: "cursorDelegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "overwriteMode"; type: "bool" }
- Property { name: "selectionStart"; type: "int"; isReadonly: true }
- Property { name: "selectionEnd"; type: "int"; isReadonly: true }
- Property { name: "selectedText"; type: "string"; isReadonly: true }
- Property { name: "activeFocusOnPress"; type: "bool" }
- Property { name: "persistentSelection"; type: "bool" }
- Property { name: "textMargin"; type: "double" }
- Property { name: "inputMethodHints"; type: "Qt::InputMethodHints" }
- Property { name: "selectByKeyboard"; revision: 1; type: "bool" }
- Property { name: "selectByMouse"; type: "bool" }
- Property { name: "mouseSelectionMode"; type: "SelectionMode" }
- Property { name: "canPaste"; type: "bool"; isReadonly: true }
- Property { name: "canUndo"; type: "bool"; isReadonly: true }
- Property { name: "canRedo"; type: "bool"; isReadonly: true }
- Property { name: "inputMethodComposing"; type: "bool"; isReadonly: true }
- Property { name: "baseUrl"; type: "QUrl" }
- Property { name: "renderType"; type: "RenderType" }
- Property {
- name: "textDocument"
- revision: 1
- type: "QQuickTextDocument"
- isReadonly: true
- isPointer: true
- }
- Property { name: "hoveredLink"; revision: 2; type: "string"; isReadonly: true }
- Property { name: "padding"; revision: 6; type: "double" }
- Property { name: "topPadding"; revision: 6; type: "double" }
- Property { name: "leftPadding"; revision: 6; type: "double" }
- Property { name: "rightPadding"; revision: 6; type: "double" }
- Property { name: "bottomPadding"; revision: 6; type: "double" }
- Property { name: "preeditText"; revision: 7; type: "string"; isReadonly: true }
- Property { name: "tabStopDistance"; revision: 10; type: "double" }
- Signal { name: "preeditTextChanged"; revision: 7 }
- Signal { name: "contentSizeChanged" }
- Signal {
- name: "colorChanged"
- Parameter { name: "color"; type: "QColor" }
- }
- Signal {
- name: "selectionColorChanged"
- Parameter { name: "color"; type: "QColor" }
- }
- Signal {
- name: "selectedTextColorChanged"
- Parameter { name: "color"; type: "QColor" }
- }
- Signal {
- name: "fontChanged"
- Parameter { name: "font"; type: "QFont" }
- }
- Signal {
- name: "horizontalAlignmentChanged"
- Parameter { name: "alignment"; type: "QQuickTextEdit::HAlignment" }
- }
- Signal {
- name: "verticalAlignmentChanged"
- Parameter { name: "alignment"; type: "QQuickTextEdit::VAlignment" }
- }
- Signal {
- name: "textFormatChanged"
- Parameter { name: "textFormat"; type: "QQuickTextEdit::TextFormat" }
- }
- Signal {
- name: "readOnlyChanged"
- Parameter { name: "isReadOnly"; type: "bool" }
- }
- Signal {
- name: "cursorVisibleChanged"
- Parameter { name: "isCursorVisible"; type: "bool" }
- }
- Signal {
- name: "overwriteModeChanged"
- Parameter { name: "overwriteMode"; type: "bool" }
- }
- Signal {
- name: "activeFocusOnPressChanged"
- Parameter { name: "activeFocusOnPressed"; type: "bool" }
- }
- Signal {
- name: "persistentSelectionChanged"
- Parameter { name: "isPersistentSelection"; type: "bool" }
- }
- Signal {
- name: "textMarginChanged"
- Parameter { name: "textMargin"; type: "double" }
- }
- Signal {
- name: "selectByKeyboardChanged"
- revision: 1
- Parameter { name: "selectByKeyboard"; type: "bool" }
- }
- Signal {
- name: "selectByMouseChanged"
- Parameter { name: "selectByMouse"; type: "bool" }
- }
- Signal {
- name: "mouseSelectionModeChanged"
- Parameter { name: "mode"; type: "QQuickTextEdit::SelectionMode" }
- }
- Signal {
- name: "linkActivated"
- Parameter { name: "link"; type: "string" }
- }
- Signal {
- name: "linkHovered"
- revision: 2
- Parameter { name: "link"; type: "string" }
- }
- Signal { name: "editingFinished"; revision: 6 }
- Signal { name: "paddingChanged"; revision: 6 }
- Signal { name: "topPaddingChanged"; revision: 6 }
- Signal { name: "leftPaddingChanged"; revision: 6 }
- Signal { name: "rightPaddingChanged"; revision: 6 }
- Signal { name: "bottomPaddingChanged"; revision: 6 }
- Signal {
- name: "tabStopDistanceChanged"
- revision: 10
- Parameter { name: "distance"; type: "double" }
- }
- Method { name: "selectAll" }
- Method { name: "selectWord" }
- Method {
- name: "select"
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- }
- Method { name: "deselect" }
- Method {
- name: "isRightToLeft"
- type: "bool"
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- }
- Method { name: "cut" }
- Method { name: "copy" }
- Method { name: "paste" }
- Method { name: "undo" }
- Method { name: "redo" }
- Method {
- name: "insert"
- Parameter { name: "position"; type: "int" }
- Parameter { name: "text"; type: "string" }
- }
- Method {
- name: "remove"
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- }
- Method {
- name: "append"
- revision: 2
- Parameter { name: "text"; type: "string" }
- }
- Method { name: "clear"; revision: 7 }
- Method {
- name: "inputMethodQuery"
- revision: 4
- type: "QVariant"
- Parameter { name: "query"; type: "Qt::InputMethodQuery" }
- Parameter { name: "argument"; type: "QVariant" }
- }
- Method {
- name: "positionToRectangle"
- type: "QRectF"
- Parameter { type: "int" }
- }
- Method {
- name: "positionAt"
- type: "int"
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- Method {
- name: "moveCursorSelection"
- Parameter { name: "pos"; type: "int" }
- }
- Method {
- name: "moveCursorSelection"
- Parameter { name: "pos"; type: "int" }
- Parameter { name: "mode"; type: "SelectionMode" }
- }
- Method {
- name: "getText"
- type: "string"
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- }
- Method {
- name: "getFormattedText"
- type: "string"
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- }
- Method {
- name: "linkAt"
- revision: 3
- type: "string"
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- }
- Component {
- name: "QQuickTextInput"
- defaultProperty: "data"
- prototype: "QQuickImplicitSizeItem"
- exports: [
- "QtQuick/TextInput 2.0",
- "QtQuick/TextInput 2.2",
- "QtQuick/TextInput 2.4",
- "QtQuick/TextInput 2.6",
- "QtQuick/TextInput 2.7",
- "QtQuick/TextInput 2.9"
- ]
- exportMetaObjectRevisions: [0, 2, 4, 6, 7, 9]
- Enum {
- name: "EchoMode"
- values: {
- "Normal": 0,
- "NoEcho": 1,
- "Password": 2,
- "PasswordEchoOnEdit": 3
- }
- }
- Enum {
- name: "HAlignment"
- values: {
- "AlignLeft": 1,
- "AlignRight": 2,
- "AlignHCenter": 4
- }
- }
- Enum {
- name: "VAlignment"
- values: {
- "AlignTop": 32,
- "AlignBottom": 64,
- "AlignVCenter": 128
- }
- }
- Enum {
- name: "WrapMode"
- values: {
- "NoWrap": 0,
- "WordWrap": 1,
- "WrapAnywhere": 3,
- "WrapAtWordBoundaryOrAnywhere": 4,
- "Wrap": 4
- }
- }
- Enum {
- name: "SelectionMode"
- values: {
- "SelectCharacters": 0,
- "SelectWords": 1
- }
- }
- Enum {
- name: "CursorPosition"
- values: {
- "CursorBetweenCharacters": 0,
- "CursorOnCharacter": 1
- }
- }
- Enum {
- name: "RenderType"
- values: {
- "QtRendering": 0,
- "NativeRendering": 1
- }
- }
- Property { name: "text"; type: "string" }
- Property { name: "length"; type: "int"; isReadonly: true }
- Property { name: "color"; type: "QColor" }
- Property { name: "selectionColor"; type: "QColor" }
- Property { name: "selectedTextColor"; type: "QColor" }
- Property { name: "font"; type: "QFont" }
- Property { name: "horizontalAlignment"; type: "HAlignment" }
- Property { name: "effectiveHorizontalAlignment"; type: "HAlignment"; isReadonly: true }
- Property { name: "verticalAlignment"; type: "VAlignment" }
- Property { name: "wrapMode"; type: "WrapMode" }
- Property { name: "readOnly"; type: "bool" }
- Property { name: "cursorVisible"; type: "bool" }
- Property { name: "cursorPosition"; type: "int" }
- Property { name: "cursorRectangle"; type: "QRectF"; isReadonly: true }
- Property { name: "cursorDelegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "overwriteMode"; type: "bool" }
- Property { name: "selectionStart"; type: "int"; isReadonly: true }
- Property { name: "selectionEnd"; type: "int"; isReadonly: true }
- Property { name: "selectedText"; type: "string"; isReadonly: true }
- Property { name: "maximumLength"; type: "int" }
- Property { name: "validator"; type: "QValidator"; isPointer: true }
- Property { name: "inputMask"; type: "string" }
- Property { name: "inputMethodHints"; type: "Qt::InputMethodHints" }
- Property { name: "acceptableInput"; type: "bool"; isReadonly: true }
- Property { name: "echoMode"; type: "EchoMode" }
- Property { name: "activeFocusOnPress"; type: "bool" }
- Property { name: "passwordCharacter"; type: "string" }
- Property { name: "passwordMaskDelay"; revision: 4; type: "int" }
- Property { name: "displayText"; type: "string"; isReadonly: true }
- Property { name: "preeditText"; revision: 7; type: "string"; isReadonly: true }
- Property { name: "autoScroll"; type: "bool" }
- Property { name: "selectByMouse"; type: "bool" }
- Property { name: "mouseSelectionMode"; type: "SelectionMode" }
- Property { name: "persistentSelection"; type: "bool" }
- Property { name: "canPaste"; type: "bool"; isReadonly: true }
- Property { name: "canUndo"; type: "bool"; isReadonly: true }
- Property { name: "canRedo"; type: "bool"; isReadonly: true }
- Property { name: "inputMethodComposing"; type: "bool"; isReadonly: true }
- Property { name: "contentWidth"; type: "double"; isReadonly: true }
- Property { name: "contentHeight"; type: "double"; isReadonly: true }
- Property { name: "renderType"; type: "RenderType" }
- Property { name: "padding"; revision: 6; type: "double" }
- Property { name: "topPadding"; revision: 6; type: "double" }
- Property { name: "leftPadding"; revision: 6; type: "double" }
- Property { name: "rightPadding"; revision: 6; type: "double" }
- Property { name: "bottomPadding"; revision: 6; type: "double" }
- Signal { name: "accepted" }
- Signal { name: "editingFinished"; revision: 2 }
- Signal { name: "textEdited"; revision: 9 }
- Signal {
- name: "fontChanged"
- Parameter { name: "font"; type: "QFont" }
- }
- Signal {
- name: "horizontalAlignmentChanged"
- Parameter { name: "alignment"; type: "QQuickTextInput::HAlignment" }
- }
- Signal {
- name: "verticalAlignmentChanged"
- Parameter { name: "alignment"; type: "QQuickTextInput::VAlignment" }
- }
- Signal {
- name: "readOnlyChanged"
- Parameter { name: "isReadOnly"; type: "bool" }
- }
- Signal {
- name: "cursorVisibleChanged"
- Parameter { name: "isCursorVisible"; type: "bool" }
- }
- Signal {
- name: "overwriteModeChanged"
- Parameter { name: "overwriteMode"; type: "bool" }
- }
- Signal {
- name: "maximumLengthChanged"
- Parameter { name: "maximumLength"; type: "int" }
- }
- Signal {
- name: "inputMaskChanged"
- Parameter { name: "inputMask"; type: "string" }
- }
- Signal {
- name: "echoModeChanged"
- Parameter { name: "echoMode"; type: "QQuickTextInput::EchoMode" }
- }
- Signal {
- name: "passwordMaskDelayChanged"
- revision: 4
- Parameter { name: "delay"; type: "int" }
- }
- Signal { name: "preeditTextChanged"; revision: 7 }
- Signal {
- name: "activeFocusOnPressChanged"
- Parameter { name: "activeFocusOnPress"; type: "bool" }
- }
- Signal {
- name: "autoScrollChanged"
- Parameter { name: "autoScroll"; type: "bool" }
- }
- Signal {
- name: "selectByMouseChanged"
- Parameter { name: "selectByMouse"; type: "bool" }
- }
- Signal {
- name: "mouseSelectionModeChanged"
- Parameter { name: "mode"; type: "QQuickTextInput::SelectionMode" }
- }
- Signal { name: "contentSizeChanged" }
- Signal { name: "paddingChanged"; revision: 6 }
- Signal { name: "topPaddingChanged"; revision: 6 }
- Signal { name: "leftPaddingChanged"; revision: 6 }
- Signal { name: "rightPaddingChanged"; revision: 6 }
- Signal { name: "bottomPaddingChanged"; revision: 6 }
- Method { name: "selectAll" }
- Method { name: "selectWord" }
- Method {
- name: "select"
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- }
- Method { name: "deselect" }
- Method {
- name: "isRightToLeft"
- type: "bool"
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- }
- Method { name: "cut" }
- Method { name: "copy" }
- Method { name: "paste" }
- Method { name: "undo" }
- Method { name: "redo" }
- Method {
- name: "insert"
- Parameter { name: "position"; type: "int" }
- Parameter { name: "text"; type: "string" }
- }
- Method {
- name: "remove"
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- }
- Method {
- name: "ensureVisible"
- revision: 4
- Parameter { name: "position"; type: "int" }
- }
- Method { name: "clear"; revision: 7 }
- Method {
- name: "positionAt"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "positionToRectangle"
- type: "QRectF"
- Parameter { name: "pos"; type: "int" }
- }
- Method {
- name: "moveCursorSelection"
- Parameter { name: "pos"; type: "int" }
- }
- Method {
- name: "moveCursorSelection"
- Parameter { name: "pos"; type: "int" }
- Parameter { name: "mode"; type: "SelectionMode" }
- }
- Method {
- name: "inputMethodQuery"
- revision: 4
- type: "QVariant"
- Parameter { name: "query"; type: "Qt::InputMethodQuery" }
- Parameter { name: "argument"; type: "QVariant" }
- }
- Method {
- name: "getText"
- type: "string"
- Parameter { name: "start"; type: "int" }
- Parameter { name: "end"; type: "int" }
- }
- }
- Component {
- name: "QQuickTextLine"
- prototype: "QObject"
- Property { name: "number"; type: "int"; isReadonly: true }
- Property { name: "width"; type: "double" }
- Property { name: "height"; type: "double" }
- Property { name: "x"; type: "double" }
- Property { name: "y"; type: "double" }
- }
- Component {
- name: "QQuickTextMetrics"
- prototype: "QObject"
- exports: ["QtQuick/TextMetrics 2.4"]
- exportMetaObjectRevisions: [0]
- Property { name: "font"; type: "QFont" }
- Property { name: "text"; type: "string" }
- Property { name: "advanceWidth"; type: "double"; isReadonly: true }
- Property { name: "boundingRect"; type: "QRectF"; isReadonly: true }
- Property { name: "width"; type: "double"; isReadonly: true }
- Property { name: "height"; type: "double"; isReadonly: true }
- Property { name: "tightBoundingRect"; type: "QRectF"; isReadonly: true }
- Property { name: "elidedText"; type: "string"; isReadonly: true }
- Property { name: "elide"; type: "Qt::TextElideMode" }
- Property { name: "elideWidth"; type: "double" }
- Signal { name: "metricsChanged" }
- }
- Component {
- name: "QQuickTouchPoint"
- prototype: "QObject"
- exports: ["QtQuick/TouchPoint 2.0", "QtQuick/TouchPoint 2.9"]
- exportMetaObjectRevisions: [0, 0]
- Property { name: "pointId"; type: "int"; isReadonly: true }
- Property { name: "uniqueId"; revision: 9; type: "QPointingDeviceUniqueId"; isReadonly: true }
- Property { name: "pressed"; type: "bool"; isReadonly: true }
- Property { name: "x"; type: "double"; isReadonly: true }
- Property { name: "y"; type: "double"; isReadonly: true }
- Property { name: "ellipseDiameters"; revision: 9; type: "QSizeF"; isReadonly: true }
- Property { name: "pressure"; type: "double"; isReadonly: true }
- Property { name: "rotation"; revision: 9; type: "double"; isReadonly: true }
- Property { name: "velocity"; type: "QVector2D"; isReadonly: true }
- Property { name: "area"; type: "QRectF"; isReadonly: true }
- Property { name: "startX"; type: "double"; isReadonly: true }
- Property { name: "startY"; type: "double"; isReadonly: true }
- Property { name: "previousX"; type: "double"; isReadonly: true }
- Property { name: "previousY"; type: "double"; isReadonly: true }
- Property { name: "sceneX"; type: "double"; isReadonly: true }
- Property { name: "sceneY"; type: "double"; isReadonly: true }
- Signal { name: "uniqueIdChanged"; revision: 9 }
- Signal { name: "ellipseDiametersChanged"; revision: 9 }
- Signal { name: "rotationChanged"; revision: 9 }
- }
- Component { name: "QQuickTransform"; prototype: "QObject" }
- Component {
- name: "QQuickTransition"
- defaultProperty: "animations"
- prototype: "QObject"
- exports: ["QtQuick/Transition 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "from"; type: "string" }
- Property { name: "to"; type: "string" }
- Property { name: "reversible"; type: "bool" }
- Property { name: "running"; type: "bool"; isReadonly: true }
- Property { name: "animations"; type: "QQuickAbstractAnimation"; isList: true; isReadonly: true }
- Property { name: "enabled"; type: "bool" }
- }
- Component {
- name: "QQuickTranslate"
- prototype: "QQuickTransform"
- exports: ["QtQuick/Translate 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "x"; type: "double" }
- Property { name: "y"; type: "double" }
- }
- Component {
- name: "QQuickUniformAnimator"
- prototype: "QQuickAnimator"
- exports: ["QtQuick/UniformAnimator 2.2"]
- exportMetaObjectRevisions: [0]
- Property { name: "uniform"; type: "string" }
- Signal {
- name: "uniformChanged"
- Parameter { type: "string" }
- }
- }
- Component {
- name: "QQuickVector3dAnimation"
- prototype: "QQuickPropertyAnimation"
- exports: ["QtQuick/Vector3dAnimation 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "from"; type: "QVector3D" }
- Property { name: "to"; type: "QVector3D" }
- }
- Component {
- name: "QQuickViewSection"
- prototype: "QObject"
- exports: ["QtQuick/ViewSection 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "SectionCriteria"
- values: {
- "FullString": 0,
- "FirstCharacter": 1
- }
- }
- Enum {
- name: "LabelPositioning"
- values: {
- "InlineLabels": 1,
- "CurrentLabelAtStart": 2,
- "NextLabelAtEnd": 4
- }
- }
- Property { name: "property"; type: "string" }
- Property { name: "criteria"; type: "SectionCriteria" }
- Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
- Property { name: "labelPositioning"; type: "int" }
- Signal { name: "sectionsChanged" }
- }
- Component {
- name: "QQuickViewTransitionAttached"
- prototype: "QObject"
- exports: ["QtQuick/ViewTransition 2.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "index"; type: "int"; isReadonly: true }
- Property { name: "item"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "destination"; type: "QPointF"; isReadonly: true }
- Property { name: "targetIndexes"; type: "QList<int>"; isReadonly: true }
- Property { name: "targetItems"; type: "QObject"; isList: true; isReadonly: true }
- }
- Component {
- name: "QQuickWheelEvent"
- prototype: "QObject"
- Property { name: "x"; type: "double"; isReadonly: true }
- Property { name: "y"; type: "double"; isReadonly: true }
- Property { name: "angleDelta"; type: "QPoint"; isReadonly: true }
- Property { name: "pixelDelta"; type: "QPoint"; isReadonly: true }
- Property { name: "buttons"; type: "int"; isReadonly: true }
- Property { name: "modifiers"; type: "int"; isReadonly: true }
- Property { name: "inverted"; type: "bool"; isReadonly: true }
- Property { name: "accepted"; type: "bool" }
- }
- Component {
- name: "QQuickWheelHandler"
- prototype: "QQuickSinglePointHandler"
- exports: ["QtQuick/WheelHandler 2.14"]
- exportMetaObjectRevisions: [0]
- Property { name: "orientation"; type: "Qt::Orientation" }
- Property { name: "invertible"; type: "bool" }
- Property { name: "activeTimeout"; type: "double" }
- Property { name: "rotation"; type: "double" }
- Property { name: "rotationScale"; type: "double" }
- Property { name: "property"; type: "string" }
- Property { name: "targetScaleMultiplier"; type: "double" }
- Property { name: "targetTransformAroundCursor"; type: "bool" }
- Signal {
- name: "wheel"
- Parameter { name: "event"; type: "QQuickPointerScrollEvent"; isPointer: true }
- }
- }
- Component {
- name: "QQuickWorkerScript"
- prototype: "QObject"
- exports: ["QtQuick/WorkerScript 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "source"; type: "QUrl" }
- Signal {
- name: "message"
- Parameter { name: "messageObject"; type: "QJSValue" }
- }
- Method {
- name: "sendMessage"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- }
- Component {
- name: "QQuickXAnimator"
- prototype: "QQuickAnimator"
- exports: ["QtQuick/XAnimator 2.2"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickYAnimator"
- prototype: "QQuickAnimator"
- exports: ["QtQuick/YAnimator 2.2"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QRegExpValidator"
- prototype: "QValidator"
- exports: ["QtQuick/RegExpValidator 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "regExp"; type: "QRegExp" }
- Signal {
- name: "regExpChanged"
- Parameter { name: "regExp"; type: "QRegExp" }
- }
- }
- Component {
- name: "QRegularExpressionValidator"
- prototype: "QValidator"
- exports: ["QtQuick/RegularExpressionValidator 2.14"]
- exportMetaObjectRevisions: [0]
- Property { name: "regularExpression"; type: "QRegularExpression" }
- Signal {
- name: "regularExpressionChanged"
- Parameter { name: "re"; type: "QRegularExpression" }
- }
- Method {
- name: "setRegularExpression"
- Parameter { name: "re"; type: "QRegularExpression" }
- }
- }
- Component {
- name: "QValidator"
- prototype: "QObject"
- Enum {
- name: "State"
- values: {
- "Invalid": 0,
- "Intermediate": 1,
- "Acceptable": 2
- }
- }
- Signal { name: "changed" }
- }
-}
diff --git a/src/imports/settings/plugin.cpp b/src/imports/settings/plugin.cpp
index eb7d5027a4..e8e640412b 100644
--- a/src/imports/settings/plugin.cpp
+++ b/src/imports/settings/plugin.cpp
@@ -42,20 +42,20 @@
#include "qqmlsettings_p.h"
+extern void qml_register_types_Qt_labs_settings();
+
QT_BEGIN_NAMESPACE
-class QmlSettingsPlugin : public QQmlExtensionPlugin
+class QmlSettingsPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QmlSettingsPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
+ QmlSettingsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- Q_ASSERT(QByteArray(uri) == QByteArray("Qt.labs.settings"));
- qmlRegisterType<QQmlSettings>(uri, 1, 0, "Settings");
- qmlRegisterModule(uri, 1, 1); // QTBUG-73239
+ volatile auto registration = &qml_register_types_Qt_labs_settings;
+ Q_UNUSED(registration);
}
};
diff --git a/src/imports/settings/plugins.qmltypes b/src/imports/settings/plugins.qmltypes
deleted file mode 100644
index bbc5c1cf8f..0000000000
--- a/src/imports/settings/plugins.qmltypes
+++ /dev/null
@@ -1,36 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt.labs.settings 1.1'
-
-Module {
- dependencies: []
- Component {
- name: "QQmlSettings"
- prototype: "QObject"
- exports: ["Qt.labs.settings/Settings 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "category"; type: "string" }
- Property { name: "fileName"; type: "string" }
- Method {
- name: "value"
- type: "QVariant"
- Parameter { name: "key"; type: "string" }
- Parameter { name: "defaultValue"; type: "QVariant" }
- }
- Method {
- name: "value"
- type: "QVariant"
- Parameter { name: "key"; type: "string" }
- }
- Method {
- name: "setValue"
- Parameter { name: "key"; type: "string" }
- Parameter { name: "value"; type: "QVariant" }
- }
- Method { name: "sync" }
- }
-}
diff --git a/src/imports/settings/qqmlsettings.cpp b/src/imports/settings/qqmlsettings.cpp
index d43f9bafb7..de45f87638 100644
--- a/src/imports/settings/qqmlsettings.cpp
+++ b/src/imports/settings/qqmlsettings.cpp
@@ -335,7 +335,7 @@ void QQmlSettingsPrivate::load()
const QVariant currentValue = instance()->value(property.name(), previousValue);
if (!currentValue.isNull() && (!previousValue.isValid()
- || (currentValue.canConvert(previousValue.type()) && previousValue != currentValue))) {
+ || (currentValue.canConvert(previousValue.userType()) && previousValue != currentValue))) {
property.write(q, currentValue);
qCDebug(lcSettings) << "QQmlSettings: load" << property.name() << "setting:" << currentValue << "default:" << previousValue;
}
diff --git a/src/imports/settings/qqmlsettings_p.h b/src/imports/settings/qqmlsettings_p.h
index a86c8b4751..3f1b83f541 100644
--- a/src/imports/settings/qqmlsettings_p.h
+++ b/src/imports/settings/qqmlsettings_p.h
@@ -66,6 +66,7 @@ class QQmlSettings : public QObject, public QQmlParserStatus
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QString category READ category WRITE setCategory FINAL)
Q_PROPERTY(QString fileName READ fileName WRITE setFileName FINAL)
+ QML_NAMED_ELEMENT(Settings)
public:
explicit QQmlSettings(QObject *parent = 0);
diff --git a/src/imports/settings/settings.pro b/src/imports/settings/settings.pro
index 816a6a9fef..d8062a2e55 100644
--- a/src/imports/settings/settings.pro
+++ b/src/imports/settings/settings.pro
@@ -12,4 +12,6 @@ SOURCES += \
plugin.cpp \
qqmlsettings.cpp
+CONFIG += qmltypes install_qmltypes
+
load(qml_plugin)
diff --git a/src/imports/shapes/plugin.cpp b/src/imports/shapes/plugin.cpp
index 0679a70630..48eecbd8f1 100644
--- a/src/imports/shapes/plugin.cpp
+++ b/src/imports/shapes/plugin.cpp
@@ -52,26 +52,14 @@ public:
QmlShapesPlugin(QObject *parent = nullptr)
: QQmlExtensionPlugin(parent)
{
+ volatile auto registration = &qml_register_types_QtQuick_Shapes;
+ Q_UNUSED(registration);
}
void registerTypes(const char *uri) override
{
- Q_ASSERT(QByteArray(uri) == QByteArray("QtQuick.Shapes"));
- qmlRegisterType<QQuickShape>(uri, 1, 0, "Shape");
- qmlRegisterType<QQuickShapePath>(uri, 1, 0, "ShapePath");
- qmlRegisterUncreatableType<QQuickShapeGradient>(uri, 1, 0, "ShapeGradient", QQuickShapeGradient::tr("ShapeGradient is an abstract base class"));
- qmlRegisterType<QQuickShapeLinearGradient>(uri, 1, 0, "LinearGradient");
- qmlRegisterType<QQuickShapeRadialGradient>(uri, 1, 0, "RadialGradient");
- qmlRegisterType<QQuickShapeConicalGradient>(uri, 1, 0, "ConicalGradient");
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions
- qmlRegisterModule(uri, 1, QT_VERSION_MINOR);
-
- // revision in Qt 5.11: added containsMode property
- qmlRegisterType<QQuickShape, 11>(uri, 1, 11, "Shape");
-
- // revision in Qt 5.14: added scale property
- qmlRegisterType<QQuickShapePath, 14>(uri, 1, 14, "ShapePath"); // QTBUG-61942
+ Q_UNUSED(uri);
+ QQuickShapesModule::defineModule();
}
};
diff --git a/src/imports/shapes/plugins.qmltypes b/src/imports/shapes/plugins.qmltypes
deleted file mode 100644
index cd779e7149..0000000000
--- a/src/imports/shapes/plugins.qmltypes
+++ /dev/null
@@ -1,154 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Shapes 1.14'
-
-Module {
- dependencies: ["QtQuick 2.0"]
- Component {
- name: "QQuickShape"
- defaultProperty: "data"
- prototype: "QQuickItem"
- exports: ["QtQuick.Shapes/Shape 1.0", "QtQuick.Shapes/Shape 1.11"]
- exportMetaObjectRevisions: [0, 11]
- Enum {
- name: "RendererType"
- values: {
- "UnknownRenderer": 0,
- "GeometryRenderer": 1,
- "NvprRenderer": 2,
- "SoftwareRenderer": 3
- }
- }
- Enum {
- name: "Status"
- values: {
- "Null": 0,
- "Ready": 1,
- "Processing": 2
- }
- }
- Enum {
- name: "ContainsMode"
- values: {
- "BoundingRectContains": 0,
- "FillContains": 1
- }
- }
- Property { name: "rendererType"; type: "RendererType"; isReadonly: true }
- Property { name: "asynchronous"; type: "bool" }
- Property { name: "vendorExtensionsEnabled"; type: "bool" }
- Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "containsMode"; revision: 11; type: "ContainsMode" }
- Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
- Signal { name: "rendererChanged" }
- Signal { name: "containsModeChanged"; revision: 11 }
- }
- Component {
- name: "QQuickShapeConicalGradient"
- defaultProperty: "stops"
- prototype: "QQuickShapeGradient"
- exports: ["QtQuick.Shapes/ConicalGradient 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "centerX"; type: "double" }
- Property { name: "centerY"; type: "double" }
- Property { name: "angle"; type: "double" }
- }
- Component {
- name: "QQuickShapeGradient"
- defaultProperty: "stops"
- prototype: "QQuickGradient"
- exports: ["QtQuick.Shapes/ShapeGradient 1.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "SpreadMode"
- values: {
- "PadSpread": 0,
- "RepeatSpread": 1,
- "ReflectSpread": 2
- }
- }
- Property { name: "spread"; type: "SpreadMode" }
- }
- Component {
- name: "QQuickShapeLinearGradient"
- defaultProperty: "stops"
- prototype: "QQuickShapeGradient"
- exports: ["QtQuick.Shapes/LinearGradient 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "x1"; type: "double" }
- Property { name: "y1"; type: "double" }
- Property { name: "x2"; type: "double" }
- Property { name: "y2"; type: "double" }
- }
- Component {
- name: "QQuickShapePath"
- defaultProperty: "pathElements"
- prototype: "QQuickPath"
- exports: [
- "QtQuick.Shapes/ShapePath 1.0",
- "QtQuick.Shapes/ShapePath 1.14"
- ]
- exportMetaObjectRevisions: [0, 14]
- Enum {
- name: "FillRule"
- values: {
- "OddEvenFill": 0,
- "WindingFill": 1
- }
- }
- Enum {
- name: "JoinStyle"
- values: {
- "MiterJoin": 0,
- "BevelJoin": 64,
- "RoundJoin": 128
- }
- }
- Enum {
- name: "CapStyle"
- values: {
- "FlatCap": 0,
- "SquareCap": 16,
- "RoundCap": 32
- }
- }
- Enum {
- name: "StrokeStyle"
- values: {
- "SolidLine": 1,
- "DashLine": 2
- }
- }
- Property { name: "strokeColor"; type: "QColor" }
- Property { name: "strokeWidth"; type: "double" }
- Property { name: "fillColor"; type: "QColor" }
- Property { name: "fillRule"; type: "FillRule" }
- Property { name: "joinStyle"; type: "JoinStyle" }
- Property { name: "miterLimit"; type: "int" }
- Property { name: "capStyle"; type: "CapStyle" }
- Property { name: "strokeStyle"; type: "StrokeStyle" }
- Property { name: "dashOffset"; type: "double" }
- Property { name: "dashPattern"; type: "QVector<qreal>" }
- Property { name: "fillGradient"; type: "QQuickShapeGradient"; isPointer: true }
- Property { name: "scale"; revision: 14; type: "QSizeF" }
- Signal { name: "shapePathChanged" }
- }
- Component {
- name: "QQuickShapeRadialGradient"
- defaultProperty: "stops"
- prototype: "QQuickShapeGradient"
- exports: ["QtQuick.Shapes/RadialGradient 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "centerX"; type: "double" }
- Property { name: "centerY"; type: "double" }
- Property { name: "centerRadius"; type: "double" }
- Property { name: "focalX"; type: "double" }
- Property { name: "focalY"; type: "double" }
- Property { name: "focalRadius"; type: "double" }
- }
-}
diff --git a/src/imports/sharedimage/plugin.cpp b/src/imports/sharedimage/plugin.cpp
index b75e38e303..d7c2ef8d17 100644
--- a/src/imports/sharedimage/plugin.cpp
+++ b/src/imports/sharedimage/plugin.cpp
@@ -99,19 +99,19 @@
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 QQmlExtensionPlugin
+class QtQuickSharedImagePlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQuickSharedImagePlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) {}
-
- void registerTypes(const char *uri) override
+ QtQuickSharedImagePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- Q_ASSERT(uri == QStringLiteral("Qt.labs.sharedimage"));
- qmlRegisterModule(uri, 1, 0);
+ 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/sharedimage/plugins.qmltypes b/src/imports/sharedimage/plugins.qmltypes
deleted file mode 100644
index 29639e7697..0000000000
--- a/src/imports/sharedimage/plugins.qmltypes
+++ /dev/null
@@ -1,11 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt.labs.sharedimage 1.0'
-
-Module {
- dependencies: ["QtQuick 2.0"]
-}
diff --git a/src/imports/sharedimage/sharedimage.pro b/src/imports/sharedimage/sharedimage.pro
index 46a6a56ca5..8ab4f10405 100644
--- a/src/imports/sharedimage/sharedimage.pro
+++ b/src/imports/sharedimage/sharedimage.pro
@@ -14,4 +14,5 @@ HEADERS += \
sharedimageprovider.h \
qsharedimageloader_p.h
+CONFIG += qmltypes install_qmltypes
load(qml_plugin)
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 974d8a8fac..117a358e53 100644
--- a/src/imports/statemachine/finalstate.h
+++ b/src/imports/statemachine/finalstate.h
@@ -45,6 +45,7 @@
#include <QtCore/QFinalState>
#include <QtQml/QQmlListProperty>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -54,6 +55,7 @@ class FinalState : public QFinalState
Q_OBJECT
Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged)
Q_CLASSINFO("DefaultProperty", "children")
+ QML_ELEMENT
public:
explicit FinalState(QState *parent = 0);
@@ -64,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 bf7499b31a..c370504029 100644
--- a/src/imports/statemachine/plugin.cpp
+++ b/src/imports/statemachine/plugin.cpp
@@ -42,35 +42,26 @@
#include "state.h"
#include "statemachine.h"
#include "timeouttransition.h"
+#include "statemachineforeign.h"
#include <QHistoryState>
#include <QQmlExtensionPlugin>
#include <qqml.h>
+extern void qml_register_types_QtQml_StateMachine();
+
QT_BEGIN_NAMESPACE
-class QtQmlStateMachinePlugin : public QQmlExtensionPlugin
+class QtQmlStateMachinePlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQmlStateMachinePlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
+ QtQmlStateMachinePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- qmlRegisterType<State>(uri, 1, 0, "State");
- qmlRegisterType<StateMachine>(uri, 1, 0, "StateMachine");
- qmlRegisterType<QHistoryState>(uri, 1, 0, "HistoryState");
- qmlRegisterType<FinalState>(uri, 1, 0, "FinalState");
- qmlRegisterUncreatableType<QState>(uri, 1, 0, "QState", "Don't use this, use State instead");
- qmlRegisterUncreatableType<QAbstractState>(uri, 1, 0, "QAbstractState", "Don't use this, use State instead");
- qmlRegisterUncreatableType<QSignalTransition>(uri, 1, 0, "QSignalTransition", "Don't use this, use SignalTransition instead");
- qmlRegisterCustomType<SignalTransition>(uri, 1, 0, "SignalTransition", new SignalTransitionParser);
- qmlRegisterType<TimeoutTransition>(uri, 1, 0, "TimeoutTransition");
- qmlProtectModule(uri, 1);
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 1, QT_VERSION_MINOR);
+ volatile auto registration = &qml_register_types_QtQml_StateMachine;
+ Q_UNUSED(registration);
}
};
diff --git a/src/imports/statemachine/plugins.qmltypes b/src/imports/statemachine/plugins.qmltypes
deleted file mode 100644
index 541b1cc114..0000000000
--- a/src/imports/statemachine/plugins.qmltypes
+++ /dev/null
@@ -1,173 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.StateMachine 1.14'
-
-Module {
- dependencies: []
- Component {
- name: "FinalState"
- defaultProperty: "children"
- prototype: "QFinalState"
- exports: ["QtQml.StateMachine/FinalState 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "children"; type: "QObject"; isList: true; isReadonly: true }
- }
- Component {
- name: "QAbstractState"
- prototype: "QObject"
- exports: ["QtQml.StateMachine/QAbstractState 1.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "active"; type: "bool"; isReadonly: true }
- Signal { name: "entered" }
- Signal { name: "exited" }
- Signal {
- name: "activeChanged"
- Parameter { name: "active"; type: "bool" }
- }
- }
- Component {
- name: "QAbstractTransition"
- prototype: "QObject"
- Enum {
- name: "TransitionType"
- values: {
- "ExternalTransition": 0,
- "InternalTransition": 1
- }
- }
- Property { name: "sourceState"; type: "QState"; isReadonly: true; isPointer: true }
- Property { name: "targetState"; type: "QAbstractState"; isPointer: true }
- Property { name: "targetStates"; type: "QList<QAbstractState*>" }
- Property { name: "transitionType"; revision: 1; type: "TransitionType" }
- Signal { name: "triggered" }
- }
- Component { name: "QFinalState"; prototype: "QAbstractState" }
- Component {
- name: "QHistoryState"
- prototype: "QAbstractState"
- exports: ["QtQml.StateMachine/HistoryState 1.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "HistoryType"
- values: {
- "ShallowHistory": 0,
- "DeepHistory": 1
- }
- }
- Property { name: "defaultState"; type: "QAbstractState"; isPointer: true }
- Property { name: "defaultTransition"; type: "QAbstractTransition"; isPointer: true }
- Property { name: "historyType"; type: "HistoryType" }
- }
- Component {
- name: "QSignalTransition"
- prototype: "QAbstractTransition"
- exports: ["QtQml.StateMachine/QSignalTransition 1.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "senderObject"; type: "QObject"; isPointer: true }
- Property { name: "signal"; type: "QByteArray" }
- }
- Component {
- name: "QState"
- prototype: "QAbstractState"
- exports: ["QtQml.StateMachine/QState 1.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "ChildMode"
- values: {
- "ExclusiveStates": 0,
- "ParallelStates": 1
- }
- }
- Enum {
- name: "RestorePolicy"
- values: {
- "DontRestoreProperties": 0,
- "RestoreProperties": 1
- }
- }
- Property { name: "initialState"; type: "QAbstractState"; isPointer: true }
- Property { name: "errorState"; type: "QAbstractState"; isPointer: true }
- Property { name: "childMode"; type: "ChildMode" }
- Signal { name: "finished" }
- Signal { name: "propertiesAssigned" }
- }
- Component {
- name: "QStateMachine"
- prototype: "QState"
- Property { name: "errorString"; type: "string"; isReadonly: true }
- Property { name: "globalRestorePolicy"; type: "QState::RestorePolicy" }
- Property { name: "running"; type: "bool" }
- Property { name: "animated"; type: "bool" }
- Signal { name: "started" }
- Signal { name: "stopped" }
- Signal {
- name: "runningChanged"
- Parameter { name: "running"; type: "bool" }
- }
- Method { name: "start" }
- Method { name: "stop" }
- Method {
- name: "setRunning"
- Parameter { name: "running"; type: "bool" }
- }
- }
- Component {
- name: "QTimer"
- prototype: "QObject"
- Property { name: "singleShot"; type: "bool" }
- Property { name: "interval"; type: "int" }
- Property { name: "remainingTime"; type: "int"; isReadonly: true }
- Property { name: "timerType"; type: "Qt::TimerType" }
- Property { name: "active"; type: "bool"; isReadonly: true }
- Signal { name: "timeout" }
- Method {
- name: "start"
- Parameter { name: "msec"; type: "int" }
- }
- Method { name: "start" }
- Method { name: "stop" }
- }
- Component {
- name: "SignalTransition"
- prototype: "QSignalTransition"
- exports: ["QtQml.StateMachine/SignalTransition 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "signal"; type: "QJSValue" }
- Property { name: "guard"; type: "QQmlScriptString" }
- Signal { name: "invokeYourself" }
- Signal { name: "qmlSignalChanged" }
- Method { name: "invoke" }
- }
- Component {
- name: "State"
- defaultProperty: "children"
- prototype: "QState"
- exports: ["QtQml.StateMachine/State 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "children"; type: "QObject"; isList: true; isReadonly: true }
- }
- Component {
- name: "StateMachine"
- defaultProperty: "children"
- prototype: "QStateMachine"
- exports: ["QtQml.StateMachine/StateMachine 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "children"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "running"; type: "bool" }
- Signal { name: "qmlRunningChanged" }
- }
- Component {
- name: "TimeoutTransition"
- prototype: "QSignalTransition"
- exports: ["QtQml.StateMachine/TimeoutTransition 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "timeout"; type: "int" }
- }
-}
diff --git a/src/imports/statemachine/signaltransition.cpp b/src/imports/statemachine/signaltransition.cpp
index 468f2020c7..69edaa4e48 100644
--- a/src/imports/statemachine/signaltransition.cpp
+++ b/src/imports/statemachine/signaltransition.cpp
@@ -268,8 +268,6 @@ void SignalTransitionParser::applyBindings(
\qmlsignal QAbstractTransition::triggered()
This signal is emitted when the transition has been triggered.
-
- The corresponding handler is \c onTriggered.
*/
/*!
diff --git a/src/imports/statemachine/signaltransition.h b/src/imports/statemachine/signaltransition.h
index f005c5e9b1..748e230b3e 100644
--- a/src/imports/statemachine/signaltransition.h
+++ b/src/imports/statemachine/signaltransition.h
@@ -57,6 +57,7 @@ class SignalTransition : public QSignalTransition, public QQmlParserStatus
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QJSValue signal READ signal WRITE setSignal NOTIFY qmlSignalChanged)
Q_PROPERTY(QQmlScriptString guard READ guard WRITE setGuard NOTIFY guardChanged)
+ QML_ELEMENT
public:
explicit SignalTransition(QState *parent = nullptr);
@@ -101,6 +102,12 @@ public:
void applyBindings(QObject *object, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
};
+template<>
+inline QQmlCustomParser *qmlCreateCustomParser<SignalTransition>()
+{
+ return new SignalTransitionParser;
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/imports/statemachine/state.cpp b/src/imports/statemachine/state.cpp
index af76087256..ff0f55f197 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);
}
/*!
@@ -95,8 +97,6 @@ QQmlListProperty<QObject> State::children()
This signal is emitted when the State becomes active.
- The corresponding handler is \c onEntered.
-
\sa active, exited
*/
@@ -105,8 +105,6 @@ QQmlListProperty<QObject> State::children()
This signal is emitted when the State becomes inactive.
- The corresponding handler is \c onExited.
-
\sa active, entered
*/
@@ -119,7 +117,6 @@ QQmlListProperty<QObject> State::children()
\brief Provides a general-purpose state for StateMachine.
-
State objects can have child states as well as transitions to other
states. State is part of \l{The Declarative State Machine Framework}.
@@ -178,8 +175,6 @@ QQmlListProperty<QObject> State::children()
This signal is emitted when a final child state of this state is entered.
- The corresponding handler is \c onFinished.
-
\sa QAbstractState::active, QAbstractState::entered, QAbstractState::exited
*/
diff --git a/src/imports/statemachine/state.h b/src/imports/statemachine/state.h
index 8e8cefab19..68184775ab 100644
--- a/src/imports/statemachine/state.h
+++ b/src/imports/statemachine/state.h
@@ -45,6 +45,7 @@
#include <QtCore/QState>
#include <QtQml/QQmlParserStatus>
#include <QtQml/QQmlListProperty>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -54,6 +55,7 @@ class State : public QState, public QQmlParserStatus
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged)
Q_CLASSINFO("DefaultProperty", "children")
+ QML_ELEMENT
public:
explicit State(QState *parent = 0);
@@ -67,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..de6c84227d 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);
}
/*!
@@ -209,8 +211,6 @@ QQmlListProperty<QObject> StateMachine::children()
This signal is emitted when the state machine has entered its initial state
(State::initialState).
- The corresponding handler is \c onStarted.
-
\sa running, start(), State::finished
*/
@@ -228,8 +228,6 @@ QQmlListProperty<QObject> StateMachine::children()
This signal is emitted when the state machine has stopped.
- The corresponding handler is \c onStopped.
-
\sa running, stop(), State::finished
*/
diff --git a/src/imports/statemachine/statemachine.h b/src/imports/statemachine/statemachine.h
index 1fa7a9da43..cc0360db54 100644
--- a/src/imports/statemachine/statemachine.h
+++ b/src/imports/statemachine/statemachine.h
@@ -45,6 +45,7 @@
#include <QtCore/QStateMachine>
#include <QtQml/QQmlParserStatus>
#include <QtQml/QQmlListProperty>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -58,6 +59,7 @@ class StateMachine : public QStateMachine, public QQmlParserStatus
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY qmlRunningChanged)
Q_CLASSINFO("DefaultProperty", "children")
+ QML_ELEMENT
public:
explicit StateMachine(QObject *parent = 0);
@@ -80,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/statemachine/statemachine.pro b/src/imports/statemachine/statemachine.pro
index 926a9d4a5e..d4977d8eb8 100644
--- a/src/imports/statemachine/statemachine.pro
+++ b/src/imports/statemachine/statemachine.pro
@@ -19,6 +19,9 @@ HEADERS = \
$$PWD/signaltransition.h \
$$PWD/state.h \
$$PWD/statemachine.h \
- $$PWD/timeouttransition.h
+ $$PWD/timeouttransition.h \
+ $$PWD/statemachineforeign.h
+
+CONFIG += qmltypes install_qmltypes
load(qml_plugin)
diff --git a/src/imports/statemachine/statemachineforeign.h b/src/imports/statemachine/statemachineforeign.h
new file mode 100644
index 0000000000..363c9d0e31
--- /dev/null
+++ b/src/imports/statemachine/statemachineforeign.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 STATEMACHINEFOREIGN_H
+#define STATEMACHINEFOREIGN_H
+
+#include <QtQml/qqml.h>
+#include <QtCore/qhistorystate.h>
+#include <QtCore/qstate.h>
+#include <QtCore/qabstractstate.h>
+#include <QtCore/qsignaltransition.h>
+
+struct QHistoryStateForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QHistoryState)
+ QML_NAMED_ELEMENT(HistoryState)
+};
+
+struct QStateForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QState)
+ QML_NAMED_ELEMENT(QState)
+ QML_UNCREATABLE("Don't use this, use State instead.")
+};
+
+struct QAbstractStateForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QAbstractState)
+ QML_NAMED_ELEMENT(QAbstractState)
+ QML_UNCREATABLE("Don't use this, use State instead.")
+};
+
+struct QSignalTransitionForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QSignalTransition)
+ QML_NAMED_ELEMENT(QSignalTransition)
+ QML_UNCREATABLE("Don't use this, use SignalTransition instead.")
+};
+
+#endif // STATEMACHINEFOREIGN_H
diff --git a/src/imports/statemachine/timeouttransition.h b/src/imports/statemachine/timeouttransition.h
index 2fc850fc70..cc3a22e0e5 100644
--- a/src/imports/statemachine/timeouttransition.h
+++ b/src/imports/statemachine/timeouttransition.h
@@ -42,6 +42,7 @@
#include <QtCore/QSignalTransition>
#include <QtQml/QQmlParserStatus>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
class QTimer;
@@ -51,6 +52,7 @@ class TimeoutTransition : public QSignalTransition, public QQmlParserStatus
Q_OBJECT
Q_PROPERTY(int timeout READ timeout WRITE setTimeout NOTIFY timeoutChanged)
Q_INTERFACES(QQmlParserStatus)
+ QML_ELEMENT
public:
TimeoutTransition(QState *parent = nullptr);
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/dependencies.json b/src/imports/testlib/dependencies.json
new file mode 100644
index 0000000000..b2c4125178
--- /dev/null
+++ b/src/imports/testlib/dependencies.json
@@ -0,0 +1 @@
+["QtQuick 2.0", "QtQuick.Window 2.0"]
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index c52cf417a6..83fc150e6c 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -37,123 +37,33 @@
**
****************************************************************************/
-#include <private/qv4scopedvalue_p.h>
+#include "quicktestevent_p.h"
+#include "quicktestutil_p.h"
+
#include <QtQml/qqmlextensionplugin.h>
#include <QtQml/qqml.h>
-#include <QtQml/qjsvalue.h>
-#include <QtQml/qjsengine.h>
-#include "QtQuickTest/private/quicktestresult_p.h"
-#include "QtQuickTest/private/quicktestevent_p.h"
-#include "private/qtestoptions_p.h"
-#include "QtQuick/qquickitem.h"
-#include <QtQml/private/qqmlengine_p.h>
-#include <QtGui/QGuiApplication>
-#include <QtGui/qstylehints.h>
+#include <QtQuickTest/quicktest.h>
+#include <QtQuickTest/private/quicktestresult_p.h>
+#include <QtQuickTest/private/qtestoptions_p.h>
QML_DECLARE_TYPE(QuickTestResult)
QML_DECLARE_TYPE(QuickTestEvent)
-
-#include <QtDebug>
-
-QT_BEGIN_NAMESPACE
-
-class QuickTestUtil : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(bool printAvailableFunctions READ printAvailableFunctions NOTIFY printAvailableFunctionsChanged)
- Q_PROPERTY(int dragThreshold READ dragThreshold NOTIFY dragThresholdChanged)
-public:
- QuickTestUtil(QObject *parent = nullptr)
- :QObject(parent)
- {}
-
- ~QuickTestUtil() override
- {}
- bool printAvailableFunctions() const
- {
- return QTest::printAvailableFunctions;
- }
- int dragThreshold() const { return QGuiApplication::styleHints()->startDragDistance(); }
-
-Q_SIGNALS:
- void printAvailableFunctionsChanged();
- void dragThresholdChanged();
-
-public Q_SLOTS:
-
- QJSValue typeName(const QVariant& v) const
- {
- QString name(v.typeName());
- if (v.canConvert<QObject*>()) {
- QQmlType type;
- const QMetaObject *mo = v.value<QObject*>()->metaObject();
- while (!type.isValid() && mo) {
- type = QQmlMetaType::qmlType(mo);
- mo = mo->superClass();
- }
- if (type.isValid()) {
- name = type.qmlTypeName();
- }
- }
-
- QQmlEngine *engine = qmlEngine(this);
- QV4::ExecutionEngine *v4 = engine->handle();
- return QJSValue(v4, v4->newString(name)->asReturnedValue());
- }
-
- bool compare(const QVariant& act, const QVariant& exp) const {
- return act == exp;
- }
-
- QJSValue callerFile(int frameIndex = 0) const
- {
- QQmlEngine *engine = qmlEngine(this);
- QV4::ExecutionEngine *v4 = engine->handle();
- QV4::Scope scope(v4);
-
- QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2);
- return (stack.size() > frameIndex + 1)
- ? QJSValue(v4, v4->newString(stack.at(frameIndex + 1).source)->asReturnedValue())
- : QJSValue();
- }
- int callerLine(int frameIndex = 0) const
- {
- QQmlEngine *engine = qmlEngine(this);
- QV4::ExecutionEngine *v4 = engine->handle();
-
- QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2);
- if (stack.size() > frameIndex + 1)
- return stack.at(frameIndex + 1).line;
- return -1;
- }
-};
-
-QT_END_NAMESPACE
-
QML_DECLARE_TYPE(QuickTestUtil)
+extern void qml_register_types_QtTest();
+
QT_BEGIN_NAMESPACE
-class QTestQmlModule : public QQmlExtensionPlugin
+class QTestQmlModule : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QTestQmlModule(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
+ QTestQmlModule(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtTest"));
- qmlRegisterType<QuickTestResult, 0>(uri,1,0,"TestResult");
- qmlRegisterType<QuickTestResult, 1>(uri,1,1,"TestResult");
- qmlRegisterType<QuickTestResult, 13>(uri,1,13,"TestResult");
- qmlRegisterType<QuickTestEvent>(uri,1,0,"TestEvent");
- qmlRegisterType<QuickTestEvent>(uri,1,2,"TestEvent");
- qmlRegisterType<QuickTestUtil>(uri,1,0,"TestUtil");
- qmlRegisterAnonymousType<QQuickTouchEventSequence>(uri, 1);
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 1, QT_VERSION_MINOR);
+ volatile auto registration = &qml_register_types_QtTest;
+ Q_UNUSED(registration);
}
};
diff --git a/src/imports/testlib/plugins.qmltypes b/src/imports/testlib/plugins.qmltypes
deleted file mode 100644
index 6a1371e5f1..0000000000
--- a/src/imports/testlib/plugins.qmltypes
+++ /dev/null
@@ -1,368 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtTest 1.14'
-
-Module {
- dependencies: ["QtQuick 2.0", "QtQuick.Window 2.0"]
- Component {
- name: "QQuickTouchEventSequence"
- prototype: "QObject"
- Method {
- name: "press"
- type: "QObject*"
- Parameter { name: "touchId"; type: "int" }
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- Method {
- name: "move"
- type: "QObject*"
- Parameter { name: "touchId"; type: "int" }
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- Method {
- name: "release"
- type: "QObject*"
- Parameter { name: "touchId"; type: "int" }
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- Method {
- name: "stationary"
- type: "QObject*"
- Parameter { name: "touchId"; type: "int" }
- }
- Method { name: "commit"; type: "QObject*" }
- }
- Component {
- name: "QuickTestEvent"
- prototype: "QObject"
- exports: ["QtTest/TestEvent 1.0", "QtTest/TestEvent 1.2"]
- exportMetaObjectRevisions: [0, 0]
- Property { name: "defaultMouseDelay"; type: "int"; isReadonly: true }
- Method {
- name: "keyPress"
- type: "bool"
- Parameter { name: "key"; type: "int" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "keyRelease"
- type: "bool"
- Parameter { name: "key"; type: "int" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "keyClick"
- type: "bool"
- Parameter { name: "key"; type: "int" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "keyPressChar"
- type: "bool"
- Parameter { name: "character"; type: "string" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "keyReleaseChar"
- type: "bool"
- Parameter { name: "character"; type: "string" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "keyClickChar"
- type: "bool"
- Parameter { name: "character"; type: "string" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "keySequence"
- revision: 2
- type: "bool"
- Parameter { name: "keySequence"; type: "QVariant" }
- }
- Method {
- name: "mousePress"
- type: "bool"
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- Parameter { name: "button"; type: "int" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "mouseRelease"
- type: "bool"
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- Parameter { name: "button"; type: "int" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "mouseClick"
- type: "bool"
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- Parameter { name: "button"; type: "int" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "mouseDoubleClick"
- type: "bool"
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- Parameter { name: "button"; type: "int" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "mouseDoubleClickSequence"
- type: "bool"
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- Parameter { name: "button"; type: "int" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "mouseMove"
- type: "bool"
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- Parameter { name: "delay"; type: "int" }
- Parameter { name: "buttons"; type: "int" }
- }
- Method {
- name: "mouseWheel"
- type: "bool"
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- Parameter { name: "buttons"; type: "int" }
- Parameter { name: "modifiers"; type: "int" }
- Parameter { name: "xDelta"; type: "int" }
- Parameter { name: "yDelta"; type: "int" }
- Parameter { name: "delay"; type: "int" }
- }
- Method {
- name: "touchEvent"
- type: "QQuickTouchEventSequence*"
- Parameter { name: "item"; type: "QObject"; isPointer: true }
- }
- Method { name: "touchEvent"; type: "QQuickTouchEventSequence*" }
- }
- Component {
- name: "QuickTestResult"
- prototype: "QObject"
- exports: [
- "QtTest/TestResult 1.0",
- "QtTest/TestResult 1.1",
- "QtTest/TestResult 1.13"
- ]
- exportMetaObjectRevisions: [0, 1, 13]
- Enum {
- name: "RunMode"
- values: {
- "RepeatUntilValidMeasurement": 0,
- "RunOnce": 1
- }
- }
- Property { name: "testCaseName"; type: "string" }
- Property { name: "functionName"; type: "string" }
- Property { name: "dataTag"; type: "string" }
- Property { name: "failed"; type: "bool"; isReadonly: true }
- Property { name: "skipped"; type: "bool" }
- Property { name: "passCount"; type: "int"; isReadonly: true }
- Property { name: "failCount"; type: "int"; isReadonly: true }
- Property { name: "skipCount"; type: "int"; isReadonly: true }
- Property { name: "functionsToRun"; type: "QStringList"; isReadonly: true }
- Property { name: "tagsToRun"; type: "QStringList"; isReadonly: true }
- Signal { name: "programNameChanged" }
- Method { name: "reset" }
- Method { name: "startLogging" }
- Method { name: "stopLogging" }
- Method { name: "initTestTable" }
- Method { name: "clearTestTable" }
- Method { name: "finishTestData" }
- Method { name: "finishTestDataCleanup" }
- Method { name: "finishTestFunction" }
- Method {
- name: "stringify"
- Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "fail"
- Parameter { name: "message"; type: "string" }
- Parameter { name: "location"; type: "QUrl" }
- Parameter { name: "line"; type: "int" }
- }
- Method {
- name: "verify"
- type: "bool"
- Parameter { name: "success"; type: "bool" }
- Parameter { name: "message"; type: "string" }
- Parameter { name: "location"; type: "QUrl" }
- Parameter { name: "line"; type: "int" }
- }
- Method {
- name: "compare"
- type: "bool"
- Parameter { name: "success"; type: "bool" }
- Parameter { name: "message"; type: "string" }
- Parameter { name: "val1"; type: "QVariant" }
- Parameter { name: "val2"; type: "QVariant" }
- Parameter { name: "location"; type: "QUrl" }
- Parameter { name: "line"; type: "int" }
- }
- Method {
- name: "fuzzyCompare"
- type: "bool"
- Parameter { name: "actual"; type: "QVariant" }
- Parameter { name: "expected"; type: "QVariant" }
- Parameter { name: "delta"; type: "double" }
- }
- Method {
- name: "skip"
- Parameter { name: "message"; type: "string" }
- Parameter { name: "location"; type: "QUrl" }
- Parameter { name: "line"; type: "int" }
- }
- Method {
- name: "expectFail"
- type: "bool"
- Parameter { name: "tag"; type: "string" }
- Parameter { name: "comment"; type: "string" }
- Parameter { name: "location"; type: "QUrl" }
- Parameter { name: "line"; type: "int" }
- }
- Method {
- name: "expectFailContinue"
- type: "bool"
- Parameter { name: "tag"; type: "string" }
- Parameter { name: "comment"; type: "string" }
- Parameter { name: "location"; type: "QUrl" }
- Parameter { name: "line"; type: "int" }
- }
- Method {
- name: "warn"
- Parameter { name: "message"; type: "string" }
- Parameter { name: "location"; type: "QUrl" }
- Parameter { name: "line"; type: "int" }
- }
- Method {
- name: "ignoreWarning"
- Parameter { name: "message"; type: "QJSValue" }
- }
- Method {
- name: "wait"
- Parameter { name: "ms"; type: "int" }
- }
- Method {
- name: "sleep"
- Parameter { name: "ms"; type: "int" }
- }
- Method {
- name: "waitForRendering"
- type: "bool"
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- Parameter { name: "timeout"; type: "int" }
- }
- Method {
- name: "waitForRendering"
- type: "bool"
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- }
- Method { name: "startMeasurement" }
- Method { name: "beginDataRun" }
- Method { name: "endDataRun" }
- Method { name: "measurementAccepted"; type: "bool" }
- Method { name: "needsMoreMeasurements"; type: "bool" }
- Method {
- name: "startBenchmark"
- Parameter { name: "runMode"; type: "RunMode" }
- Parameter { name: "tag"; type: "string" }
- }
- Method { name: "isBenchmarkDone"; type: "bool" }
- Method { name: "nextBenchmark" }
- Method { name: "stopBenchmark" }
- Method {
- name: "grabImage"
- type: "QObject*"
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- }
- Method {
- name: "findChild"
- revision: 1
- type: "QObject*"
- Parameter { name: "parent"; type: "QObject"; isPointer: true }
- Parameter { name: "objectName"; type: "string" }
- }
- Method {
- name: "isPolishScheduled"
- revision: 13
- type: "bool"
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- }
- Method {
- name: "waitForItemPolished"
- revision: 13
- type: "bool"
- Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
- Parameter { name: "timeout"; type: "int" }
- }
- }
- Component {
- name: "QuickTestUtil"
- prototype: "QObject"
- exports: ["QtTest/TestUtil 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "printAvailableFunctions"; type: "bool"; isReadonly: true }
- Property { name: "dragThreshold"; type: "int"; isReadonly: true }
- Method {
- name: "typeName"
- type: "QJSValue"
- Parameter { name: "v"; type: "QVariant" }
- }
- Method {
- name: "compare"
- type: "bool"
- Parameter { name: "act"; type: "QVariant" }
- Parameter { name: "exp"; type: "QVariant" }
- }
- Method {
- name: "callerFile"
- type: "QJSValue"
- Parameter { name: "frameIndex"; type: "int" }
- }
- Method { name: "callerFile"; type: "QJSValue" }
- Method {
- name: "callerLine"
- type: "int"
- Parameter { name: "frameIndex"; type: "int" }
- }
- Method { name: "callerLine"; type: "int" }
- }
-}
diff --git a/src/qmltest/quicktestevent.cpp b/src/imports/testlib/quicktestevent.cpp
index 1e949615c2..f2d7f93d26 100644
--- a/src/qmltest/quicktestevent.cpp
+++ b/src/imports/testlib/quicktestevent.cpp
@@ -125,7 +125,7 @@ bool QuickTestEvent::keyClickChar(const QString &character, int modifiers, int d
// valueToKeySequence() is copied from qquickshortcut.cpp
static QKeySequence valueToKeySequence(const QVariant &value)
{
- if (value.type() == QVariant::Int)
+ if (value.userType() == QMetaType::Int)
return QKeySequence(static_cast<QKeySequence::StandardKey>(value.toInt()));
return QKeySequence::fromString(value.toString());
}
@@ -138,6 +138,8 @@ bool QuickTestEvent::keySequence(const QVariant &keySequence)
return false;
#if QT_CONFIG(shortcut)
QTest::keySequence(window, valueToKeySequence(keySequence));
+#else
+ Q_UNUSED(keySequence);
#endif
return true;
}
@@ -195,7 +197,7 @@ namespace QtQuickTest
me.setTimestamp(++lastMouseTimestamp);
break;
case MouseRelease:
- me = QMouseEvent(QEvent::MouseButtonRelease, pos, window->mapToGlobal(pos), button, nullptr, stateKey);
+ me = QMouseEvent(QEvent::MouseButtonRelease, pos, window->mapToGlobal(pos), button, {}, stateKey);
me.setTimestamp(++lastMouseTimestamp);
lastMouseTimestamp += 500; // avoid double clicks being generated
break;
diff --git a/src/qmltest/quicktestevent_p.h b/src/imports/testlib/quicktestevent_p.h
index 5208c03a82..f452e4ff82 100644
--- a/src/qmltest/quicktestevent_p.h
+++ b/src/imports/testlib/quicktestevent_p.h
@@ -51,17 +51,19 @@
// We mean it.
//
-#include <QtQuickTest/quicktestglobal.h>
#include <QtCore/qobject.h>
#include <QtGui/QWindow>
+#include <QtQml/qqml.h>
#include <QtTest/qtesttouch.h>
QT_BEGIN_NAMESPACE
class QuickTestEvent;
-class Q_QUICK_TEST_EXPORT QQuickTouchEventSequence : public QObject
+class QQuickTouchEventSequence : public QObject
{
Q_OBJECT
+ QML_ANONYMOUS
+
public:
explicit QQuickTouchEventSequence(QuickTestEvent *testEvent, QObject *item = nullptr);
public slots:
@@ -76,10 +78,11 @@ private:
QuickTestEvent * const m_testEvent;
};
-class Q_QUICK_TEST_EXPORT QuickTestEvent : public QObject
+class QuickTestEvent : public QObject
{
Q_OBJECT
Q_PROPERTY(int defaultMouseDelay READ defaultMouseDelay FINAL)
+ QML_NAMED_ELEMENT(TestEvent)
public:
QuickTestEvent(QObject *parent = nullptr);
~QuickTestEvent() override;
diff --git a/src/quick/util/qquickutilmodule_p.h b/src/imports/testlib/quicktestresultforeign_p.h
index b03eeddede..92ff8e8a5a 100644
--- a/src/quick/util/qquickutilmodule_p.h
+++ b/src/imports/testlib/quicktestresultforeign_p.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtQuick module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QQUICKUTILMODULE_H
-#define QQUICKUTILMODULE_H
+#ifndef QUICKTESTRESULTFOREIGN_P_H
+#define QUICKTESTRESULTFOREIGN_P_H
//
// W A R N I N G
@@ -51,16 +51,18 @@
// We mean it.
//
-#include <qqml.h>
+#include <QtQuickTest/private/quicktestresult_p.h>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
-class QQuickUtilModule
+struct QuickTestResultForeign
{
-public:
- static void defineModule();
+ Q_GADGET
+ QML_FOREIGN(QuickTestResult)
+ QML_NAMED_ELEMENT(TestResult)
};
QT_END_NAMESPACE
-#endif // QQUICKUTILMODULE_H
+#endif // QUICKTESTRESULTFOREIGN_P_H
diff --git a/src/imports/testlib/quicktestutil.cpp b/src/imports/testlib/quicktestutil.cpp
new file mode 100644
index 0000000000..d9e6a2fba5
--- /dev/null
+++ b/src/imports/testlib/quicktestutil.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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: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 "quicktestutil_p.h"
+
+#include <QtQuickTest/private/qtestoptions_p.h>
+#include <QtQml/private/qqmltype_p.h>
+#include <QtQml/private/qqmlmetatype_p.h>
+#include <QtQml/private/qv4engine_p.h>
+#include <QtQml/private/qv4scopedvalue_p.h>
+
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qstylehints.h>
+#include <QtQml/qqmlengine.h>
+
+QT_BEGIN_NAMESPACE
+
+bool QuickTestUtil::printAvailableFunctions() const
+{
+ return QTest::printAvailableFunctions;
+}
+
+int QuickTestUtil::dragThreshold() const
+{
+ return QGuiApplication::styleHints()->startDragDistance();
+}
+
+QJSValue QuickTestUtil::typeName(const QVariant &v) const
+{
+ QString name = QString::fromUtf8(v.typeName());
+ if (v.canConvert<QObject*>()) {
+ QQmlType type;
+ const QMetaObject *mo = v.value<QObject*>()->metaObject();
+ while (!type.isValid() && mo) {
+ type = QQmlMetaType::qmlType(mo);
+ mo = mo->superClass();
+ }
+ if (type.isValid()) {
+ name = type.qmlTypeName();
+ }
+ }
+
+ QQmlEngine *engine = qmlEngine(this);
+ QV4::ExecutionEngine *v4 = engine->handle();
+ return QJSValue(v4, v4->newString(name)->asReturnedValue());
+}
+
+bool QuickTestUtil::compare(const QVariant &act, const QVariant &exp) const {
+ return act == exp;
+}
+
+QJSValue QuickTestUtil::callerFile(int frameIndex) const
+{
+ QQmlEngine *engine = qmlEngine(this);
+ QV4::ExecutionEngine *v4 = engine->handle();
+ QV4::Scope scope(v4);
+
+ QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2);
+ return (stack.size() > frameIndex + 1)
+ ? QJSValue(v4, v4->newString(stack.at(frameIndex + 1).source)->asReturnedValue())
+ : QJSValue();
+}
+
+int QuickTestUtil::callerLine(int frameIndex) const
+{
+ QQmlEngine *engine = qmlEngine(this);
+ QV4::ExecutionEngine *v4 = engine->handle();
+
+ QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2);
+ if (stack.size() > frameIndex + 1)
+ return stack.at(frameIndex + 1).line;
+ return -1;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/testlib/quicktestutil_p.h b/src/imports/testlib/quicktestutil_p.h
new file mode 100644
index 0000000000..2456bf88a7
--- /dev/null
+++ b/src/imports/testlib/quicktestutil_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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: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 QUICKTESTUTIL_P_H
+#define QUICKTESTUTIL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qobject.h>
+#include <QtQml/qqml.h>
+#include <QtQml/qjsvalue.h>
+
+QT_BEGIN_NAMESPACE
+
+class QuickTestUtil : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool printAvailableFunctions READ printAvailableFunctions NOTIFY printAvailableFunctionsChanged)
+ Q_PROPERTY(int dragThreshold READ dragThreshold NOTIFY dragThresholdChanged)
+ QML_NAMED_ELEMENT(TestUtil)
+public:
+ QuickTestUtil(QObject *parent = nullptr) :QObject(parent) {}
+ ~QuickTestUtil() override {}
+
+ bool printAvailableFunctions() const;
+ int dragThreshold() const;
+
+Q_SIGNALS:
+ void printAvailableFunctionsChanged();
+ void dragThresholdChanged();
+
+public Q_SLOTS:
+
+ QJSValue typeName(const QVariant& v) const;
+ bool compare(const QVariant& act, const QVariant& exp) const;
+
+ QJSValue callerFile(int frameIndex = 0) const;
+ int callerLine(int frameIndex = 0) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QUICKTESTUTIL_P_H
diff --git a/src/imports/testlib/testlib.pro b/src/imports/testlib/testlib.pro
index acbe82e5e6..d5e315d7da 100644
--- a/src/imports/testlib/testlib.pro
+++ b/src/imports/testlib/testlib.pro
@@ -3,9 +3,17 @@ TARGET = qmltestplugin
TARGETPATH = QtTest
IMPORT_VERSION = 1.$$QT_MINOR_VERSION
-QT += qml quick qmltest qmltest-private qml-private core-private testlib
+QT += quick qmltest-private qml-private core-private testlib gui-private
-SOURCES += main.cpp
+SOURCES += \
+ main.cpp \
+ quicktestevent.cpp \
+ quicktestutil.cpp
+
+HEADERS += \
+ quicktestevent_p.h \
+ quicktestresultforeign_p.h \
+ quicktestutil_p.h
QML_FILES = \
TestCase.qml \
@@ -15,3 +23,4 @@ QML_FILES = \
load(qml_plugin)
OTHER_FILES += testlib.json
+CONFIG += qmltypes install_qmltypes
diff --git a/src/imports/wavefrontmesh/plugin.cpp b/src/imports/wavefrontmesh/plugin.cpp
index 1a266b7e36..eea0db19db 100644
--- a/src/imports/wavefrontmesh/plugin.cpp
+++ b/src/imports/wavefrontmesh/plugin.cpp
@@ -42,25 +42,20 @@
#include "qwavefrontmesh.h"
+extern void qml_register_types_Qt_labs_wavefrontmesh();
+
QT_BEGIN_NAMESPACE
-class QmlWavefrontMeshPlugin : public QQmlExtensionPlugin
+class QmlWavefrontMeshPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
QmlWavefrontMeshPlugin(QObject *parent = nullptr)
- : QQmlExtensionPlugin(parent)
+ : QQmlEngineExtensionPlugin(parent)
{
- }
-
- void registerTypes(const char *uri) override
- {
- Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.wavefrontmesh"));
- qmlRegisterType<QWavefrontMesh>(uri, 1, 0, "WavefrontMesh");
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.12 onward
- qmlRegisterModule(uri, 1, QT_VERSION_MINOR);
+ volatile auto registration = &qml_register_types_Qt_labs_wavefrontmesh;
+ Q_UNUSED(registration);
}
};
diff --git a/src/imports/wavefrontmesh/plugins.qmltypes b/src/imports/wavefrontmesh/plugins.qmltypes
deleted file mode 100644
index 4e6a1dca73..0000000000
--- a/src/imports/wavefrontmesh/plugins.qmltypes
+++ /dev/null
@@ -1,37 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt.labs.wavefrontmesh 1.14'
-
-Module {
- dependencies: ["QtQuick 2.0"]
- Component {
- name: "QWavefrontMesh"
- prototype: "QQuickShaderEffectMesh"
- exports: ["Qt.labs.wavefrontmesh/WavefrontMesh 1.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Error"
- values: {
- "NoError": 0,
- "InvalidSourceError": 1,
- "UnsupportedFaceShapeError": 2,
- "UnsupportedIndexSizeError": 3,
- "FileNotFoundError": 4,
- "NoAttributesError": 5,
- "MissingPositionAttributeError": 6,
- "MissingTextureCoordinateAttributeError": 7,
- "MissingPositionAndTextureCoordinateAttributesError": 8,
- "TooManyAttributesError": 9,
- "InvalidPlaneDefinitionError": 10
- }
- }
- Property { name: "source"; type: "QUrl" }
- Property { name: "lastError"; type: "Error"; isReadonly: true }
- Property { name: "projectionPlaneV"; type: "QVector3D" }
- Property { name: "projectionPlaneW"; type: "QVector3D" }
- }
-}
diff --git a/src/imports/wavefrontmesh/qwavefrontmesh.cpp b/src/imports/wavefrontmesh/qwavefrontmesh.cpp
index e973ef0103..1772c40c50 100644
--- a/src/imports/wavefrontmesh/qwavefrontmesh.cpp
+++ b/src/imports/wavefrontmesh/qwavefrontmesh.cpp
@@ -257,7 +257,7 @@ void QWavefrontMesh::readData()
while (!stream.atEnd()) {
stream.readLineInto(&buffer);
- QVector<QStringRef> tokens = buffer.splitRef(space, QString::SkipEmptyParts);
+ QVector<QStringRef> tokens = buffer.splitRef(space, Qt::SkipEmptyParts);
if (tokens.size() < 2)
continue;
@@ -316,7 +316,7 @@ void QWavefrontMesh::readData()
if (tokens.size() >= 4 && tokens.size() <= 5) {
{
bool ok;
- QVector<QStringRef> faceTokens = tokens.at(1).split(slash, QString::SkipEmptyParts);
+ QVector<QStringRef> faceTokens = tokens.at(1).split(slash, Qt::SkipEmptyParts);
Q_ASSERT(!faceTokens.isEmpty());
p1 = faceTokens.at(0).toInt(&ok) - 1;
@@ -336,7 +336,7 @@ void QWavefrontMesh::readData()
{
bool ok;
- QVector<QStringRef> faceTokens = tokens.at(2).split(slash, QString::SkipEmptyParts);
+ QVector<QStringRef> faceTokens = tokens.at(2).split(slash, Qt::SkipEmptyParts);
Q_ASSERT(!faceTokens.isEmpty());
p2 = faceTokens.at(0).toInt(&ok) - 1;
@@ -356,7 +356,7 @@ void QWavefrontMesh::readData()
{
bool ok;
- QVector<QStringRef> faceTokens = tokens.at(3).split(slash, QString::SkipEmptyParts);
+ QVector<QStringRef> faceTokens = tokens.at(3).split(slash, Qt::SkipEmptyParts);
Q_ASSERT(!faceTokens.isEmpty());
p3 = faceTokens.at(0).toInt(&ok) - 1;
@@ -394,7 +394,7 @@ void QWavefrontMesh::readData()
if (tokens.size() == 5) {
bool ok;
- QVector<QStringRef> faceTokens = tokens.at(4).split(slash, QString::SkipEmptyParts);
+ QVector<QStringRef> faceTokens = tokens.at(4).split(slash, Qt::SkipEmptyParts);
Q_ASSERT(!faceTokens.isEmpty());
int p4 = faceTokens.at(0).toInt(&ok) - 1;
diff --git a/src/imports/wavefrontmesh/qwavefrontmesh.h b/src/imports/wavefrontmesh/qwavefrontmesh.h
index e3ded8078e..a8a40c1a6a 100644
--- a/src/imports/wavefrontmesh/qwavefrontmesh.h
+++ b/src/imports/wavefrontmesh/qwavefrontmesh.h
@@ -55,6 +55,8 @@ class QWavefrontMesh : public QQuickShaderEffectMesh
Q_PROPERTY(Error lastError READ lastError NOTIFY lastErrorChanged)
Q_PROPERTY(QVector3D projectionPlaneV READ projectionPlaneV WRITE setProjectionPlaneV NOTIFY projectionPlaneVChanged)
Q_PROPERTY(QVector3D projectionPlaneW READ projectionPlaneW WRITE setProjectionPlaneW NOTIFY projectionPlaneWChanged)
+ QML_NAMED_ELEMENT(WavefrontMesh)
+
public:
enum Error {
NoError,
diff --git a/src/imports/wavefrontmesh/wavefrontmesh.pro b/src/imports/wavefrontmesh/wavefrontmesh.pro
index 85bd500089..0b28410750 100644
--- a/src/imports/wavefrontmesh/wavefrontmesh.pro
+++ b/src/imports/wavefrontmesh/wavefrontmesh.pro
@@ -12,4 +12,5 @@ SOURCES += \
HEADERS += \
qwavefrontmesh.h
+CONFIG += qmltypes install_qmltypes
load(qml_plugin)
diff --git a/src/imports/window/plugin.cpp b/src/imports/window/plugin.cpp
index dfe1dcf62e..5152fa02ec 100644
--- a/src/imports/window/plugin.cpp
+++ b/src/imports/window/plugin.cpp
@@ -39,7 +39,9 @@
#include <QtQml/qqmlextensionplugin.h>
-#include <private/qquickwindowmodule_p.h>
+#include "plugin.h"
+
+extern void qml_register_types_QtQuick_Window();
QT_BEGIN_NAMESPACE
@@ -58,21 +60,16 @@ QT_BEGIN_NAMESPACE
\endqml
*/
-
//![class decl]
-class QtQuick2WindowPlugin : public QQmlExtensionPlugin
+class QtQuick2WindowPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQuick2WindowPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
+ QtQuick2WindowPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Window"));
- QQuickWindowModule::defineModule();
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
+ volatile auto registration = &qml_register_types_QtQuick_Window;
+ Q_UNUSED(registration);
}
};
//![class decl]
diff --git a/src/imports/window/plugin.h b/src/imports/window/plugin.h
new file mode 100644
index 0000000000..3bc2d91ddb
--- /dev/null
+++ b/src/imports/window/plugin.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick 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 PLUGIN_H
+#define PLUGIN_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 <QtGui/private/qwindow_p.h>
+#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/private/qquickwindowattached_p.h>
+#include <QtQuick/private/qquickscreen_p.h>
+#include <QtQuick/private/qquickwindowmodule_p.h>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QWindowForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QWindow)
+ QML_ANONYMOUS
+ QML_ADDED_IN_MINOR_VERSION(1)
+};
+
+struct QQuickWindowForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QQuickWindow)
+ QML_NAMED_ELEMENT(Window)
+ QML_ADDED_IN_MINOR_VERSION(0)
+ QML_REMOVED_IN_MINOR_VERSION(1)
+};
+
+struct QQuickWindowForeignAttached
+{
+ Q_GADGET
+ QML_FOREIGN(QQuickWindowAttached)
+ QML_ANONYMOUS
+};
+
+struct QQuickScreenInfoForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QQuickScreenInfo)
+ QML_NAMED_ELEMENT(ScreenInfo)
+ QML_ADDED_IN_MINOR_VERSION(3)
+ QML_UNCREATABLE("ScreenInfo can only be used via the attached property.")
+};
+
+struct QQuickScreenForeignAttached
+{
+ Q_GADGET
+ QML_FOREIGN(QQuickScreenAttached)
+ QML_ANONYMOUS
+};
+
+struct QQuickScreenForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QQuickScreen)
+ QML_NAMED_ELEMENT(Screen)
+ QML_UNCREATABLE("Screen can only be used via the attached property.")
+};
+
+struct QQuickWindowQmlImplForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QQuickWindowQmlImpl)
+ QML_NAMED_ELEMENT(Window)
+ QML_ADDED_IN_MINOR_VERSION(1)
+};
+
+struct QQuickRootItemForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QQuickRootItem)
+ QML_ANONYMOUS
+};
+
+QT_END_NAMESPACE
+
+#endif // PLUGIN_H
diff --git a/src/imports/window/plugins.qmltypes b/src/imports/window/plugins.qmltypes
deleted file mode 100644
index 693673c4cd..0000000000
--- a/src/imports/window/plugins.qmltypes
+++ /dev/null
@@ -1,373 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Window 2.14'
-
-Module {
- dependencies: ["QtQuick 2.0"]
- Component {
- name: "QQuickRootItem"
- defaultProperty: "data"
- prototype: "QQuickItem"
- Method {
- name: "setWidth"
- Parameter { name: "w"; type: "int" }
- }
- Method {
- name: "setHeight"
- Parameter { name: "h"; type: "int" }
- }
- }
- Component {
- name: "QQuickScreen"
- prototype: "QObject"
- exports: ["QtQuick.Window/Screen 2.0", "QtQuick.Window/Screen 2.3"]
- isCreatable: false
- exportMetaObjectRevisions: [0, 3]
- attachedType: "QQuickScreenAttached"
- }
- Component {
- name: "QQuickScreenAttached"
- prototype: "QQuickScreenInfo"
- Property { name: "orientationUpdateMask"; type: "Qt::ScreenOrientations" }
- Method {
- name: "angleBetween"
- type: "int"
- Parameter { name: "a"; type: "int" }
- Parameter { name: "b"; type: "int" }
- }
- }
- Component {
- name: "QQuickScreenInfo"
- prototype: "QObject"
- exports: [
- "QtQuick.Window/ScreenInfo 2.10",
- "QtQuick.Window/ScreenInfo 2.3"
- ]
- isCreatable: false
- exportMetaObjectRevisions: [10, 3]
- Property { name: "name"; type: "string"; isReadonly: true }
- Property { name: "manufacturer"; revision: 10; type: "string"; isReadonly: true }
- Property { name: "model"; revision: 10; type: "string"; isReadonly: true }
- Property { name: "serialNumber"; revision: 10; type: "string"; isReadonly: true }
- Property { name: "width"; type: "int"; isReadonly: true }
- Property { name: "height"; type: "int"; isReadonly: true }
- Property { name: "desktopAvailableWidth"; type: "int"; isReadonly: true }
- Property { name: "desktopAvailableHeight"; type: "int"; isReadonly: true }
- Property { name: "logicalPixelDensity"; type: "double"; isReadonly: true }
- Property { name: "pixelDensity"; type: "double"; isReadonly: true }
- Property { name: "devicePixelRatio"; type: "double"; isReadonly: true }
- Property { name: "primaryOrientation"; type: "Qt::ScreenOrientation"; isReadonly: true }
- Property { name: "orientation"; type: "Qt::ScreenOrientation"; isReadonly: true }
- Property { name: "virtualX"; revision: 3; type: "int"; isReadonly: true }
- Property { name: "virtualY"; revision: 3; type: "int"; isReadonly: true }
- Signal { name: "manufacturerChanged"; revision: 10 }
- Signal { name: "modelChanged"; revision: 10 }
- Signal { name: "serialNumberChanged"; revision: 10 }
- Signal { name: "desktopGeometryChanged" }
- Signal { name: "virtualXChanged"; revision: 3 }
- Signal { name: "virtualYChanged"; revision: 3 }
- }
- Component {
- name: "QQuickWindow"
- defaultProperty: "data"
- prototype: "QWindow"
- exports: ["QtQuick.Window/Window 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "CreateTextureOptions"
- values: {
- "TextureHasAlphaChannel": 1,
- "TextureHasMipmaps": 2,
- "TextureOwnsGLTexture": 4,
- "TextureCanUseAtlas": 8,
- "TextureIsOpaque": 16
- }
- }
- Enum {
- name: "SceneGraphError"
- values: {
- "ContextNotAvailable": 1
- }
- }
- Enum {
- name: "TextRenderType"
- values: {
- "QtTextRendering": 0,
- "NativeTextRendering": 1
- }
- }
- Enum {
- name: "NativeObjectType"
- values: {
- "NativeObjectTexture": 0
- }
- }
- Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "color"; type: "QColor" }
- Property { name: "contentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property {
- name: "activeFocusItem"
- revision: 1
- type: "QQuickItem"
- isReadonly: true
- isPointer: true
- }
- Signal { name: "frameSwapped" }
- Signal {
- name: "openglContextCreated"
- revision: 2
- Parameter { name: "context"; type: "QOpenGLContext"; isPointer: true }
- }
- Signal { name: "sceneGraphInitialized" }
- Signal { name: "sceneGraphInvalidated" }
- Signal { name: "beforeSynchronizing" }
- Signal { name: "afterSynchronizing"; revision: 2 }
- Signal { name: "beforeRendering" }
- Signal { name: "afterRendering" }
- Signal { name: "afterAnimating"; revision: 2 }
- Signal { name: "sceneGraphAboutToStop"; revision: 2 }
- Signal {
- name: "closing"
- revision: 1
- Parameter { name: "close"; type: "QQuickCloseEvent"; isPointer: true }
- }
- Signal {
- name: "colorChanged"
- Parameter { type: "QColor" }
- }
- Signal { name: "activeFocusItemChanged"; revision: 1 }
- Signal {
- name: "sceneGraphError"
- revision: 2
- Parameter { name: "error"; type: "QQuickWindow::SceneGraphError" }
- Parameter { name: "message"; type: "string" }
- }
- Signal { name: "beforeRenderPassRecording"; revision: 14 }
- Signal { name: "afterRenderPassRecording"; revision: 14 }
- Method { name: "update" }
- Method { name: "releaseResources" }
- }
- Component {
- name: "QQuickWindowAttached"
- prototype: "QObject"
- Property { name: "visibility"; type: "QWindow::Visibility"; isReadonly: true }
- Property { name: "active"; type: "bool"; isReadonly: true }
- Property { name: "activeFocusItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "contentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
- Property { name: "width"; type: "int"; isReadonly: true }
- Property { name: "height"; type: "int"; isReadonly: true }
- Property { name: "window"; type: "QQuickWindow"; isReadonly: true; isPointer: true }
- }
- Component {
- name: "QQuickWindowQmlImpl"
- defaultProperty: "data"
- prototype: "QQuickWindow"
- exports: [
- "QtQuick.Window/Window 2.1",
- "QtQuick.Window/Window 2.13",
- "QtQuick.Window/Window 2.2",
- "QtQuick.Window/Window 2.3"
- ]
- exportMetaObjectRevisions: [0, 13, 2, 3]
- attachedType: "QQuickWindowAttached"
- Property { name: "visible"; type: "bool" }
- Property { name: "visibility"; type: "Visibility" }
- Property { name: "screen"; revision: 3; type: "QObject"; isPointer: true }
- Signal {
- name: "visibleChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "visibilityChanged"
- Parameter { name: "visibility"; type: "QWindow::Visibility" }
- }
- Signal { name: "screenChanged"; revision: 3 }
- }
- Component {
- name: "QWindow"
- prototype: "QObject"
- Enum {
- name: "Visibility"
- values: {
- "Hidden": 0,
- "AutomaticVisibility": 1,
- "Windowed": 2,
- "Minimized": 3,
- "Maximized": 4,
- "FullScreen": 5
- }
- }
- Enum {
- name: "AncestorMode"
- values: {
- "ExcludeTransients": 0,
- "IncludeTransients": 1
- }
- }
- Property { name: "title"; type: "string" }
- Property { name: "modality"; type: "Qt::WindowModality" }
- Property { name: "flags"; type: "Qt::WindowFlags" }
- Property { name: "x"; type: "int" }
- Property { name: "y"; type: "int" }
- Property { name: "width"; type: "int" }
- Property { name: "height"; type: "int" }
- Property { name: "minimumWidth"; type: "int" }
- Property { name: "minimumHeight"; type: "int" }
- Property { name: "maximumWidth"; type: "int" }
- Property { name: "maximumHeight"; type: "int" }
- Property { name: "visible"; type: "bool" }
- Property { name: "active"; revision: 1; type: "bool"; isReadonly: true }
- Property { name: "visibility"; revision: 1; type: "Visibility" }
- Property { name: "contentOrientation"; type: "Qt::ScreenOrientation" }
- Property { name: "opacity"; revision: 1; type: "double" }
- Property { name: "transientParent"; revision: 13; type: "QWindow"; isPointer: true }
- Signal {
- name: "screenChanged"
- Parameter { name: "screen"; type: "QScreen"; isPointer: true }
- }
- Signal {
- name: "modalityChanged"
- Parameter { name: "modality"; type: "Qt::WindowModality" }
- }
- Signal {
- name: "windowStateChanged"
- Parameter { name: "windowState"; type: "Qt::WindowState" }
- }
- Signal {
- name: "windowTitleChanged"
- revision: 2
- Parameter { name: "title"; type: "string" }
- }
- Signal {
- name: "xChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "yChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "widthChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "heightChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "minimumWidthChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "minimumHeightChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "maximumWidthChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "maximumHeightChanged"
- Parameter { name: "arg"; type: "int" }
- }
- Signal {
- name: "visibleChanged"
- Parameter { name: "arg"; type: "bool" }
- }
- Signal {
- name: "visibilityChanged"
- revision: 1
- Parameter { name: "visibility"; type: "QWindow::Visibility" }
- }
- Signal { name: "activeChanged"; revision: 1 }
- Signal {
- name: "contentOrientationChanged"
- Parameter { name: "orientation"; type: "Qt::ScreenOrientation" }
- }
- Signal {
- name: "focusObjectChanged"
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "opacityChanged"
- revision: 1
- Parameter { name: "opacity"; type: "double" }
- }
- Signal {
- name: "transientParentChanged"
- revision: 13
- Parameter { name: "transientParent"; type: "QWindow"; isPointer: true }
- }
- Method { name: "requestActivate"; revision: 1 }
- Method {
- name: "setVisible"
- Parameter { name: "visible"; type: "bool" }
- }
- Method { name: "show" }
- Method { name: "hide" }
- Method { name: "showMinimized" }
- Method { name: "showMaximized" }
- Method { name: "showFullScreen" }
- Method { name: "showNormal" }
- Method { name: "close"; type: "bool" }
- Method { name: "raise" }
- Method { name: "lower" }
- Method {
- name: "setTitle"
- Parameter { type: "string" }
- }
- Method {
- name: "setX"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setY"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setWidth"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setHeight"
- Parameter { name: "arg"; type: "int" }
- }
- Method {
- name: "setGeometry"
- Parameter { name: "posx"; type: "int" }
- Parameter { name: "posy"; type: "int" }
- Parameter { name: "w"; type: "int" }
- Parameter { name: "h"; type: "int" }
- }
- Method {
- name: "setGeometry"
- Parameter { name: "rect"; type: "QRect" }
- }
- Method {
- name: "setMinimumWidth"
- Parameter { name: "w"; type: "int" }
- }
- Method {
- name: "setMinimumHeight"
- Parameter { name: "h"; type: "int" }
- }
- Method {
- name: "setMaximumWidth"
- Parameter { name: "w"; type: "int" }
- }
- Method {
- name: "setMaximumHeight"
- Parameter { name: "h"; type: "int" }
- }
- Method {
- name: "alert"
- revision: 1
- Parameter { name: "msec"; type: "int" }
- }
- Method { name: "requestUpdate"; revision: 3 }
- }
-}
diff --git a/src/imports/window/window.pro b/src/imports/window/window.pro
index 77bd9518e9..068169b36f 100644
--- a/src/imports/window/window.pro
+++ b/src/imports/window/window.pro
@@ -6,6 +6,10 @@ IMPORT_VERSION = 2.$$QT_MINOR_VERSION
SOURCES += \
plugin.cpp
+HEADERS += \
+ plugin.h
+
QT += quick-private qml-private
+CONFIG += qmltypes install_qmltypes
load(qml_plugin)
diff --git a/src/imports/workerscript/plugin.cpp b/src/imports/workerscript/plugin.cpp
index 5b3bff7934..1323b17ef4 100644
--- a/src/imports/workerscript/plugin.cpp
+++ b/src/imports/workerscript/plugin.cpp
@@ -37,9 +37,8 @@
**
****************************************************************************/
-#include <QtQmlWorkerScript/private/qqmlworkerscriptmodule_p.h>
+#include <QtQmlWorkerScript/private/qtqmlworkerscriptglobal_p.h>
#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -59,20 +58,15 @@ QT_BEGIN_NAMESPACE
\endqml
*/
-class QtQmlWorkerScriptPlugin : public QQmlExtensionPlugin
+class QtQmlWorkerScriptPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQmlWorkerScriptPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
+ QtQmlWorkerScriptPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQml.WorkerScript"));
-
- QQmlWorkerScriptModule::defineModule();
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
+ volatile auto registration = &qml_register_types_QtQml_WorkerScript;
+ Q_UNUSED(registration);
}
};
diff --git a/src/imports/workerscript/plugins.qmltypes b/src/imports/workerscript/plugins.qmltypes
deleted file mode 100644
index b1d6107022..0000000000
--- a/src/imports/workerscript/plugins.qmltypes
+++ /dev/null
@@ -1,26 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQml.WorkerScript 2.14'
-
-Module {
- dependencies: []
- Component {
- name: "QQuickWorkerScript"
- prototype: "QObject"
- exports: ["QtQml.WorkerScript/WorkerScript 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "source"; type: "QUrl" }
- Signal {
- name: "message"
- Parameter { name: "messageObject"; type: "QJSValue" }
- }
- Method {
- name: "sendMessage"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- }
-}
diff --git a/src/particles/particles.pro b/src/particles/particles.pro
index 6a3fb1bdc4..aaaa83419a 100644
--- a/src/particles/particles.pro
+++ b/src/particles/particles.pro
@@ -16,4 +16,10 @@ exists("qqml_enable_gcov") {
include(particles.pri)
+QMLTYPES_FILENAME = plugins.qmltypes
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick/Particles.2
+QML_IMPORT_NAME = QtQuick.Particles
+IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+CONFIG += qmltypes install_qmltypes install_metatypes
+
load(qt_module)
diff --git a/src/particles/qquickage_p.h b/src/particles/qquickage_p.h
index 5db6167dc1..890c6a63c1 100644
--- a/src/particles/qquickage_p.h
+++ b/src/particles/qquickage_p.h
@@ -59,6 +59,7 @@ class QQuickAgeAffector : public QQuickParticleAffector
Q_OBJECT
Q_PROPERTY(int lifeLeft READ lifeLeft WRITE setLifeLeft NOTIFY lifeLeftChanged)
Q_PROPERTY(bool advancePosition READ advancePosition WRITE setAdvancePosition NOTIFY advancePositionChanged)
+ QML_NAMED_ELEMENT(Age)
public:
explicit QQuickAgeAffector(QQuickItem *parent = 0);
diff --git a/src/particles/qquickangledirection_p.h b/src/particles/qquickangledirection_p.h
index 66290fb19e..d0fdf5a68c 100644
--- a/src/particles/qquickangledirection_p.h
+++ b/src/particles/qquickangledirection_p.h
@@ -51,6 +51,8 @@
// We mean it.
//
#include "qquickdirection_p.h"
+#include <QtQml/qqml.h>
+
QT_BEGIN_NAMESPACE
class QQuickAngleDirection : public QQuickDirection
@@ -60,6 +62,7 @@ class QQuickAngleDirection : public QQuickDirection
Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged)
Q_PROPERTY(qreal angleVariation READ angleVariation WRITE setAngleVariation NOTIFY angleVariationChanged)
Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged)
+ QML_NAMED_ELEMENT(AngleDirection)
public:
explicit QQuickAngleDirection(QObject *parent = 0);
QPointF sample(const QPointF &from) override;
diff --git a/src/particles/qquickcumulativedirection.cpp b/src/particles/qquickcumulativedirection.cpp
index 905d44cae9..e37435e960 100644
--- a/src/particles/qquickcumulativedirection.cpp
+++ b/src/particles/qquickcumulativedirection.cpp
@@ -56,7 +56,7 @@ QQuickCumulativeDirection::QQuickCumulativeDirection(QObject *parent):QQuickDire
QQmlListProperty<QQuickDirection> QQuickCumulativeDirection::directions()
{
- return QQmlListProperty<QQuickDirection>(this, m_directions);//TODO: Proper list property
+ return QQmlListProperty<QQuickDirection>(this, &m_directions);//TODO: Proper list property
}
QPointF QQuickCumulativeDirection::sample(const QPointF &from)
diff --git a/src/particles/qquickcumulativedirection_p.h b/src/particles/qquickcumulativedirection_p.h
index 39f8ab8a24..5160d8f09a 100644
--- a/src/particles/qquickcumulativedirection_p.h
+++ b/src/particles/qquickcumulativedirection_p.h
@@ -52,6 +52,8 @@
//
#include "qquickdirection_p.h"
#include <QQmlListProperty>
+#include <QtQml/qqml.h>
+
QT_BEGIN_NAMESPACE
class QQuickCumulativeDirection : public QQuickDirection
@@ -59,6 +61,7 @@ class QQuickCumulativeDirection : public QQuickDirection
Q_OBJECT
Q_PROPERTY(QQmlListProperty<QQuickDirection> directions READ directions)
Q_CLASSINFO("DefaultProperty", "directions")
+ QML_NAMED_ELEMENT(CumulativeDirection)
public:
explicit QQuickCumulativeDirection(QObject *parent = 0);
QQmlListProperty<QQuickDirection> directions();
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp
index 5e2133dfaf..aa2617e64c 100644
--- a/src/particles/qquickcustomaffector.cpp
+++ b/src/particles/qquickcustomaffector.cpp
@@ -57,8 +57,6 @@ QT_BEGIN_NAMESPACE
Note that JavaScript is slower to execute, so it is not recommended to use this in
high-volume particle systems.
-
- The corresponding handler is \c onAffectParticles.
*/
/*!
diff --git a/src/particles/qquickcustomaffector_p.h b/src/particles/qquickcustomaffector_p.h
index 5b1ea55659..5e8671514d 100644
--- a/src/particles/qquickcustomaffector_p.h
+++ b/src/particles/qquickcustomaffector_p.h
@@ -52,6 +52,7 @@
//
#include <QObject>
+#include <QtQml/qqml.h>
#include "qquickparticlesystem_p.h"
#include "qquickparticleextruder_p.h"
#include "qquickparticleaffector_p.h"
@@ -66,6 +67,7 @@ class QQuickCustomAffector : public QQuickParticleAffector
Q_PROPERTY(QQuickDirection *position READ position WRITE setPosition NOTIFY positionChanged RESET positionReset)
Q_PROPERTY(QQuickDirection *velocity READ velocity WRITE setVelocity NOTIFY velocityChanged RESET velocityReset)
Q_PROPERTY(QQuickDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged RESET accelerationReset)
+ QML_NAMED_ELEMENT(Affector)
public:
explicit QQuickCustomAffector(QQuickItem *parent = 0);
diff --git a/src/particles/qquickcustomparticle_p.h b/src/particles/qquickcustomparticle_p.h
index e2292cb33b..444f7ad215 100644
--- a/src/particles/qquickcustomparticle_p.h
+++ b/src/particles/qquickcustomparticle_p.h
@@ -67,6 +67,7 @@ class QQuickCustomParticle : public QQuickParticlePainter
Q_OBJECT
Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged)
Q_PROPERTY(QByteArray vertexShader READ vertexShader WRITE setVertexShader NOTIFY vertexShaderChanged)
+ QML_NAMED_ELEMENT(CustomParticle)
public:
explicit QQuickCustomParticle(QQuickItem* parent=0);
diff --git a/src/particles/qquickdirection_p.h b/src/particles/qquickdirection_p.h
index 10960f9920..60b4d8eb1d 100644
--- a/src/particles/qquickdirection_p.h
+++ b/src/particles/qquickdirection_p.h
@@ -53,12 +53,16 @@
#include <QObject>
#include <QPointF>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
class QQuickDirection : public QObject
{
Q_OBJECT
+ QML_NAMED_ELEMENT(NullVector)
+ QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.")
+
public:
explicit QQuickDirection(QObject *parent = 0);
diff --git a/src/particles/qquickellipseextruder_p.h b/src/particles/qquickellipseextruder_p.h
index 0af7f4d94f..c92443fedf 100644
--- a/src/particles/qquickellipseextruder_p.h
+++ b/src/particles/qquickellipseextruder_p.h
@@ -58,6 +58,7 @@ class QQuickEllipseExtruder : public QQuickParticleExtruder
{
Q_OBJECT
Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)//###Use base class? If it's still box
+ QML_NAMED_ELEMENT(EllipseShape)
public:
explicit QQuickEllipseExtruder(QObject *parent = 0);
QPointF extrude(const QRectF &) override;
diff --git a/src/particles/qquickfriction_p.h b/src/particles/qquickfriction_p.h
index 05ae7a38d5..5686bb37d5 100644
--- a/src/particles/qquickfriction_p.h
+++ b/src/particles/qquickfriction_p.h
@@ -59,6 +59,7 @@ class QQuickFrictionAffector : public QQuickParticleAffector
Q_OBJECT
Q_PROPERTY(qreal factor READ factor WRITE setFactor NOTIFY factorChanged)
Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged)
+ QML_NAMED_ELEMENT(Friction)
public:
explicit QQuickFrictionAffector(QQuickItem *parent = 0);
diff --git a/src/particles/qquickgravity_p.h b/src/particles/qquickgravity_p.h
index 333d3d1534..ef7cc770b7 100644
--- a/src/particles/qquickgravity_p.h
+++ b/src/particles/qquickgravity_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
#include "qquickparticleaffector_p.h"
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -60,6 +61,7 @@ class QQuickGravityAffector : public QQuickParticleAffector
Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged)
Q_PROPERTY(qreal acceleration READ magnitude WRITE setAcceleration NOTIFY magnitudeChanged)
Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
+ QML_NAMED_ELEMENT(Gravity)
public:
explicit QQuickGravityAffector(QQuickItem *parent = 0);
qreal magnitude() const;
diff --git a/src/particles/qquickgroupgoal_p.h b/src/particles/qquickgroupgoal_p.h
index 9a56ef5cce..022b244ed7 100644
--- a/src/particles/qquickgroupgoal_p.h
+++ b/src/particles/qquickgroupgoal_p.h
@@ -61,6 +61,7 @@ class QQuickGroupGoalAffector : public QQuickParticleAffector
Q_OBJECT
Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged)
Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged)
+ QML_NAMED_ELEMENT(GroupGoal)
public:
explicit QQuickGroupGoalAffector(QQuickItem *parent = 0);
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index c6fe2f516d..4d67691771 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -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/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h
index 45eb73b86c..fdb404861c 100644
--- a/src/particles/qquickimageparticle_p.h
+++ b/src/particles/qquickimageparticle_p.h
@@ -202,6 +202,7 @@ class QQuickImageParticle : public QQuickParticlePainter
Q_PROPERTY(bool spritesInterpolate READ spritesInterpolate WRITE setSpritesInterpolate NOTIFY spritesInterpolateChanged)
Q_PROPERTY(EntryEffect entryEffect READ entryEffect WRITE setEntryEffect NOTIFY entryEffectChanged)
+ QML_NAMED_ELEMENT(ImageParticle)
public:
explicit QQuickImageParticle(QQuickItem *parent = 0);
virtual ~QQuickImageParticle();
diff --git a/src/particles/qquickitemparticle.cpp b/src/particles/qquickitemparticle.cpp
index de74c8a2c4..ce254c212d 100644
--- a/src/particles/qquickitemparticle.cpp
+++ b/src/particles/qquickitemparticle.cpp
@@ -160,8 +160,15 @@ void QQuickItemParticle::take(QQuickItem *item, bool prioritize)
void QQuickItemParticle::give(QQuickItem *item)
{
- //TODO: This
- Q_UNUSED(item);
+ for (auto groupId : groupIds()) {
+ for (QQuickParticleData* data : qAsConst(m_system->groupData[groupId]->data)) {
+ if (data->delegate == item){
+ m_deletables << item;
+ data->delegate = nullptr;
+ return;
+ }
+ }
+ }
}
void QQuickItemParticle::initialize(int gIdx, int pIdx)
@@ -181,8 +188,11 @@ void QQuickItemParticle::processDeletables()
item->setOpacity(0.);
item->setVisible(false);
QQuickItemParticleAttached* mpa;
- if ((mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(item))))
- mpa->detach();//reparent as well?
+ if ((mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(item)))) {
+ if (mpa->m_parentItem != nullptr)
+ item->setParentItem(mpa->m_parentItem);
+ mpa->detach();
+ }
int idx = -1;
if ((idx = m_managed.indexOf(item)) != -1) {
m_managed.takeAt(idx);
@@ -197,13 +207,15 @@ void QQuickItemParticle::tick(int time)
{
Q_UNUSED(time);//only needed because QTickAnimationProxy expects one
processDeletables();
-
for (auto groupId : groupIds()) {
for (QQuickParticleData* d : qAsConst(m_system->groupData[groupId]->data)) {
if (!d->delegate && d->t != -1 && d->stillAlive(m_system)) {
+ QQuickItem* parentItem = nullptr;
if (!m_pendingItems.isEmpty()){
- d->delegate = m_pendingItems.front();
+ QQuickItem *item = m_pendingItems.front();
m_pendingItems.pop_front();
+ parentItem = item->parentItem();
+ d->delegate = item;
}else if (m_delegate){
d->delegate = qobject_cast<QQuickItem*>(m_delegate->create(qmlContext(this)));
if (d->delegate)
@@ -214,6 +226,7 @@ void QQuickItemParticle::tick(int time)
d->delegate->setY(d->curY(m_system) - d->delegate->height() / 2);
QQuickItemParticleAttached* mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(d->delegate));
if (mpa){
+ mpa->m_parentItem = parentItem;
mpa->m_mp = this;
mpa->attach();
}
diff --git a/src/particles/qquickitemparticle_p.h b/src/particles/qquickitemparticle_p.h
index b278008460..32c9881691 100644
--- a/src/particles/qquickitemparticle_p.h
+++ b/src/particles/qquickitemparticle_p.h
@@ -63,6 +63,8 @@ class QQuickItemParticle : public QQuickParticlePainter
Q_OBJECT
Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged)
Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
+ QML_NAMED_ELEMENT(ItemParticle)
+ QML_ATTACHED(QQuickItemParticleAttached)
public:
explicit QQuickItemParticle(QQuickItem *parent = 0);
~QQuickItemParticle();
@@ -127,13 +129,14 @@ class QQuickItemParticleAttached : public QObject
Q_PROPERTY(QQuickItemParticle* particle READ particle CONSTANT);
public:
QQuickItemParticleAttached(QObject* parent)
- : QObject(parent), m_mp(0)
+ : QObject(parent), m_mp(0), m_parentItem(nullptr)
{;}
QQuickItemParticle* particle() const { return m_mp; }
void detach(){Q_EMIT detached();}
void attach(){Q_EMIT attached();}
private:
QQuickItemParticle* m_mp;
+ QPointer<QQuickItem> m_parentItem;
friend class QQuickItemParticle;
Q_SIGNALS:
void detached();
@@ -142,6 +145,4 @@ Q_SIGNALS:
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickItemParticle, QML_HAS_ATTACHED_PROPERTIES)
-
#endif // ITEMPARTICLE_H
diff --git a/src/particles/qquicklineextruder_p.h b/src/particles/qquicklineextruder_p.h
index 306f3a1dd6..76ac5aaf11 100644
--- a/src/particles/qquicklineextruder_p.h
+++ b/src/particles/qquicklineextruder_p.h
@@ -57,6 +57,7 @@ class QQuickLineExtruder : public QQuickParticleExtruder
Q_OBJECT
//Default is topleft to bottom right. Flipped makes it topright to bottom left
Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged)
+ QML_NAMED_ELEMENT(LineShape)
public:
explicit QQuickLineExtruder(QObject *parent = 0);
diff --git a/src/particles/qquickmaskextruder_p.h b/src/particles/qquickmaskextruder_p.h
index bbb61b0d28..419d162811 100644
--- a/src/particles/qquickmaskextruder_p.h
+++ b/src/particles/qquickmaskextruder_p.h
@@ -61,6 +61,7 @@ class QQuickMaskExtruder : public QQuickParticleExtruder
{
Q_OBJECT
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ QML_NAMED_ELEMENT(MaskShape)
public:
explicit QQuickMaskExtruder(QObject *parent = 0);
QPointF extrude(const QRectF &) override;
diff --git a/src/particles/qquickparticleaffector.cpp b/src/particles/qquickparticleaffector.cpp
index ffbd5674f0..3e3346997e 100644
--- a/src/particles/qquickparticleaffector.cpp
+++ b/src/particles/qquickparticleaffector.cpp
@@ -126,8 +126,6 @@ QT_BEGIN_NAMESPACE
signal with a high-volume particle system.
(\a {x}, \a {y}) is the particle's current position.
-
- The corresponding handler is \c onAffected.
*/
QQuickParticleAffector::QQuickParticleAffector(QQuickItem *parent) :
QQuickItem(parent), m_needsReset(false), m_ignoresTime(false), m_onceOff(false), m_enabled(true)
diff --git a/src/particles/qquickparticleaffector_p.h b/src/particles/qquickparticleaffector_p.h
index 5c9652bc32..fd4887333e 100644
--- a/src/particles/qquickparticleaffector_p.h
+++ b/src/particles/qquickparticleaffector_p.h
@@ -68,6 +68,9 @@ class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleAffector : public QQuickItem
Q_PROPERTY(bool once READ onceOff WRITE setOnceOff NOTIFY onceChanged)
Q_PROPERTY(QQuickParticleExtruder* shape READ shape WRITE setShape NOTIFY shapeChanged)
+ QML_NAMED_ELEMENT(ParticleAffector)
+ QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.")
+
public:
explicit QQuickParticleAffector(QQuickItem *parent = 0);
virtual void affectSystem(qreal dt);
diff --git a/src/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp
index c0d9fa941d..3e9d7c02a9 100644
--- a/src/particles/qquickparticleemitter.cpp
+++ b/src/particles/qquickparticleemitter.cpp
@@ -196,8 +196,6 @@ QT_BEGIN_NAMESPACE
\note JavaScript is slower to execute, so it is not recommended to use this in
high-volume particle systems.
-
- The corresponding handler is \c onEmitParticles.
*/
/*! \qmlmethod QtQuick.Particles::Emitter::burst(int count)
diff --git a/src/particles/qquickparticleemitter_p.h b/src/particles/qquickparticleemitter_p.h
index 64b9bcef32..b97d3f812a 100644
--- a/src/particles/qquickparticleemitter_p.h
+++ b/src/particles/qquickparticleemitter_p.h
@@ -83,6 +83,7 @@ class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleEmitter : public QQuickItem
Q_PROPERTY(QQuickDirection *velocity READ velocity WRITE setVelocity NOTIFY velocityChanged)
Q_PROPERTY(QQuickDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged)
Q_PROPERTY(qreal velocityFromMovement READ velocityFromMovement WRITE setVelocityFromMovement NOTIFY velocityFromMovementChanged)
+ QML_NAMED_ELEMENT(Emitter)
public:
explicit QQuickParticleEmitter(QQuickItem *parent = 0);
diff --git a/src/particles/qquickparticleextruder_p.h b/src/particles/qquickparticleextruder_p.h
index 38b2e34c77..24f7a0a2fa 100644
--- a/src/particles/qquickparticleextruder_p.h
+++ b/src/particles/qquickparticleextruder_p.h
@@ -54,6 +54,7 @@
#include <QObject>
#include <QRectF>
#include <QPointF>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -61,6 +62,9 @@ class QQuickParticleExtruder : public QObject
{
Q_OBJECT
+ QML_NAMED_ELEMENT(ParticleExtruder)
+ QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.")
+
public:
explicit QQuickParticleExtruder(QObject *parent = 0);
virtual QPointF extrude(const QRectF &);
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/qquickparticlegroup_p.h b/src/particles/qquickparticlegroup_p.h
index 0314234569..8d068fbe9c 100644
--- a/src/particles/qquickparticlegroup_p.h
+++ b/src/particles/qquickparticlegroup_p.h
@@ -66,6 +66,7 @@ class QQuickParticleGroup : public QQuickStochasticState, public QQmlParserStatu
//Intercept children requests and assign to the group & system
Q_PROPERTY(QQmlListProperty<QObject> particleChildren READ particleChildren DESIGNABLE false)//### Hidden property for in-state system definitions - ought not to be used in actual "Sprite" states
Q_CLASSINFO("DefaultProperty", "particleChildren")
+ QML_NAMED_ELEMENT(ParticleGroup)
Q_INTERFACES(QQmlParserStatus)
public:
diff --git a/src/particles/qquickparticlepainter_p.h b/src/particles/qquickparticlepainter_p.h
index 16fc6b6f45..e3d13b8a21 100644
--- a/src/particles/qquickparticlepainter_p.h
+++ b/src/particles/qquickparticlepainter_p.h
@@ -64,6 +64,9 @@ class QQuickParticlePainter : public QQuickItem
Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged)
Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged)
+ QML_NAMED_ELEMENT(ParticlePainter)
+ QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.")
+
public: // data
typedef QQuickParticleVarLengthArray<QQuickParticleGroupData::ID, 4> GroupIDs;
diff --git a/src/particles/qquickparticlesmodule.cpp b/src/particles/qquickparticlesmodule.cpp
index 03f47a3961..801af079e6 100644
--- a/src/particles/qquickparticlesmodule.cpp
+++ b/src/particles/qquickparticlesmodule.cpp
@@ -81,50 +81,6 @@ QT_BEGIN_NAMESPACE
void QQuickParticlesModule::defineModule()
{
initResources();
-
- const char* uri = "QtQuick.Particles";
-
- qmlRegisterType<QQuickParticleSystem>(uri, 2, 0, "ParticleSystem");
- qmlRegisterType<QQuickParticleGroup>(uri, 2, 0, "ParticleGroup");
-
- qmlRegisterType<QQuickImageParticle>(uri, 2, 0, "ImageParticle");
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickCustomParticle>(uri, 2, 0, "CustomParticle");
-#endif
- qmlRegisterType<QQuickItemParticle>(uri, 2, 0, "ItemParticle");
-
- qmlRegisterType<QQuickParticleEmitter>(uri, 2, 0, "Emitter");
- qmlRegisterType<QQuickTrailEmitter>(uri, 2, 0, "TrailEmitter");
-
- qmlRegisterType<QQuickEllipseExtruder>(uri, 2, 0, "EllipseShape");
- qmlRegisterType<QQuickRectangleExtruder>(uri, 2, 0, "RectangleShape");
- qmlRegisterType<QQuickLineExtruder>(uri, 2, 0, "LineShape");
- qmlRegisterType<QQuickMaskExtruder>(uri, 2, 0, "MaskShape");
-
- qmlRegisterType<QQuickPointDirection>(uri, 2, 0, "PointDirection");
- qmlRegisterType<QQuickAngleDirection>(uri, 2, 0, "AngleDirection");
- qmlRegisterType<QQuickTargetDirection>(uri, 2, 0, "TargetDirection");
- qmlRegisterType<QQuickCumulativeDirection>(uri, 2, 0, "CumulativeDirection");
-
- qmlRegisterType<QQuickCustomAffector>(uri, 2, 0, "Affector");
- qmlRegisterType<QQuickWanderAffector>(uri, 2, 0, "Wander");
- qmlRegisterType<QQuickFrictionAffector>(uri, 2, 0, "Friction");
- qmlRegisterType<QQuickAttractorAffector>(uri, 2, 0, "Attractor");
- qmlRegisterType<QQuickGravityAffector>(uri, 2, 0, "Gravity");
- qmlRegisterType<QQuickAgeAffector>(uri, 2, 0, "Age");
- qmlRegisterType<QQuickSpriteGoalAffector>(uri, 2, 0, "SpriteGoal");
- qmlRegisterType<QQuickGroupGoalAffector>(uri, 2, 0, "GroupGoal");
- qmlRegisterType<QQuickTurbulenceAffector>(uri, 2, 0 , "Turbulence");
-
- //Exposed just for completeness
- qmlRegisterUncreatableType<QQuickParticleAffector>(uri, 2, 0, "ParticleAffector",
- QStringLiteral("Abstract type. Use one of the inheriting types instead."));
- qmlRegisterUncreatableType<QQuickParticlePainter>(uri, 2, 0, "ParticlePainter",
- QStringLiteral("Abstract type. Use one of the inheriting types instead."));
- qmlRegisterUncreatableType<QQuickParticleExtruder>(uri, 2, 0, "ParticleExtruder",
- QStringLiteral("Abstract type. Use one of the inheriting types instead."));
- qmlRegisterUncreatableType<QQuickDirection>(uri, 2, 0, "NullVector",
- QStringLiteral("Abstract type. Use one of the inheriting types instead."));
}
QT_END_NAMESPACE
diff --git a/src/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h
index c602183e74..7c0a1ffd7d 100644
--- a/src/particles/qquickparticlesystem_p.h
+++ b/src/particles/qquickparticlesystem_p.h
@@ -351,6 +351,7 @@ class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleSystem : public QQuickItem
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged)
+ QML_NAMED_ELEMENT(ParticleSystem)
public:
explicit QQuickParticleSystem(QQuickItem *parent = nullptr);
diff --git a/src/particles/qquickpointattractor_p.h b/src/particles/qquickpointattractor_p.h
index 47985b5e82..28bbaaa84f 100644
--- a/src/particles/qquickpointattractor_p.h
+++ b/src/particles/qquickpointattractor_p.h
@@ -62,6 +62,7 @@ class QQuickAttractorAffector : public QQuickParticleAffector
Q_PROPERTY(qreal pointY READ pointY WRITE setPointY NOTIFY pointYChanged)
Q_PROPERTY(AffectableParameters affectedParameter READ affectedParameter WRITE setAffectedParameter NOTIFY affectedParameterChanged)
Q_PROPERTY(Proportion proportionalToDistance READ proportionalToDistance WRITE setProportionalToDistance NOTIFY proportionalToDistanceChanged)
+ QML_NAMED_ELEMENT(Attractor)
public:
enum Proportion{
diff --git a/src/particles/qquickpointdirection_p.h b/src/particles/qquickpointdirection_p.h
index a80be928ad..9103a570c9 100644
--- a/src/particles/qquickpointdirection_p.h
+++ b/src/particles/qquickpointdirection_p.h
@@ -61,6 +61,7 @@ class QQuickPointDirection : public QQuickDirection
Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
Q_PROPERTY(qreal xVariation READ xVariation WRITE setXVariation NOTIFY xVariationChanged)
Q_PROPERTY(qreal yVariation READ yVariation WRITE setYVariation NOTIFY yVariationChanged)
+ QML_NAMED_ELEMENT(PointDirection)
public:
explicit QQuickPointDirection(QObject *parent = 0);
QPointF sample(const QPointF &from) override;
diff --git a/src/particles/qquickrectangleextruder_p.h b/src/particles/qquickrectangleextruder_p.h
index 630cf3050d..7c0a6c2bf1 100644
--- a/src/particles/qquickrectangleextruder_p.h
+++ b/src/particles/qquickrectangleextruder_p.h
@@ -59,6 +59,7 @@ class QQuickRectangleExtruder : public QQuickParticleExtruder
{
Q_OBJECT
Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)
+ QML_NAMED_ELEMENT(RectangleShape)
public:
explicit QQuickRectangleExtruder(QObject *parent = 0);
diff --git a/src/particles/qquickspritegoal_p.h b/src/particles/qquickspritegoal_p.h
index e569603550..d5f9bb88ae 100644
--- a/src/particles/qquickspritegoal_p.h
+++ b/src/particles/qquickspritegoal_p.h
@@ -63,6 +63,7 @@ class QQuickSpriteGoalAffector : public QQuickParticleAffector
Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged)
Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged)
Q_PROPERTY(bool systemStates READ systemStates WRITE setSystemStates NOTIFY systemStatesChanged)
+ QML_NAMED_ELEMENT(SpriteGoal)
public:
explicit QQuickSpriteGoalAffector(QQuickItem *parent = 0);
diff --git a/src/particles/qquicktargetdirection_p.h b/src/particles/qquicktargetdirection_p.h
index 13e826743e..232d375d8c 100644
--- a/src/particles/qquicktargetdirection_p.h
+++ b/src/particles/qquicktargetdirection_p.h
@@ -51,6 +51,8 @@
// We mean it.
//
#include "qquickdirection_p.h"
+#include <QtQml/qqml.h>
+
QT_BEGIN_NAMESPACE
class QQuickItem;
@@ -68,6 +70,7 @@ class QQuickTargetDirection : public QQuickDirection
Q_PROPERTY(bool proportionalMagnitude READ proportionalMagnitude WRITE setProportionalMagnitude NOTIFY proprotionalMagnitudeChanged)
Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged)
Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged)
+ QML_NAMED_ELEMENT(TargetDirection)
public:
explicit QQuickTargetDirection(QObject *parent = 0);
diff --git a/src/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp
index 102dc7bd2e..5720460bae 100644
--- a/src/particles/qquicktrailemitter.cpp
+++ b/src/particles/qquicktrailemitter.cpp
@@ -123,7 +123,7 @@ QQuickTrailEmitter::QQuickTrailEmitter(QQuickItem *parent) :
This signal is emitted when particles are emitted from the \a followed particle. \a particles contains an array of particle objects which can be directly manipulated.
- The corresponding handler is \c onEmitFollowParticles. If you use this signal handler, emitParticles will not be emitted.
+ If you use this signal handler, emitParticles will not be emitted.
*/
bool QQuickTrailEmitter::isEmitFollowConnected()
diff --git a/src/particles/qquicktrailemitter_p.h b/src/particles/qquicktrailemitter_p.h
index 22b96afd25..270bec52cf 100644
--- a/src/particles/qquicktrailemitter_p.h
+++ b/src/particles/qquicktrailemitter_p.h
@@ -64,6 +64,7 @@ class QQuickTrailEmitter : public QQuickParticleEmitter
Q_PROPERTY(QQuickParticleExtruder* emitShape READ emissonShape WRITE setEmissionShape NOTIFY emissionShapeChanged)
Q_PROPERTY(qreal emitHeight READ emitterYVariation WRITE setEmitterYVariation NOTIFY emitterYVariationChanged)
Q_PROPERTY(qreal emitWidth READ emitterXVariation WRITE setEmitterXVariation NOTIFY emitterXVariationChanged)
+ QML_NAMED_ELEMENT(TrailEmitter)
public:
enum EmitSize {
diff --git a/src/particles/qquickturbulence_p.h b/src/particles/qquickturbulence_p.h
index e73f3ba153..52011381e4 100644
--- a/src/particles/qquickturbulence_p.h
+++ b/src/particles/qquickturbulence_p.h
@@ -62,7 +62,9 @@ class QQuickTurbulenceAffector : public QQuickParticleAffector
Q_OBJECT
Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
Q_PROPERTY(QUrl noiseSource READ noiseSource WRITE setNoiseSource NOTIFY noiseSourceChanged)
- public:
+ QML_NAMED_ELEMENT(Turbulence)
+
+public:
explicit QQuickTurbulenceAffector(QQuickItem *parent = 0);
~QQuickTurbulenceAffector();
void affectSystem(qreal dt) override;
diff --git a/src/particles/qquickwander_p.h b/src/particles/qquickwander_p.h
index 0ad19d4d13..bf7acdacfb 100644
--- a/src/particles/qquickwander_p.h
+++ b/src/particles/qquickwander_p.h
@@ -71,6 +71,7 @@ class QQuickWanderAffector : public QQuickParticleAffector
Q_PROPERTY(qreal xVariance READ xVariance WRITE setXVariance NOTIFY xVarianceChanged)
Q_PROPERTY(qreal yVariance READ yVariance WRITE setYVariance NOTIFY yVarianceChanged)
Q_PROPERTY(AffectableParameters affectedParameter READ affectedParameter WRITE setAffectedParameter NOTIFY affectedParameterChanged)
+ QML_NAMED_ELEMENT(Wander)
public:
enum AffectableParameters {
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/particles/shaders_ng/imageparticle_colored.frag.qsb b/src/particles/shaders_ng/imageparticle_colored.frag.qsb
index 7ae640d224..106109271e 100644
--- a/src/particles/shaders_ng/imageparticle_colored.frag.qsb
+++ b/src/particles/shaders_ng/imageparticle_colored.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_colored.vert.qsb b/src/particles/shaders_ng/imageparticle_colored.vert.qsb
index 0e2938b72c..e29c1029c1 100644
--- a/src/particles/shaders_ng/imageparticle_colored.vert.qsb
+++ b/src/particles/shaders_ng/imageparticle_colored.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_deformed.frag.qsb b/src/particles/shaders_ng/imageparticle_deformed.frag.qsb
index fa9d9d35bb..d2f74b40df 100644
--- a/src/particles/shaders_ng/imageparticle_deformed.frag.qsb
+++ b/src/particles/shaders_ng/imageparticle_deformed.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_deformed.vert.qsb b/src/particles/shaders_ng/imageparticle_deformed.vert.qsb
index 65092d5b26..c2e5bab0cb 100644
--- a/src/particles/shaders_ng/imageparticle_deformed.vert.qsb
+++ b/src/particles/shaders_ng/imageparticle_deformed.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_simple.frag.qsb b/src/particles/shaders_ng/imageparticle_simple.frag.qsb
index a5874cba24..8031dc8765 100644
--- a/src/particles/shaders_ng/imageparticle_simple.frag.qsb
+++ b/src/particles/shaders_ng/imageparticle_simple.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_simple.vert.qsb b/src/particles/shaders_ng/imageparticle_simple.vert.qsb
index da815d7e19..03f71415f5 100644
--- a/src/particles/shaders_ng/imageparticle_simple.vert.qsb
+++ b/src/particles/shaders_ng/imageparticle_simple.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_sprite.frag.qsb b/src/particles/shaders_ng/imageparticle_sprite.frag.qsb
index 778550344b..847de59aa6 100644
--- a/src/particles/shaders_ng/imageparticle_sprite.frag.qsb
+++ b/src/particles/shaders_ng/imageparticle_sprite.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_sprite.vert.qsb b/src/particles/shaders_ng/imageparticle_sprite.vert.qsb
index 45b21ace8a..e310af8fc8 100644
--- a/src/particles/shaders_ng/imageparticle_sprite.vert.qsb
+++ b/src/particles/shaders_ng/imageparticle_sprite.vert.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_tabled.frag.qsb b/src/particles/shaders_ng/imageparticle_tabled.frag.qsb
index c5dcc2c68f..6fe2d5a3f2 100644
--- a/src/particles/shaders_ng/imageparticle_tabled.frag.qsb
+++ b/src/particles/shaders_ng/imageparticle_tabled.frag.qsb
Binary files differ
diff --git a/src/particles/shaders_ng/imageparticle_tabled.vert.qsb b/src/particles/shaders_ng/imageparticle_tabled.vert.qsb
index ea42607570..740f6b6769 100644
--- a/src/particles/shaders_ng/imageparticle_tabled.vert.qsb
+++ b/src/particles/shaders_ng/imageparticle_tabled.vert.qsb
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
index bdcbf0023a..d435e82390 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
@@ -94,7 +94,7 @@ qint64 NullDevice::writeData(const char *data, qint64 len)
// (otherwise we assert in QVariant::operator<< when actually saving it)
static bool isSaveable(const QVariant &value)
{
- const int valType = static_cast<int>(value.type());
+ const int valType = static_cast<int>(value.userType());
if (valType >= QMetaType::User)
return false;
NullDevice nullDevice;
@@ -220,7 +220,7 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const
//QObject * is not streamable.
//Convert all such instances to a String value
- if (value.type() == QVariant::List) {
+ if (value.userType() == QMetaType::QVariantList) {
QVariantList contents;
QVariantList list = value.toList();
int count = list.size();
@@ -230,7 +230,7 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const
return contents;
}
- if (value.type() == QVariant::Map) {
+ if (value.userType() == QMetaType::QVariantMap) {
QVariantMap contents;
const auto map = value.toMap();
for (auto i = map.cbegin(), end = map.cend(); i != end; ++i)
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_local/qlocalclientconnection.cpp b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
index 1708166a8a..e641a901ad 100644
--- a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
+++ b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
@@ -133,7 +133,7 @@ bool QLocalClientConnection::connectToServer()
connect(m_socket, &QLocalSocket::connected,
this, &QLocalClientConnection::connectionEstablished);
connect(m_socket, static_cast<void(QLocalSocket::*)(QLocalSocket::LocalSocketError)>(
- &QLocalSocket::error), m_socket, [this](QLocalSocket::LocalSocketError) {
+ &QLocalSocket::errorOccurred), m_socket, [this](QLocalSocket::LocalSocketError) {
m_socket->disconnectFromServer();
m_socket->connectToServer(m_filename);
}, Qt::QueuedConnection);
diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
index bf73440a39..c504ea605a 100644
--- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
+++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
@@ -183,7 +183,7 @@ QQmlNativeDebugConnector::QQmlNativeDebugConnector()
: m_blockingMode(false)
{
const QString args = commandLineArguments();
- const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), QString::SkipEmptyParts);
+ const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), Qt::SkipEmptyParts);
QStringList services;
for (const QStringRef &strArgument : lstjsDebugArguments) {
if (strArgument == QLatin1String("block")) {
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/qqmlpreviewfileengine.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp
index 72de52bbe1..5e78539155 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp
@@ -195,7 +195,7 @@ QAbstractFileEngine::FileFlags QQmlPreviewFileEngine::fileFlags(
if (m_fallback)
return m_fallback->fileFlags(type);
- QAbstractFileEngine::FileFlags ret = 0;
+ QAbstractFileEngine::FileFlags ret;
if (type & PermsMask) {
ret |= QAbstractFileEngine::FileFlags(
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.cpp
index bb43f75c63..acd19a6f73 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.cpp
@@ -54,7 +54,6 @@ QQmlPreviewFileLoader::QQmlPreviewFileLoader(QQmlPreviewServiceImpl *service) :
m_blacklist.blacklist(":/qt-project.org");
m_blacklist.blacklist(":/QtQuick/Controls/Styles");
m_blacklist.blacklist(":/ExtrasImports/QtQuick/Controls/Styles");
- m_blacklist.blacklist(":/qgradient");
// Target specific configuration should not replaced with files from the host.
m_blacklist.blacklist("/etc");
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_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
index a688e98b3f..4702bc3c33 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
@@ -153,7 +153,7 @@ void QQmlProfilerAdapter::receiveData(const QVector<QQmlProfilerData> &new_data,
if (locations.isEmpty())
locations = new_locations;
else
- locations.unite(new_locations);
+ locations.insert(new_locations);
service->dataReady(this);
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
index 12c36f3dd6..fb2a28ea01 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
@@ -168,7 +168,7 @@ void QV4ProfilerAdapter::receiveData(
if (m_functionLocations.isEmpty())
m_functionLocations = locations;
else
- m_functionLocations.unite(locations);
+ m_functionLocations.insert(locations);
if (m_functionCallData.isEmpty())
m_functionCallData = functionCallData;
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index cc663cd6b3..4d68a4508b 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -345,7 +345,7 @@ void QQmlDebugServerImpl::parseArguments()
QString fileName;
QStringList services;
- const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), QString::SkipEmptyParts);
+ const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), Qt::SkipEmptyParts);
for (auto argsIt = lstjsDebugArguments.begin(), argsItEnd = lstjsDebugArguments.end(); argsIt != argsItEnd; ++argsIt) {
const QStringRef &strArgument = *argsIt;
if (strArgument.startsWith(QLatin1String("port:"))) {
@@ -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/plugins/scenegraph/d3d12/d3d12.pro b/src/plugins/scenegraph/d3d12/d3d12.pro
index 9cca5458ee..7192efe449 100644
--- a/src/plugins/scenegraph/d3d12/d3d12.pro
+++ b/src/plugins/scenegraph/d3d12/d3d12.pro
@@ -6,6 +6,18 @@ PLUGIN_TYPE = scenegraph
PLUGIN_CLASS_NAME = QSGD3D12Adaptation
load(qt_plugin)
+TRACEPOINT_PROVIDER = $$PWD/d3d12.tracepoints
+CONFIG += qt_tracepoints
+debug_and_release {
+ CONFIG(debug, debug|release) {
+ INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/debug
+ } else {
+ INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/release
+ }
+} else {
+ INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/
+}
+
QMAKE_TARGET_PRODUCT = "Qt Quick D3D12 Renderer (Qt $$QT_VERSION)"
QMAKE_TARGET_DESCRIPTION = "Quick D3D12 Renderer for Qt."
diff --git a/src/plugins/scenegraph/d3d12/d3d12.tracepoints b/src/plugins/scenegraph/d3d12/d3d12.tracepoints
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/plugins/scenegraph/d3d12/d3d12.tracepoints
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h
index b30994fe0d..b80de28bed 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h
@@ -363,8 +363,8 @@ public:
uint genTexture();
void createTexture(uint id, const QSize &size, QImage::Format format, TextureCreateFlags flags);
void queueTextureResize(uint id, const QSize &size);
- void queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos = QPoint(), TextureUploadFlags flags = 0);
- void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos, TextureUploadFlags flags = 0);
+ void queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos = QPoint(), TextureUploadFlags flags = { });
+ void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos, TextureUploadFlags flags = { });
void releaseTexture(uint id);
void useTexture(uint id);
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp
index 4a6894e69e..79ffee7689 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp
@@ -49,6 +49,8 @@
#include <QGuiApplication>
#include <QScreen>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
// NOTE: Avoid categorized logging. It is slow.
@@ -403,6 +405,8 @@ void QSGD3D12RenderLoop::renderWindow(QQuickWindow *window)
return;
}
+ Q_TRACE_SCOPE(QSG_renderWindow);
+
if (!data.grabOnly)
wd->flushFrameSynchronousEvents();
@@ -412,14 +416,17 @@ void QSGD3D12RenderLoop::renderWindow(QQuickWindow *window)
if (profileFrames)
renderTimer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
+ Q_TRACE(QSG_polishItems_entry);
wd->polishItems();
if (profileFrames)
polishTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -462,15 +469,19 @@ void QSGD3D12RenderLoop::renderWindow(QQuickWindow *window)
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
wd->renderSceneGraph(window->size());
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (!data.grabOnly) {
// The engine is able to have multiple frames in flight. This in effect is
@@ -497,6 +508,7 @@ void QSGD3D12RenderLoop::renderWindow(QQuickWindow *window)
qint64 swapTime = 0;
if (profileFrames)
swapTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
index 4302a9119b..91a35627ea 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
@@ -52,6 +52,8 @@
#include <QQueue>
#include <QGuiApplication>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
// NOTE: Avoid categorized logging. It is slow.
@@ -560,11 +562,13 @@ void QSGD3D12RenderThread::sync(bool inExpose)
void QSGD3D12RenderThread::syncAndRender()
{
+ Q_TRACE_SCOPE(QSG_syncAndRender);
if (Q_UNLIKELY(debug_time())) {
sinceLastTime = threadTimer.nsecsElapsed();
threadTimer.start();
}
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
+ Q_TRACE(QSG_sync_entry);
QElapsedTimer waitTimer;
waitTimer.start();
@@ -587,6 +591,7 @@ void QSGD3D12RenderThread::syncAndRender()
if (Q_UNLIKELY(debug_time()))
syncTime = threadTimer.nsecsElapsed();
#endif
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
@@ -598,6 +603,7 @@ void QSGD3D12RenderThread::syncAndRender()
msleep(waitTime);
return;
}
+ Q_TRACE(QSG_render_entry);
if (Q_UNLIKELY(debug_loop()))
qDebug("RT - rendering started");
@@ -623,8 +629,10 @@ void QSGD3D12RenderThread::syncAndRender()
wd->renderSceneGraph(engine->windowSize());
if (Q_UNLIKELY(debug_time()))
renderTime = threadTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
// The engine is able to have multiple frames in flight. This in effect is
// similar to BufferQueueingOpenGL. Provide an env var to force the
@@ -641,8 +649,10 @@ void QSGD3D12RenderThread::syncAndRender()
// blockOnEachFrame is not used, but emit it for compatibility.
wd->fireFrameSwapped();
} else {
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync, 1);
+ Q_TRACE(QSG_swap_entry);
if (Q_UNLIKELY(debug_loop()))
qDebug("RT - window not ready, skipping render");
}
@@ -664,6 +674,7 @@ void QSGD3D12RenderThread::syncAndRender()
int((renderTime - syncTime) / 1000000),
int(threadTimer.elapsed() - renderTime / 1000000));
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
@@ -1103,6 +1114,8 @@ void QSGD3D12ThreadedRenderLoop::polishAndSync(WindowData *w, bool inExpose)
return;
}
+ Q_TRACE_SCOPE(QSG_polishAndSync);
+
// Flush pending touch events.
QQuickWindowPrivate::get(window)->flushFrameSynchronousEvents();
// The delivery of the event might have caused the window to stop rendering
@@ -1120,14 +1133,17 @@ void QSGD3D12ThreadedRenderLoop::polishAndSync(WindowData *w, bool inExpose)
if (Q_UNLIKELY(debug_time()))
timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
+ Q_TRACE(QSG_polishItems_entry);
QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
wd->polishItems();
if (Q_UNLIKELY(debug_time()))
polishTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncPolish);
+ Q_TRACE(QSG_wait_entry);
w->updateDuringSync = false;
@@ -1144,8 +1160,11 @@ void QSGD3D12ThreadedRenderLoop::polishAndSync(WindowData *w, bool inExpose)
qDebug("polishAndSync - wait for sync");
if (Q_UNLIKELY(debug_time()))
waitTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_wait_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncWait);
+ Q_TRACE(QSG_sync_entry);
+
w->thread->waitCondition.wait(&w->thread->mutex);
lockedForSync = false;
w->thread->mutex.unlock();
@@ -1154,8 +1173,10 @@ void QSGD3D12ThreadedRenderLoop::polishAndSync(WindowData *w, bool inExpose)
if (Q_UNLIKELY(debug_time()))
syncTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncSync);
+ Q_TRACE(QSG_animations_entry);
if (!animationTimer && anim->isRunning()) {
if (Q_UNLIKELY(debug_loop()))
@@ -1177,6 +1198,7 @@ void QSGD3D12ThreadedRenderLoop::polishAndSync(WindowData *w, bool inExpose)
<< ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000
<< " - (on gui thread) " << window;
+ Q_TRACE(QSG_animations_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncAnimations);
}
diff --git a/src/plugins/scenegraph/openvg/openvg.pro b/src/plugins/scenegraph/openvg/openvg.pro
index 43c2636343..7f9f4bfec5 100644
--- a/src/plugins/scenegraph/openvg/openvg.pro
+++ b/src/plugins/scenegraph/openvg/openvg.pro
@@ -6,6 +6,18 @@ PLUGIN_TYPE = scenegraph
PLUGIN_CLASS_NAME = QSGOpenVGAdaptation
load(qt_plugin)
+TRACEPOINT_PROVIDER = $$PWD/openvg.tracepoints
+CONFIG += qt_tracepoints
+debug_and_release {
+ CONFIG(debug, debug|release) {
+ INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/debug
+ } else {
+ INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/release
+ }
+} else {
+ INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/
+}
+
QMAKE_TARGET_PRODUCT = "Qt Quick OpenVG Renderer (Qt $$QT_VERSION)"
QMAKE_TARGET_DESCRIPTION = "Quick OpenVG Renderer for Qt."
diff --git a/src/plugins/scenegraph/openvg/openvg.tracepoints b/src/plugins/scenegraph/openvg/openvg.tracepoints
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/openvg.tracepoints
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp
index 85651ece9d..90ccab2682 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp
@@ -47,6 +47,8 @@
#include <private/qquickwindow_p.h>
#include <private/qquickprofiler_p.h>
+#include <qtquick_tracepoints_p.h>
+
#include "qopenvgcontext_p.h"
QT_BEGIN_NAMESPACE
@@ -171,6 +173,8 @@ void QSGOpenVGRenderLoop::renderWindow(QQuickWindow *window)
if (!cd->isRenderable() || !m_windows.contains(window))
return;
+ Q_TRACE_SCOPE(QSG_renderWindow);
+
WindowData &data = const_cast<WindowData &>(m_windows[window]);
if (vg == nullptr) {
@@ -198,14 +202,17 @@ void QSGOpenVGRenderLoop::renderWindow(QQuickWindow *window)
if (profileFrames)
renderTimer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
+ Q_TRACE(QSG_polishItems_entry);
cd->polishItems();
if (profileFrames)
polishTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -214,8 +221,10 @@ void QSGOpenVGRenderLoop::renderWindow(QQuickWindow *window)
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
// setup coordinate system for window
vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
@@ -227,8 +236,10 @@ void QSGOpenVGRenderLoop::renderWindow(QQuickWindow *window)
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (data.grabOnly) {
grabContent = vg->readFramebuffer(window->size() * window->effectiveDevicePixelRatio());
@@ -243,6 +254,7 @@ void QSGOpenVGRenderLoop::renderWindow(QQuickWindow *window)
qint64 swapTime = 0;
if (profileFrames)
swapTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/qml/Qt5QmlConfigExtras.cmake.in b/src/qml/Qt5QmlConfigExtras.cmake.in
index 9ddb9885cd..4242143bca 100644
--- a/src/qml/Qt5QmlConfigExtras.cmake.in
+++ b/src/qml/Qt5QmlConfigExtras.cmake.in
@@ -1,5 +1,7 @@
-file(GLOB _qt5qml_other_plugins "${CMAKE_CURRENT_LIST_DIR}/Qt5Qml_*Factory.cmake")
+if(QT5_STRICT_PLUGIN_GLOB OR Qt5Qml_STRICT_PLUGIN_GLOB)
+ file(GLOB _qt5qml_other_plugins "${CMAKE_CURRENT_LIST_DIR}/Qt5Qml_*Factory.cmake")
-foreach(_other_plugin ${_qt5qml_other_plugins})
- include(${_other_plugin} OPTIONAL)
-endforeach()
+ foreach(_other_plugin ${_qt5qml_other_plugins})
+ include(${_other_plugin} OPTIONAL)
+ endforeach()
+endif()
diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp
index 7a784a2b35..82f3e53d68 100644
--- a/src/qml/animations/qabstractanimationjob.cpp
+++ b/src/qml/animations/qabstractanimationjob.cpp
@@ -45,8 +45,6 @@
#include "private/qqmlengine_p.h"
#include "private/qqmlglobal_p.h"
-#define DEFAULT_TIMER_INTERVAL 16
-
QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD
@@ -641,7 +639,7 @@ void QAbstractAnimationJob::removeAnimationChangeListener(QAnimationJobChangeLis
void QAbstractAnimationJob::debugAnimation(QDebug d) const
{
- d << "AbstractAnimationJob(" << hex << (const void *) this << dec << ") state:"
+ d << "AbstractAnimationJob(" << Qt::hex << (const void *) this << Qt::dec << ") state:"
<< m_state << "duration:" << duration();
}
diff --git a/src/qml/animations/qcontinuinganimationgroupjob.cpp b/src/qml/animations/qcontinuinganimationgroupjob.cpp
index 10096bf19c..88c0e9e60e 100644
--- a/src/qml/animations/qcontinuinganimationgroupjob.cpp
+++ b/src/qml/animations/qcontinuinganimationgroupjob.cpp
@@ -120,7 +120,7 @@ void QContinuingAnimationGroupJob::uncontrolledAnimationFinished(QAbstractAnimat
void QContinuingAnimationGroupJob::debugAnimation(QDebug d) const
{
- d << "ContinuingAnimationGroupJob(" << hex << (const void *) this << dec << ")";
+ d << "ContinuingAnimationGroupJob(" << Qt::hex << (const void *) this << Qt::dec << ")";
debugChildren(d);
}
diff --git a/src/qml/animations/qparallelanimationgroupjob.cpp b/src/qml/animations/qparallelanimationgroupjob.cpp
index 700fdf9fd9..420a934ba2 100644
--- a/src/qml/animations/qparallelanimationgroupjob.cpp
+++ b/src/qml/animations/qparallelanimationgroupjob.cpp
@@ -239,7 +239,7 @@ void QParallelAnimationGroupJob::uncontrolledAnimationFinished(QAbstractAnimatio
void QParallelAnimationGroupJob::debugAnimation(QDebug d) const
{
- d << "ParallelAnimationGroupJob(" << hex << (const void *) this << dec << ")";
+ d << "ParallelAnimationGroupJob(" << Qt::hex << (const void *) this << Qt::dec << ")";
debugChildren(d);
}
diff --git a/src/qml/animations/qpauseanimationjob.cpp b/src/qml/animations/qpauseanimationjob.cpp
index 0652ed578b..aac04d2f8d 100644
--- a/src/qml/animations/qpauseanimationjob.cpp
+++ b/src/qml/animations/qpauseanimationjob.cpp
@@ -67,7 +67,7 @@ void QPauseAnimationJob::updateCurrentTime(int)
void QPauseAnimationJob::debugAnimation(QDebug d) const
{
- d << "PauseAnimationJob(" << hex << (const void *) this << dec << ")" << "duration:" << m_duration;
+ d << "PauseAnimationJob(" << Qt::hex << (const void *) this << Qt::dec << ")" << "duration:" << m_duration;
}
QT_END_NAMESPACE
diff --git a/src/qml/animations/qsequentialanimationgroupjob.cpp b/src/qml/animations/qsequentialanimationgroupjob.cpp
index d98546122f..dc57444b32 100644
--- a/src/qml/animations/qsequentialanimationgroupjob.cpp
+++ b/src/qml/animations/qsequentialanimationgroupjob.cpp
@@ -426,7 +426,7 @@ void QSequentialAnimationGroupJob::animationRemoved(QAbstractAnimationJob *anim,
void QSequentialAnimationGroupJob::debugAnimation(QDebug d) const
{
- d << "SequentialAnimationGroupJob(" << hex << (const void *) this << dec << ")" << "currentAnimation:" << (void *)m_currentAnimation;
+ d << "SequentialAnimationGroupJob(" << Qt::hex << (const void *) this << Qt::dec << ")" << "currentAnimation:" << (void *)m_currentAnimation;
debugChildren(d);
}
diff --git a/src/qml/common/common.pri b/src/qml/common/common.pri
index bcc3ea0fa0..b333c0f6d9 100644
--- a/src/qml/common/common.pri
+++ b/src/qml/common/common.pri
@@ -28,6 +28,7 @@ HEADERS += \
$$PWD/qqmljsdiagnosticmessage_p.h \
$$PWD/qqmljsfixedpoolarray_p.h \
$$PWD/qqmljsmemorypool_p.h \
+ $$PWD/qqmljssourcelocation_p.h \
$$PWD/qv4alloca_p.h \
$$PWD/qv4calldata_p.h \
$$PWD/qv4compileddata_p.h \
diff --git a/src/qml/common/qqmlapiversion_p.h b/src/qml/common/qqmlapiversion_p.h
index eca05558d8..44d8e3f236 100644
--- a/src/qml/common/qqmlapiversion_p.h
+++ b/src/qml/common/qqmlapiversion_p.h
@@ -51,6 +51,6 @@
// We mean it.
//
-#define Q_QML_PRIVATE_API_VERSION 5
+#define Q_QML_PRIVATE_API_VERSION 8
#endif // QQMLAPIVERSION_P_H
diff --git a/src/qml/common/qqmljsdiagnosticmessage_p.h b/src/qml/common/qqmljsdiagnosticmessage_p.h
index 763332ba76..9f5380ae0c 100644
--- a/src/qml/common/qqmljsdiagnosticmessage_p.h
+++ b/src/qml/common/qqmljsdiagnosticmessage_p.h
@@ -58,6 +58,8 @@
// QQmlSourceLocation -> line/column change.
#include <private/qqmlapiversion_p.h>
+#include "qqmljssourcelocation_p.h"
+
QT_BEGIN_NAMESPACE
namespace QQmlJS {
@@ -65,8 +67,7 @@ struct DiagnosticMessage
{
QString message;
QtMsgType type = QtCriticalMsg;
- quint32 line = 0;
- quint32 column = 0;
+ SourceLocation loc;
bool isError() const
{
diff --git a/src/qml/parser/qqmljssourcelocation_p.h b/src/qml/common/qqmljssourcelocation_p.h
index d76e701d49..7c75541eb1 100644
--- a/src/qml/parser/qqmljssourcelocation_p.h
+++ b/src/qml/common/qqmljssourcelocation_p.h
@@ -40,8 +40,6 @@
#ifndef QQMLJSSOURCELOCATION_P_H
#define QQMLJSSOURCELOCATION_P_H
-#include "qqmljsglobal_p.h"
-
#include <QtCore/qglobal.h>
//
@@ -57,7 +55,7 @@
QT_BEGIN_NAMESPACE
-namespace QQmlJS { namespace AST {
+namespace QQmlJS {
class SourceLocation
{
@@ -80,7 +78,7 @@ public:
quint32 startColumn;
};
-} } // namespace AST
+} // namespace QQmlJS
QT_END_NAMESPACE
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h
index 1f5ad9bd86..a5a1cf8969 100644
--- a/src/qml/common/qv4compileddata_p.h
+++ b/src/qml/common/qv4compileddata_p.h
@@ -75,7 +75,7 @@ QT_BEGIN_NAMESPACE
// Also change the comment behind the number to describe the latest change. This has the added
// benefit that if another patch changes the version too, it will result in a merge conflict, and
// not get removed silently.
-#define QV4_DATA_STRUCTURE_VERSION 0x25 // Extend size of "register" count (nRegisters)
+#define QV4_DATA_STRUCTURE_VERSION 0x29// support additional required property features
class QIODevice;
class QQmlTypeNameCache;
@@ -112,6 +112,7 @@ struct TableIterator
int index;
const ItemType *operator->() { return (container->*IndexedGetter)(index); }
+ ItemType operator*() {return *operator->();}
void operator++() { ++index; }
bool operator==(const TableIterator &rhs) const { return index == rhs.index; }
bool operator!=(const TableIterator &rhs) const { return index != rhs.index; }
@@ -597,6 +598,15 @@ struct Binding
static_assert(sizeof(Binding) == 24, "Binding structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+struct InlineComponent
+{
+ quint32_le objectIndex;
+ quint32_le nameIndex;
+ Location location;
+};
+
+static_assert(sizeof(InlineComponent) == 12, "InlineComponent structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+
struct EnumValue
{
quint32_le nameIndex;
@@ -658,7 +668,8 @@ struct Property
{
quint32_le nameIndex;
union {
- quint32_le_bitfield<0, 29> builtinTypeOrTypeNameIndex;
+ quint32_le_bitfield<0, 28> builtinTypeOrTypeNameIndex;
+ quint32_le_bitfield<28, 1> isRequired;
quint32_le_bitfield<29, 1> isBuiltinType;
quint32_le_bitfield<30, 1> isList;
quint32_le_bitfield<31, 1> isReadOnly;
@@ -684,6 +695,12 @@ struct Property
};
static_assert(sizeof(Property) == 12, "Property structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+struct RequiredPropertyExtraData {
+ quint32_le nameIndex;
+};
+
+static_assert (sizeof(RequiredPropertyExtraData) == 4, "RequiredPropertyExtraData structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+
struct Alias {
enum Flags : unsigned int {
IsReadOnly = 0x1,
@@ -720,7 +737,9 @@ struct Object
NoFlag = 0x0,
IsComponent = 0x1, // object was identified to be an explicit or implicit component boundary
HasDeferredBindings = 0x2, // any of the bindings are deferred
- HasCustomParserBindings = 0x4
+ HasCustomParserBindings = 0x4,
+ IsInlineComponentRoot = 0x8,
+ InPartOfInlineComponent = 0x10
};
// Depending on the use, this may be the type name to instantiate before instantiating this
@@ -750,12 +769,18 @@ struct Object
quint32_le offsetToNamedObjectsInComponent;
Location location;
Location locationOfIdProperty;
+ quint32_le offsetToInlineComponents;
+ quint16_le nInlineComponents;
+ quint32_le offsetToRequiredPropertyExtraData;
+ quint16_le nRequiredPropertyExtraData;
// Function[]
// Property[]
// Signal[]
// Binding[]
+// InlineComponent[]
+// RequiredPropertyExtraData[]
- static int calculateSizeExcludingSignalsAndEnums(int nFunctions, int nProperties, int nAliases, int nEnums, int nSignals, int nBindings, int nNamedObjectsInComponent)
+ static int calculateSizeExcludingSignalsAndEnums(int nFunctions, int nProperties, int nAliases, int nEnums, int nSignals, int nBindings, int nNamedObjectsInComponent, int nInlineComponents, int nRequiredPropertyExtraData)
{
return ( sizeof(Object)
+ nFunctions * sizeof(quint32)
@@ -765,6 +790,8 @@ struct Object
+ nSignals * sizeof(quint32)
+ nBindings * sizeof(Binding)
+ nNamedObjectsInComponent * sizeof(int)
+ + nInlineComponents * sizeof(InlineComponent)
+ + nRequiredPropertyExtraData * sizeof(RequiredPropertyExtraData)
+ 0x7
) & ~0x7;
}
@@ -803,11 +830,31 @@ struct Object
return reinterpret_cast<const Signal*>(reinterpret_cast<const char*>(this) + offset);
}
+ const InlineComponent *inlineComponentAt(int idx) const
+ {
+ return inlineComponentTable() + idx;
+ }
+
const quint32_le *namedObjectsInComponentTable() const
{
return reinterpret_cast<const quint32_le*>(reinterpret_cast<const char *>(this) + offsetToNamedObjectsInComponent);
}
+ const InlineComponent *inlineComponentTable() const
+ {
+ return reinterpret_cast<const InlineComponent*>(reinterpret_cast<const char *>(this) + offsetToInlineComponents);
+ }
+
+ const RequiredPropertyExtraData *requiredPropertyExtraDataAt(int idx) const
+ {
+ return requiredPropertyExtraDataTable() + idx;
+ }
+
+ const RequiredPropertyExtraData *requiredPropertyExtraDataTable() const
+ {
+ return reinterpret_cast<const RequiredPropertyExtraData*>(reinterpret_cast<const char *>(this) + offsetToRequiredPropertyExtraData);
+ }
+
// --- QQmlPropertyCacheCreator interface
int propertyCount() const { return nProperties; }
int aliasCount() const { return nAliases; }
@@ -832,17 +879,26 @@ struct Object
SignalIterator signalsBegin() const { return SignalIterator(this, 0); }
SignalIterator signalsEnd() const { return SignalIterator(this, nSignals); }
+ typedef TableIterator<InlineComponent, Object, &Object::inlineComponentAt> InlineComponentIterator;
+ InlineComponentIterator inlineComponentsBegin() const {return InlineComponentIterator(this, 0);}
+ InlineComponentIterator inlineComponentsEnd() const {return InlineComponentIterator(this, nInlineComponents);}
+
+ typedef TableIterator<RequiredPropertyExtraData, Object, &Object::requiredPropertyExtraDataAt> RequiredPropertyExtraDataIterator;
+ RequiredPropertyExtraDataIterator requiredPropertyExtraDataBegin() const {return RequiredPropertyExtraDataIterator(this, 0); };
+ RequiredPropertyExtraDataIterator requiredPropertyExtraDataEnd() const {return RequiredPropertyExtraDataIterator(this, nRequiredPropertyExtraData); };
+
int namedObjectsInComponentCount() const { return nNamedObjectsInComponent; }
// ---
};
-static_assert(sizeof(Object) == 68, "Object structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(Object) == 84, "Object structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Import
{
enum ImportType : unsigned int {
ImportLibrary = 0x1,
ImportFile = 0x2,
- ImportScript = 0x3
+ ImportScript = 0x3,
+ ImportInlineComponent = 0x4
};
quint32_le type;
@@ -1071,7 +1127,7 @@ struct TypeReferenceMap : QHash<int, TypeReference>
}
auto prop = obj->propertiesBegin();
- auto propEnd = obj->propertiesEnd();
+ auto const propEnd = obj->propertiesEnd();
for ( ; prop != propEnd; ++prop) {
if (!prop->isBuiltinType) {
TypeReference &r = this->add(prop->builtinTypeOrTypeNameIndex, prop->location);
@@ -1080,11 +1136,17 @@ struct TypeReferenceMap : QHash<int, TypeReference>
}
auto binding = obj->bindingsBegin();
- auto bindingEnd = obj->bindingsEnd();
+ auto const bindingEnd = obj->bindingsEnd();
for ( ; binding != bindingEnd; ++binding) {
if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty)
this->add(binding->propertyNameIndex, binding->location);
}
+
+ auto ic = obj->inlineComponentsBegin();
+ auto const icEnd = obj->inlineComponentsEnd();
+ for (; ic != icEnd; ++ic) {
+ this->add(ic->nameIndex, ic->location);
+ }
}
template <typename Iterator>
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 665d2633a7..89f99e21cd 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -64,6 +64,33 @@ using namespace QQmlJS;
return false; \
}
+void Object::simplifyRequiredProperties() {
+ // if a property of the current object was marked as required
+ // do not store that information in the ExtraData
+ // but rather mark the property as required
+ QSet<int> required;
+ for (auto it = this->requiredPropertyExtraDataBegin(); it != this->requiredPropertyExtraDataEnd(); ++it)
+ required.insert(it->nameIndex);
+ if (required.isEmpty())
+ return;
+ for (auto it = this->propertiesBegin(); it != this->propertiesEnd(); ++it) {
+ auto requiredIt = required.find(it->nameIndex);
+ if (requiredIt != required.end()) {
+ it->isRequired = true;
+ required.erase(requiredIt);
+ }
+ }
+ QmlIR::RequiredPropertyExtraData *prev = nullptr;
+ auto current = this->requiredPropertyExtraDatas->first;
+ while (current) {
+ if (required.contains(current->nameIndex))
+ prev = current;
+ else
+ requiredPropertyExtraDatas->unlink(prev, current);
+ current = current->next;
+ }
+}
+
bool Parameter::init(QV4::Compiler::JSUnitGenerator *stringGenerator, const QString &parameterName,
const QString &typeName)
{
@@ -142,7 +169,7 @@ QV4::CompiledData::BuiltinType Parameter::stringToBuiltinType(const QString &typ
return QV4::CompiledData::BuiltinType::InvalidBuiltin;
}
-void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::AST::SourceLocation &loc)
+void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::SourceLocation &loc)
{
inheritedTypeNameIndex = typeNameIndex;
@@ -161,10 +188,12 @@ void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, cons
bindings = pool->New<PoolList<Binding> >();
functions = pool->New<PoolList<Function> >();
functionsAndExpressions = pool->New<PoolList<CompiledFunctionOrExpression> >();
+ inlineComponents = pool->New<PoolList<InlineComponent>>();
+ requiredPropertyExtraDatas = pool->New<PoolList<RequiredPropertyExtraData>>();
declarationsOverride = nullptr;
}
-QString IRBuilder::sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation)
+QString IRBuilder::sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::SourceLocation *errorLocation)
{
QSet<int> functionNames;
for (auto functionit = obj->functionsBegin(); functionit != obj->functionsEnd(); ++functionit) {
@@ -220,7 +249,7 @@ QString Object::appendSignal(Signal *signal)
return QString(); // no error
}
-QString Object::appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation)
+QString Object::appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation)
{
Object *target = declarationsOverride;
if (!target)
@@ -244,15 +273,17 @@ QString Object::appendProperty(Property *prop, const QString &propertyName, bool
return QString(); // no error
}
-QString Object::appendAlias(Alias *alias, const QString &aliasName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation)
+QString Object::appendAlias(Alias *alias, const QString &aliasName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation)
{
Object *target = declarationsOverride;
if (!target)
target = this;
- for (Alias *p = target->aliases->first; p; p = p->next)
- if (p->nameIndex == alias->nameIndex)
- return tr("Duplicate alias name");
+ auto aliasWithSameName = std::find_if(target->aliases->begin(), target->aliases->end(), [&alias](const Alias &targetAlias){
+ return targetAlias.nameIndex == alias->nameIndex;
+ });
+ if (aliasWithSameName != target->aliases->end())
+ return tr("Duplicate alias name");
if (aliasName.constData()->isUpper())
return tr("Alias names cannot begin with an upper case letter");
@@ -279,6 +310,16 @@ void Object::appendFunction(QmlIR::Function *f)
target->functions->append(f);
}
+void Object::appendInlineComponent(InlineComponent *ic)
+{
+ inlineComponents->append(ic);
+}
+
+void Object::appendRequiredPropertyExtraData(RequiredPropertyExtraData *extraData)
+{
+ requiredPropertyExtraDatas->append(extraData);
+}
+
QString Object::appendBinding(Binding *b, bool isListBinding)
{
const bool bindingToDefaultProperty = (b->propertyNameIndex == quint32(0));
@@ -317,8 +358,8 @@ QString Object::bindingAsString(Document *doc, int scriptIndex) const
QQmlJS::AST::Node *node = foe->node;
if (QQmlJS::AST::ExpressionStatement *exprStmt = QQmlJS::AST::cast<QQmlJS::AST::ExpressionStatement *>(node))
node = exprStmt->expression;
- QQmlJS::AST::SourceLocation start = node->firstSourceLocation();
- QQmlJS::AST::SourceLocation end = node->lastSourceLocation();
+ QQmlJS::SourceLocation start = node->firstSourceLocation();
+ QQmlJS::SourceLocation end = node->lastSourceLocation();
return doc->code.mid(start.offset, end.offset + end.length - start.offset);
}
@@ -401,7 +442,7 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen
// Extract errors from the parser
for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) {
if (m.isWarning()) {
- qWarning("%s:%d : %s", qPrintable(url), m.line, qPrintable(m.message));
+ qWarning("%s:%d : %s", qPrintable(url), m.loc.startLine, qPrintable(m.message));
continue;
}
@@ -429,7 +470,7 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen
accept(program->headers);
if (program->members->next) {
- QQmlJS::AST::SourceLocation loc = program->members->next->firstSourceLocation();
+ QQmlJS::SourceLocation loc = program->members->next->firstSourceLocation();
recordError(loc, QCoreApplication::translate("QQmlParser", "Unexpected object definition"));
return false;
}
@@ -444,6 +485,10 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen
qSwap(_imports, output->imports);
qSwap(_pragmas, output->pragmas);
qSwap(_objects, output->objects);
+
+ for (auto object: output->objects)
+ object->simplifyRequiredProperties();
+
return errors.isEmpty();
}
@@ -490,7 +535,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiObjectDefinition *node)
int idx = 0;
if (!defineQMLObject(&idx, node))
return false;
- const QQmlJS::AST::SourceLocation nameLocation = node->qualifiedTypeNameId->identifierToken;
+ const QQmlJS::SourceLocation nameLocation = node->qualifiedTypeNameId->identifierToken;
appendBinding(nameLocation, nameLocation, emptyStringIndex, idx);
} else {
int idx = 0;
@@ -501,6 +546,39 @@ bool IRBuilder::visit(QQmlJS::AST::UiObjectDefinition *node)
return false;
}
+bool IRBuilder::visit(QQmlJS::AST::UiInlineComponent *ast)
+{
+ int idx = -1;
+ if (insideInlineComponent) {
+ recordError(ast->firstSourceLocation(), QLatin1String("Nested inline components are not supported"));
+ return false;
+ }
+ if (inlineComponentsNames.contains(ast->name.toString())) {
+ recordError(ast->firstSourceLocation(), QLatin1String("Inline component names must be unique per file"));
+ return false;
+ } else {
+ inlineComponentsNames.insert(ast->name.toString());
+ }
+ {
+ QScopedValueRollback<bool> rollBack {insideInlineComponent, true};
+ if (!defineQMLObject(&idx, ast->component))
+ return false;
+ }
+ Q_ASSERT(idx > 0);
+ Object* definedObject = _objects.at(idx);
+ definedObject->flags |= QV4::CompiledData::Object::IsInlineComponentRoot;
+ definedObject->flags |= QV4::CompiledData::Object::InPartOfInlineComponent;
+ definedObject->isInlineComponent = true;
+ auto inlineComponent = New<InlineComponent>();
+ inlineComponent->nameIndex = registerString(ast->name.toString());
+ inlineComponent->objectIndex = idx;
+ auto location = ast->firstSourceLocation();
+ inlineComponent->location.line = location.startLine;
+ inlineComponent->location.column = location.startColumn;
+ _object->appendInlineComponent(inlineComponent);
+ return false;
+}
+
bool IRBuilder::visit(QQmlJS::AST::UiObjectBinding *node)
{
int idx = 0;
@@ -518,7 +596,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiScriptBinding *node)
bool IRBuilder::visit(QQmlJS::AST::UiArrayBinding *node)
{
- const QQmlJS::AST::SourceLocation qualifiedNameLocation = node->qualifiedId->identifierToken;
+ const QQmlJS::SourceLocation qualifiedNameLocation = node->qualifiedId->identifierToken;
Object *object = nullptr;
QQmlJS::AST::UiQualifiedId *name = node->qualifiedId;
if (!resolveQualifiedId(&name, &object))
@@ -583,7 +661,7 @@ void IRBuilder::accept(QQmlJS::AST::Node *node)
QQmlJS::AST::Node::accept(node, this);
}
-bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::AST::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride)
+bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride)
{
if (QQmlJS::AST::UiQualifiedId *lastName = qualifiedTypeNameId) {
while (lastName->next)
@@ -595,12 +673,16 @@ bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qu
}
Object *obj = New<Object>();
+
_objects.append(obj);
*objectIndex = _objects.size() - 1;
qSwap(_object, obj);
_object->init(pool, registerString(asString(qualifiedTypeNameId)), emptyStringIndex, location);
_object->declarationsOverride = declarationsOverride;
+ if (insideInlineComponent) {
+ _object->flags |= QV4::CompiledData::Object::InPartOfInlineComponent;
+ }
// A new object is also a boundary for property declarations.
Property *declaration = nullptr;
@@ -615,7 +697,7 @@ bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qu
if (!errors.isEmpty())
return false;
- QQmlJS::AST::SourceLocation loc;
+ QQmlJS::SourceLocation loc;
QString error = sanityCheckFunctionNames(obj, illegalNames, &loc);
if (!error.isEmpty()) {
recordError(loc, error);
@@ -792,10 +874,10 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
{
if (node->type == QQmlJS::AST::UiPublicMember::Signal) {
Signal *signal = New<Signal>();
- QString signalName = node->name.toString();
+ const QString signalName = node->name.toString();
signal->nameIndex = registerString(signalName);
- QQmlJS::AST::SourceLocation loc = node->typeToken;
+ QQmlJS::SourceLocation loc = node->typeToken;
signal->location.line = loc.startLine;
signal->location.column = loc.startColumn;
@@ -821,8 +903,14 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
p = p->next;
}
- if (signalName.at(0).isUpper())
- COMPILE_EXCEPTION(node->identifierToken, tr("Signal names cannot begin with an upper case letter"));
+ for (const QChar &ch : signalName) {
+ if (ch.isLower())
+ break;
+ if (ch.isUpper()) {
+ COMPILE_EXCEPTION(node->identifierToken,
+ tr("Signal names cannot begin with an upper case letter"));
+ }
+ }
if (illegalNames.contains(signalName))
COMPILE_EXCEPTION(node->identifierToken, tr("Illegal signal name"));
@@ -841,6 +929,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
Property *property = New<Property>();
property->isReadOnly = node->isReadonlyMember;
+ property->isRequired = node->isRequired;
QV4::CompiledData::BuiltinType builtinPropertyType = Parameter::stringToBuiltinType(memberType);
bool typeFound = builtinPropertyType != QV4::CompiledData::BuiltinType::InvalidBuiltin;
@@ -871,11 +960,11 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
const QString propName = name.toString();
property->nameIndex = registerString(propName);
- QQmlJS::AST::SourceLocation loc = node->firstSourceLocation();
+ QQmlJS::SourceLocation loc = node->firstSourceLocation();
property->location.line = loc.startLine;
property->location.column = loc.startColumn;
- QQmlJS::AST::SourceLocation errorLocation;
+ QQmlJS::SourceLocation errorLocation;
QString error;
if (illegalNames.contains(propName))
@@ -916,7 +1005,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node)
const int index = _object->functionsAndExpressions->append(foe);
Function *f = New<Function>();
- QQmlJS::AST::SourceLocation loc = funDecl->identifierToken;
+ QQmlJS::SourceLocation loc = funDecl->identifierToken;
f->location.line = loc.startLine;
f->location.column = loc.startColumn;
f->index = index;
@@ -942,6 +1031,14 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node)
return false;
}
+bool IRBuilder::visit(AST::UiRequired *ast)
+{
+ auto extraData = New<RequiredPropertyExtraData>();
+ extraData->nameIndex = registerString(ast->name.toString());
+ _object->appendRequiredPropertyExtraData(extraData);
+ return false;
+}
+
QString IRBuilder::asString(QQmlJS::AST::UiQualifiedId *node)
{
QString s;
@@ -982,14 +1079,14 @@ void IRBuilder::extractVersion(const QStringRef &string, int *maj, int *min)
}
}
-QStringRef IRBuilder::textRefAt(const QQmlJS::AST::SourceLocation &first, const QQmlJS::AST::SourceLocation &last) const
+QStringRef IRBuilder::textRefAt(const QQmlJS::SourceLocation &first, const QQmlJS::SourceLocation &last) const
{
return QStringRef(&sourceCode, first.offset, last.offset + last.length - first.offset);
}
void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement, QQmlJS::AST::Node *parentNode)
{
- QQmlJS::AST::SourceLocation loc = statement->firstSourceLocation();
+ QQmlJS::SourceLocation loc = statement->firstSourceLocation();
binding->valueLocation.line = loc.startLine;
binding->valueLocation.column = loc.startColumn;
binding->type = QV4::CompiledData::Binding::Type_Invalid;
@@ -1166,7 +1263,7 @@ void IRBuilder::tryGeneratingTranslationBinding(const QStringRef &base, AST::Arg
void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode)
{
- const QQmlJS::AST::SourceLocation qualifiedNameLocation = name->identifierToken;
+ const QQmlJS::SourceLocation qualifiedNameLocation = name->identifierToken;
Object *object = nullptr;
if (!resolveQualifiedId(&name, &object))
return;
@@ -1181,7 +1278,7 @@ void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Sta
void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment)
{
- const QQmlJS::AST::SourceLocation qualifiedNameLocation = name->identifierToken;
+ const QQmlJS::SourceLocation qualifiedNameLocation = name->identifierToken;
Object *object = nullptr;
if (!resolveQualifiedId(&name, &object, isOnAssignment))
return;
@@ -1190,7 +1287,7 @@ void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex,
qSwap(_object, object);
}
-void IRBuilder::appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex,
+void IRBuilder::appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex,
QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode)
{
Binding *binding = New<Binding>();
@@ -1206,7 +1303,7 @@ void IRBuilder::appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLo
}
}
-void IRBuilder::appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem, bool isOnAssignment)
+void IRBuilder::appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem, bool isOnAssignment)
{
if (stringAt(propertyNameIndex) == QLatin1String("id")) {
recordError(nameLocation, tr("Invalid component id specification"));
@@ -1255,7 +1352,7 @@ bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node)
const QString propName = node->name.toString();
alias->nameIndex = registerString(propName);
- QQmlJS::AST::SourceLocation loc = node->firstSourceLocation();
+ QQmlJS::SourceLocation loc = node->firstSourceLocation();
alias->location.line = loc.startLine;
alias->location.column = loc.startColumn;
@@ -1264,7 +1361,7 @@ bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node)
if (!node->statement && !node->binding)
COMPILE_EXCEPTION(loc, tr("No property alias location"));
- QQmlJS::AST::SourceLocation rhsLoc;
+ QQmlJS::SourceLocation rhsLoc;
if (node->binding)
rhsLoc = node->binding->firstSourceLocation();
else if (node->statement)
@@ -1299,7 +1396,7 @@ bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node)
propertyValue += QLatin1Char('.') + aliasReference.at(2);
alias->propertyNameIndex = registerString(propertyValue);
- QQmlJS::AST::SourceLocation errorLocation;
+ QQmlJS::SourceLocation errorLocation;
QString error;
if (illegalNames.contains(propName))
@@ -1325,9 +1422,9 @@ Object *IRBuilder::bindingsTarget() const
return _object;
}
-bool IRBuilder::setId(const QQmlJS::AST::SourceLocation &idLocation, QQmlJS::AST::Statement *value)
+bool IRBuilder::setId(const QQmlJS::SourceLocation &idLocation, QQmlJS::AST::Statement *value)
{
- QQmlJS::AST::SourceLocation loc = value->firstSourceLocation();
+ QQmlJS::SourceLocation loc = value->firstSourceLocation();
QStringRef str;
QQmlJS::AST::Node *node = value;
@@ -1429,7 +1526,7 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O
binding->type = QV4::CompiledData::Binding::Type_GroupProperty;
int objIndex = 0;
- if (!defineQMLObject(&objIndex, nullptr, QQmlJS::AST::SourceLocation(), nullptr, nullptr))
+ if (!defineQMLObject(&objIndex, nullptr, QQmlJS::SourceLocation(), nullptr, nullptr))
return false;
binding->value.objectIndex = objIndex;
@@ -1452,11 +1549,10 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O
return true;
}
-void IRBuilder::recordError(const QQmlJS::AST::SourceLocation &location, const QString &description)
+void IRBuilder::recordError(const QQmlJS::SourceLocation &location, const QString &description)
{
QQmlJS::DiagnosticMessage error;
- error.line = location.startLine;
- error.column = location.startColumn;
+ error.loc = location;
error.message = description;
errors << error;
}
@@ -1544,7 +1640,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
uint nextOffset = objectOffset + objectOffsetTableSize;
for (Object *o : qAsConst(output.objects)) {
objectOffsets.insert(o, nextOffset);
- nextOffset += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.size());
+ nextOffset += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.size(), o->inlineComponentCount(), o->requiredPropertyExtraDataCount());
int signalTableSize = 0;
for (const Signal *s = o->firstSignal(); s; s = s->next)
@@ -1623,6 +1719,14 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
objectToWrite->offsetToNamedObjectsInComponent = nextOffset;
nextOffset += objectToWrite->nNamedObjectsInComponent * sizeof(quint32);
+ objectToWrite->nInlineComponents = o->inlineComponentCount();
+ objectToWrite->offsetToInlineComponents = nextOffset;
+ nextOffset += objectToWrite->nInlineComponents * sizeof (QV4::CompiledData::InlineComponent);
+
+ objectToWrite->nRequiredPropertyExtraData = o->requiredPropertyExtraDataCount();
+ objectToWrite->offsetToRequiredPropertyExtraData = nextOffset;
+ nextOffset += objectToWrite->nRequiredPropertyExtraData * sizeof(QV4::CompiledData::RequiredPropertyExtraData);
+
quint32_le *functionsTable = reinterpret_cast<quint32_le *>(objectPtr + objectToWrite->offsetToFunctions);
for (const Function *f = o->firstFunction(); f; f = f->next)
*functionsTable++ = o->runtimeFunctionIndices.at(f->index);
@@ -1694,6 +1798,22 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
for (int i = 0; i < o->namedObjectsInComponent.size(); ++i) {
*namedObjectInComponentPtr++ = o->namedObjectsInComponent.at(i);
}
+
+ char *inlineComponentPtr = objectPtr + objectToWrite->offsetToInlineComponents;
+ for (auto it = o->inlineComponentsBegin(); it != o->inlineComponentsEnd(); ++it) {
+ const InlineComponent *ic = it.ptr;
+ QV4::CompiledData::InlineComponent *icToWrite = reinterpret_cast<QV4::CompiledData::InlineComponent*>(inlineComponentPtr);
+ *icToWrite = *ic;
+ inlineComponentPtr += sizeof(QV4::CompiledData::InlineComponent);
+ }
+
+ char *requiredPropertyExtraDataPtr = objectPtr + objectToWrite->offsetToRequiredPropertyExtraData;
+ for (auto it = o->requiredPropertyExtraDataBegin(); it != o->requiredPropertyExtraDataEnd(); ++it) {
+ const RequiredPropertyExtraData *extraData = it.ptr;
+ QV4::CompiledData::RequiredPropertyExtraData *extraDataToWrite = reinterpret_cast<QV4::CompiledData::RequiredPropertyExtraData*>(requiredPropertyExtraDataPtr);
+ *extraDataToWrite = *extraData;
+ requiredPropertyExtraDataPtr += sizeof(QV4::CompiledData::RequiredPropertyExtraData);
+ }
}
if (!output.javaScriptCompilationUnit.data) {
@@ -1841,12 +1961,14 @@ bool JSCodeGen::generateCodeForComponents(const QVector<quint32> &componentRoots
bool JSCodeGen::compileComponent(int contextObject)
{
const QmlIR::Object *obj = document->objects.at(contextObject);
- if (obj->flags & QV4::CompiledData::Object::IsComponent) {
+ if (obj->flags & QV4::CompiledData::Object::IsComponent && !obj->isInlineComponent) {
Q_ASSERT(obj->bindingCount() == 1);
const QV4::CompiledData::Binding *componentBinding = obj->firstBinding();
Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object);
contextObject = componentBinding->value.objectIndex;
}
+ for (auto it = obj->inlineComponentsBegin(); it != obj->inlineComponentsEnd(); ++it)
+ compileComponent(it->objectIndex);
return compileJavaScriptCodeInObjectsRecursively(contextObject, contextObject);
}
@@ -1854,7 +1976,7 @@ bool JSCodeGen::compileComponent(int contextObject)
bool JSCodeGen::compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex)
{
QmlIR::Object *object = document->objects.at(objectIndex);
- if (object->flags & QV4::CompiledData::Object::IsComponent)
+ if (object->flags & QV4::CompiledData::Object::IsComponent && !object->isInlineComponent)
return true;
if (object->functionsAndExpressions->count > 0) {
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index 4279f5b768..9629a73199 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -158,6 +158,13 @@ struct PoolList
}
struct Iterator {
+ // turn Iterator into a proper iterator
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = T;
+ using difference_type = ptrdiff_t;
+ using pointer = T *;
+ using reference = T &;
+
T *ptr;
explicit Iterator(T *p) : ptr(p) {}
@@ -178,8 +185,15 @@ struct PoolList
return *ptr;
}
- void operator++() {
+ Iterator& operator++() {
+ ptr = ptr->next;
+ return *this;
+ }
+
+ Iterator operator++(int) {
+ Iterator that {ptr};
ptr = ptr->next;
+ return that;
}
bool operator==(const Iterator &rhs) const {
@@ -193,6 +207,8 @@ struct PoolList
Iterator begin() { return Iterator(first); }
Iterator end() { return Iterator(nullptr); }
+
+ using iterator = Iterator;
};
struct Object;
@@ -259,11 +275,21 @@ struct Binding : public QV4::CompiledData::Binding
Binding *next;
};
+struct InlineComponent : public QV4::CompiledData::InlineComponent
+{
+ InlineComponent *next;
+};
+
struct Alias : public QV4::CompiledData::Alias
{
Alias *next;
};
+struct RequiredPropertyExtraData : public QV4::CompiledData::RequiredPropertyExtraData
+{
+ RequiredPropertyExtraData *next;
+};
+
struct Function
{
QV4::CompiledData::Location location;
@@ -300,6 +326,7 @@ public:
int id;
int indexOfDefaultPropertyOrAlias;
bool defaultPropertyIsAlias;
+ bool isInlineComponent = false;
quint32 flags;
QV4::CompiledData::Location location;
@@ -317,6 +344,11 @@ public:
int bindingCount() const { return bindings->count; }
const Function *firstFunction() const { return functions->first; }
int functionCount() const { return functions->count; }
+ const InlineComponent *inlineComponent() const { return inlineComponents->first; }
+ int inlineComponentCount() const { return inlineComponents->count; }
+ const RequiredPropertyExtraData *requiredPropertyExtraData() const {return requiredPropertyExtraDatas->first; }
+ int requiredPropertyExtraDataCount() const { return requiredPropertyExtraDatas->count; }
+ void simplifyRequiredProperties();
PoolList<Binding>::Iterator bindingsBegin() const { return bindings->begin(); }
PoolList<Binding>::Iterator bindingsEnd() const { return bindings->end(); }
@@ -330,18 +362,24 @@ public:
PoolList<Signal>::Iterator signalsEnd() const { return qmlSignals->end(); }
PoolList<Function>::Iterator functionsBegin() const { return functions->begin(); }
PoolList<Function>::Iterator functionsEnd() const { return functions->end(); }
+ PoolList<InlineComponent>::Iterator inlineComponentsBegin() const { return inlineComponents->begin(); }
+ PoolList<InlineComponent>::Iterator inlineComponentsEnd() const { return inlineComponents->end(); }
+ PoolList<RequiredPropertyExtraData>::Iterator requiredPropertyExtraDataBegin() const {return requiredPropertyExtraDatas->begin(); }
+ PoolList<RequiredPropertyExtraData>::Iterator requiredPropertyExtraDataEnd() const {return requiredPropertyExtraDatas->end(); }
// If set, then declarations for this object (and init bindings for these) should go into the
// specified object. Used for declarations inside group properties.
Object *declarationsOverride;
- void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::AST::SourceLocation &location = QQmlJS::AST::SourceLocation());
+ void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::SourceLocation &location = QQmlJS::SourceLocation());
QString appendEnum(Enum *enumeration);
QString appendSignal(Signal *signal);
- QString appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation);
- QString appendAlias(Alias *prop, const QString &aliasName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation);
+ QString appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation);
+ QString appendAlias(Alias *prop, const QString &aliasName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation);
void appendFunction(QmlIR::Function *f);
+ void appendInlineComponent(InlineComponent *ic);
+ void appendRequiredPropertyExtraData(RequiredPropertyExtraData *extraData);
QString appendBinding(Binding *b, bool isListBinding);
Binding *findBinding(quint32 nameIndex) const;
@@ -365,6 +403,8 @@ private:
PoolList<Signal> *qmlSignals;
PoolList<Binding> *bindings;
PoolList<Function> *functions;
+ PoolList<InlineComponent> *inlineComponents;
+ PoolList<RequiredPropertyExtraData> *requiredPropertyExtraDatas;
};
struct Q_QMLCOMPILER_PRIVATE_EXPORT Pragma
@@ -393,6 +433,9 @@ struct Q_QMLCOMPILER_PRIVATE_EXPORT Document
int registerString(const QString &str) { return jsGenerator.registerString(str); }
QString stringAt(int index) const { return jsGenerator.stringForIndex(index); }
+
+ int objectCount() const {return objects.size();}
+ Object* objectAt(int i) const {return objects.at(i);}
};
class Q_QMLCOMPILER_PRIVATE_EXPORT ScriptDirectivesCollector : public QQmlJS::Directives
@@ -433,31 +476,33 @@ public:
bool visit(QQmlJS::AST::UiArrayBinding *ast) override;
bool visit(QQmlJS::AST::UiObjectBinding *ast) override;
bool visit(QQmlJS::AST::UiObjectDefinition *ast) override;
+ bool visit(QQmlJS::AST::UiInlineComponent *ast) override;
bool visit(QQmlJS::AST::UiEnumDeclaration *ast) override;
bool visit(QQmlJS::AST::UiPublicMember *ast) override;
bool visit(QQmlJS::AST::UiScriptBinding *ast) override;
bool visit(QQmlJS::AST::UiSourceElement *ast) override;
+ bool visit(QQmlJS::AST::UiRequired *ast) override;
void throwRecursionDepthError() override
{
- recordError(QQmlJS::AST::SourceLocation(),
+ recordError(QQmlJS::SourceLocation(),
QStringLiteral("Maximum statement or expression depth exceeded"));
}
void accept(QQmlJS::AST::Node *node);
// returns index in _objects
- bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::AST::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride = nullptr);
+ bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride = nullptr);
bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiObjectDefinition *node, Object *declarationsOverride = nullptr)
{ return defineQMLObject(objectIndex, node->qualifiedTypeNameId, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer, declarationsOverride); }
static QString asString(QQmlJS::AST::UiQualifiedId *node);
QStringRef asStringRef(QQmlJS::AST::Node *node);
static void extractVersion(const QStringRef &string, int *maj, int *min);
- QStringRef textRefAt(const QQmlJS::AST::SourceLocation &loc) const
+ QStringRef textRefAt(const QQmlJS::SourceLocation &loc) const
{ return QStringRef(&sourceCode, loc.offset, loc.length); }
- QStringRef textRefAt(const QQmlJS::AST::SourceLocation &first,
- const QQmlJS::AST::SourceLocation &last) const;
+ QStringRef textRefAt(const QQmlJS::SourceLocation &first,
+ const QQmlJS::SourceLocation &last) const;
void setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement,
QQmlJS::AST::Node *parentNode);
@@ -466,24 +511,24 @@ public:
void appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value,
QQmlJS::AST::Node *parentNode);
void appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment = false);
- void appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation,
- const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex,
+ void appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation,
+ const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex,
QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode);
- void appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation,
- const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex,
+ void appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation,
+ const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex,
int objectIndex, bool isListItem = false, bool isOnAssignment = false);
bool appendAlias(QQmlJS::AST::UiPublicMember *node);
Object *bindingsTarget() const;
- bool setId(const QQmlJS::AST::SourceLocation &idLocation, QQmlJS::AST::Statement *value);
+ bool setId(const QQmlJS::SourceLocation &idLocation, QQmlJS::AST::Statement *value);
// resolves qualified name (font.pixelSize for example) and returns the last name along
// with the object any right-hand-side of a binding should apply to.
bool resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, Object **object, bool onAssignment = false);
- void recordError(const QQmlJS::AST::SourceLocation &location, const QString &description);
+ void recordError(const QQmlJS::SourceLocation &location, const QString &description);
quint32 registerString(const QString &str) const { return jsGenerator->registerString(str); }
template <typename _Tp> _Tp *New() { return pool->New<_Tp>(); }
@@ -493,11 +538,12 @@ public:
static bool isStatementNodeScript(QQmlJS::AST::Statement *statement);
static bool isRedundantNullInitializerForPropertyDeclaration(Property *property, QQmlJS::AST::Statement *statement);
- QString sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation);
+ QString sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::SourceLocation *errorLocation);
QList<QQmlJS::DiagnosticMessage> errors;
QSet<QString> illegalNames;
+ QSet<QString> inlineComponentsNames;
QList<const QV4::CompiledData::Import *> _imports;
QList<Pragma*> _pragmas;
@@ -511,6 +557,8 @@ public:
QQmlJS::MemoryPool *pool;
QString sourceCode;
QV4::Compiler::JSUnitGenerator *jsGenerator;
+
+ bool insideInlineComponent = false;
};
struct Q_QMLCOMPILER_PRIVATE_EXPORT QmlUnitGenerator
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp
index 7df1614ffe..f8a41edb6a 100644
--- a/src/qml/compiler/qv4bytecodegenerator.cpp
+++ b/src/qml/compiler/qv4bytecodegenerator.cpp
@@ -45,7 +45,7 @@ QT_USE_NAMESPACE
using namespace QV4;
using namespace Moth;
-void BytecodeGenerator::setLocation(const QQmlJS::AST::SourceLocation &loc)
+void BytecodeGenerator::setLocation(const QQmlJS::SourceLocation &loc)
{
currentLine = static_cast<int>(loc.startLine);
}
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index 8c509dd9f1..1895a34a68 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -56,10 +56,8 @@
QT_BEGIN_NAMESPACE
namespace QQmlJS {
-namespace AST {
class SourceLocation;
}
-}
namespace QV4 {
@@ -244,7 +242,7 @@ QT_WARNING_POP
- void setLocation(const QQmlJS::AST::SourceLocation &loc);
+ void setLocation(const QQmlJS::SourceLocation &loc);
ExceptionHandler *exceptionHandler() const {
return currentExceptionHandler;
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index c43ea64e2e..4588690307 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1371,6 +1371,40 @@ bool Codegen::visit(BinaryExpression *ast)
setExprResult(Reference::fromAccumulator(this));
}
return false;
+ } else if (ast->op == QSOperator::Coalesce) {
+
+ Reference left = expression(ast->left);
+ if (hasError())
+ return false;
+
+ BytecodeGenerator::Label iftrue = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label iffalse = bytecodeGenerator->newLabel();
+
+ Instruction::CmpNeNull cmp;
+
+ left = left.storeOnStack();
+ left.loadInAccumulator();
+ bytecodeGenerator->addInstruction(cmp);
+
+ bytecodeGenerator->jumpTrue().link(iftrue);
+ bytecodeGenerator->jumpFalse().link(iffalse);
+
+ blockTailCalls.unblock();
+
+ iftrue.link();
+
+ left.loadInAccumulator();
+
+ BytecodeGenerator::Jump jump_endif = bytecodeGenerator->jump();
+
+ iffalse.link();
+
+ Reference right = expression(ast->right);
+ right.loadInAccumulator();
+ jump_endif.link();
+ setExprResult(Reference::fromAccumulator(this));
+
+ return false;
} else if (ast->op == QSOperator::Assign) {
if (AST::Pattern *p = ast->left->patternCast()) {
RegisterScope scope(this);
@@ -1497,7 +1531,9 @@ bool Codegen::visit(BinaryExpression *ast)
break;
}
-
+ case QSOperator::As:
+ setExprResult(left);
+ break;
} // switch
return false;
@@ -3785,8 +3821,7 @@ void Codegen::throwError(ErrorType errorType, const SourceLocation &loc, const Q
_errorType = errorType;
_error.message = detail;
- _error.line = loc.startLine;
- _error.column = loc.startColumn;
+ _error.loc = loc;
}
void Codegen::throwSyntaxError(const SourceLocation &loc, const QString &detail)
@@ -4069,7 +4104,7 @@ Codegen::Reference Codegen::Reference::asLValue() const
case Accumulator:
Q_UNREACHABLE();
case Super:
- codegen->throwSyntaxError(AST::SourceLocation(), QStringLiteral("Super lvalues not implemented."));
+ codegen->throwSyntaxError(SourceLocation(), QStringLiteral("Super lvalues not implemented."));
return *this;
case Member:
if (!propertyBase.isStackSlot()) {
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index 82a4fc3289..255698d790 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -661,12 +661,12 @@ protected:
bool visit(QQmlJS::AST::UiSourceElement *ast) override;
bool throwSyntaxErrorOnEvalOrArgumentsInStrictMode(const Reference &r,
- const QQmlJS::AST::SourceLocation &loc);
- virtual void throwSyntaxError(const QQmlJS::AST::SourceLocation &loc, const QString &detail);
- virtual void throwReferenceError(const QQmlJS::AST::SourceLocation &loc, const QString &detail);
+ const QQmlJS::SourceLocation &loc);
+ virtual void throwSyntaxError(const QQmlJS::SourceLocation &loc, const QString &detail);
+ virtual void throwReferenceError(const QQmlJS::SourceLocation &loc, const QString &detail);
void throwRecursionDepthError() override
{
- throwSyntaxError(QQmlJS::AST::SourceLocation(),
+ throwSyntaxError(QQmlJS::SourceLocation(),
QStringLiteral("Maximum statement or expression depth exceeded"));
}
@@ -700,7 +700,7 @@ public:
Reference referenceForName(
const QString &name, bool lhs,
- const QQmlJS::AST::SourceLocation &accessLocation = QQmlJS::AST::SourceLocation());
+ const QQmlJS::SourceLocation &accessLocation = QQmlJS::SourceLocation());
QV4::CompiledData::CompilationUnit generateCompilationUnit(bool generateUnitData = true);
static QV4::CompiledData::CompilationUnit compileModule(
@@ -810,7 +810,7 @@ protected:
private:
VolatileMemoryLocations scanVolatileMemoryLocations(QQmlJS::AST::Node *ast);
void handleConstruct(const Reference &base, QQmlJS::AST::ArgumentList *args);
- void throwError(ErrorType errorType, const QQmlJS::AST::SourceLocation &loc,
+ void throwError(ErrorType errorType, const QQmlJS::SourceLocation &loc,
const QString &detail);
};
diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp
index 88837b0feb..872fc94dc9 100644
--- a/src/qml/compiler/qv4compilercontext.cpp
+++ b/src/qml/compiler/qv4compilercontext.cpp
@@ -45,6 +45,7 @@ QT_USE_NAMESPACE
using namespace QV4;
using namespace QV4::Compiler;
using namespace QQmlJS::AST;
+using namespace QQmlJS;
QT_BEGIN_NAMESPACE
@@ -86,7 +87,7 @@ bool Context::Member::requiresTDZCheck(const SourceLocation &accessLocation, boo
}
bool Context::addLocalVar(const QString &name, Context::MemberType type, VariableScope scope, FunctionExpression *function,
- const QQmlJS::AST::SourceLocation &endOfInitializer)
+ const QQmlJS::SourceLocation &endOfInitializer)
{
// ### can this happen?
if (name.isEmpty())
@@ -122,7 +123,7 @@ bool Context::addLocalVar(const QString &name, Context::MemberType type, Variabl
return true;
}
-Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::AST::SourceLocation &accessLocation)
+Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::SourceLocation &accessLocation)
{
int scope = 0;
Context *c = this;
diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h
index 8c124ac409..4a14009c35 100644
--- a/src/qml/compiler/qv4compilercontext_p.h
+++ b/src/qml/compiler/qv4compilercontext_p.h
@@ -183,10 +183,10 @@ struct Context {
QQmlJS::AST::VariableScope scope = QQmlJS::AST::VariableScope::Var;
mutable bool canEscape = false;
QQmlJS::AST::FunctionExpression *function = nullptr;
- QQmlJS::AST::SourceLocation endOfInitializerLocation;
+ QQmlJS::SourceLocation endOfInitializerLocation;
bool isLexicallyScoped() const { return this->scope != QQmlJS::AST::VariableScope::Var; }
- bool requiresTDZCheck(const QQmlJS::AST::SourceLocation &accessLocation, bool accessAcrossContextBoundaries) const;
+ bool requiresTDZCheck(const QQmlJS::SourceLocation &accessLocation, bool accessAcrossContextBoundaries) const;
};
typedef QMap<QString, Member> MemberMap;
@@ -227,7 +227,7 @@ struct Context {
bool isWithBlock = false;
bool isCatchBlock = false;
QString caughtVariable;
- QQmlJS::AST::SourceLocation lastBlockInitializerLocation;
+ QQmlJS::SourceLocation lastBlockInitializerLocation;
enum UsesArgumentsObject {
ArgumentsObjectUnknown,
@@ -331,7 +331,7 @@ struct Context {
}
bool addLocalVar(const QString &name, MemberType contextType, QQmlJS::AST::VariableScope scope, QQmlJS::AST::FunctionExpression *function = nullptr,
- const QQmlJS::AST::SourceLocation &endOfInitializer = QQmlJS::AST::SourceLocation());
+ const QQmlJS::SourceLocation &endOfInitializer = QQmlJS::SourceLocation());
struct ResolvedName {
enum Type {
@@ -348,10 +348,10 @@ struct Context {
bool requiresTDZCheck = false;
int scope = -1;
int index = -1;
- QQmlJS::AST::SourceLocation endOfDeclarationLocation;
+ QQmlJS::SourceLocation endOfDeclarationLocation;
bool isValid() const { return type != Unresolved; }
};
- ResolvedName resolveName(const QString &name, const QQmlJS::AST::SourceLocation &accessLocation);
+ ResolvedName resolveName(const QString &name, const QQmlJS::SourceLocation &accessLocation);
void emitBlockHeader(Compiler::Codegen *codegen);
void emitBlockFooter(Compiler::Codegen *codegen);
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp
index ab0ebf3d4b..a1ddee8234 100644
--- a/src/qml/compiler/qv4compilerscanfunctions.cpp
+++ b/src/qml/compiler/qv4compilerscanfunctions.cpp
@@ -55,7 +55,7 @@ using namespace QV4::Compiler;
using namespace QQmlJS;
using namespace QQmlJS::AST;
-static CompiledData::Location location(const QQmlJS::AST::SourceLocation &astLocation)
+static CompiledData::Location location(const QQmlJS::SourceLocation &astLocation)
{
CompiledData::Location target;
target.line = astLocation.startLine;
@@ -129,7 +129,7 @@ void ScanFunctions::checkDirectivePrologue(StatementList *ast)
}
}
-void ScanFunctions::checkName(const QStringRef &name, const SourceLocation &loc)
+void ScanFunctions::checkName(const QStringRef &name, const QQmlJS::SourceLocation &loc)
{
if (_context->isStrict) {
if (name == QLatin1String("implements")
@@ -330,7 +330,7 @@ bool ScanFunctions::visit(PatternElement *ast)
BoundNames names;
ast->boundNames(&names);
- QQmlJS::AST::SourceLocation lastInitializerLocation = ast->lastSourceLocation();
+ QQmlJS::SourceLocation lastInitializerLocation = ast->lastSourceLocation();
if (_context->lastBlockInitializerLocation.isValid())
lastInitializerLocation = _context->lastBlockInitializerLocation;
diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h
index 2de80eac44..e39aa2454e 100644
--- a/src/qml/compiler/qv4compilerscanfunctions_p.h
+++ b/src/qml/compiler/qv4compilerscanfunctions_p.h
@@ -97,7 +97,7 @@ protected:
void checkDirectivePrologue(QQmlJS::AST::StatementList *ast);
- void checkName(const QStringRef &name, const QQmlJS::AST::SourceLocation &loc);
+ void checkName(const QStringRef &name, const QQmlJS::SourceLocation &loc);
bool visit(QQmlJS::AST::Program *ast) override;
void endVisit(QQmlJS::AST::Program *) override;
diff --git a/src/qml/debugger/qqmldebug.cpp b/src/qml/debugger/qqmldebug.cpp
index 6532576e03..58b8ea2c4f 100644
--- a/src/qml/debugger/qqmldebug.cpp
+++ b/src/qml/debugger/qqmldebug.cpp
@@ -65,8 +65,7 @@ QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning)
*/
QStringList QQmlDebuggingEnabler::debuggerServices()
{
- return QStringList() << QV4DebugService::s_key << QQmlEngineDebugService::s_key
- << QDebugMessageService::s_key;
+ return {QV4DebugService::s_key, QQmlEngineDebugService::s_key, QDebugMessageService::s_key};
}
/*!
@@ -76,7 +75,7 @@ QStringList QQmlDebuggingEnabler::debuggerServices()
*/
QStringList QQmlDebuggingEnabler::inspectorServices()
{
- return QStringList() << QQmlInspectorService::s_key;
+ return {QQmlInspectorService::s_key};
}
/*!
@@ -87,8 +86,7 @@ QStringList QQmlDebuggingEnabler::inspectorServices()
*/
QStringList QQmlDebuggingEnabler::profilerServices()
{
- return QStringList() << QQmlProfilerService::s_key << QQmlEngineControlService::s_key
- << QDebugMessageService::s_key;
+ return {QQmlProfilerService::s_key, QQmlEngineControlService::s_key, QDebugMessageService::s_key};
}
/*!
@@ -99,7 +97,7 @@ QStringList QQmlDebuggingEnabler::profilerServices()
*/
QStringList QQmlDebuggingEnabler::nativeDebuggerServices()
{
- return QStringList() << QQmlNativeDebugService::s_key;
+ return {QQmlNativeDebugService::s_key};
}
/*!
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..b259e047a1 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,11 @@ public:
class QDebugMessageService {};
class QQmlEngineControlService {};
class QQmlNativeDebugService {};
+class QQmlDebugTranslationService {
+public:
+ virtual QString foundElidedText(QObject *, const QString &, const QString &) {return {};}
+ virtual void foundTranslationBinding(QQmlTranslationBinding *, QObject *, QQmlContextData *) {}
+};
#else
@@ -162,6 +168,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/dependencies.json b/src/qml/dependencies.json
new file mode 100644
index 0000000000..fe51488c70
--- /dev/null
+++ b/src/qml/dependencies.json
@@ -0,0 +1 @@
+[]
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..fc9fa60282
--- /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
+}
+//! [document]
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/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc
index c91ce28f42..0dec7fd66d 100644
--- a/src/qml/doc/src/cppintegration/data.qdoc
+++ b/src/qml/doc/src/cppintegration/data.qdoc
@@ -327,6 +327,11 @@ In both the Q_PROPERTY and return from Q_INVOKABLE cases, the elements
of a std::vector are copied. This copying may be an expensive operation,
so std::vector should be used judiciously.
+You can also create a list-like data structure by constructing a QJSValue using
+QJSEngine::newArray(). Such a JavaScript array does not need any conversion
+when passing it between QML and C++. See \l{QJSValue#Working With Arrays} for
+details on how to manipulate JavaScript arrays from C++.
+
Other sequence types are not supported transparently, and instead an
instance of any other sequence type will be passed between QML and C++ as an
opaque QVariantList.
@@ -400,6 +405,14 @@ properties:
Q_DECLARE_METATYPE(Actor)
\endcode
+The usual pattern is to use a gadget class as the type of a property, or to
+emit a gadget as a signal argument. In such cases, the gadget instance is
+passed by value between C++ and QML (because it's a value type). If QML code
+changes a property of a gadget property, the entire gadget is re-created and
+passed back to the C++ property setter. In Qt 5, gadget types cannot be
+instantiated by direct declaration in QML. In contrast, a QObject instance can
+be declared; and QObject instances are always passed by pointer from C++ to QML.
+
\section1 Enumeration Types
To use a custom enumeration as a data type, its class must be registered and
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index 2e8102bd65..cbbbd9ba58 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 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/extending-tutorial.qdoc b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
index 43987354ae..458768bf18 100644
--- a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
+++ b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
@@ -103,11 +103,22 @@ functionality of an existing QObject-based class, it could inherit from that cla
Alternatively, if we want to create a visual item that doesn't need to perform drawing
operations with the QPainter API, we can just subclass QQuickItem.
-The \c PieChart class defines the two properties, \c name and \c color, with the Q_PROPERTY macro,
-and overrides QQuickPaintedItem::paint(). The class implementation in \c piechart.cpp
-simply sets and returns the \c m_name and \c m_color values as appropriate, and
-implements \c paint() to draw a simple pie chart. It also turns off the
-QGraphicsItem::ItemHasNoContents flag to enable painting:
+The \c PieChart class defines the two properties, \c name and \c color, with the
+Q_PROPERTY macro, and overrides QQuickPaintedItem::paint(). The \c PieChart
+class is registered using the QML_ELEMENT macro, to allow it to be used from
+QML. If you don't register the class, \c app.qml won't be able to create a
+\c PieChart.
+
+For the registration to take effect, the \c qmltypes option is added to
+\c CONFIG in the project file and a \c QML_IMPORT_NAME and
+\c QML_IMPORT_MAJOR_VERSION are given:
+
+\snippet tutorials/extending-qml/chapter1-basics/chapter1-basics.pro 0
+
+The class implementation in \c piechart.cpp simply sets and returns the
+\c m_name and \c m_color values as appropriate, and implements \c paint() to
+draw a simple pie chart. It also turns off the QGraphicsItem::ItemHasNoContents
+flag to enable painting:
\snippet tutorials/extending-qml/chapter1-basics/piechart.cpp 0
\dots 0
@@ -125,18 +136,15 @@ provided for various other \l {QML Basic Types}{basic types}; for example, a str
like "640x480" can be automatically converted to a QSize value.
We'll also create a C++ application that uses a QQuickView to run and
-display \c app.qml. The application must register the \c PieChart type
-using the qmlRegisterType() function, to allow it to be used from QML. If
-you don't register the type, \c app.qml won't be able to create a \c PieChart.
+display \c app.qml.
Here is the application \c main.cpp:
\snippet tutorials/extending-qml/chapter1-basics/main.cpp 0
-This call to qmlRegisterType() registers the \c PieChart type as a type called "PieChart",
-in a type namespace called "Charts", with a version of 1.0.
-
-Lastly, we write a \c .pro project file that includes the files and the \c declarative library:
+We write a \c .pro project file that includes the files and the \c qml library, and
+defines a type namespace called "Charts" with a version of 1.0 for any types exposed
+to QML:
\quotefile tutorials/extending-qml/chapter1-basics/chapter1-basics.pro
@@ -144,7 +152,7 @@ Now we can build and run the application:
\image extending-tutorial-chapter1.png
-\note You may see a warning \e {Expression ... depends on non-NOTIFYable properties:
+\note You may see a warning \e {Expression ... depends on non-NOTIFYable properties:
PieChart::name}. This happens because we add a binding to the writable \c name
property, but haven't yet defined a notify signal for it. The QML engine therefore
cannot update the binding if the \c name value changes. This is addressed in
@@ -314,15 +322,13 @@ item when its contents are drawn:
\snippet tutorials/extending-qml/chapter4-customPropertyTypes/piechart.cpp 0
-Like the \c PieChart type, the \c PieSlice type has to be registered
-using qmlRegisterType() to be used from QML. As with \c PieChart, we'll add the
-type to the "Charts" type namespace, version 1.0:
+Like the \c PieChart type, the \c PieSlice type has to be exposted to QML
+using QML_ELEMENT. As with \c PieChart, we add the "Charts" type namespace,
+version 1.0 to the .pro file:
-\snippet tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp 0
-\dots
-\snippet tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp 1
+\snippet tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h 0
\dots
-\snippet tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp 2
+\quotefile tutorials/extending-qml/chapter1-basics/chapter4-customPropertyTypes.pro
The source code from the following files are referred to in this chapter:
\generatelist examplefiles .*chapter4.*
@@ -453,7 +459,7 @@ In this tutorial, we've shown the basic steps for creating a QML extension:
\list
\li Define new QML types by subclassing QObject and registering them with
- qmlRegisterType()
+ QML_ELEMENT or QML_NAMED_ELEMENT()
\li Add callable methods using \l Q_INVOKABLE or Qt slots, and connect to Qt signals
with an \c onSignal syntax
\li Add property bindings by defining \l{Qt's Property System}{NOTIFY} signals
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/external-resources.qdoc b/src/qml/doc/src/external-resources.qdoc
index 68c5ab4664..c11174db43 100644
--- a/src/qml/doc/src/external-resources.qdoc
+++ b/src/qml/doc/src/external-resources.qdoc
@@ -45,7 +45,7 @@
\title Mozilla Developer Network Date Reference
*/
/*!
- \externalpage hhttps://www.froglogic.com/squish/gui-testing
+ \externalpage https://www.froglogic.com/squish/gui-testing
\title Squish
*/
/*!
@@ -76,3 +76,7 @@
\externalpage https://fontawesome.com/
\title Font Awesome
*/
+/*!
+ \externalpage https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
+ \title Nullish Coalescing
+*/
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/javascript/finetuning.qdoc b/src/qml/doc/src/javascript/finetuning.qdoc
new file mode 100644
index 0000000000..fcd710db8b
--- /dev/null
+++ b/src/qml/doc/src/javascript/finetuning.qdoc
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+/*!
+
+\page qtqml-javascript-finetuning.html
+\title Fine-tuning the JavaScript Engine
+\brief Describes the environment variables available, to control how Javascript is run.
+
+Running JavaScript code can be influenced by a few environment variables, particularly:
+
+\table
+ \header
+ \li Environment Variable
+ \li Description
+ \row
+ \li \c{QV4_JIT_CALL_THRESHOLD}
+ \li The JavaScript engine contains a Just-In-Time compiler (JIT). The JIT will compile
+ frequently run JavaScript functions into machine code to run faster. This
+ environment variable determines how often a function needs to be run to be
+ considered for JIT compilation. The default value is 3 times.
+ \row
+ \li \c{QV4_FORCE_INTERPRETER}
+ \li Setting this environment variable disables the JIT and runs all
+ functions through the interpreter, no matter how often they are called.
+ \row
+ \li \c{QV4_JS_MAX_STACK_SIZE}
+ \li The JavaScript engine reserves a special memory area as a stack to run JavaScript.
+ This stack is separate from the C++ stack. Usually this area is 4MB in size. If this
+ environment variable contains a number, the JavaScript engine interprets it as the
+ size of the memory area, in bytes, to be allocated as the JavaScript stack.
+ \row
+ \li \c{QV4_GC_MAX_STACK_SIZE}
+ \li In addition to the regular JavaScript stack, the JavaScript engine keeps another stack
+ for the garbage collector, usually 2MB of memory. If the garbage collector needs to
+ handle an excessive number of objects at the same time, this stack might overrun.
+ If it contains a number, this environment variable is interpreted as the size in bytes
+ of the memory area that will be allocated as the stack for the garbage collector.
+ \row
+ \li \c{QV4_CRASH_ON_STACKOVERFLOW}
+ \li Usually the JavaScript engine tries to catch C++ stack overflows caused by
+ excessively recursive JavaScript code, and generates a non-fatal error condition.
+ There are separate recursion checks for compiling JavaScript and running JavaScript. A
+ stack overflow when compiling JavaScript indicates that the code contains deeply nested
+ objects and functions. A stack overflow at run-time indicates that the code results in
+ a deeply recursive program. The check for this is only indirectly related to the
+ JavaScript stack size mentioned above, as each JavaScript function call consumes stack
+ space on both, the C++ and the JavaScript stack. The code that checks for excessive
+ recursion is necessarily conservative, as the available stack size depends on many
+ factors and can often be customized by the user. With this environment variable set, the
+ JavaScript engine does not check for stack overflows when compiling or running
+ JavaScript and will not generate exceptions for them. Instead, when the stack overflows
+ the program attempts an invalid memory access. This most likely terminates the
+ program. In turn, the program gets to use up all the stack space the operating system
+ can provide.
+ \warning malicious code may be able to evade the termination and access unexpected
+ memory locations this way.
+ \row
+ \li \c{QV4_MAX_CALL_DEPTH}
+ \li Stack overflows when running (as opposed to compiling) JavaScript are prevented by
+ controlling the call depth: the number of nested function invocations. By
+ default, an exception is generated if the call depth exceeds 1234. If it contains a
+ number, this environment variable overrides the maximum call depth. Beware that the
+ recursion limit when compiling JavaScript is not affected.
+ \row
+ \li \c{QV4_MM_AGGRESSIVE_GC}
+ \li Setting this environment variable runs the garbage collector before each memory
+ allocation. This is very expensive at run-time, but it quickly uncovers many memory
+ management errors, for example the manual deletion of an object belonging to the QML
+ engine from C++.
+ \row
+ \li \c{QV4_PROFILE_WRITE_PERF_MAP}
+ \li On Linux, the \c perf utility can be used to profile programs. To analyze JIT-compiled
+ JavaScript functions, it needs to know about their names and locations in memory. To
+ provide this information, there's a convention to create a special file called
+ \c{perf-<pid>.map} in \e{/tmp} which perf then reads. This environment variable, if
+ set, causes the JIT to generate this file.
+\endtable
+
+*/
+
diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc
index c22c392b80..bc75f843fb 100644
--- a/src/qml/doc/src/javascript/hostenvironment.qdoc
+++ b/src/qml/doc/src/javascript/hostenvironment.qdoc
@@ -42,6 +42,8 @@ Like a browser or server-side JavaScript environment, the QML runtime implements
all of the built-in types and functions defined by the standard, such as Object, Array, and Math.
The QML runtime implements the 7th edition of the standard.
+Since Qt 5.15 \l{Nullish Coalescing} is also implemented in the QML runtime.
+
The standard ECMAScript built-ins are not explicitly documented in the QML documentation. For more
information on their use, please refer to the ECMA-262 7th edition standard or one of the many online
JavaScript reference and tutorial sites, such as the \l{W3Schools JavaScript Reference} (JavaScript Objects
diff --git a/src/qml/doc/src/javascript/imports.qdoc b/src/qml/doc/src/javascript/imports.qdoc
index 8e26c4aadd..9227f0e604 100644
--- a/src/qml/doc/src/javascript/imports.qdoc
+++ b/src/qml/doc/src/javascript/imports.qdoc
@@ -154,7 +154,7 @@ var importedEnumValue = JsQtTest.MyQmlObject.EnumValue3
\endcode
In particular, this may be useful in order to access functionality provided
-via a singleton type; see qmlRegisterSingletonType() for more information.
+via a singleton type; see QML_SINGLETON for more information.
\note The .import syntax doesn't work for scripts used in the \l {WorkerScript}
*/
diff --git a/src/qml/doc/src/javascript/topic.qdoc b/src/qml/doc/src/javascript/topic.qdoc
index 0c06e14b4c..05fb1ddfdc 100644
--- a/src/qml/doc/src/javascript/topic.qdoc
+++ b/src/qml/doc/src/javascript/topic.qdoc
@@ -81,4 +81,11 @@ These limitations and extensions are documented in the description of the
\l{qtqml-javascript-hostenvironment.html}{JavaScript Host Environment} provided
by the QML engine.
+\section1 Fine Tuning the JavaScript engine
+
+For specific use cases you may want to override some of the parameters the
+JavaScript engine uses for handling memory and compiling JavaScript. See
+\l{qtqml-javascript-finetuning.html}{Fine Tuning the JavaScript engine} for
+more information on these parameters.
+
*/
diff --git a/src/qml/doc/src/qmldiskcache.qdoc b/src/qml/doc/src/qmldiskcache.qdoc
new file mode 100644
index 0000000000..100334296c
--- /dev/null
+++ b/src/qml/doc/src/qmldiskcache.qdoc
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qmldiskcache.html
+\title The QML Disk Cache
+\brief QML caches compiled documents on disk to improve load time.
+
+When your application loads a QML or JavaScript file for the first time,
+the QML engine compiles the file into a byte code representation on the
+fly and runs it. The compiling process can be time consuming, and subsequent
+loads of the same document yield the same result. To optimize this step, the
+QML engine can cache the result. It stores the byte code in a cache file and
+later loads the cache file instead of re-compiling when the same file is
+requested again. Usually the files are stored in a subdirectory \c{qmlcache}
+of the system's cache directory, as denoted by QStandardPaths::CacheLocation.
+Checks are in place to make sure that the cache files are only loaded if all
+of the following conditions are met:
+\list
+ \li The Qt version has not changed
+ \li The source code in the original file has not changed
+ \li The QML debugger is not running
+\endlist
+
+The disk caching behavior can be fine tuned using the following environment
+variables:
+
+\table
+ \header
+ \li Environment Variable
+ \li Description
+ \row
+ \li \c{QML_DISABLE_DISK_CACHE}
+ \li Disables the disk cache and forces re-compilation from source for
+ all QML and JavaScript files.
+ \row
+ \li \c{QML_FORCE_DISK_CACHE}
+ \li Enables the disk cache even when debugging QML. You cannot use the
+ JavaScript debugger this way. It may fail to stop at breakpoints,
+ for example. You can still use the QML inspector to explore the
+ object hierarchy, though. \c{QML_FORCE_DISK_CACHE} overrides
+ \c{QML_DISABLE_DISK_CACHE}.
+ \row
+ \li \c{QML_DISK_CACHE_PATH}
+ \li Specifies a custom location where the cache files shall be stored
+ instead of using the default location.
+\endtable
+
+You can also specify \c{CONFIG += qtquickcompiler} in your \c{.pro} file
+to perform the compilation ahead of time and integrate the resulting byte code
+directly into your executable. For more information, see \l{Qt Quick Compiler}.
+
+*/
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 67c0f6bb25..0ff0de1ef9 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -26,6 +26,274 @@
****************************************************************************/
/*!
+ \macro QML_ELEMENT
+ \relates QQmlEngine
+
+ Declares the enclosing type or namespace to be available in QML, using its
+ class or namespace name as the QML element name.
+
+ For example, this makes the C++ class \c Slider available as a QML type
+ named \c Slider.
+
+ \code
+ class Slider : public QObject
+ {
+ Q_OBJECT
+ QML_ELEMENT
+ ...
+ }
+ \endcode
+
+ You can use the build system to register the type in the type namespace
+ \e {com.mycompany.qmlcomponents} with major version \c 1 by specifying the
+ following in your project file:
+
+ \badcode
+ CONFIG += qmltypes
+ QML_IMPORT_NAME = com.mycompany.qmlcomponents
+ QML_IMPORT_MAJOR_VERSION = 1
+ \endcode
+
+ Once registered, the type can be used in QML by importing the
+ same type namespace and version number:
+
+ \qml
+ import com.mycompany.qmlcomponents 1.0
+
+ Slider {
+ // ...
+ }
+ \endqml
+
+ You can also make namespaces tagged with Q_NAMESPACE available this way, in
+ order to expose any enums tagged with Q_ENUM_NS they contain.
+
+ \sa {Choosing the Correct Integration Method Between C++ and QML}, QML_NAMED_ELEMENT(),
+ Q_REVISION(), QML_ADDED_IN_MINOR_VERSION()
+*/
+
+/*!
+ \macro QML_NAMED_ELEMENT(name)
+ \relates QQmlEngine
+
+ Declares the enclosing type or namespace to be available in QML, using \a name
+ as the element name. Otherwise behaves the same as QML_ELEMENT.
+
+ \sa {Choosing the Correct Integration Method Between C++ and QML}, QML_ELEMENT
+*/
+
+/*!
+ \macro QML_ANONYMOUS
+ \relates QQmlEngine
+
+ Declares the enclosing type to be available, but anonymous in QML. The type
+ cannot be created or used as property type, but when passed from C++, it is
+ recognized.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_INTERFACE
+*/
+
+/*!
+ \macro QML_INTERFACE
+ \relates QQmlEngine
+
+ This macro registers the enclosing C++ type in the QML system as an interface.
+
+ Types registered as an interface in QML should also declare themselves as an
+ interface with the \l {The Meta-Object System}{meta object system}. For
+ example:
+
+ \code
+ struct FooInterface
+ {
+ QML_INTERFACE
+ public:
+ virtual ~FooInterface();
+ virtual void doSomething() = 0;
+ };
+
+ Q_DECLARE_INTERFACE(FooInterface, "org.foo.FooInterface")
+ \endcode
+
+ When registered with QML in this way, they can be used as property types:
+
+ Q_PROPERTY(FooInterface *foo READ foo WRITE setFoo)
+
+ When you assign a \l QObject sub-class to this property, the QML engine does
+ the interface cast to \c FooInterface* automatically.
+
+ Interface types are implicitly anonymous and uncreatable in QML.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_ANONYMOUS
+*/
+
+/*!
+ \macro QML_UNCREATABLE(reason)
+ \relates QQmlEngine
+
+ Declares that the enclosing type shall not be creatable from QML. This takes
+ effect if the type is available in QML, by having a \l QML_ELEMENT or
+ \l QML_NAMED_ELEMENT() macro. The \a reason will be emitted as error message if an
+ attempt to create the type from QML is detected.
+
+ Some QML types are implicitly uncreatable, in particular types exposed with
+ \l QML_ANONYMOUS or namespaces exposed with \l QML_ELEMENT or
+ \l QML_NAMED_ELEMENT(). For such types, \l QML_UNCREATABLE() can be used to
+ provide a custom error message.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS
+*/
+
+/*!
+ \macro QML_SINGLETON
+ \relates QQmlEngine
+
+ Declares the enclosing type to be a singleton in QML. This only takes effect
+ if the type is available in QML, by having a \l QML_ELEMENT or
+ \l QML_NAMED_ELEMENT() macro. By default, each QQmlEngine will try to create a
+ singleton instance using the type's default constructor when the type is first
+ accessed. If there is no default constructor the singleton is initially
+ inaccessible. This behavior can be overridden by calling
+ \l qmlRegisterSingletonType() with a specific factory function or
+ \l qmlRegisterSingletonInstance() with a specific instance for the same class
+ and the same type namespace and version.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT(), qmlRegisterSingletonInstance().
+*/
+
+/*!
+ \macro QML_ADDED_IN_MINOR_VERSION(VERSION)
+ \relates QQmlEngine
+
+ Declares that the enclosing type or namespace was added in the specified minor
+ \a VERSION, relative to the module major version. The minor version is assumed
+ to be in line with any revisions given by \l Q_REVISION() macros on methods,
+ slots, or signals, and any REVISION tags on properties declared with
+ \l Q_PROPERTY().
+
+ \l QML_ADDED_IN_MINOR_VERSION() only takes effect if the type or namespace is
+ available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(),
+ \l QML_ANONYMOUS, or \l QML_INTERFACE macro.
+
+ If the QML module the type belongs to is imported with a lower version than
+ the one determined this way, the QML type is invisible.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT()
+*/
+
+/*!
+ \macro QML_REMOVED_IN_MINOR_VERSION(VERSION)
+ \relates QQmlEngine
+
+ Declares that the enclosing type or namespace was removed in the specified
+ minor \a VERSION, relative to the module major version. This is primarily
+ useful when replacing the implementation of a QML type. If a corresponding
+ \l QML_ADDED_IN_MINOR_VERSION() is present on a different type or namespace of
+ the same QML name, then the removed type is used when importing versions of
+ the module lower than \a VERSION, and the added type is used when importing
+ versions of the module greater or equal \a VERSION.
+
+ \l QML_REMOVED_IN_MINOR_VERSION() only takes effect if type or namespace is
+ available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(),
+ \l QML_ANONYMOUS, or \l QML_INTERFACE macro.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT()
+*/
+
+/*!
+ \macro QML_ATTACHED(ATTACHED_TYPE)
+ \relates QQmlEngine
+
+ Declares that the enclosing type attaches \a ATTACHED_TYPE as an
+ \l {Attached Properties and Attached Signal Handlers}
+ {attached property} to other types. This takes effect if the type
+ is exposed to QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT(), qmlAttachedPropertiesObject(),
+ {Providing Attached Properties}
+*/
+
+/*!
+ \macro QML_EXTENDED(EXTENDED_TYPE)
+ \relates QQmlEngine
+
+ Declares that the enclosing type uses \a EXTENDED_TYPE as an extension to
+ provide further properties and methods in QML. This takes effect if the type
+ is exposed to QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT(), {Registering Extension Objects}
+*/
+
+/*!
+ \macro QML_FOREIGN(FOREIGN_TYPE)
+ \relates QQmlEngine
+
+ Declares that any \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), \l QML_ANONYMOUS,
+ \l QML_INTERFACE, \l QML_UNCREATABLE(), \l QML_SINGLETON,
+ \l QML_ADDED_IN_MINOR_VERSION(), \l QML_REMOVED_IN_MINOR_VERSION(),
+ \l QML_ATTACHED(), or \l QML_EXTENDED() macros in the enclosing C++ type do
+ not apply to the enclosing type but instead to \a FOREIGN_TYPE. The enclosing
+ type still needs to be registered with the
+ \l {The Meta-Object System}{meta object system} using a \l Q_GADGET or
+ \l Q_OBJECT macro.
+
+ This is useful for registering types that cannot be amended to add the macros,
+ for example because they belong to 3rdparty libraries.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT()
+*/
+
+/*!
+ \macro QML_UNAVAILABLE
+ \relates QQmlEngine
+
+ This macro declares the enclosing type to be unavailable in QML. It registers
+ an internal dummy type called \c QQmlTypeNotAvailable as \l QML_FOREIGN()
+ type, using any further QML macros you specify.
+
+ Normally, the types exported by a module should be fixed. However, if a C++
+ type is not available, you should at least "reserve" the QML type name, and
+ give the user of the unavailable type a meaningful error message.
+
+ Example:
+
+ \code
+ #ifdef NO_GAMES_ALLOWED
+ struct MinehuntGame
+ {
+ Q_GADGET
+ QML_NAMED_ELEMENT(Game)
+ QML_UNAVAILABLE
+ QML_UNCREATABLE("Get back to work, slacker!");
+ };
+ #else
+ class MinehuntGame : public QObject
+ {
+ Q_OBJECT
+ QML_NAMED_ELEMENT(Game)
+ // ...
+ };
+ #endif
+ \endcode
+
+ This will cause any QML which attempts to use the "Game" type to produce an
+ error message:
+
+ \badcode
+ fun.qml: Get back to work, slacker!
+ Game {
+ ^
+ \endcode
+
+ Using this technique, you only need a \l Q_GADGET struct to customize the error
+ message, not a full-blown \l QObject. Without \l QML_UNCREATABLE(),
+ \l QML_UNAVAILABLE still results in a more specific error message than the usual
+ "is not a type" for completely unknown types.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_FOREIGN()
+*/
+
+/*!
\macro QML_DECLARE_TYPE()
\relates QQmlEngine
@@ -41,7 +309,8 @@
Current the only supported type info is \c QML_HAS_ATTACHED_PROPERTIES which
declares that the \a Type supports \l {Attached Properties and Attached Signal Handlers}
- {attached properties}.
+ {attached properties}. QML_DECLARE_TYPEINFO() is not necessary if \a Type contains the
+ QML_ATTACHED macro.
*/
/*!
@@ -106,7 +375,8 @@
QML written to previous versions to continue to work, even if more advanced versions of
some of its types are available.
- \sa {Choosing the Correct Integration Method Between C++ and QML}
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT(),
+ {Choosing the Correct Integration Method Between C++ and QML}
*/
/*!
@@ -143,7 +413,7 @@
Returns the QML type id.
- \sa qmlRegisterTypeNotAvailable(),
+ \sa QML_UNCREATABLE(), qmlRegisterTypeNotAvailable(),
{Choosing the Correct Integration Method Between C++ and QML}
*/
@@ -158,7 +428,7 @@
Returns the QML type id.
- \sa qmlRegisterType(), {Registering Extension Objects}
+ \sa QML_EXTENDED(), qmlRegisterType(), {Registering Extension Objects}
*/
@@ -180,7 +450,7 @@
Returns the QML type id.
- \sa qmlRegisterUncreatableType()
+ \sa QML_EXTENDED(), QML_UNCREATABLE(), qmlRegisterUncreatableType()
*/
/*!
@@ -220,6 +490,8 @@
\code
Component.onCompleted: console.log(MyNamespace.Key2)
\endcode
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE()
*/
/*!
@@ -235,6 +507,8 @@
the \a parser provided.
Returns the QML type id.
+
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED()
*/
/*!
@@ -269,7 +543,7 @@
Without this, a generic "Game is not a type" message would be given.
- \sa qmlRegisterUncreatableType(),
+ \sa QML_UNAVAILABLE, qmlRegisterUncreatableType(),
{Choosing the Correct Integration Method Between C++ and QML}
*/
@@ -353,7 +627,7 @@
Returns the QML type id.
\since 5.14
- \sa {Choosing the Correct Integration Method Between C++ and QML}
+ \sa QML_ANONYMOUS, {Choosing the Correct Integration Method Between C++ and QML}
*/
/*!
@@ -397,6 +671,8 @@
the interface cast to \c FooInterface* automatically.
Returns the QML type id.
+
+ \sa QML_INTERFACE
*/
/*!
@@ -455,7 +731,7 @@
}
\endqml
- \sa {Choosing the Correct Integration Method Between C++ and QML}
+ \sa QML_SINGLETON, {Choosing the Correct Integration Method Between C++ and QML}
*/
/*!
@@ -477,8 +753,7 @@
Returns 0 if type \e T is not a valid attaching type, or if \a create is false and no
attachment object instance has previously been created for \a attachee.
- \sa {Providing Attached Properties}
-
+ \sa QML_ATTACHED(), {Providing Attached Properties}
*/
/*!
@@ -571,7 +846,7 @@
}
\endqml
- \sa {Choosing the Correct Integration Method Between C++ and QML}
+ \sa QML_SINGLETON, {Choosing the Correct Integration Method Between C++ and QML}
*/
@@ -626,10 +901,12 @@
That can be done by adding a pragma Singleton statement among the imports of the type's QML file. In addition
the type must be defined in a qmldir file with a singleton keyword and the qmldir must be imported by the QML
files using the singleton.
+
+ \sa QML_SINGLETON
*/
/*!
- \fn int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject* cppObject)
+ \fn int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *cppObject)
\relates QQmlEngine
\since 5.14
@@ -718,7 +995,7 @@
}
\endqml
- \sa qmlRegisterSingletonType
+ \sa QML_SINGLETON, qmlRegisterSingletonType
*/
/*!
@@ -792,5 +1069,5 @@
Returns -1 if no matching type was found or one of the given parameters
was invalid.
- \sa qmlRegisterType(), qmlRegisterSingletonType()
+ \sa QML_ELEMENT, QML_NAMED_ELEMENT, QML_SINGLETON, qmlRegisterType(), qmlRegisterSingletonType()
*/
diff --git a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
index 2de4eb0c18..a4119ff793 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,80 @@ 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 qml/qml-documents/Images.qml document
+
+In other files, it has to be prefixed with the name of its containing component.
+
+\snippet 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 qml/qml-documents/A.qml document
+\snippet 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 +179,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 +213,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 +233,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/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
index 0faad43f4f..99c7fa5621 100644
--- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
+++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
@@ -422,7 +422,7 @@ import QtQuick.tooling 1.1
// Component objects.
Module {
// A Component object directly corresponds to a type exported
- // in a plugin with a call to qmlRegisterType.
+ // using the QML_ELEMENT or QML_NAMED_ELEMENT macros.
Component {
// The name is a unique identifier used to refer to this type.
@@ -440,25 +440,34 @@ Module {
attachedType: "QQuickAnimationAttached"
// The list of exports determines how a type can be imported.
- // Each string has the format "URI/Name version" and matches the
- // arguments to qmlRegisterType. Usually types are only exported
- // once, if at all.
- // If the "URI/" part of the string is missing that means the
- // type should be put into the package defined by the URI the
- // module was imported with.
- // For example if this module was imported with 'import Foo 4.8'
- // the Animation object would be found in the package Foo and
- // QtQuick.
+ // Each string has the format "URI/Name version". The URI is
+ // the import name given via the build system, for example as
+ // QML_IMPORT_NAME in qmake. The name is either the C++ class
+ // name or, in case of QML_NAMED_ELEMENT(), an explicitly given
+ // name. The version is constructed from the major version
+ // given via the build system, as QML_IMPORT_MAJOR_VERSION in
+ // qmake, and any revisions given in the class or its base
+ // classes by Q_REVISION(), the REVISION argument to Q_PROPERTY,
+ // or QML_ADDED_IN_MINOR_VERSION(). Usually types are only
+ // exported once, if at all. The following tells us that there
+ // are two variants of Animation, and that 'import QtQuick 2.0'
+ // will expose a different revision than imports of later
+ // versions.
exports: [
- "Animation 4.7",
- "QtQuick/Animation 1.0"
+ "QtQuick/Animation 2.0",
+ "QtQuick/Animation 2.1"
]
// The meta object revisions for the exports specified in 'exports'.
- // Describes with revisioned properties will be visible in an export.
- // The list must have exactly the same length as the 'exports' list.
- // For example the 'animations' propery described below will only be
- // available through the QtQuick/Animation 1.0 export.
+ // Each meta object revision may add additional properties or methods,
+ // relative to the previous one. Those will only be visible when the
+ // module is imported with at least the corresponding version as
+ // specified in the 'exports' list.
+ // The exportMetaObjectRevisions list must have exactly the same
+ // length as the 'exports' list. For example, the 'animations' property
+ // described below will only be available through the QtQuick/Animation
+ // 2.1 export. Usually the revisions will match the versions in the
+ // 'exports' list.
exportMetaObjectRevisions: [0, 1]
Property {
@@ -479,17 +488,14 @@ Module {
Enum {
name: "Loops"
- values: {
- "Infinite": -2,
- "OnceOnly": 1
- }
+ values: [ "Infinite", "OnceOnly" ]
}
// Signal and Method work the same way. The inner Parameter
// declarations also support the isReadonly, isPointer and isList
// attributes which mean the same as for Property
Method { name: "restart" }
- Signal { name: "started"; revision: 2 }
+ Signal { name: "started"; revision: 1 }
Signal {
name: "runningChanged"
Parameter { type: "bool" }
diff --git a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc
index 01e81e7c19..496245820a 100644
--- a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc
+++ b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc
@@ -1,19 +1,22 @@
-QQmlExtensionPlugin is a plugin interface that makes it possible to
+\l QQmlEngineExtensionPlugin is a plugin interface that makes it possible to
create QML extensions that can be loaded dynamically into QML applications.
These extensions allow custom QML types to be made available to the
QML engine.
To write a QML extension plugin:
\list 1
-\li Subclass QQmlExtensionPlugin
+\li Subclass \l QQmlEngineExtensionPlugin and use the Q_PLUGIN_METADATA() macro
+ to register the plugin with the Qt meta object system.
+\li Use the \l QML_ELEMENT and \l QML_NAMED_ELEMENT() macros to declare
+ QML types.
+\li Write a project file for the plugin. Add:
\list
- \li Use the Q_PLUGIN_METADATA() macro to register the plugin with
- the Qt meta object system
- \li Override the \l{QQmlExtensionPlugin::}{registerTypes()} method
- and call qmlRegisterType() to register the types to be exported
- by the plugin
+ \li \c {CONFIG += qmltypes} to instruct the build system to generate
+ QML types.
+ \li \c {QML_IMPORT_NAME = <my.import.name>} to specify the import name.
+ \li \c {QML_IMPORT_MAJOR_VERSION = <version>} to specify the import
+ major version.
\endlist
-\li Write a project file for the plugin
\li Create a \l{Module Definition qmldir Files}{qmldir file} to
describe the plugin
\endlist
@@ -27,26 +30,18 @@ issues in the library user's code.
Suppose there is a new \c TimeModel C++ class that should be made available
as a new QML type. It provides the current time through \c hour and \c minute
-properties.
+properties. It declares a QML type called \c Time via \l QML_NAMED_ELEMENT().
-\snippet qmlextensionplugins/plugin.cpp 0
+\snippet qmlextensionplugins/timemodel.h 0
\dots
To make this type available, we create a plugin class named \c QExampleQmlPlugin
-which is a subclass of \l QQmlExtensionPlugin. It overrides the
-\l{QQmlExtensionPlugin::}{registerTypes()} method in order to register the \c TimeModel
-type using qmlRegisterType(). It also uses the Q_PLUGIN_METADATA() macro in the class
-definition to register the plugin with the Qt meta object system using a unique
-identifier for the plugin.
+which is a subclass of \l QQmlEngineExtensionPlugin. It uses the
+Q_PLUGIN_METADATA() macro in the class definition to register the plugin with the
+Qt meta object system using a unique identifier for the plugin.
\snippet qmlextensionplugins/plugin.cpp plugin
-This registers the \c TimeModel class with version \c{1.0} of this plugin library, as
-a QML type called \c Time. The Q_ASSERT() macro can ensure the type namespace is
-imported correctly by any QML components that use this plugin. The
-\l{Defining QML Types from C++} article has more information about registering C++
-types into the runtime.
-
\section1 Project settings for the plugin
Additionally, the project file (\c .pro) defines the project as a plugin library,
@@ -55,14 +50,22 @@ the plugin target name and various other details:
\code
TEMPLATE = lib
-CONFIG += qt plugin
+CONFIG += qt plugin qmltypes
QT += qml
-DESTDIR = imports/TimeExample
-TARGET = qmlqtimeexampleplugin
+QML_IMPORT_NAME = TimeExample
+QML_IMPORT_MAJOR_VERSION = 1
+
+DESTDIR = imports/$$QML_IMPORT_NAME
+TARGET = qmlqtimeexampleplugin
+
SOURCES += qexampleqmlplugin.cpp
\endcode
+This registers the \c TimeModel class with the import \c{TimeExample 1.0}, as
+a QML type called \c Time. The \l{Defining QML Types from C++} article has more
+information about registering C++ types for usage in QML.
+
\section1 Plugin definition in the qmldir
Finally, a \l{Module Definition qmldir Files}{qmldir file} is required
diff --git a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
index 57e0ba1a14..fdba452271 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
@@ -127,15 +127,15 @@ Rectangle {
In this case, the engine will emit an error and refuse to load the file.
-\section4 Non-module Namespace Imports
+\section4 C++ Module Imports
-Types can also be registered into namespaces directly via the various
-registration functions in C++ (such as qmlRegisterType()). The types which
-have been registered into a namespace in this way may be imported by importing
-the namespace, as if the namespace was a module identifier.
+Usually, C++ types are declared using the QML_ELEMENT and QML_NAMED_ELEMENT()
+macros and registered via the build system using QML_IMPORT_NAME and
+QML_IMPORT_MAJOR_VERSION. The import name and version given this way form a
+module that can be imported to access the types.
This is most common in client applications which define their own QML object
-types in C++ and register them with the QML type system manually.
+types in C++.
\section4 Importing into a Qualified Local Namespace
@@ -299,6 +299,13 @@ Additional import paths can be added through QQmlEngine::addImportPath() or the
\l{Prototyping with qmlscene}{qmlscene} tool, you can also use the \c -I option
to add an import path.
+You can specify multiple import paths in the \c QML2_IMPORT_PATH environment
+variable by joining them using the path separator. On Windows the path separator
+is a semicolon (;), on other platforms it is a colon (:). This means that you
+cannot specify resource paths or URLs in QML2_IMPORT_PATH, as they contain
+colons themselves. However, you can add resource paths and URLs by calling
+QQmlEngine::addImportPath() programatically.
+
\section1 Debugging
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index 401e099ebf..ecfef2e04f 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 Qt Quick} 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/doc/src/qmllanguageref/typesystem/basictypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc
index 5144fe219e..53984a440d 100644
--- a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc
@@ -582,34 +582,15 @@ property is only invoked when the property is reassigned to a different object v
QML objects (and certainly not JavaScript object either) and the key-value
pairs in \c attributes are \e not QML properties. Rather, the \c items
property holds an array of values, and \c attributes holds a set of key-value
- pairs. Since they are stored as a set of values, instead of as an object,
- their contents \e cannot be modified individually:
-
- \qml
- Item {
- property variant items: [1, 2, 3, "four", "five"]
- property variant attributes: { 'color': 'red', 'width': 100 }
-
- Component.onCompleted: {
- items[0] = 10
- console.log(items[0]) // This will still be '1'!
- attributes.color = 'blue'
- console.log(attributes.color) // This will still be 'red'!
- }
- }
- \endqml
-
- Since it is not possible to individually add or remove items from a list or
- object stored in a \c variant, the only way to modify its contents is to
- reassign a new value. However, this is not efficient, as it causes the value
- to be serialized and deserialized.
+ pairs.
Additionally, since \c items and \c attributes are not QML objects, changing
- their individual values do not trigger property change notifications. If
- the above example had \c onNumberChanged or \c onAnimalChanged signal
- handlers, they would not have been called. If, however, the \c items or
- \c attributes properties themselves were reassigned to different values, then
- such handlers would be called.
+ the values they contain does not trigger property change notifications. If
+ the above example had \c onItemsChanged or \c onAttributesChanged signal
+ handlers, they would not be called when assigning individual entries in
+ either property. If, however, the \c items or \c attributes properties
+ themselves were reassigned to different values, then such handlers would be
+ called.
JavaScript programmers should also note that when a JavaScript object is
copied to an array or map property, the \e contents of the object (that is,
diff --git a/src/qml/doc/src/qtqml.qdoc b/src/qml/doc/src/qtqml.qdoc
index 68d2b66950..205cbc147d 100644
--- a/src/qml/doc/src/qtqml.qdoc
+++ b/src/qml/doc/src/qtqml.qdoc
@@ -155,6 +155,8 @@ Further information for writing QML applications:
- essential information for application development with QML and Qt Quick
\li \l{Qt Quick} - a module which provides a set of QML types and C++ classes
for building user interfaces and applications with QML
+\li \l{The QML Disk Cache}
+ - how to fine tune if and where the QML engine caches compilation results.
\endlist
\section2 Reference
diff --git a/src/qml/inlinecomponentutils_p.h b/src/qml/inlinecomponentutils_p.h
new file mode 100644
index 0000000000..99b28349cd
--- /dev/null
+++ b/src/qml/inlinecomponentutils_p.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** 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 INLINECOMPONENTUTILS_P_H
+#define INLINECOMPONENTUTILS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qv4compileddata_p.h>
+#include <private/qv4executablecompilationunit_p.h>
+
+namespace icutils {
+struct Node {
+ Node() = default;
+ Node(const Node &) = default;
+ Node(Node &&) = default;
+ Node& operator=(Node const &) = default;
+ Node& operator=(Node &&) = default;
+ bool operator==(Node const &other) const {return index == other.index;}
+
+ Node(std::vector<QV4::CompiledData::InlineComponent>::size_type s) {
+ index = quint32(s);
+ temporaryMark = 0;
+ permanentMark = 0;
+ }
+
+ union {
+ quint32_le_bitfield<0, 30> index;
+ quint32_le_bitfield<30, 1> temporaryMark;
+ quint32_le_bitfield<31, 1> permanentMark;
+ };
+};
+
+using AdjacencyList = std::vector<std::vector<Node*>>;
+
+template<typename ObjectContainer, typename InlineComponent>
+void fillAdjacencyListForInlineComponents(ObjectContainer *objectContainer, AdjacencyList &adjacencyList, std::vector<Node> &nodes, const std::vector<InlineComponent> &allICs) {
+ using CompiledObject = typename ObjectContainer::CompiledObject;
+ // add an edge from A to B if A and B are inline components with the same containing type
+ // and A inherits from B (ignore indirect chains through external types for now)
+ // or if A instantiates B
+ for (typename std::vector<InlineComponent>::size_type i = 0; i < allICs.size(); ++i) {
+ const auto& ic = allICs[i];
+ const CompiledObject *obj = objectContainer->objectAt(ic.objectIndex);
+ QV4::ResolvedTypeReference *currentICTypeRef = objectContainer->resolvedType(ic.nameIndex);
+ auto createEdgeFromTypeRef = [&](QV4::ResolvedTypeReference *targetTypeRef) {
+ if (targetTypeRef && targetTypeRef->type.isInlineComponentType()) {
+ if (targetTypeRef->type.containingType() == currentICTypeRef->type.containingType()) {
+ auto icIt = std::find_if(allICs.cbegin(), allICs.cend(), [&](const QV4::CompiledData::InlineComponent &icSearched){
+ return int(icSearched.objectIndex) == targetTypeRef->type.inlineComponentObjectId();
+ });
+ Q_ASSERT(icIt != allICs.cend());
+ Node& target = nodes[i];
+ adjacencyList[std::distance(allICs.cbegin(), icIt)].push_back(&target);
+ }
+ }
+ };
+ if (obj->inheritedTypeNameIndex != 0) {
+ QV4::ResolvedTypeReference *parentTypeRef = objectContainer->resolvedType(obj->inheritedTypeNameIndex);
+ createEdgeFromTypeRef(parentTypeRef);
+
+ }
+ auto referencedInICObjectIndex = ic.objectIndex + 1;
+ while (int(referencedInICObjectIndex) < objectContainer->objectCount()) {
+ auto potentiallyReferencedInICObject = objectContainer->objectAt(referencedInICObjectIndex);
+ bool stillInIC = !(potentiallyReferencedInICObject-> flags & QV4::CompiledData::Object::IsInlineComponentRoot)
+ && (potentiallyReferencedInICObject-> flags & QV4::CompiledData::Object::InPartOfInlineComponent);
+ if (!stillInIC)
+ break;
+ createEdgeFromTypeRef(objectContainer->resolvedType(potentiallyReferencedInICObject->inheritedTypeNameIndex));
+ ++referencedInICObjectIndex;
+ }
+ }
+};
+
+inline void topoVisit(Node *node, AdjacencyList &adjacencyList, bool &hasCycle, std::vector<Node> &nodesSorted) {
+ if (node->permanentMark)
+ return;
+ if (node->temporaryMark) {
+ hasCycle = true;
+ return;
+ }
+ node->temporaryMark = 1;
+
+ auto const &edges = adjacencyList[node->index];
+ for (auto edgeTarget =edges.begin(); edgeTarget != edges.end(); ++edgeTarget) {
+ topoVisit(*edgeTarget, adjacencyList, hasCycle, nodesSorted);
+ }
+
+ node->temporaryMark = 0;
+ node->permanentMark = 1;
+ nodesSorted.push_back(*node);
+};
+
+// Use DFS based topological sorting (https://en.wikipedia.org/wiki/Topological_sorting)
+inline std::vector<Node> topoSort(std::vector<Node> &nodes, AdjacencyList &adjacencyList, bool &hasCycle) {
+ std::vector<Node> nodesSorted;
+ nodesSorted.reserve(nodes.size());
+
+ hasCycle = false;
+ auto currentNodeIt = std::find_if(nodes.begin(), nodes.end(), [](const Node& node) {
+ return node.permanentMark == 0;
+ });
+ // Do a topological sort of all inline components
+ // afterwards, nodesSorted contains the nodes for the inline components in reverse topological order
+ while (currentNodeIt != nodes.end() && !hasCycle) {
+ Node& currentNode = *currentNodeIt;
+ topoVisit(&currentNode, adjacencyList, hasCycle, nodesSorted);
+ currentNodeIt = std::find_if(nodes.begin(), nodes.end(), [](const Node& node) {
+ return node.permanentMark == 0;
+ });
+ }
+ return nodesSorted;
+}
+}
+
+#endif // INLINECOMPONENTUTILS_P_H
diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp
index 800ee22cd7..cc8af723b2 100644
--- a/src/qml/jit/qv4assemblercommon.cpp
+++ b/src/qml/jit/qv4assemblercommon.cpp
@@ -96,8 +96,9 @@ private:
static void printDisassembledOutputWithCalls(QByteArray processedOutput,
const QHash<const void*, const char*>& functions)
{
- for (QHash<const void*, const char*>::ConstIterator it = functions.begin(), end = functions.end();
- it != end; ++it) {
+ const auto symbols = Runtime::symbolTable();
+ const QByteArray padding(" ; ");
+ for (auto it = functions.begin(), end = functions.end(); it != end; ++it) {
const QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16);
int idx = 0;
while (idx >= 0) {
@@ -107,7 +108,9 @@ static void printDisassembledOutputWithCalls(QByteArray processedOutput,
idx = processedOutput.indexOf('\n', idx);
if (idx < 0)
break;
- processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; ") + it.value());
+ const char *functionName = it.value();
+ processedOutput = processedOutput.insert(
+ idx, padding + QByteArray(functionName ? functionName : symbols[it.key()]));
}
}
@@ -143,7 +146,7 @@ void PlatformAssemblerCommon::link(Function *function, const char *jitKind)
// We use debugAddress here because it's actually for debugging and hidden behind an
// environment variable.
const QByteArray name = Function::prettyName(function, linkBuffer.debugAddress()).toUtf8();
- codeRef = linkBuffer.finalizeCodeWithDisassembly(jitKind, "function %s", name.constData());
+ codeRef = linkBuffer.finalizeCodeWithDisassembly(jitKind, name.constData());
WTF::setDataFile(stderr);
printDisassembledOutputWithCalls(buf.data(), functions);
@@ -302,27 +305,29 @@ void JIT::PlatformAssemblerCommon::passPointerAsArg(void *ptr, int arg)
storePtr(TrustedImmPtr(ptr), argStackAddress(arg));
}
-void PlatformAssemblerCommon::callRuntime(const char *functionName, const void *funcPtr)
+void PlatformAssemblerCommon::callRuntime(const void *funcPtr, const char *functionName)
{
#ifndef QT_NO_DEBUG
Q_ASSERT(remainingArgcForCall == 0);
remainingArgcForCall = NoCall;
#endif
- callRuntimeUnchecked(functionName, funcPtr);
+ callRuntimeUnchecked(funcPtr, functionName);
if (argcOnStackForCall > 0) {
addPtr(TrustedImm32(argcOnStackForCall), StackPointerRegister);
argcOnStackForCall = 0;
}
}
-void PlatformAssemblerCommon::callRuntimeUnchecked(const char *functionName, const void *funcPtr)
+void PlatformAssemblerCommon::callRuntimeUnchecked(const void *funcPtr, const char *functionName)
{
+ Q_ASSERT(functionName || Runtime::symbolTable().contains(funcPtr));
functions.insert(funcPtr, functionName);
callAbsolute(funcPtr);
}
-void PlatformAssemblerCommon::tailCallRuntime(const char *functionName, const void *funcPtr)
+void PlatformAssemblerCommon::tailCallRuntime(const void *funcPtr, const char *functionName)
{
+ Q_ASSERT(functionName || Runtime::symbolTable().contains(funcPtr));
functions.insert(funcPtr, functionName);
setTailCallArg(EngineRegister, 1);
setTailCallArg(CppStackFrameRegister, 0);
diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h
index b18d082be6..ead1e757de 100644
--- a/src/qml/jit/qv4assemblercommon_p.h
+++ b/src/qml/jit/qv4assemblercommon_p.h
@@ -706,9 +706,9 @@ public:
void passCppFrameAsArg(int arg);
void passInt32AsArg(int value, int arg);
void passPointerAsArg(void *ptr, int arg);
- void callRuntime(const char *functionName, const void *funcPtr);
- void callRuntimeUnchecked(const char *functionName, const void *funcPtr);
- void tailCallRuntime(const char *functionName, const void *funcPtr);
+ void callRuntime(const void *funcPtr, const char *functionName = nullptr);
+ void callRuntimeUnchecked(const void *funcPtr, const char *functionName = nullptr);
+ void tailCallRuntime(const void *funcPtr, const char *functionName = nullptr);
void setTailCallArg(RegisterID src, int arg);
Address jsAlloca(int slotCount);
void storeInt32AsValue(int srcInt, Address destAddr);
diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp
index 59de86a85d..25652e0a63 100644
--- a/src/qml/jit/qv4baselineassembler.cpp
+++ b/src/qml/jit/qv4baselineassembler.cpp
@@ -61,7 +61,8 @@ namespace JIT {
#define ASM_GENERATE_RUNTIME_CALL(function, destination) \
pasm()->GENERATE_RUNTIME_CALL(function, destination)
-#define callHelper(x) PlatformAssemblerCommon::callRuntimeUnchecked(#x, reinterpret_cast<void *>(&x))
+#define callHelper(x) \
+ PlatformAssemblerCommon::callRuntimeUnchecked(reinterpret_cast<void *>(&x), #x)
const QV4::Value::ValueTypeInternal IntegerTag = QV4::Value::ValueTypeInternal::Integer;
@@ -83,10 +84,9 @@ public:
: PlatformAssemblerCommon(constantTable)
{}
- void callRuntime(const char *functionName, const void *funcPtr,
- CallResultDestination dest)
+ void callRuntime(const void *funcPtr, CallResultDestination dest)
{
- PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
+ PlatformAssemblerCommon::callRuntime(funcPtr);
if (dest == CallResultDestination::InAccumulator)
saveReturnValueInAccumulator();
}
@@ -240,7 +240,7 @@ public:
auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
move(AccumulatorRegister, registerForArg(0));
- callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper));
+ callHelper(toInt32Helper);
saveReturnValueInAccumulator();
isInt.link(this);
@@ -383,10 +383,9 @@ public:
: PlatformAssemblerCommon(constantTable)
{}
- void callRuntime(const char *functionName, const void *funcPtr,
- CallResultDestination dest)
+ void callRuntime(const void *funcPtr, CallResultDestination dest)
{
- PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
+ PlatformAssemblerCommon::callRuntime(funcPtr);
if (dest == CallResultDestination::InAccumulator)
saveReturnValueInAccumulator();
}
@@ -491,7 +490,7 @@ public:
move(AccumulatorRegisterValue, registerForArg(0));
move(AccumulatorRegisterTag, registerForArg(1));
}
- callRuntimeUnchecked("toNumberHelper", reinterpret_cast<void *>(&toNumberHelper));
+ callHelper(toNumberHelper);
saveReturnValueInAccumulator();
if (ArgInRegCount < 2)
addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
@@ -548,7 +547,7 @@ public:
move(AccumulatorRegisterValue, registerForArg(0));
move(AccumulatorRegisterTag, registerForArg(1));
}
- callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper));
+ callHelper(toInt32Helper);
saveReturnValueInAccumulator();
if (ArgInRegCount < 2)
addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
@@ -570,7 +569,7 @@ public:
move(AccumulatorRegisterValue, registerForArg(0));
move(AccumulatorRegisterTag, registerForArg(1));
}
- callRuntimeUnchecked("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper));
+ callHelper(toInt32Helper);
saveReturnValueInAccumulator();
if (ArgInRegCount < 2)
addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
@@ -1267,7 +1266,7 @@ void BaselineAssembler::cmpeqInt(int lhs)
else
pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1));
pasm()->pushAccumulatorAsArg(0);
- pasm()->callRuntimeUnchecked("Equal", (void*)Runtime::Equal::call);
+ pasm()->callRuntimeUnchecked((void*)Runtime::Equal::call);
pasm()->saveReturnValueInAccumulator();
if (PlatformAssembler::ArgInRegCount < 2)
pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
@@ -1291,7 +1290,7 @@ void BaselineAssembler::cmpneInt(int lhs)
else
pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1));
pasm()->pushAccumulatorAsArg(0);
- pasm()->callRuntimeUnchecked("NotEqual", (void*)Runtime::NotEqual::call);
+ pasm()->callRuntimeUnchecked((void*)Runtime::NotEqual::call);
pasm()->saveReturnValueInAccumulator();
if (PlatformAssembler::ArgInRegCount < 2)
pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
@@ -1305,7 +1304,7 @@ void BaselineAssembler::cmpneInt(int lhs)
done.link(pasm());
}
-void BaselineAssembler::cmp(int cond, CmpFunc function, const char *functionName, int lhs)
+void BaselineAssembler::cmp(int cond, CmpFunc function, int lhs)
{
auto c = static_cast<PlatformAssembler::RelationalCondition>(cond);
auto done = pasm()->binopBothIntPath(regAddr(lhs), [this, c](){
@@ -1321,7 +1320,7 @@ void BaselineAssembler::cmp(int cond, CmpFunc function, const char *functionName
pasm()->passAccumulatorAsArg(1);
pasm()->passJSSlotAsArg(lhs, 0);
- callRuntime(functionName, reinterpret_cast<void*>(function), CallResultDestination::InAccumulator);
+ callRuntime(reinterpret_cast<void*>(function), CallResultDestination::InAccumulator);
checkException();
// done.
@@ -1331,50 +1330,42 @@ void BaselineAssembler::cmp(int cond, CmpFunc function, const char *functionName
void BaselineAssembler::cmpeq(int lhs)
{
- cmp(PlatformAssembler::Equal, &Runtime::CompareEqual::call,
- "CompareEqual", lhs);
+ cmp(PlatformAssembler::Equal, &Runtime::CompareEqual::call, lhs);
}
void BaselineAssembler::cmpne(int lhs)
{
- cmp(PlatformAssembler::NotEqual, &Runtime::CompareNotEqual::call,
- "CompareNotEqual", lhs);
+ cmp(PlatformAssembler::NotEqual, &Runtime::CompareNotEqual::call, lhs);
}
void BaselineAssembler::cmpgt(int lhs)
{
- cmp(PlatformAssembler::GreaterThan, &Runtime::CompareGreaterThan::call,
- "CompareGreaterThan", lhs);
+ cmp(PlatformAssembler::GreaterThan, &Runtime::CompareGreaterThan::call, lhs);
}
void BaselineAssembler::cmpge(int lhs)
{
- cmp(PlatformAssembler::GreaterThanOrEqual, &Runtime::CompareGreaterEqual::call,
- "CompareGreaterEqual", lhs);
+ cmp(PlatformAssembler::GreaterThanOrEqual, &Runtime::CompareGreaterEqual::call, lhs);
}
void BaselineAssembler::cmplt(int lhs)
{
- cmp(PlatformAssembler::LessThan, &Runtime::CompareLessThan::call,
- "CompareLessThan", lhs);
+ cmp(PlatformAssembler::LessThan, &Runtime::CompareLessThan::call, lhs);
}
void BaselineAssembler::cmple(int lhs)
{
- cmp(PlatformAssembler::LessThanOrEqual, &Runtime::CompareLessEqual::call,
- "CompareLessEqual", lhs);
+ cmp(PlatformAssembler::LessThanOrEqual, &Runtime::CompareLessEqual::call, lhs);
}
void BaselineAssembler::cmpStrictEqual(int lhs)
{
- cmp(PlatformAssembler::Equal, &Runtime::CompareStrictEqual::call,
- "RuntimeHelpers::strictEqual", lhs);
+ cmp(PlatformAssembler::Equal, &Runtime::CompareStrictEqual::call, lhs);
}
void BaselineAssembler::cmpStrictNotEqual(int lhs)
{
- cmp(PlatformAssembler::NotEqual, &Runtime::CompareStrictNotEqual::call,
- "RuntimeHelpers::strictNotEqual", lhs);
+ cmp(PlatformAssembler::NotEqual, &Runtime::CompareStrictNotEqual::call, lhs);
}
int BaselineAssembler::jump(int offset)
@@ -1463,9 +1454,9 @@ void BaselineAssembler::passPointerAsArg(void *ptr, int arg)
pasm()->passPointerAsArg(ptr, arg);
}
-void BaselineAssembler::callRuntime(const char *functionName, const void *funcPtr, CallResultDestination dest)
+void BaselineAssembler::callRuntime(const void *funcPtr, CallResultDestination dest)
{
- pasm()->callRuntime(functionName, funcPtr, dest);
+ pasm()->callRuntime(funcPtr, dest);
}
void BaselineAssembler::saveAccumulatorInFrame()
@@ -1498,8 +1489,9 @@ void BaselineAssembler::jsTailCall(int func, int thisObject, int argc, int argv)
pasm()->storeInt32AsValue(argv, Address(tos.base, argvOffset));
pasm()->moveReg(regAddr(thisObject), Address(tos.base, thisOffset));
pasm()->moveReg(regAddr(func), Address(tos.base, funcOffset));
- pasm()->tailCallRuntime("TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing",
- reinterpret_cast<void *>(TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing));
+ pasm()->tailCallRuntime(
+ reinterpret_cast<void *>(TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing),
+ "TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing");
}
void BaselineAssembler::checkException()
diff --git a/src/qml/jit/qv4baselineassembler_p.h b/src/qml/jit/qv4baselineassembler_p.h
index 33fd288ac3..c2c735282b 100644
--- a/src/qml/jit/qv4baselineassembler_p.h
+++ b/src/qml/jit/qv4baselineassembler_p.h
@@ -62,16 +62,11 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
namespace JIT {
-#define JIT_STRINGIFYx(s) #s
-#define JIT_STRINGIFY(s) JIT_STRINGIFYx(s)
-
#define GENERATE_RUNTIME_CALL(function, destination) \
- callRuntime(JIT_STRINGIFY(function), \
- reinterpret_cast<void *>(&Runtime::function::call), \
+ callRuntime(reinterpret_cast<void *>(&Runtime::function::call), \
destination)
#define GENERATE_TAIL_CALL(function) \
- tailCallRuntime(JIT_STRINGIFY(function), \
- reinterpret_cast<void *>(&function))
+ tailCallRuntime(reinterpret_cast<void *>(&function))
class BaselineAssembler {
public:
@@ -153,7 +148,7 @@ public:
void passCppFrameAsArg(int arg);
void passInt32AsArg(int value, int arg);
void passPointerAsArg(void *ptr, int arg);
- void callRuntime(const char *functionName, const void *funcPtr, CallResultDestination dest);
+ void callRuntime(const void *funcPtr, CallResultDestination dest);
void saveAccumulatorInFrame();
void loadAccumulatorFromFrame();
void jsTailCall(int func, int thisObject, int argc, int argv);
@@ -179,7 +174,7 @@ protected:
private:
typedef unsigned(*CmpFunc)(const Value&,const Value&);
- void cmp(int cond, CmpFunc function, const char *functionName, int lhs);
+ void cmp(int cond, CmpFunc function, int lhs);
};
} // namespace JIT
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index 065fbc1c0a..6946a64d11 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -71,11 +71,6 @@
#include <private/qqmlglobal_p.h>
#include <qqmlengine.h>
-#undef Q_D
-#undef Q_Q
-#define Q_D(blah)
-#define Q_Q(blah)
-
Q_DECLARE_METATYPE(QList<int>)
/*!
@@ -257,7 +252,7 @@ Q_DECLARE_METATYPE(QList<int>)
\l installExtensions().
\value TranslationExtension Indicates that translation functions (\c qsTr(),
- for example) should be installed.
+ for example) should be installed. This also installs the Qt.uiLanguage property.
\value ConsoleExtension Indicates that console functions (\c console.log(),
for example) should be installed.
@@ -692,7 +687,6 @@ QJSValue QJSEngine::newArray(uint length)
*/
QJSValue QJSEngine::newQObject(QObject *object)
{
- Q_D(QJSEngine);
QV4::ExecutionEngine *v4 = m_v4Engine;
QV4::Scope scope(v4);
if (object) {
@@ -719,7 +713,6 @@ QJSValue QJSEngine::newQObject(QObject *object)
*/
QJSValue QJSEngine::newQMetaObject(const QMetaObject* metaObject) {
- Q_D(QJSEngine);
QV4::ExecutionEngine *v4 = m_v4Engine;
QV4::Scope scope(v4);
QV4::ScopedValue v(scope, QV4::QMetaObjectWrapper::create(v4, metaObject));
@@ -1004,6 +997,35 @@ void QJSEngine::throwError(QJSValue::ErrorType errorType, const QString &message
m_v4Engine->throwError(e);
}
+/*!
+ \property QJSEngine::uiLanguage
+ \brief the language to be used for translating user interface strings
+ \since 5.15
+
+ This property holds the name of the language to be used for user interface
+ string translations. It is exposed for reading and writing as \c{Qt.uiLanguage} when
+ the QJSEngine::TranslationExtension is installed on the engine. It is always exposed
+ in instances of QQmlEngine.
+
+ You can set the value freely and use it in bindings. It is recommended to set it
+ after installing translators in your application. By convention, an empty string
+ means no translation from the language used in the source code is intended to occur.
+*/
+void QJSEngine::setUiLanguage(const QString &language)
+{
+ Q_D(QJSEngine);
+ if (language == d->uiLanguage)
+ return;
+ d->uiLanguage = language;
+ emit uiLanguageChanged();
+}
+
+QString QJSEngine::uiLanguage() const
+{
+ Q_D(const QJSEngine);
+ return d->uiLanguage;
+}
+
QJSEnginePrivate *QJSEnginePrivate::get(QV4::ExecutionEngine *e)
{
return e->jsEngine()->d_func();
diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h
index 31a4d68baa..31229e1f20 100644
--- a/src/qml/jsapi/qjsengine.h
+++ b/src/qml/jsapi/qjsengine.h
@@ -60,6 +60,7 @@ class Q_QML_EXPORT QJSEngine
: public QObject
{
Q_OBJECT
+ Q_PROPERTY(QString uiLanguage READ uiLanguage WRITE setUiLanguage NOTIFY uiLanguageChanged)
public:
QJSEngine();
explicit QJSEngine(QObject *parent);
@@ -121,6 +122,12 @@ public:
void throwError(const QString &message);
void throwError(QJSValue::ErrorType errorType, const QString &message = QString());
+ QString uiLanguage() const;
+ void setUiLanguage(const QString &language);
+
+Q_SIGNALS:
+ void uiLanguageChanged();
+
private:
QJSValue create(int type, const void *ptr);
diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h
index 164a70d000..7866a5bdda 100644
--- a/src/qml/jsapi/qjsengine_p.h
+++ b/src/qml/jsapi/qjsengine_p.h
@@ -107,6 +107,7 @@ public:
// Shared by QQmlEngine
mutable QRecursiveMutex mutex;
+ QString uiLanguage;
// These methods may be called from the QML loader thread
inline QQmlPropertyCache *cache(QObject *obj, int minorVersion = -1);
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index c2957dd294..b40bc1f18b 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -314,7 +314,7 @@ bool QJSValue::isBool() const
if (val)
return val->isBoolean();
QVariant *variant = QJSValuePrivate::getVariant(this);
- return variant && variant->type() == QVariant::Bool;
+ return variant && variant->userType() == QMetaType::Bool;
}
/*!
@@ -520,9 +520,9 @@ QString QJSValue::toString() const
if (!val) {
QVariant *variant = QJSValuePrivate::getVariant(this);
Q_ASSERT(variant);
- if (variant->type() == QVariant::Map)
+ if (variant->userType() == QMetaType::QVariantMap)
return QStringLiteral("[object Object]");
- else if (variant->type() == QVariant::List) {
+ else if (variant->userType() == QMetaType::QVariantList) {
const QVariantList list = variant->toList();
QString result;
for (int i = 0; i < list.count(); ++i) {
@@ -558,7 +558,7 @@ double QJSValue::toNumber() const
QVariant *variant = QJSValuePrivate::getVariant(this);
Q_ASSERT(variant);
- if (variant->type() == QVariant::String)
+ if (variant->userType() == QMetaType::QString)
return RuntimeHelpers::stringToNumber(variant->toString());
else if (variant->canConvert<double>())
return variant->value<double>();
@@ -1040,7 +1040,7 @@ bool QJSValue::equals(const QJSValue& other) const
Q_ASSERT(variant);
if (!ov)
return *variant == *QJSValuePrivate::getVariant(&other);
- if (variant->type() == QVariant::Map || variant->type() == QVariant::List)
+ if (variant->userType() == QMetaType::QVariantMap || variant->userType() == QMetaType::QVariantList)
return false;
return js_equal(variant->toString(), *ov);
}
@@ -1083,7 +1083,7 @@ bool QJSValue::strictlyEquals(const QJSValue& other) const
Q_ASSERT(variant);
if (!ov)
return *variant == *QJSValuePrivate::getVariant(&other);
- if (variant->type() == QVariant::Map || variant->type() == QVariant::List)
+ if (variant->userType() == QMetaType::QVariantMap || variant->userType() == QMetaType::QVariantList)
return false;
if (String *s = ov->stringValue())
return variant->toString() == s->toQString();
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index e6f6fd1b7a..df9f117d04 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -597,65 +597,63 @@ ReturnedValue ArrayPrototype::method_findIndex(const FunctionObject *b, const Va
return Encode(-1);
}
-ReturnedValue ArrayPrototype::method_join(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+ReturnedValue ArrayPrototype::method_join(const FunctionObject *functionObject,
+ const Value *thisObject, const Value *argv, int argc)
{
- Scope scope(b);
+ Scope scope(functionObject);
ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
return Encode(scope.engine->newString());
- ScopedValue arg(scope, argc ? argv[0] : Value::undefinedValue());
-
- QString r4;
- if (arg->isUndefined())
- r4 = QStringLiteral(",");
- else
- r4 = arg->toQString();
+ // We cannot optimize the resolution of the argument away in case of length == 0
+ // It may have side effects.
+ ScopedValue argument(scope, argc ? argv[0] : Value::undefinedValue());
+ const QString separator = argument->isUndefined()
+ ? QStringLiteral(",")
+ : argument->toQString();
- ScopedValue length(scope, instance->get(scope.engine->id_length()));
- const quint32 r2 = length->isUndefined() ? 0 : length->toUInt32();
-
- if (!r2)
+ ScopedValue scopedLength(scope, instance->get(scope.engine->id_length()));
+ const quint32 genericLength = scopedLength->isUndefined() ? 0 : scopedLength->toUInt32();
+ if (!genericLength)
return Encode(scope.engine->newString());
- QString R;
-
- // ### FIXME
- if (ArrayObject *a = instance->as<ArrayObject>()) {
- ScopedValue e(scope);
- for (uint i = 0; i < a->getLength(); ++i) {
+ QString result;
+ if (auto *arrayObject = instance->as<ArrayObject>()) {
+ ScopedValue entry(scope);
+ const qint64 arrayLength = arrayObject->getLength();
+ Q_ASSERT(arrayLength >= 0);
+ Q_ASSERT(arrayLength <= std::numeric_limits<quint32>::max());
+ for (quint32 i = 0; i < quint32(arrayLength); ++i) {
if (i)
- R += r4;
+ result += separator;
- e = a->get(i);
+ entry = arrayObject->get(i);
CHECK_EXCEPTION();
- if (!e->isNullOrUndefined())
- R += e->toQString();
+ if (!entry->isNullOrUndefined())
+ result += entry->toQString();
}
} else {
- //
- // crazy!
- //
ScopedString name(scope, scope.engine->newString(QStringLiteral("0")));
- ScopedValue r6(scope, instance->get(name));
- if (!r6->isNullOrUndefined())
- R = r6->toQString();
+ ScopedValue value(scope, instance->get(name));
+ CHECK_EXCEPTION();
+
+ if (!value->isNullOrUndefined())
+ result = value->toQString();
- ScopedValue r12(scope);
- for (quint32 k = 1; k < r2; ++k) {
- R += r4;
+ for (quint32 i = 1; i < genericLength; ++i) {
+ result += separator;
- name = Value::fromDouble(k).toString(scope.engine);
- r12 = instance->get(name);
+ name = Value::fromDouble(i).toString(scope.engine);
+ value = instance->get(name);
CHECK_EXCEPTION();
- if (!r12->isNullOrUndefined())
- R += r12->toQString();
+ if (!value->isNullOrUndefined())
+ result += value->toQString();
}
}
- return Encode(scope.engine->newString(R));
+ return Encode(scope.engine->newString(result));
}
ReturnedValue ArrayPrototype::method_pop(const FunctionObject *b, const Value *thisObject, const Value *, int)
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index 5ab8cf2dcb..da1b91e69a 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -92,7 +92,7 @@ ReturnedValue DataViewCtor::virtualCallAsConstructor(const FunctionObject *f, co
uint byteLength = (argc < 3 || argv[2].isUndefined()) ? (bufferLength - offset) : ::toIndex(scope.engine, argv[2]);
if (scope.hasException())
return Encode::undefined();
- if (offset + byteLength > bufferLength)
+ if (offset > bufferLength || byteLength > bufferLength - offset)
return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range"));
Scoped<DataView> a(scope, scope.engine->memoryManager->allocate<DataView>());
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index c2f48ffeac..bebcbd7e44 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -682,17 +682,17 @@ static inline QString ToTimeString(double t)
static inline QString ToLocaleString(double t)
{
- return ToDateTime(t, Qt::LocalTime).toString(Qt::DefaultLocaleShortDate);
+ return QLocale().toString(ToDateTime(t, Qt::LocalTime), QLocale::ShortFormat);
}
static inline QString ToLocaleDateString(double t)
{
- return ToDateTime(t, Qt::LocalTime).date().toString(Qt::DefaultLocaleShortDate);
+ return QLocale().toString(ToDateTime(t, Qt::LocalTime).date(), QLocale::ShortFormat);
}
static inline QString ToLocaleTimeString(double t)
{
- return ToDateTime(t, Qt::LocalTime).time().toString(Qt::DefaultLocaleShortDate);
+ return QLocale().toString(ToDateTime(t, Qt::LocalTime).time(), QLocale::ShortFormat);
}
static double getLocalTZA()
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index df2c46b64a..680ccc02a8 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -303,15 +303,19 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
memoryManager = new QV4::MemoryManager(this);
if (maxCallDepth == -1) {
- ok = false;
- maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok);
- if (!ok || maxCallDepth <= 0) {
+ if (qEnvironmentVariableIsSet("QV4_CRASH_ON_STACKOVERFLOW")) {
+ maxCallDepth = std::numeric_limits<qint32>::max();
+ } else {
+ ok = false;
+ maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok);
+ if (!ok || maxCallDepth <= 0) {
#if defined(QT_NO_DEBUG) && !defined(__SANITIZE_ADDRESS__) && !__has_feature(address_sanitizer)
- maxCallDepth = 1234;
+ maxCallDepth = 1234;
#else
- // no (tail call) optimization is done, so there'll be a lot mare stack frames active
- maxCallDepth = 200;
+ // no (tail call) optimization is done, so there'll be a lot mare stack frames active
+ maxCallDepth = 200;
#endif
+ }
}
}
Q_ASSERT(maxCallDepth > 0);
@@ -1262,20 +1266,15 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file)
void ExecutionEngine::markObjects(MarkStack *markStack)
{
- for (int i = 0; i < NClasses; ++i)
- if (classes[i]) {
- classes[i]->mark(markStack);
- if (markStack->top >= markStack->limit)
- markStack->drain();
- }
- markStack->drain();
+ for (int i = 0; i < NClasses; ++i) {
+ if (Heap::InternalClass *c = classes[i])
+ c->mark(markStack);
+ }
identifierTable->markObjects(markStack);
- for (auto compilationUnit: compilationUnits) {
+ for (auto compilationUnit: compilationUnits)
compilationUnit->markObjects(markStack);
- markStack->drain();
- }
}
ReturnedValue ExecutionEngine::throwError(const Value &value)
@@ -1457,7 +1456,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
if (const QV4::VariantObject *v = value.as<QV4::VariantObject>())
return v->d()->data();
- if (typeHint == QVariant::Bool)
+ if (typeHint == QMetaType::Bool)
return QVariant(value.toBoolean());
if (typeHint == QMetaType::QJsonValue)
@@ -1522,7 +1521,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
retn = QVariant(typeHint, temp);
QMetaType::destroy(typeHint, temp);
auto retnAsIterable = retn.value<QtMetaTypePrivate::QSequentialIterableImpl>();
- if (retnAsIterable._iteratorCapabilities & QtMetaTypePrivate::ContainerIsAppendable) {
+ if (retnAsIterable.containerCapabilities() & QtMetaTypePrivate::ContainerIsAppendable) {
auto const length = a->getLength();
QV4::ScopedValue arrayValue(scope);
for (qint64 i = 0; i < length; ++i) {
@@ -1533,8 +1532,8 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
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));
+ QString::fromUtf8(QMetaType::typeName(originalType)),
+ QString::fromUtf8(QMetaType::typeName(retnAsIterable._metaType_id)));
// create default constructed value
asVariant = QVariant(retnAsIterable._metaType_id, nullptr);
}
@@ -1558,7 +1557,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
if (String *s = value.stringValue()) {
const QString &str = s->toQString();
// QChars are stored as a strings
- if (typeHint == QVariant::Char && str.size() == 1)
+ if (typeHint == QMetaType::QChar && str.size() == 1)
return str.at(0);
return str;
}
@@ -1857,7 +1856,7 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data)
Q_ASSERT(data != nullptr);
QVariant variant(type, data);
- if (QMetaType::Type(variant.type()) == QMetaType::QVariant) {
+ if (QMetaType::Type(variant.userType()) == QMetaType::QVariant) {
// unwrap it: this is tested in QJSEngine, and makes the most sense for
// end-user code too.
return variantToJS(this, *reinterpret_cast<const QVariant*>(data));
@@ -1911,10 +1910,10 @@ QQmlRefPointer<ExecutableCompilationUnit> ExecutionEngine::compileModule(
sourceCode, sourceTimeStamp, &diagnostics);
for (const QQmlJS::DiagnosticMessage &m : diagnostics) {
if (m.isError()) {
- throwSyntaxError(m.message, url.toString(), m.line, m.column);
+ throwSyntaxError(m.message, url.toString(), m.loc.startLine, m.loc.startColumn);
return nullptr;
} else {
- qWarning() << url << ':' << m.line << ':' << m.column
+ qWarning() << url << ':' << m.loc.startLine << ':' << m.loc.startColumn
<< ": warning: " << m.message;
}
}
@@ -1974,11 +1973,12 @@ void ExecutionEngine::initQmlGlobalObject()
void ExecutionEngine::initializeGlobal()
{
QV4::Scope scope(this);
- QV4::GlobalExtensions::init(globalObject, QJSEngine::AllExtensions);
QV4::ScopedObject qt(scope, memoryManager->allocate<QV4::QtObject>(qmlEngine()));
globalObject->defineDefaultProperty(QStringLiteral("Qt"), qt);
+ QV4::GlobalExtensions::init(globalObject, QJSEngine::AllExtensions);
+
#if QT_CONFIG(qml_locale)
QQmlLocale::registerStringLocaleCompare(this);
QQmlDateExtension::registerExtension(this);
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp
index 79e2ec2a5d..29e1c6dbf7 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit.cpp
+++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp
@@ -53,6 +53,7 @@
#include <private/qv4compilationunitmapper_p.h>
#include <private/qml_compile_hash_p.h>
#include <private/qqmltypewrapper_p.h>
+#include <private/inlinecomponentutils_p.h>
#include <QtQml/qqmlfile.h>
#include <QtQml/qqmlpropertymap.h>
@@ -62,6 +63,7 @@
#include <QtCore/qfileinfo.h>
#include <QtCore/qscopeguard.h>
#include <QtCore/qcryptographichash.h>
+#include <QtCore/QScopedValueRollback>
#if defined(QML_COMPILE_HASH)
# ifdef Q_OS_LINUX
@@ -94,11 +96,15 @@ ExecutableCompilationUnit::~ExecutableCompilationUnit()
QString ExecutableCompilationUnit::localCacheFilePath(const QUrl &url)
{
+ static const QByteArray envCachePath = qgetenv("QML_DISK_CACHE_PATH");
+
const QString localSourcePath = QQmlFile::urlToLocalFileOrQrc(url);
const QString cacheFileSuffix = QFileInfo(localSourcePath + QLatin1Char('c')).completeSuffix();
QCryptographicHash fileNameHash(QCryptographicHash::Sha1);
fileNameHash.addData(localSourcePath.toUtf8());
- QString directory = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String("/qmlcache/");
+ QString directory = envCachePath.isEmpty()
+ ? QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String("/qmlcache/")
+ : QString::fromLocal8Bit(envCachePath) + QLatin1String("/");
QDir::root().mkpath(directory);
return directory + QString::fromUtf8(fileNameHash.result().toHex()) + QLatin1Char('.') + cacheFileSuffix;
}
@@ -121,7 +127,7 @@ static QString toString(QV4::ReturnedValue v)
static void dumpConstantTable(const StaticValue *constants, uint count)
{
QDebug d = qDebug();
- d.nospace() << right;
+ d.nospace() << Qt::right;
for (uint i = 0; i < count; ++i) {
d << qSetFieldWidth(8) << i << qSetFieldWidth(0) << ": "
<< toString(constants[i].asReturnedValue()).toUtf8().constData() << "\n";
@@ -283,7 +289,7 @@ void ExecutableCompilationUnit::unlink()
Q_ASSERT(data && propertyCaches.count() > 0 && propertyCaches.at(/*root object*/0));
if (qmlEngine)
qmlEngine->unregisterInternalCompositeType(this);
- QQmlMetaType::unregisterInternalCompositeType(this);
+ QQmlMetaType::unregisterInternalCompositeType({metaTypeId, listMetaTypeId});
isRegisteredWithEngine = false;
}
@@ -383,21 +389,26 @@ IdentifierHash ExecutableCompilationUnit::createNamedObjectsPerComponent(int com
return *namedObjectsPerComponentCache.insert(componentObjectIndex, namedObjectCache);
}
-void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngine)
+void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngine, CompositeMetaTypeIds typeIds)
{
this->qmlEngine = qmlEngine;
// Add to type registry of composites
if (propertyCaches.needsVMEMetaObject(/*root object*/0)) {
- QQmlMetaType::registerInternalCompositeType(this);
+ // typeIds is only valid for types that have references to themselves.
+ if (!typeIds.isValid())
+ typeIds = QQmlMetaType::registerInternalCompositeType(rootPropertyCache()->className());
+ metaTypeId = typeIds.id;
+ listMetaTypeId = typeIds.listId;
qmlEngine->registerInternalCompositeType(this);
+
} else {
const QV4::CompiledData::Object *obj = objectAt(/*root object*/0);
auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
- if (typeRef->compilationUnit) {
- metaTypeId = typeRef->compilationUnit->metaTypeId;
- listMetaTypeId = typeRef->compilationUnit->listMetaTypeId;
+ if (const auto compilationUnit = typeRef->compilationUnit()) {
+ metaTypeId = compilationUnit->metaTypeId;
+ listMetaTypeId = compilationUnit->listMetaTypeId;
} else {
metaTypeId = typeRef->type.typeId();
listMetaTypeId = typeRef->type.qListTypeId();
@@ -405,29 +416,105 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi
}
// Collect some data for instantiation later.
+ using namespace icutils;
+ std::vector<QV4::CompiledData::InlineComponent> allICs {};
+ for (int i=0; i != objectCount(); ++i) {
+ const CompiledObject *obj = objectAt(i);
+ for (auto it = obj->inlineComponentsBegin(); it != obj->inlineComponentsEnd(); ++it) {
+ allICs.push_back(*it);
+ }
+ }
+ std::vector<Node> nodes;
+ nodes.resize(allICs.size());
+ std::iota(nodes.begin(), nodes.end(), 0);
+ AdjacencyList adjacencyList;
+ adjacencyList.resize(nodes.size());
+ fillAdjacencyListForInlineComponents(this, adjacencyList, nodes, allICs);
+ bool hasCycle = false;
+ auto nodesSorted = topoSort(nodes, adjacencyList, hasCycle);
+ Q_ASSERT(!hasCycle); // would have already been discovered by qqmlpropertycachcecreator
+
+ // We need to first iterate over all inline components, as the containing component might create instances of them
+ // and in that case we need to add its object count
+ for (auto nodeIt = nodesSorted.rbegin(); nodeIt != nodesSorted.rend(); ++nodeIt) {
+ const auto &ic = allICs.at(nodeIt->index);
+ int lastICRoot = ic.objectIndex;
+ for (int i = ic.objectIndex; i<objectCount(); ++i) {
+ const QV4::CompiledData::Object *obj = objectAt(i);
+ bool leftCurrentInlineComponent =
+ (i != lastICRoot && obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot)
+ || !(obj->flags & QV4::CompiledData::Object::InPartOfInlineComponent);
+ if (leftCurrentInlineComponent)
+ break;
+ inlineComponentData[lastICRoot].totalBindingCount += obj->nBindings;
+
+ if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
+ if (typeRef->type.isValid() && typeRef->type.parserStatusCast() != -1)
+ ++inlineComponentData[lastICRoot].totalParserStatusCount;
+
+ ++inlineComponentData[lastICRoot].totalObjectCount;
+ if (const auto compilationUnit = typeRef->compilationUnit()) {
+ // if the type is an inline component type, we have to extract the information from it
+ // This requires that inline components are visited in the correct order
+ auto icRoot = compilationUnit->icRoot;
+ if (typeRef->type.isInlineComponentType()) {
+ icRoot = typeRef->type.inlineComponendId();
+ }
+ QScopedValueRollback<int> rollback {compilationUnit->icRoot, icRoot};
+ inlineComponentData[lastICRoot].totalBindingCount += compilationUnit->totalBindingsCount();
+ inlineComponentData[lastICRoot].totalParserStatusCount += compilationUnit->totalParserStatusCount();
+ inlineComponentData[lastICRoot].totalObjectCount += compilationUnit->totalObjectCount();
+ }
+ }
+ }
+ }
int bindingCount = 0;
int parserStatusCount = 0;
int objectCount = 0;
for (quint32 i = 0, count = this->objectCount(); i < count; ++i) {
const QV4::CompiledData::Object *obj = objectAt(i);
+ if (obj->flags & QV4::CompiledData::Object::InPartOfInlineComponent) {
+ continue;
+ }
bindingCount += obj->nBindings;
if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
- if (typeRef->type.isValid()) {
- if (typeRef->type.parserStatusCast() != -1)
- ++parserStatusCount;
- }
+ if (typeRef->type.isValid() && typeRef->type.parserStatusCast() != -1)
+ ++parserStatusCount;
++objectCount;
- if (typeRef->compilationUnit) {
- bindingCount += typeRef->compilationUnit->totalBindingsCount;
- parserStatusCount += typeRef->compilationUnit->totalParserStatusCount;
- objectCount += typeRef->compilationUnit->totalObjectCount;
+ if (const auto compilationUnit = typeRef->compilationUnit()) {
+ auto icRoot = compilationUnit->icRoot;
+ if (typeRef->type.isInlineComponentType()) {
+ icRoot = typeRef->type.inlineComponendId();
+ }
+ QScopedValueRollback<int> rollback {compilationUnit->icRoot, icRoot};
+ bindingCount += compilationUnit->totalBindingsCount();
+ parserStatusCount += compilationUnit->totalParserStatusCount();
+ objectCount += compilationUnit->totalObjectCount();
}
}
}
- totalBindingsCount = bindingCount;
- totalParserStatusCount = parserStatusCount;
- totalObjectCount = objectCount;
+ m_totalBindingsCount = bindingCount;
+ m_totalParserStatusCount = parserStatusCount;
+ m_totalObjectCount = objectCount;
+}
+
+int ExecutableCompilationUnit::totalBindingsCount() const {
+ if (icRoot == -1)
+ return m_totalBindingsCount;
+ return inlineComponentData[icRoot].totalBindingCount;
+}
+
+int ExecutableCompilationUnit::totalObjectCount() const {
+ if (icRoot == -1)
+ return m_totalObjectCount;
+ return inlineComponentData[icRoot].totalObjectCount;
+}
+
+int ExecutableCompilationUnit::totalParserStatusCount() const {
+ if (icRoot == -1)
+ return m_totalParserStatusCount;
+ return inlineComponentData[icRoot].totalParserStatusCount;
}
bool ExecutableCompilationUnit::verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const
@@ -445,6 +532,13 @@ bool ExecutableCompilationUnit::verifyChecksum(const CompiledData::DependentType
sizeof(data->dependencyMD5Checksum)) == 0;
}
+CompositeMetaTypeIds ExecutableCompilationUnit::typeIdsForComponent(int objectid) const
+{
+ if (objectid == 0)
+ return {metaTypeId, listMetaTypeId};
+ return inlineComponentData[objectid].typeIds;
+}
+
QStringList ExecutableCompilationUnit::moduleRequests() const
{
QStringList requests;
@@ -712,7 +806,7 @@ QQmlRefPointer<QQmlPropertyCache> ResolvedTypeReference::propertyCache() const
if (type.isValid())
return typePropertyCache;
else
- return compilationUnit->rootPropertyCache();
+ return m_compilationUnit->rootPropertyCache();
}
/*!
@@ -726,21 +820,22 @@ QQmlRefPointer<QQmlPropertyCache> ResolvedTypeReference::createPropertyCache(QQm
typePropertyCache = QQmlEnginePrivate::get(engine)->cache(type.metaObject(), minorVersion);
return typePropertyCache;
} else {
- return compilationUnit->rootPropertyCache();
+ Q_ASSERT(m_compilationUnit);
+ return m_compilationUnit->rootPropertyCache();
}
}
bool ResolvedTypeReference::addToHash(QCryptographicHash *hash, QQmlEngine *engine)
{
- if (type.isValid()) {
+ if (type.isValid() && !type.isInlineComponentType()) {
bool ok = false;
hash->addData(createPropertyCache(engine)->checksum(&ok));
return ok;
}
- if (!compilationUnit)
+ if (!m_compilationUnit)
return false;
- hash->addData(compilationUnit->data->md5Checksum,
- sizeof(compilationUnit->data->md5Checksum));
+ hash->addData(m_compilationUnit->data->md5Checksum,
+ sizeof(m_compilationUnit->data->md5Checksum));
return true;
}
@@ -761,8 +856,8 @@ void ResolvedTypeReference::doDynamicTypeCheck()
mo = typePropertyCache->firstCppMetaObject();
else if (type.isValid())
mo = type.metaObject();
- else if (compilationUnit)
- mo = compilationUnit->rootPropertyCache()->firstCppMetaObject();
+ else if (m_compilationUnit)
+ mo = m_compilationUnit->rootPropertyCache()->firstCppMetaObject();
isFullyDynamicType = qtTypeInherits<QQmlPropertyMap>(mo);
}
diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h
index 6eef3b12c3..7bfb68da9d 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit_p.h
+++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h
@@ -58,11 +58,32 @@
#include <private/qqmlpropertycachevector_p.h>
#include <private/qqmltype_p.h>
#include <private/qqmlnullablevalue_p.h>
+#include <private/qqmlmetatype_p.h>
QT_BEGIN_NAMESPACE
class QQmlScriptData;
class QQmlEnginePrivate;
+
+struct InlineComponentData {
+
+ InlineComponentData() = default;
+ InlineComponentData(const CompositeMetaTypeIds &typeIds, int objectIndex, int nameIndex, int totalObjectCount, int totalBindingCount, int totalParserStatusCount)
+ : typeIds(typeIds)
+ , objectIndex(objectIndex)
+ , nameIndex(nameIndex)
+ , totalObjectCount(totalObjectCount)
+ , totalBindingCount(totalBindingCount)
+ , totalParserStatusCount(totalParserStatusCount) {}
+
+ CompositeMetaTypeIds typeIds;
+ int objectIndex = -1;
+ int nameIndex = -1;
+ int totalObjectCount = 0;
+ int totalBindingCount = 0;
+ int totalParserStatusCount = 0;
+};
+
namespace QV4 {
// index is per-object binding index
@@ -142,11 +163,16 @@ public:
QHash<int, IdentifierHash> namedObjectsPerComponentCache;
inline IdentifierHash namedObjectsPerComponent(int componentObjectIndex);
- void finalizeCompositeType(QQmlEnginePrivate *qmlEngine);
+ void finalizeCompositeType(QQmlEnginePrivate *qmlEngine, CompositeMetaTypeIds typeIdsForComponent);
- int totalBindingsCount = 0; // Number of bindings used in this type
- int totalParserStatusCount = 0; // Number of instantiated types that are QQmlParserStatus subclasses
- int totalObjectCount = 0; // Number of objects explicitly instantiated
+ int m_totalBindingsCount = 0; // Number of bindings used in this type
+ int m_totalParserStatusCount = 0; // Number of instantiated types that are QQmlParserStatus subclasses
+ int m_totalObjectCount = 0; // Number of objects explicitly instantiated
+ int icRoot = -1;
+
+ int totalBindingsCount() const;
+ int totalParserStatusCount() const;
+ int totalObjectCount() const;
QVector<QQmlRefPointer<QQmlScriptData>> dependentScripts;
ResolvedTypeReferenceMap resolvedTypes;
@@ -154,10 +180,14 @@ public:
bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const;
+ CompositeMetaTypeIds typeIdsForComponent(int objectid = 0) const;
+
int metaTypeId = -1;
int listMetaTypeId = -1;
bool isRegisteredWithEngine = false;
+ QHash<int, InlineComponentData> inlineComponentData;
+
QScopedPointer<CompilationUnitMapper> backingFile;
// --- interface for QQmlPropertyCacheCreator
@@ -295,27 +325,73 @@ private:
struct ResolvedTypeReference
{
+public:
ResolvedTypeReference()
- : majorVersion(0)
- , minorVersion(0)
- , isFullyDynamicType(false)
+ : m_compilationUnit(nullptr)
+ , m_stronglyReferencesCompilationUnit(true)
+ , majorVersion(0)
+ , minorVersion(0)
+ , isFullyDynamicType(false)
{}
+ ~ResolvedTypeReference()
+ {
+ if (m_stronglyReferencesCompilationUnit && m_compilationUnit)
+ m_compilationUnit->release();
+ }
+
+ QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit() { return m_compilationUnit; }
+ void setCompilationUnit(QQmlRefPointer<QV4::ExecutableCompilationUnit> unit)
+ {
+ if (m_compilationUnit == unit.data())
+ return;
+ if (m_stronglyReferencesCompilationUnit) {
+ if (m_compilationUnit)
+ m_compilationUnit->release();
+ m_compilationUnit = unit.take();
+ } else {
+ m_compilationUnit = unit.data();
+ }
+ }
+
+ bool referencesCompilationUnit() const { return m_stronglyReferencesCompilationUnit; }
+ void setReferencesCompilationUnit(bool doReference)
+ {
+ if (doReference == m_stronglyReferencesCompilationUnit)
+ return;
+ m_stronglyReferencesCompilationUnit = doReference;
+ if (!m_compilationUnit)
+ return;
+ if (doReference) {
+ m_compilationUnit->addref();
+ } else if (m_compilationUnit->count() == 1) {
+ m_compilationUnit->release();
+ m_compilationUnit = nullptr;
+ } else {
+ m_compilationUnit->release();
+ }
+ }
+
+ QQmlRefPointer<QQmlPropertyCache> propertyCache() const;
+ QQmlRefPointer<QQmlPropertyCache> createPropertyCache(QQmlEngine *);
+ bool addToHash(QCryptographicHash *hash, QQmlEngine *engine);
+
+ void doDynamicTypeCheck();
+
QQmlType type;
QQmlRefPointer<QQmlPropertyCache> typePropertyCache;
- QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
+private:
+ Q_DISABLE_COPY_MOVE(ResolvedTypeReference)
+ QV4::ExecutableCompilationUnit *m_compilationUnit;
+ bool m_stronglyReferencesCompilationUnit;
+
+public:
int majorVersion;
int minorVersion;
// Types such as QQmlPropertyMap can add properties dynamically at run-time and
// therefore cannot have a property cache installed when instantiated.
bool isFullyDynamicType;
-
- QQmlRefPointer<QQmlPropertyCache> propertyCache() const;
- QQmlRefPointer<QQmlPropertyCache> createPropertyCache(QQmlEngine *);
- bool addToHash(QCryptographicHash *hash, QQmlEngine *engine);
-
- void doDynamicTypeCheck();
};
IdentifierHash ExecutableCompilationUnit::namedObjectsPerComponent(int componentObjectIndex)
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp
index 79c372348f..f4901e3e4d 100644
--- a/src/qml/jsruntime/qv4persistent.cpp
+++ b/src/qml/jsruntime/qv4persistent.cpp
@@ -240,7 +240,6 @@ void PersistentValueStorage::mark(MarkStack *markStack)
if (Managed *m = p->values[i].as<Managed>())
m->mark(markStack);
}
- markStack->drain();
p = p->header.next;
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 9d0b65cc0a..66b79aa0e8 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -638,10 +638,11 @@ void QObjectWrapper::markWrapper(QObject *object, MarkStack *markStack)
if (!ddata)
return;
- if (ddata->jsEngineId == markStack->engine->m_engineId)
+ const QV4::ExecutionEngine *engine = markStack->engine();
+ if (ddata->jsEngineId == engine->m_engineId)
ddata->jsWrapper.markOnce(markStack);
- else if (markStack->engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object)
- markStack->engine->m_multiplyWrappedQObjects->mark(object, markStack);
+ else if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object)
+ engine->m_multiplyWrappedQObjects->mark(object, markStack);
}
void QObjectWrapper::setProperty(ExecutionEngine *engine, int propertyIndex, const Value &value)
@@ -1654,7 +1655,7 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const
}
CallArgument::CallArgument()
-: type(QVariant::Invalid)
+: type(QMetaType::UnknownType)
{
}
@@ -2077,7 +2078,7 @@ ReturnedValue QObjectMethod::callInternal(const Value *thisObject, const Value *
if (!d()->valueTypeWrapper)
return Encode::undefined();
- object = QQmlObjectOrGadget(d()->propertyCache(), d()->valueTypeWrapper->gadgetPtr);
+ object = QQmlObjectOrGadget(d()->propertyCache(), d()->valueTypeWrapper->gadgetPtr());
}
QQmlPropertyData method;
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index f9e4d258fc..5fc94b9ddd 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -2336,6 +2336,133 @@ Bool Runtime::CompareStrictNotEqual::call(const Value &left, const Value &right)
return ! RuntimeHelpers::strictEqual(left, right);
}
+template<typename Operation>
+static inline const void *symbol()
+{
+ return reinterpret_cast<void *>(&Operation::call);
+}
+
+QHash<const void *, const char *> Runtime::symbolTable()
+{
+ static const QHash<const void *, const char *> symbols({
+#ifndef V4_BOOTSTRAP
+ {symbol<CallGlobalLookup>(), "CallGlobalLookup" },
+ {symbol<CallQmlContextPropertyLookup>(), "CallQmlContextPropertyLookup" },
+ {symbol<CallName>(), "CallName" },
+ {symbol<CallProperty>(), "CallProperty" },
+ {symbol<CallPropertyLookup>(), "CallPropertyLookup" },
+ {symbol<CallElement>(), "CallElement" },
+ {symbol<CallValue>(), "CallValue" },
+ {symbol<CallWithReceiver>(), "CallWithReceiver" },
+ {symbol<CallPossiblyDirectEval>(), "CallPossiblyDirectEval" },
+ {symbol<CallWithSpread>(), "CallWithSpread" },
+ {symbol<TailCall>(), "TailCall" },
+
+ {symbol<Construct>(), "Construct" },
+ {symbol<ConstructWithSpread>(), "ConstructWithSpread" },
+
+ {symbol<StoreNameStrict>(), "StoreNameStrict" },
+ {symbol<StoreNameSloppy>(), "StoreNameSloppy" },
+ {symbol<StoreProperty>(), "StoreProperty" },
+ {symbol<StoreElement>(), "StoreElement" },
+ {symbol<LoadProperty>(), "LoadProperty" },
+ {symbol<LoadName>(), "LoadName" },
+ {symbol<LoadElement>(), "LoadElement" },
+ {symbol<LoadSuperProperty>(), "LoadSuperProperty" },
+ {symbol<StoreSuperProperty>(), "StoreSuperProperty" },
+ {symbol<LoadSuperConstructor>(), "LoadSuperConstructor" },
+ {symbol<LoadGlobalLookup>(), "LoadGlobalLookup" },
+ {symbol<LoadQmlContextPropertyLookup>(), "LoadQmlContextPropertyLookup" },
+ {symbol<GetLookup>(), "GetLookup" },
+ {symbol<SetLookupStrict>(), "SetLookupStrict" },
+ {symbol<SetLookupSloppy>(), "SetLookupSloppy" },
+
+ {symbol<TypeofValue>(), "TypeofValue" },
+ {symbol<TypeofName>(), "TypeofName" },
+
+ {symbol<DeleteProperty_NoThrow>(), "DeleteProperty_NoThrow" },
+ {symbol<DeleteProperty>(), "DeleteProperty" },
+ {symbol<DeleteName_NoThrow>(), "DeleteName_NoThrow" },
+ {symbol<DeleteName>(), "DeleteName" },
+
+ {symbol<ThrowException>(), "ThrowException" },
+ {symbol<PushCallContext>(), "PushCallContext" },
+ {symbol<PushWithContext>(), "PushWithContext" },
+ {symbol<PushCatchContext>(), "PushCatchContext" },
+ {symbol<PushBlockContext>(), "PushBlockContext" },
+ {symbol<CloneBlockContext>(), "CloneBlockContext" },
+ {symbol<PushScriptContext>(), "PushScriptContext" },
+ {symbol<PopScriptContext>(), "PopScriptContext" },
+ {symbol<ThrowReferenceError>(), "ThrowReferenceError" },
+ {symbol<ThrowOnNullOrUndefined>(), "ThrowOnNullOrUndefined" },
+
+ {symbol<Closure>(), "Closure" },
+
+ {symbol<ConvertThisToObject>(), "ConvertThisToObject" },
+ {symbol<DeclareVar>(), "DeclareVar" },
+ {symbol<CreateMappedArgumentsObject>(), "CreateMappedArgumentsObject" },
+ {symbol<CreateUnmappedArgumentsObject>(), "CreateUnmappedArgumentsObject" },
+ {symbol<CreateRestParameter>(), "CreateRestParameter" },
+
+ {symbol<ArrayLiteral>(), "ArrayLiteral" },
+ {symbol<ObjectLiteral>(), "ObjectLiteral" },
+ {symbol<CreateClass>(), "CreateClass" },
+
+ {symbol<GetIterator>(), "GetIterator" },
+ {symbol<IteratorNext>(), "IteratorNext" },
+ {symbol<IteratorNextForYieldStar>(), "IteratorNextForYieldStar" },
+ {symbol<IteratorClose>(), "IteratorClose" },
+ {symbol<DestructureRestElement>(), "DestructureRestElement" },
+
+ {symbol<ToObject>(), "ToObject" },
+ {symbol<ToBoolean>(), "ToBoolean" },
+ {symbol<ToNumber>(), "ToNumber" },
+
+ {symbol<UMinus>(), "UMinus" },
+
+ {symbol<Instanceof>(), "Instanceof" },
+ {symbol<In>(), "In" },
+ {symbol<Add>(), "Add" },
+ {symbol<Sub>(), "Sub" },
+ {symbol<Mul>(), "Mul" },
+ {symbol<Div>(), "Div" },
+ {symbol<Mod>(), "Mod" },
+ {symbol<Exp>(), "Exp" },
+ {symbol<BitAnd>(), "BitAnd" },
+ {symbol<BitOr>(), "BitOr" },
+ {symbol<BitXor>(), "BitXor" },
+ {symbol<Shl>(), "Shl" },
+ {symbol<Shr>(), "Shr" },
+ {symbol<UShr>(), "UShr" },
+ {symbol<GreaterThan>(), "GreaterThan" },
+ {symbol<LessThan>(), "LessThan" },
+ {symbol<GreaterEqual>(), "GreaterEqual" },
+ {symbol<LessEqual>(), "LessEqual" },
+ {symbol<Equal>(), "Equal" },
+ {symbol<NotEqual>(), "NotEqual" },
+ {symbol<StrictEqual>(), "StrictEqual" },
+ {symbol<StrictNotEqual>(), "StrictNotEqual" },
+
+ {symbol<CompareGreaterThan>(), "CompareGreaterThan" },
+ {symbol<CompareLessThan>(), "CompareLessThan" },
+ {symbol<CompareGreaterEqual>(), "CompareGreaterEqual" },
+ {symbol<CompareLessEqual>(), "CompareLessEqual" },
+ {symbol<CompareEqual>(), "CompareEqual" },
+ {symbol<CompareNotEqual>(), "CompareNotEqual" },
+ {symbol<CompareStrictEqual>(), "CompareStrictEqual" },
+ {symbol<CompareStrictNotEqual>(), "CompareStrictNotEqual" },
+
+ {symbol<CompareInstanceof>(), "CompareInstanceOf" },
+ {symbol<CompareIn>(), "CompareIn" },
+
+ {symbol<RegexpLiteral>(), "RegexpLiteral" },
+ {symbol<GetTemplateObject>(), "GetTemplateObject" }
+#endif
+ });
+
+ return symbols;
+}
+
} // namespace QV4
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index 05ffb84d58..d155187e48 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -501,6 +501,8 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
static const int tailCall_argv = -3;
static const int tailCall_argc = -4;
};
+
+ static QHash<const void *, const char *> symbolTable();
};
static_assert(std::is_standard_layout<Runtime>::value, "Runtime needs to be standard layout in order for us to be able to use offsetof");
diff --git a/src/qml/jsruntime/qv4runtimecodegen.cpp b/src/qml/jsruntime/qv4runtimecodegen.cpp
index 162d75db63..b7737982b7 100644
--- a/src/qml/jsruntime/qv4runtimecodegen.cpp
+++ b/src/qml/jsruntime/qv4runtimecodegen.cpp
@@ -67,7 +67,7 @@ void RuntimeCodegen::generateFromFunctionExpression(const QString &fileName,
_module->rootContext = _module->functions.at(index);
}
-void RuntimeCodegen::throwSyntaxError(const AST::SourceLocation &loc, const QString &detail)
+void RuntimeCodegen::throwSyntaxError(const SourceLocation &loc, const QString &detail)
{
if (hasError())
return;
@@ -76,7 +76,7 @@ void RuntimeCodegen::throwSyntaxError(const AST::SourceLocation &loc, const QStr
engine->throwSyntaxError(detail, _module->fileName, loc.startLine, loc.startColumn);
}
-void RuntimeCodegen::throwReferenceError(const AST::SourceLocation &loc, const QString &detail)
+void RuntimeCodegen::throwReferenceError(const SourceLocation &loc, const QString &detail)
{
if (hasError())
return;
diff --git a/src/qml/jsruntime/qv4runtimecodegen_p.h b/src/qml/jsruntime/qv4runtimecodegen_p.h
index 71aaf1fb55..d3a30ce35d 100644
--- a/src/qml/jsruntime/qv4runtimecodegen_p.h
+++ b/src/qml/jsruntime/qv4runtimecodegen_p.h
@@ -69,8 +69,8 @@ public:
QQmlJS::AST::FunctionExpression *ast,
Compiler::Module *module);
- void throwSyntaxError(const QQmlJS::AST::SourceLocation &loc, const QString &detail) override;
- void throwReferenceError(const QQmlJS::AST::SourceLocation &loc, const QString &detail) override;
+ void throwSyntaxError(const QQmlJS::SourceLocation &loc, const QString &detail) override;
+ void throwReferenceError(const QQmlJS::SourceLocation &loc, const QString &detail) override;
private:
ExecutionEngine *engine;
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 2fab9e4b7b..2add1222ea 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -52,6 +52,7 @@
#include <private/qqmljsparser_p.h>
#include <private/qqmljsast_p.h>
#include <private/qqmlengine_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
#include <private/qv4profiling_p.h>
#include <qv4runtimecodegen_p.h>
@@ -109,10 +110,10 @@ void Script::parse()
const auto diagnosticMessages = parser.diagnosticMessages();
for (const DiagnosticMessage &m : diagnosticMessages) {
if (m.isError()) {
- valueScope.engine->throwSyntaxError(m.message, sourceFile, m.line, m.column);
+ valueScope.engine->throwSyntaxError(m.message, sourceFile, m.loc.startLine, m.loc.startColumn);
return;
} else {
- qWarning() << sourceFile << ':' << m.line << ':' << m.column
+ qWarning() << sourceFile << ':' << m.loc.startLine << ':' << m.loc.startColumn
<< ": warning: " << m.message;
}
}
@@ -209,8 +210,8 @@ QV4::CompiledData::CompilationUnit Script::precompile(
const auto v4Error = cg.error();
QQmlError error;
error.setUrl(cg.url());
- error.setLine(v4Error.line);
- error.setColumn(v4Error.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(v4Error.loc.startLine));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(v4Error.loc.startColumn));
error.setDescription(v4Error.message);
reportedErrors->append(error);
}
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 6a1b003b25..d03b67aa27 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -1070,51 +1070,44 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_indexOf(const FunctionObject
return Encode(-1);
}
-ReturnedValue IntrinsicTypedArrayPrototype::method_join(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+ReturnedValue IntrinsicTypedArrayPrototype::method_join(
+ const FunctionObject *functionObject, const Value *thisObject, const Value *argv, int argc)
{
- Scope scope(b);
- Scoped<TypedArray> v(scope, thisObject);
- if (!v || v->d()->buffer->isDetachedBuffer())
+ Scope scope(functionObject);
+ Scoped<TypedArray> typedArray(scope, thisObject);
+ if (!typedArray || typedArray->d()->buffer->isDetachedBuffer())
return scope.engine->throwTypeError();
- uint len = v->length();
-
- ScopedValue arg(scope, argc ? argv[0] : Value::undefinedValue());
+ // We cannot optimize the resolution of the argument away if length is 0.
+ // It may have side effects.
+ ScopedValue argument(scope, argc ? argv[0] : Value::undefinedValue());
+ const QString separator = argument->isUndefined()
+ ? QStringLiteral(",")
+ : argument->toQString();
- QString r4;
- if (arg->isUndefined())
- r4 = QStringLiteral(",");
- else
- r4 = arg->toQString();
-
- const quint32 r2 = len;
-
- if (!r2)
+ const quint32 length = typedArray->length();
+ if (!length)
return Encode(scope.engine->newString());
- QString R;
+ QString result;
- //
- // crazy!
- //
ScopedString name(scope, scope.engine->newString(QStringLiteral("0")));
- ScopedValue r6(scope, v->get(name));
- if (!r6->isNullOrUndefined())
- R = r6->toQString();
+ ScopedValue value(scope, typedArray->get(name));
+ if (!value->isNullOrUndefined())
+ result = value->toQString();
- ScopedValue r12(scope);
- for (quint32 k = 1; k < r2; ++k) {
- R += r4;
+ for (quint32 i = 1; i < length; ++i) {
+ result += separator;
- name = Value::fromDouble(k).toString(scope.engine);
- r12 = v->get(name);
+ name = Value::fromDouble(i).toString(scope.engine);
+ value = typedArray->get(name);
CHECK_EXCEPTION();
- if (!r12->isNullOrUndefined())
- R += r12->toQString();
+ if (!value->isNullOrUndefined())
+ result += value->toQString();
}
- return Encode(scope.engine->newString(R));
+ return Encode(scope.engine->newString(result));
}
ReturnedValue IntrinsicTypedArrayPrototype::method_keys(const FunctionObject *b, const Value *thisObject, const Value *, int)
@@ -1657,6 +1650,158 @@ ReturnedValue IntrinsicTypedArrayCtor::method_of(const FunctionObject *f, const
return newObj->asReturnedValue();
}
+ReturnedValue IntrinsicTypedArrayCtor::method_from(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(f);
+ ScopedObject itemsObject(scope, argv[0]);
+ bool usingIterator = false;
+
+ ScopedFunctionObject mapfn(scope, Value::undefinedValue());
+ Value *mapArguments = nullptr;
+ if (argc > 1) {
+ mapfn = ScopedFunctionObject(scope, argv[1]);
+ if (!mapfn)
+ return scope.engine->throwTypeError(QString::fromLatin1("%1 is not a function").arg(argv[1].toQStringNoThrow()));
+ mapArguments = scope.alloc(2);
+ }
+
+ // Iterator validity check goes after map function validity has been checked.
+ if (itemsObject) {
+ // If the object claims to support iterators, then let's try use them.
+ ScopedValue it(scope, itemsObject->get(scope.engine->symbol_iterator()));
+ CHECK_EXCEPTION();
+ if (!it->isNullOrUndefined()) {
+ ScopedFunctionObject itfunc(scope, it);
+ if (!itfunc)
+ return scope.engine->throwTypeError();
+ usingIterator = true;
+ }
+ }
+
+ ScopedValue thisArg(scope);
+ if (argc > 2)
+ thisArg = argv[2];
+
+ const FunctionObject *C = thisObject->as<FunctionObject>();
+
+ if (usingIterator) {
+ // Item iteration supported, so let's go ahead and try use that.
+ CHECK_EXCEPTION();
+
+ qint64 iterableLength = 0;
+ Value *nextValue = scope.alloc(1);
+ ScopedValue done(scope);
+
+ ScopedObject lengthIterator(scope, Runtime::GetIterator::call(scope.engine, itemsObject, true));
+ CHECK_EXCEPTION(); // symbol_iterator threw; whoops.
+ if (!lengthIterator) {
+ return scope.engine->throwTypeError(); // symbol_iterator wasn't an object.
+ }
+
+ forever {
+ // Here we calculate the length of the iterable range.
+ if (iterableLength > (static_cast<qint64>(1) << 53) - 1) {
+ ScopedValue falsey(scope, Encode(false));
+ ScopedValue error(scope, scope.engine->throwTypeError());
+ return Runtime::IteratorClose::call(scope.engine, lengthIterator, falsey);
+ }
+ // Retrieve the next value. If the iteration ends, we're done here.
+ done = Value::fromReturnedValue(Runtime::IteratorNext::call(scope.engine, lengthIterator, nextValue));
+ if (scope.engine->hasException)
+ return Runtime::IteratorClose::call(scope.engine, lengthIterator, Value::fromBoolean(false));
+ if (done->toBoolean()) {
+ break;
+ }
+ iterableLength++;
+ }
+
+ // Constructor validity check goes after we have calculated the length, because that calculation can throw
+ // errors that are not type errors and at least the tests expect those rather than type errors.
+ if (!C || !C->isConstructor())
+ return scope.engine->throwTypeError();
+
+ ScopedObject iterator(scope, Runtime::GetIterator::call(scope.engine, itemsObject, true));
+ CHECK_EXCEPTION(); // symbol_iterator can throw.
+ if (!iterator) {
+ return scope.engine->throwTypeError(); // symbol_iterator wasn't an object.
+ }
+
+ ScopedObject a(scope, Value::undefinedValue());
+ ScopedValue ctorArgument(scope, Value::fromReturnedValue(QV4::Encode(int(iterableLength))));
+ a = C->callAsConstructor(ctorArgument, 1);
+ CHECK_EXCEPTION();
+
+ // We check exceptions above, and only after doing so, check the array's validity after construction.
+ if (!::validateTypedArray(a) || (a->getLength() < iterableLength))
+ return scope.engine->throwTypeError();
+
+
+ // The loop below traverses the iterator, and puts elements into the created array.
+ ScopedValue mappedValue(scope, Value::undefinedValue());
+ for (qint64 k = 0; k < iterableLength; ++k) {
+ done = Value::fromReturnedValue(Runtime::IteratorNext::call(scope.engine, iterator, nextValue));
+ if (scope.engine->hasException)
+ return Runtime::IteratorClose::call(scope.engine, iterator, Value::fromBoolean(false));
+
+ if (mapfn) {
+ mapArguments[0] = *nextValue;
+ mapArguments[1] = Value::fromDouble(k);
+ mappedValue = mapfn->call(thisArg, mapArguments, 2);
+ if (scope.engine->hasException)
+ return Runtime::IteratorClose::call(scope.engine, iterator, Value::fromBoolean(false));
+ } else {
+ mappedValue = *nextValue;
+ }
+
+ a->put(k, mappedValue);
+ if (scope.engine->hasException)
+ return Runtime::IteratorClose::call(scope.engine, iterator, Value::fromBoolean(false));
+ }
+ return a.asReturnedValue();
+ } else {
+ // Array-like fallback. We request elements by index, and put them into the created array.
+ ScopedObject arrayLike(scope, argv[0].toObject(scope.engine));
+ if (!arrayLike)
+ return scope.engine->throwTypeError(QString::fromLatin1("Cannot convert %1 to object").arg(argv[0].toQStringNoThrow()));
+
+ int len = arrayLike->getLength();
+ CHECK_EXCEPTION();
+
+ // Getting the length may throw, and must do so before we check the constructor validity.
+ if (!C || !C->isConstructor())
+ return scope.engine->throwTypeError();
+
+ ScopedObject a(scope, Value::undefinedValue());
+ ScopedValue ctorArgument(scope, Value::fromReturnedValue(QV4::Encode(len)));
+ a = C->callAsConstructor(ctorArgument, 1);
+ CHECK_EXCEPTION();
+
+ // We check exceptions above, and only after doing so, check the array's validity after construction.
+ if (!::validateTypedArray(a) || (a->getLength() < len))
+ return scope.engine->throwTypeError();
+
+ ScopedValue mappedValue(scope, Value::undefinedValue());
+ ScopedValue kValue(scope);
+ for (int k = 0; k < len; ++k) {
+ kValue = arrayLike->get(k);
+ CHECK_EXCEPTION();
+
+ if (mapfn) {
+ mapArguments[0] = kValue;
+ mapArguments[1] = Value::fromDouble(k);
+ mappedValue = mapfn->call(thisArg, mapArguments, 2);
+ CHECK_EXCEPTION();
+ } else {
+ mappedValue = kValue;
+ }
+
+ a->put(k, mappedValue);
+ CHECK_EXCEPTION();
+ }
+ return a.asReturnedValue();
+ }
+}
+
void IntrinsicTypedArrayPrototype::init(ExecutionEngine *engine, IntrinsicTypedArrayCtor *ctor)
{
Scope scope(engine);
@@ -1666,6 +1811,8 @@ void IntrinsicTypedArrayPrototype::init(ExecutionEngine *engine, IntrinsicTypedA
ctor->defineReadonlyConfigurableProperty(engine->id_name(), s);
s = scope.engine->newString(QStringLiteral("of"));
ctor->defineDefaultProperty(s, IntrinsicTypedArrayCtor::method_of);
+ s = scope.engine->newString(QStringLiteral("from"));
+ ctor->defineDefaultProperty(s, IntrinsicTypedArrayCtor::method_from, 1);
ctor->addSymbolSpecies();
defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, nullptr);
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index 64792f23a2..65656e3389 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -181,6 +181,7 @@ struct IntrinsicTypedArrayCtor: FunctionObject
static constexpr VTable::Call virtualCall = nullptr;
static ReturnedValue method_of(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_from(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
struct TypedArrayCtor: FunctionObject
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/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index ae12033eb4..42e97b1d36 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -537,29 +537,8 @@ struct ValueArray {
}
void mark(MarkStack *markStack) {
- Value *v = values;
- const Value *end = v + alloc;
- if (alloc > 32*1024) {
- // drain from time to time to avoid overflows in the js stack
- Value::HeapBasePtr *currentBase = markStack->top;
- while (v < end) {
- v->mark(markStack);
- ++v;
- if (markStack->top >= currentBase + 32*1024) {
- Value::HeapBasePtr *oldBase = markStack->base;
- markStack->base = currentBase;
- markStack->drain();
- markStack->base = oldBase;
- }
- }
- } else {
- while (v < end) {
- v->mark(markStack);
- if (markStack->top >= markStack->limit)
- markStack->drain();
- ++v;
- }
- }
+ for (Value *v = values, *end = values + alloc; v < end; ++v)
+ v->mark(markStack);
}
};
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index e117e509ab..9d7b3c6e9a 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -65,8 +65,8 @@ void Heap::VariantObject::init(const QVariant &value)
bool VariantObject::Data::isScarce() const
{
- QVariant::Type t = data().type();
- return t == QVariant::Pixmap || t == QVariant::Image;
+ int t = data().userType();
+ return t == QMetaType::QPixmap || t == QMetaType::QImage;
}
bool VariantObject::virtualIsEqualTo(Managed *m, Managed *other)
@@ -139,7 +139,7 @@ ReturnedValue VariantPrototype::method_toString(const FunctionObject *b, const V
RETURN_UNDEFINED();
const QVariant variant = o->d()->data();
QString result = variant.toString();
- if (result.isEmpty() && !variant.canConvert(QVariant::String)) {
+ if (result.isEmpty() && !variant.canConvert(QMetaType::QString)) {
QDebug dbg(&result);
dbg << variant;
// QDebug appends a space, we're not interested in continuing the stream so we chop it off.
@@ -154,17 +154,17 @@ ReturnedValue VariantPrototype::method_valueOf(const FunctionObject *b, const Va
const VariantObject *o = thisObject->as<QV4::VariantObject>();
if (o) {
QVariant v = o->d()->data();
- switch (v.type()) {
- case QVariant::Invalid:
+ switch (v.userType()) {
+ case QMetaType::UnknownType:
return Encode::undefined();
- case QVariant::String:
+ case QMetaType::QString:
return Encode(b->engine()->newString(v.toString()));
- case QVariant::Int:
+ case QMetaType::Int:
return Encode(v.toInt());
- case QVariant::Double:
- case QVariant::UInt:
+ case QMetaType::Double:
+ case QMetaType::UInt:
return Encode(v.toDouble());
- case QVariant::Bool:
+ case QMetaType::Bool:
return Encode(v.toBool());
default:
if (QMetaType::typeFlags(v.userType()) & QMetaType::IsEnumeration)
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index e143523165..fb103d492d 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -434,7 +434,7 @@ ReturnedValue VME::exec(CppStackFrame *frame, ExecutionEngine *engine)
Function *function = frame->v4Function;
Q_TRACE_SCOPE(QQmlV4_function_call, engine, function->name()->toQString(),
- function->compilationUnit->fileName(),
+ function->executableCompilationUnit()->fileName(),
function->compiledFunction->location.line,
function->compiledFunction->location.column);
Profiling::FunctionCallProfiler profiler(engine, function); // start execution profiling
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index a54cbed2c9..3ed1bc48fd 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -223,7 +223,8 @@ Chunk *MemorySegment::allocate(size_t size)
pageReservation.commit(candidate, size);
for (uint i = 0; i < requiredChunks; ++i)
setBit(candidate - base + i);
- DEBUG << "allocated chunk " << candidate << hex << size;
+ DEBUG << "allocated chunk " << candidate << Qt::hex << size;
+
return candidate;
}
}
@@ -847,16 +848,18 @@ Heap::Object *MemoryManager::allocObjectWithMemberData(const QV4::VTable *vtable
static uint markStackSize = 0;
MarkStack::MarkStack(ExecutionEngine *engine)
- : engine(engine)
+ : m_engine(engine)
{
- base = (Heap::Base **)engine->gcStack->base();
- top = base;
- limit = base + engine->maxGCStackSize()/sizeof(Heap::Base)*3/4;
+ m_base = (Heap::Base **)engine->gcStack->base();
+ m_top = m_base;
+ const size_t size = engine->maxGCStackSize() / sizeof(Heap::Base);
+ m_hardLimit = m_base + size;
+ m_softLimit = m_base + size * 3 / 4;
}
void MarkStack::drain()
{
- while (top > base) {
+ while (m_top > m_base) {
Heap::Base *h = pop();
++markStackSize;
Q_ASSERT(h); // at this point we should only have Heap::Base objects in this area on the stack. If not, weird things might happen.
@@ -903,20 +906,15 @@ void MemoryManager::collectRoots(MarkStack *markStack)
if (keepAlive)
qobjectWrapper->mark(markStack);
-
- if (markStack->top >= markStack->limit)
- markStack->drain();
}
}
void MemoryManager::mark()
{
markStackSize = 0;
-
MarkStack markStack(engine);
collectRoots(&markStack);
-
- markStack.drain();
+ // dtor of MarkStack drains
}
void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPtr)
@@ -1024,7 +1022,7 @@ static size_t dumpBins(BlockAllocator *b, const char *title)
SDUMP() << " large slot map";
HeapItem *h = b->freeBins[BlockAllocator::NumBins - 1];
while (h) {
- SDUMP() << " " << hex << (quintptr(h)/32) << h->freeData.availableSlots;
+ SDUMP() << " " << Qt::hex << (quintptr(h)/32) << h->freeData.availableSlots;
h = h->freeData.next;
}
@@ -1219,8 +1217,6 @@ void MemoryManager::collectFromJSStack(MarkStack *markStack) const
Q_ASSERT(m->inUse());
// Skip pointers to already freed objects, they are bogus as well
m->mark(markStack);
- if (markStack->top >= markStack->limit)
- markStack->drain();
}
++v;
}
diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h
index 8a53492822..117e8f4360 100644
--- a/src/qml/memory/qv4mmdefs_p.h
+++ b/src/qml/memory/qv4mmdefs_p.h
@@ -53,6 +53,7 @@
#include <private/qv4global_p.h>
#include <private/qv4runtimeapi_p.h>
#include <QtCore/qalgorithms.h>
+#include <QtCore/qmath.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -270,22 +271,41 @@ Q_STATIC_ASSERT(sizeof(HeapItem) == Chunk::SlotSize);
Q_STATIC_ASSERT(QT_POINTER_SIZE*8 == Chunk::Bits);
Q_STATIC_ASSERT((1 << Chunk::BitShift) == Chunk::Bits);
-struct MarkStack {
+struct Q_QML_PRIVATE_EXPORT MarkStack {
MarkStack(ExecutionEngine *engine);
- Heap::Base **top = nullptr;
- Heap::Base **base = nullptr;
- Heap::Base **limit = nullptr;
- ExecutionEngine *engine;
+ ~MarkStack() { drain(); }
+
void push(Heap::Base *m) {
- *top = m;
- ++top;
- }
- Heap::Base *pop() {
- --top;
- return *top;
+ *(m_top++) = m;
+
+ if (m_top < m_softLimit)
+ return;
+
+ // If at or above soft limit, partition the remaining space into at most 64 segments and
+ // allow one C++ recursion of drain() per segment, plus one for the fence post.
+ const quintptr segmentSize = qNextPowerOfTwo(quintptr(m_hardLimit - m_softLimit) / 64u);
+ if (m_drainRecursion * segmentSize <= quintptr(m_top - m_softLimit)) {
+ ++m_drainRecursion;
+ drain();
+ --m_drainRecursion;
+ } else if (m_top == m_hardLimit) {
+ qFatal("GC mark stack overrun. Either simplify your application or"
+ "increase QV4_GC_MAX_STACK_SIZE");
+ }
}
+
+ ExecutionEngine *engine() const { return m_engine; }
+
+private:
+ Heap::Base *pop() { return *(--m_top); }
void drain();
+ Heap::Base **m_top = nullptr;
+ Heap::Base **m_base = nullptr;
+ Heap::Base **m_softLimit = nullptr;
+ Heap::Base **m_hardLimit = nullptr;
+ ExecutionEngine *m_engine = nullptr;
+ quintptr m_drainRecursion = 0;
};
// Some helper to automate the generation of our
diff --git a/src/qml/parser/parser.pri b/src/qml/parser/parser.pri
index e15730f5d1..57855a82f9 100644
--- a/src/qml/parser/parser.pri
+++ b/src/qml/parser/parser.pri
@@ -5,9 +5,7 @@ HEADERS += \
$$PWD/qqmljsengine_p.h \
$$PWD/qqmljslexer_p.h \
$$PWD/qqmljsglobal_p.h \
- $$PWD/qqmljskeywords_p.h \
- $$PWD/qqmljsengine_p.h \
- $$PWD/qqmljssourcelocation_p.h
+ $$PWD/qqmljskeywords_p.h
SOURCES += \
$$PWD/qqmljsast.cpp \
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 0d9507fe2f..e4b7198b30 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -49,6 +49,7 @@
%token T_DIVIDE_EQ "/=" T_DO "do" T_DOT "."
%token T_ELSE "else" T_EQ "=" T_EQ_EQ "=="
%token T_EQ_EQ_EQ "===" T_FINALLY "finally" T_FOR "for"
+%token T_FUNCTION_STAR "function *"
%token T_FUNCTION "function" T_GE ">=" T_GT ">"
%token T_GT_GT ">>" T_GT_GT_EQ ">>=" T_GT_GT_GT ">>>"
%token T_GT_GT_GT_EQ ">>>=" T_IDENTIFIER "identifier" T_IF "if"
@@ -72,13 +73,14 @@
%token T_VAR "var" T_VOID "void" T_WHILE "while"
%token T_WITH "with" T_XOR "^" T_XOR_EQ "^="
%token T_NULL "null" T_TRUE "true" T_FALSE "false"
-%token T_CONST "const" T_LET "let"
+%token T_CONST "const" T_LET "let" T_AT "@"
%token T_DEBUGGER "debugger"
%token T_RESERVED_WORD "reserved word"
%token T_MULTILINE_STRING_LITERAL "multiline string literal"
%token T_COMMENT "comment"
%token T_COMPATIBILITY_SEMICOLON
%token T_ARROW "=>"
+%token T_QUESTION_QUESTION "??"
%token T_ENUM "enum"
%token T_ELLIPSIS "..."
%token T_YIELD "yield"
@@ -88,6 +90,8 @@
%token T_STATIC "static"
%token T_EXPORT "export"
%token T_FROM "from"
+%token T_REQUIRED "required"
+%token T_COMPONENT "component"
--- template strings
%token T_NO_SUBSTITUTION_TEMPLATE"(no subst template)"
@@ -120,8 +124,9 @@
%token T_FOR_LOOKAHEAD_OK "(for lookahead ok)"
--%left T_PLUS T_MINUS
-%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET T_OF T_STATIC T_FROM T_AS
+%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET T_OF T_STATIC T_FROM T_AS T_REQUIRED T_COMPONENT
%nonassoc REDUCE_HERE
+%right T_THEN T_ELSE
%right T_WITHOUTAS T_AS
%start TopLevel
@@ -321,6 +326,8 @@ public:
AST::UiQualifiedId *UiQualifiedId;
AST::UiEnumMemberList *UiEnumMemberList;
AST::UiVersionSpecifier *UiVersionSpecifier;
+ AST::UiAnnotation *UiAnnotation;
+ AST::UiAnnotationList *UiAnnotationList;
};
public:
@@ -383,10 +390,10 @@ public:
{ return diagnosticMessage().message; }
inline int errorLineNumber() const
- { return diagnosticMessage().line; }
+ { return diagnosticMessage().loc.startLine; }
inline int errorColumnNumber() const
- { return diagnosticMessage().column; }
+ { return diagnosticMessage().loc.startColumn; }
protected:
bool parse(int startToken);
@@ -402,7 +409,7 @@ protected:
inline QStringRef &rawStringRef(int index)
{ return rawString_stack [tos + index - 1]; }
- inline AST::SourceLocation &loc(int index)
+ inline SourceLocation &loc(int index)
{ return location_stack [tos + index - 1]; }
AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr);
@@ -410,21 +417,20 @@ protected:
void pushToken(int token);
int lookaheadToken(Lexer *lexer);
- static DiagnosticMessage compileError(const AST::SourceLocation &location,
+ static DiagnosticMessage compileError(const SourceLocation &location,
const QString &message, QtMsgType kind = QtCriticalMsg)
{
DiagnosticMessage error;
- error.line = location.startLine;
- error.column = location.startColumn;
+ error.loc = location;
error.message = message;
error.type = kind;
return error;
}
- void syntaxError(const AST::SourceLocation &location, const char *message) {
+ void syntaxError(const SourceLocation &location, const char *message) {
diagnostic_messages.append(compileError(location, QLatin1String(message)));
}
- void syntaxError(const AST::SourceLocation &location, const QString &message) {
+ void syntaxError(const SourceLocation &location, const QString &message) {
diagnostic_messages.append(compileError(location, message));
}
@@ -437,7 +443,7 @@ protected:
int stack_size = 0;
Value *sym_stack = nullptr;
int *state_stack = nullptr;
- AST::SourceLocation *location_stack = nullptr;
+ SourceLocation *location_stack = nullptr;
QVector<QStringRef> string_stack;
QVector<QStringRef> rawString_stack;
@@ -449,7 +455,7 @@ protected:
struct SavedToken {
int token;
double dval;
- AST::SourceLocation loc;
+ SourceLocation loc;
QStringRef spell;
QStringRef raw;
};
@@ -458,8 +464,8 @@ protected:
double yylval = 0.;
QStringRef yytokenspell;
QStringRef yytokenraw;
- AST::SourceLocation yylloc;
- AST::SourceLocation yyprevlloc;
+ SourceLocation yylloc;
+ SourceLocation yyprevlloc;
SavedToken token_buffer[TOKEN_BUFFER_SIZE];
SavedToken *first_token = nullptr;
@@ -472,7 +478,7 @@ protected:
CE_ParenthesizedExpression,
CE_FormalParameterList
};
- AST::SourceLocation coverExpressionErrorLocation;
+ SourceLocation coverExpressionErrorLocation;
CoverExpressionType coverExpressionType = CE_Invalid;
QList<DiagnosticMessage> diagnostic_messages;
@@ -517,7 +523,7 @@ void Parser::reallocateStack()
sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value)));
state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int)));
- location_stack = reinterpret_cast<AST::SourceLocation*> (realloc(location_stack, stack_size * sizeof(AST::SourceLocation)));
+ location_stack = reinterpret_cast<SourceLocation*> (realloc(location_stack, stack_size * sizeof(SourceLocation)));
string_stack.resize(stack_size);
rawString_stack.resize(stack_size);
}
@@ -537,9 +543,9 @@ Parser::~Parser()
}
}
-static inline AST::SourceLocation location(Lexer *lexer)
+static inline SourceLocation location(Lexer *lexer)
{
- AST::SourceLocation loc;
+ SourceLocation loc;
loc.offset = lexer->tokenOffset();
loc.length = lexer->tokenLength();
loc.startLine = lexer->tokenStartLine();
@@ -550,7 +556,7 @@ static inline AST::SourceLocation location(Lexer *lexer)
AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
{
QVarLengthArray<QStringRef, 4> nameIds;
- QVarLengthArray<AST::SourceLocation, 4> locations;
+ QVarLengthArray<SourceLocation, 4> locations;
AST::ExpressionNode *it = expr;
while (AST::FieldMemberExpression *m = AST::cast<AST::FieldMemberExpression *>(it)) {
@@ -734,7 +740,7 @@ TopLevel: T_FEED_JS_EXPRESSION Expression;
} break;
./
-TopLevel: T_FEED_UI_OBJECT_MEMBER UiObjectMember;
+TopLevel: T_FEED_UI_OBJECT_MEMBER UiAnnotatedObjectMember;
/.
case $rule_number: {
sym(1).Node = sym(2).Node;
@@ -849,13 +855,7 @@ UiVersionSpecifier: T_VERSION_NUMBER;
UiImport: UiImportHead UiVersionSpecifier Semicolon;
/.
case $rule_number: {
- auto versionToken = loc(2);
- auto version = sym(2).UiVersionSpecifier;
- sym(1).UiImport->version = version;
- if (version->minorToken.isValid()) {
- versionToken.length += version->minorToken.length + (version->minorToken.offset - versionToken.offset - versionToken.length);
- }
- sym(1).UiImport->versionToken = versionToken;
+ sym(1).UiImport->version = sym(2).UiVersionSpecifier;
sym(1).UiImport->semicolonToken = loc(3);
} break;
./
@@ -863,7 +863,6 @@ UiImport: UiImportHead UiVersionSpecifier Semicolon;
UiImport: UiImportHead UiVersionSpecifier T_AS QmlIdentifier Semicolon;
/.
case $rule_number: {
- sym(1).UiImport->versionToken = loc(2);
sym(1).UiImport->version = sym(2).UiVersionSpecifier;
sym(1).UiImport->asToken = loc(3);
sym(1).UiImport->importIdToken = loc(4);
@@ -915,21 +914,92 @@ Empty: ;
} break;
./
-UiRootMember: UiObjectDefinition;
+UiRootMember: UiAnnotatedObject;
/.
case $rule_number: {
sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
} break;
./
-UiObjectMemberList: UiObjectMember;
+UiSimpleQualifiedId: T_IDENTIFIER;
+/.
+ case $rule_number: {
+ AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
+ node->identifierToken = loc(1);
+ sym(1).Node = node;
+ } break;
+./
+
+UiSimpleQualifiedId: UiSimpleQualifiedId T_DOT T_IDENTIFIER;
+/.
+ case $rule_number: {
+ AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
+ node->dotToken = loc(2);
+ node->identifierToken = loc(3);
+ sym(1).Node = node;
+ } break;
+./
+
+UiAnnotationObjectDefinition: UiSimpleQualifiedId UiObjectInitializer;
+/.
+ case $rule_number: {
+ if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) {
+ sym(1).UiQualifiedId = qualifiedId;
+ } else {
+ sym(1).UiQualifiedId = 0;
+
+ diagnostic_messages.append(compileError(loc(1),
+ QLatin1String("Expected a qualified name id")));
+
+ return false;
+ }
+ 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::UiAnnotationList(sym(1).UiAnnotation);
+ } break;
+./
+
+UiAnnotationList: UiAnnotationList UiAnnotation;
+/.
+ case $rule_number: {
+ AST::UiAnnotationList *node = new (pool) AST::UiAnnotationList(sym(1).UiAnnotationList, sym(2).UiAnnotation);
+ sym(1).Node = node;
+ } break;
+./
+
+UiAnnotatedObject: UiAnnotationList UiObjectDefinition;
+/.
+ case $rule_number: {
+ AST::UiObjectDefinition *node = sym(2).UiObjectDefinition;
+ node->annotations = sym(1).UiAnnotationList->finish();
+ sym(1).Node = node;
+ } break;
+./
+
+UiAnnotatedObject: UiObjectDefinition;
+
+UiObjectMemberList: UiAnnotatedObjectMember;
/.
case $rule_number: {
sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
} break;
./
-UiObjectMemberList: UiObjectMemberList UiObjectMember;
+UiObjectMemberList: UiObjectMemberList UiAnnotatedObjectMember;
/.
case $rule_number: {
AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(sym(1).UiObjectMemberList, sym(2).UiObjectMember);
@@ -981,6 +1051,17 @@ UiObjectDefinition: UiQualifiedId UiObjectInitializer;
} break;
./
+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;
+./
+
+UiAnnotatedObjectMember: UiObjectMember;
+
UiObjectMember: UiObjectDefinition;
UiObjectMember: UiQualifiedId T_COLON ExpressionStatementLookahead T_LBRACKET UiArrayMemberList T_RBRACKET;
@@ -1016,15 +1097,27 @@ UiObjectMember: UiQualifiedId T_ON UiQualifiedId UiObjectInitializer;
./
-UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_RBRACE;
-/. case $rule_number: Q_FALLTHROUGH(); ./
-UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_COMMA T_RBRACE;
+UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_RBRACE Semicolon;
/.
case $rule_number: {
AST::ObjectPattern *l = new (pool) AST::ObjectPattern(sym(3).PatternPropertyList->finish());
l->lbraceToken = loc(1);
l->rbraceToken = loc(4);
AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(l);
+ node->semicolonToken = loc(5);
+ sym(1).Node = node;
+ } break;
+./
+
+
+UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_COMMA T_RBRACE Semicolon;
+/.
+ case $rule_number: {
+ AST::ObjectPattern *l = new (pool) AST::ObjectPattern(sym(3).PatternPropertyList->finish());
+ l->lbraceToken = loc(1);
+ l->rbraceToken = loc(5);
+ AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(l);
+ node->semicolonToken = loc(6);
sym(1).Node = node;
} break;
./
@@ -1176,7 +1269,7 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER Semicolon;
} break;
./
-UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier Semicolon;
+UiObjectMemberListPropertyNoInitialiser: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier Semicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
@@ -1190,23 +1283,19 @@ UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier S
} break;
./
-UiObjectMember: T_READONLY T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier Semicolon;
+UiObjectMember: UiObjectMemberListPropertyNoInitialiser;
+
+UiObjectMember: T_READONLY UiObjectMemberListPropertyNoInitialiser;
/.
case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7));
+ AST::UiPublicMember *node = sym(2).UiPublicMember;
node->isReadonlyMember = true;
node->readonlyToken = loc(1);
- node->typeModifier = stringRef(3);
- node->propertyToken = loc(2);
- node->typeModifierToken = loc(3);
- node->typeToken = loc(5);
- node->identifierToken = loc(7);
- node->semicolonToken = loc(8);
sym(1).Node = node;
} break;
./
-UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier Semicolon;
+UiObjectMemberPropertyNoInitialiser: T_PROPERTY UiPropertyType QmlIdentifier Semicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
@@ -1218,42 +1307,83 @@ UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier Semicolon;
} break;
./
-UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier Semicolon;
+
+UiObjectMember: UiObjectMemberPropertyNoInitialiser;
+
+UiObjectMember: T_DEFAULT UiObjectMemberPropertyNoInitialiser;
/.
case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4));
+ AST::UiPublicMember *node = sym(2).UiPublicMember;
node->isDefaultMember = true;
node->defaultToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->semicolonToken = loc(5);
sym(1).Node = node;
} break;
./
-UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier Semicolon;
+UiObjectMember: T_DEFAULT UiObjectMemberListPropertyNoInitialiser;
/.
case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7));
+ AST::UiPublicMember *node = sym(2).UiPublicMember;
node->isDefaultMember = true;
node->defaultToken = loc(1);
- node->typeModifier = stringRef(3);
- node->propertyToken = loc(2);
- node->typeModifierToken = loc(2);
- node->typeToken = loc(4);
- node->identifierToken = loc(7);
- node->semicolonToken = loc(8);
sym(1).Node = node;
} break;
./
+
+UiObjectMember: T_DEFAULT T_REQUIRED UiObjectMemberPropertyNoInitialiser;
+/.
+ case $rule_number: {
+ AST::UiPublicMember *node = sym(3).UiPublicMember;
+ node->isDefaultMember = true;
+ node->defaultToken = loc(1);
+ node->isRequired = true;
+ node->requiredToken = loc(2);
+ sym(1).Node = node;
+ } break;
+./
+
+
+UiObjectMember: T_REQUIRED T_DEFAULT UiObjectMemberPropertyNoInitialiser;
+/.
+ case $rule_number: {
+ AST::UiPublicMember *node = sym(3).UiPublicMember;
+ node->isDefaultMember = true;
+ node->defaultToken = loc(2);
+ node->isRequired = true;
+ node->requiredToken = loc(1);
+ sym(1).Node = node;
+ } break;
+./
+
OptionalSemicolon: | Semicolon;
/.
/* we need OptionalSemicolon because UiScriptStatement might already parse the last semicolon
and then we would miss a semicolon (see tests/auto/quick/qquickvisualdatamodel/data/objectlist.qml)*/
./
-UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon;
+UiRequired: T_REQUIRED QmlIdentifier Semicolon;
+/.
+ case $rule_number: {
+ AST::UiRequired *node = new (pool) AST::UiRequired(stringRef(2));
+ node->requiredToken = loc(1);
+ node->semicolonToken = loc(3);
+ sym(1).Node = node;
+ } break;
+./
+
+UiObjectMember: UiRequired;
+
+UiObjectMember: T_REQUIRED UiObjectMemberPropertyNoInitialiser;
+/.
+ case $rule_number: {
+ AST::UiPublicMember *node = sym(2).UiPublicMember;
+ node->requiredToken = loc(1);
+ node->isRequired = true;
+ sym(1).Node = node;
+ } break;
+./
+
+UiObjectMemberWithScriptStatement: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3), sym(5).Statement);
@@ -1265,35 +1395,29 @@ UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatemen
} break;
./
-UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon;
+UiObjectMember: UiObjectMemberWithScriptStatement;
+
+UiObjectMember: T_READONLY UiObjectMemberWithScriptStatement;
/.
case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), sym(6).Statement);
+ AST::UiPublicMember *node = sym(2).UiPublicMember;
node->isReadonlyMember = true;
node->readonlyToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->colonToken = loc(5);
sym(1).Node = node;
} break;
./
-UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon;
+UiObjectMember: T_DEFAULT UiObjectMemberWithScriptStatement;
/.
case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), sym(6).Statement);
+ AST::UiPublicMember *node = sym(2).UiPublicMember;
node->isDefaultMember = true;
node->defaultToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->colonToken = loc(5);
sym(1).Node = node;
} break;
./
-UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET Semicolon;
+UiObjectMemberWithArray: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET Semicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
@@ -1319,35 +1443,19 @@ UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T
} break;
./
-UiObjectMember: T_READONLY T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET Semicolon;
+UiObjectMember: UiObjectMemberWithArray;
+
+UiObjectMember: T_READONLY UiObjectMemberWithArray;
/.
case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7));
+ AST::UiPublicMember *node = sym(2).UiPublicMember;
node->isReadonlyMember = true;
node->readonlyToken = loc(1);
- node->typeModifier = stringRef(3);
- node->propertyToken = loc(2);
- node->typeModifierToken = loc(3);
- node->typeToken = loc(5);
- node->identifierToken = loc(7);
- node->semicolonToken = loc(8); // insert a fake ';' before ':'
-
- AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(7));
- propertyName->identifierToken = loc(7);
- propertyName->next = 0;
-
- AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(propertyName, sym(10).UiArrayMemberList->finish());
- binding->colonToken = loc(8);
- binding->lbracketToken = loc(9);
- binding->rbracketToken = loc(11);
-
- node->binding = binding;
-
sym(1).Node = node;
} break;
./
-UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer Semicolon;
+UiObjectMemberExpressionStatementLookahead: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer Semicolon;
/.
case $rule_number: {
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
@@ -1370,43 +1478,30 @@ UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatem
} break;
./
-UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer Semicolon;
+UiObjectMember: UiObjectMemberExpressionStatementLookahead;
+
+UiObjectMember: T_READONLY UiObjectMemberExpressionStatementLookahead;
/.
case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4));
+ AST::UiPublicMember *node = sym(2).UiPublicMember;
node->isReadonlyMember = true;
node->readonlyToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->semicolonToken = loc(5); // insert a fake ';' before ':'
-
- AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4));
- propertyName->identifierToken = loc(4);
- propertyName->next = 0;
-
- AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
- propertyName, sym(7).UiQualifiedId, sym(8).UiObjectInitializer);
- binding->colonToken = loc(5);
-
- node->binding = binding;
-
sym(1).Node = node;
} break;
./
-UiObjectMember: FunctionDeclarationWithTypes;
+UiObjectMember: GeneratorDeclaration;
/.
case $rule_number: {
- sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
+ auto node = new (pool) AST::UiSourceElement(sym(1).Node);
+ sym(1).Node = node;
} break;
./
-UiObjectMember: GeneratorExpression;
+UiObjectMember: FunctionDeclarationWithTypes;
/.
case $rule_number: {
- auto node = new (pool) AST::UiSourceElement(sym(1).Node);
- sym(1).Node = node;
+ sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
} break;
./
@@ -1451,6 +1546,19 @@ UiObjectMember: T_ENUM T_IDENTIFIER T_LBRACE EnumMemberList T_RBRACE;
}
./
+UiObjectMember: T_COMPONENT T_IDENTIFIER T_COLON UiObjectDefinition;
+/.
+ case $rule_number: {
+ if (!stringRef(2).front().isUpper()) {
+ diagnostic_messages.append(compileError(loc(2),
+ QLatin1String("Type name must be upper case"), QtWarningMsg));
+ }
+ auto inlineComponent = new (pool) AST::UiInlineComponent(stringRef(2), sym(4).UiObjectDefinition);
+ inlineComponent->componentToken = loc(1);
+ sym(1).Node = inlineComponent;
+ } break;
+./
+
EnumMemberList: T_IDENTIFIER;
/.
case $rule_number: {
@@ -1493,27 +1601,31 @@ EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER T_EQ T_NUMERIC_LITERAL;
}
./
-QmlIdentifier: T_IDENTIFIER;
-QmlIdentifier: T_PROPERTY;
-QmlIdentifier: T_SIGNAL;
-QmlIdentifier: T_READONLY;
-QmlIdentifier: T_ON;
-QmlIdentifier: T_GET;
-QmlIdentifier: T_SET;
-QmlIdentifier: T_FROM;
-QmlIdentifier: T_OF;
-
-JsIdentifier: T_IDENTIFIER;
-JsIdentifier: T_PROPERTY;
-JsIdentifier: T_SIGNAL;
-JsIdentifier: T_READONLY;
-JsIdentifier: T_ON;
-JsIdentifier: T_GET;
-JsIdentifier: T_SET;
-JsIdentifier: T_FROM;
-JsIdentifier: T_STATIC;
-JsIdentifier: T_OF;
-JsIdentifier: T_AS;
+QmlIdentifier: T_IDENTIFIER
+ | T_PROPERTY
+ | T_SIGNAL
+ | T_READONLY
+ | T_ON
+ | T_GET
+ | T_SET
+ | T_FROM
+ | T_OF
+ | T_REQUIRED
+ | T_COMPONENT;
+
+JsIdentifier: T_IDENTIFIER
+ | T_PROPERTY
+ | T_SIGNAL
+ | T_READONLY
+ | T_ON
+ | T_GET
+ | T_SET
+ | T_FROM
+ | T_STATIC
+ | T_OF
+ | T_AS
+ | T_REQUIRED
+ | T_COMPONENT;
IdentifierReference: JsIdentifier;
BindingIdentifier: IdentifierReference;
@@ -2537,6 +2649,20 @@ RelationalExpression_In: RelationalExpression_In T_IN ShiftExpression;
} break;
./
+TypeAssertExpression_In: RelationalExpression_In T_AS Type;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+TypeAssertExpression: RelationalExpression T_AS Type;
+/.
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::As, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
+./
+
+RelationalExpression_In: TypeAssertExpression_In;
+RelationalExpression: TypeAssertExpression;
+
EqualityExpression_In: RelationalExpression_In;
EqualityExpression: RelationalExpression;
@@ -2648,13 +2774,48 @@ LogicalORExpression_In: LogicalORExpression_In T_OR_OR LogicalANDExpression_In;
} break;
./
+CoalesceExpression: LogicalORExpression;
+CoalesceExpression_In: LogicalORExpression_In;
-ConditionalExpression: LogicalORExpression;
-ConditionalExpression_In: LogicalORExpression_In;
+CoalesceExpression: CoalesceExpression T_QUESTION_QUESTION LogicalORExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+CoalesceExpression_In: CoalesceExpression_In T_QUESTION_QUESTION LogicalORExpression_In;
+/.
+ case $rule_number: {
+
+ auto *lhs = sym(1).Expression;
+ auto *rhs = sym(3).Expression;
+
+ // Check if lhs or rhs contain || or &&
+
+ if (lhs->binaryExpressionCast() != nullptr) {
+ auto *binaryExpr = lhs->binaryExpressionCast();
+ if (binaryExpr->op == QSOperator::And || binaryExpr->op == QSOperator::Or) {
+ syntaxError(binaryExpr->operatorToken, "Left-hand side may not contain || or &&");
+ return false;
+ }
+ }
-ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression;
+ if (rhs->binaryExpressionCast() != nullptr) {
+ auto *binaryExpr = rhs->binaryExpressionCast();
+ if (binaryExpr->op == QSOperator::And || binaryExpr->op == QSOperator::Or) {
+ syntaxError(binaryExpr->operatorToken, "Right-hand side may not contain || or &&");
+ return false;
+ }
+ }
+
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(lhs, QSOperator::Coalesce, rhs);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
+./
+
+ConditionalExpression: CoalesceExpression;
+ConditionalExpression_In: CoalesceExpression_In;
+
+ConditionalExpression: CoalesceExpression T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression;
/. case $rule_number: Q_FALLTHROUGH(); ./
-ConditionalExpression_In: LogicalORExpression_In T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression_In;
+ConditionalExpression_In: CoalesceExpression_In T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression_In;
/.
case $rule_number: {
AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, sym(3).Expression, sym(5).Expression);
@@ -2680,7 +2841,7 @@ AssignmentExpression_In: LeftHandSideExpression T_EQ AssignmentExpression_In;
case $rule_number: {
// need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral
if (AST::Pattern *p = sym(1).Expression->patternCast()) {
- AST::SourceLocation errorLoc;
+ SourceLocation errorLoc;
QString errorMsg;
if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) {
syntaxError(errorLoc, errorMsg);
@@ -3233,7 +3394,7 @@ ExpressionStatementLookahead: ;
int token = lookaheadToken(lexer);
if (token == T_LBRACE)
pushToken(T_FORCE_BLOCK);
- else if (token == T_FUNCTION || token == T_CLASS || token == T_LET || token == T_CONST)
+ else if (token == T_FUNCTION || token == T_FUNCTION_STAR || token == T_CLASS || token == T_LET || token == T_CONST)
pushToken(T_FORCE_DECLARATION);
} break;
./
@@ -3346,7 +3507,7 @@ IterationStatement: T_FOR T_LPAREN LeftHandSideExpression InOrOf Expression_In T
case $rule_number: {
// need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral
if (AST::Pattern *p = sym(3).Expression->patternCast()) {
- AST::SourceLocation errorLoc;
+ SourceLocation errorLoc;
QString errorMsg;
if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) {
syntaxError(errorLoc, errorMsg);
@@ -3981,27 +4142,14 @@ GeneratorRBrace: T_RBRACE;
} break;
./
-GeneratorDeclaration: Function T_STAR BindingIdentifier GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace;
-/.
- case $rule_number: {
- AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(3), sym(5).FormalParameterList, sym(8).StatementList);
- node->functionToken = loc(1);
- node->identifierToken = loc(3);
- node->lparenToken = loc(4);
- node->rparenToken = loc(6);
- node->lbraceToken = loc(7);
- node->rbraceToken = loc(9);
- node->isGenerator = true;
- sym(1).Node = node;
- } break;
-./
+FunctionStar: T_FUNCTION_STAR %prec REDUCE_HERE;
-GeneratorDeclaration_Default: GeneratorDeclaration;
-GeneratorDeclaration_Default: Function T_STAR GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace;
+GeneratorDeclaration: FunctionStar BindingIdentifier GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace;
/.
case $rule_number: {
- AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(QStringRef(), sym(4).FormalParameterList, sym(7).StatementList);
+ AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList);
node->functionToken = loc(1);
+ node->identifierToken = loc(2);
node->lparenToken = loc(3);
node->rparenToken = loc(5);
node->lbraceToken = loc(6);
@@ -4011,27 +4159,28 @@ GeneratorDeclaration_Default: Function T_STAR GeneratorLParen FormalParameters T
} break;
./
-GeneratorExpression: T_FUNCTION T_STAR BindingIdentifier GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace;
+GeneratorDeclaration_Default: GeneratorDeclaration;
+GeneratorDeclaration_Default: FunctionStar GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace;
/.
case $rule_number: {
- AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(3), sym(5).FormalParameterList, sym(8).StatementList);
+ AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(QStringRef(), sym(3).FormalParameterList, sym(6).StatementList);
node->functionToken = loc(1);
- if (!stringRef(3).isNull())
- node->identifierToken = loc(3);
- node->lparenToken = loc(4);
- node->rparenToken = loc(6);
- node->lbraceToken = loc(7);
- node->rbraceToken = loc(9);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ node->lbraceToken = loc(5);
+ node->rbraceToken = loc(7);
node->isGenerator = true;
sym(1).Node = node;
} break;
./
-GeneratorExpression: T_FUNCTION T_STAR GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace;
+GeneratorExpression: T_FUNCTION_STAR BindingIdentifier GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace;
/.
case $rule_number: {
- AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(4).FormalParameterList, sym(7).StatementList);
+ AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList);
node->functionToken = loc(1);
+ if (!stringRef(2).isNull())
+ node->identifierToken = loc(2);
node->lparenToken = loc(3);
node->rparenToken = loc(5);
node->lbraceToken = loc(6);
@@ -4041,6 +4190,20 @@ GeneratorExpression: T_FUNCTION T_STAR GeneratorLParen FormalParameters T_RPAREN
} break;
./
+GeneratorExpression: T_FUNCTION_STAR GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace;
+/.
+ case $rule_number: {
+ AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).StatementList);
+ node->functionToken = loc(1);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ node->lbraceToken = loc(5);
+ node->rbraceToken = loc(7);
+ node->isGenerator = true;
+ sym(1).Node = node;
+ } break;
+./
+
GeneratorBody: FunctionBody;
YieldExpression: T_YIELD;
@@ -4423,7 +4586,7 @@ ExportDeclarationLookahead: ;
/.
case $rule_number: {
int token = lookaheadToken(lexer);
- if (token == T_FUNCTION || token == T_CLASS)
+ if (token == T_FUNCTION || token == T_FUNCTION_STAR || token == T_CLASS)
pushToken(T_FORCE_DECLARATION);
} break;
./
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index b63b2191b9..2a34c5a66c 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -105,6 +105,12 @@ ClassExpression *Node::asClassDefinition()
return nullptr;
}
+bool Node::ignoreRecursionDepth() const
+{
+ static const bool doIgnore = qEnvironmentVariableIsSet("QV4_CRASH_ON_STACKOVERFLOW");
+ return doIgnore;
+}
+
ExpressionNode *ExpressionNode::expressionCast()
{
return this;
@@ -161,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);
@@ -179,7 +185,7 @@ ClassExpression *NestedExpression::asClassDefinition()
return expression->asClassDefinition();
}
-void ThisExpression::accept0(Visitor *visitor)
+void ThisExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -187,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)) {
}
@@ -195,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)) {
}
@@ -203,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)) {
}
@@ -211,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)) {
}
@@ -219,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)) {
}
@@ -228,7 +234,7 @@ void SuperLiteral::accept0(Visitor *visitor)
}
-void StringLiteral::accept0(Visitor *visitor)
+void StringLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -236,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) {
@@ -245,7 +251,7 @@ void TemplateLiteral::accept0(Visitor *visitor)
}
}
-void NumericLiteral::accept0(Visitor *visitor)
+void NumericLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -253,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)) {
}
@@ -261,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);
@@ -281,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);
@@ -456,7 +462,7 @@ bool PatternProperty::convertLiteralToAssignmentPattern(MemoryPool *pool, Source
}
-void Elision::accept0(Visitor *visitor)
+void Elision::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
// ###
@@ -465,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)) {
}
@@ -473,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)) {
}
@@ -481,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)) {
}
@@ -511,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);
@@ -521,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);
@@ -530,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);
@@ -540,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);
@@ -549,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);
@@ -559,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) {
@@ -570,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);
@@ -579,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);
@@ -588,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);
@@ -597,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);
@@ -606,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);
@@ -615,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);
@@ -624,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);
@@ -633,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);
@@ -642,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);
@@ -651,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);
@@ -660,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);
@@ -669,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);
@@ -679,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);
@@ -690,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);
@@ -700,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);
@@ -709,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) {
@@ -720,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);
@@ -729,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) {
@@ -740,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)) {
}
@@ -748,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);
@@ -757,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);
@@ -768,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);
@@ -778,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);
@@ -788,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);
@@ -801,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);
@@ -812,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)) {
}
@@ -820,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)) {
}
@@ -828,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);
@@ -837,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);
@@ -847,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);
@@ -857,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);
@@ -867,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);
@@ -878,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) {
@@ -889,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);
@@ -899,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);
@@ -908,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);
@@ -917,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);
@@ -926,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);
@@ -937,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);
@@ -947,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);
@@ -956,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);
@@ -967,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);
@@ -1012,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) {
@@ -1037,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);
@@ -1046,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)) {
@@ -1054,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) {
@@ -1065,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);
@@ -1074,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)) {
}
@@ -1082,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)) {
}
@@ -1090,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);
@@ -1100,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);
@@ -1110,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)) {
@@ -1119,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) {
@@ -1130,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);
@@ -1139,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);
@@ -1150,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);
@@ -1159,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)) {
}
@@ -1167,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);
@@ -1177,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);
}
@@ -1197,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);
@@ -1206,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);
@@ -1224,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);
}
@@ -1234,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);
}
@@ -1244,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)
@@ -1254,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)
@@ -1264,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);
@@ -1282,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)
@@ -1292,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);
@@ -1301,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)) {
}
@@ -1318,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) {
@@ -1331,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)) {
}
@@ -1357,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);
@@ -1367,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);
@@ -1390,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) {
@@ -1411,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);
@@ -1428,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) {
@@ -1445,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);
@@ -1454,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);
@@ -1469,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);
@@ -1479,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) {
@@ -1508,7 +1526,7 @@ LeftHandSideExpression *LeftHandSideExpression::leftHandSideExpressionCast()
return this;
}
-void UiVersionSpecifier::accept0(Visitor *visitor)
+void UiVersionSpecifier::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1539,6 +1557,44 @@ void Type::toString(QString *out) const
};
}
+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(BaseVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ }
+
+ 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 39194068bf..9eba432e69 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -104,6 +104,8 @@ enum Op {
URShift,
InplaceURightShift,
InplaceXor,
+ As,
+ Coalesce,
Invalid
};
@@ -242,6 +244,7 @@ public:
Kind_UiImport,
Kind_UiObjectBinding,
Kind_UiObjectDefinition,
+ Kind_UiInlineComponent,
Kind_UiObjectInitializer,
Kind_UiObjectMemberList,
Kind_UiArrayMemberList,
@@ -255,7 +258,10 @@ public:
Kind_UiHeaderItemList,
Kind_UiEnumDeclaration,
Kind_UiEnumMemberList,
- Kind_UiVersionSpecifier
+ Kind_UiVersionSpecifier,
+ Kind_UiRequired,
+ Kind_UiAnnotation,
+ Kind_UiAnnotationList
};
inline Node() {}
@@ -275,10 +281,16 @@ public:
virtual FunctionExpression *asFunctionDefinition();
virtual ClassExpression *asClassDefinition();
- inline void accept(Visitor *visitor)
+ bool ignoreRecursionDepth() const;
+
+ inline void accept(BaseVisitor *visitor)
{
- Visitor::RecursionDepthCheck recursionCheck(visitor);
- if (recursionCheck()) {
+ 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.
+ // Therefore, check for ignoreRecursionDepth() _after_ calling the inline recursionCheck().
+ if (recursionCheck() || ignoreRecursionDepth()) {
if (visitor->preVisit(this))
accept0(visitor);
visitor->postVisit(this);
@@ -287,19 +299,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;
@@ -307,6 +319,14 @@ public:
int kind = Kind_Undefined;
};
+template<typename T>
+T lastListElement(T head)
+{
+ auto current = head;
+ while (current->next)
+ current = current->next;
+ return current;
+}
class QML_PARSER_EXPORT UiQualifiedId: public Node
{
@@ -332,13 +352,13 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : identifierToken; }
+ { return lastListElement(this)->identifierToken; }
// attributes
UiQualifiedId *next;
@@ -356,7 +376,7 @@ public:
, typeArguments(typeArguments)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return typeId->firstSourceLocation(); }
@@ -391,13 +411,13 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return typeId->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : typeId->lastSourceLocation(); }
+ { return lastListElement(this)->typeId->lastSourceLocation(); }
inline TypeArgumentList *finish()
{
@@ -420,7 +440,7 @@ public:
: type(type)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return colonToken; }
@@ -465,7 +485,7 @@ public:
: expression(expression)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lparenToken; }
@@ -490,7 +510,7 @@ public:
ThisExpression() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return thisToken; }
@@ -510,7 +530,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; }
@@ -530,7 +550,7 @@ public:
NullExpression() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return nullToken; }
@@ -549,7 +569,7 @@ public:
TrueLiteral() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return trueToken; }
@@ -568,7 +588,7 @@ public:
FalseLiteral() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return falseToken; }
@@ -587,7 +607,7 @@ public:
SuperLiteral() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return superToken; }
@@ -608,7 +628,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; }
@@ -628,7 +648,7 @@ public:
UiVersionSpecifier(int majorum, int minorum) : majorVersion(majorum), minorVersion(minorum) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override { return majorToken; }
@@ -652,7 +672,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; }
@@ -678,9 +698,12 @@ public:
{ return literalToken; }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : (expression ? expression->lastSourceLocation() : literalToken); }
+ {
+ auto last = lastListElement(this);
+ return (last->expression ? last->expression->lastSourceLocation() : last->literalToken);
+ }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QStringRef value;
QStringRef rawValue;
@@ -697,7 +720,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; }
@@ -732,7 +755,7 @@ public:
: elements(elts)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbracketToken; }
@@ -763,7 +786,7 @@ public:
: properties(plist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbraceToken; }
@@ -794,13 +817,13 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return commaToken; }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : commaToken; }
+ { return lastListElement(this)->commaToken; }
inline Elision *finish ()
{
@@ -900,7 +923,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
@@ -953,7 +976,7 @@ public:
return front;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
void boundNames(BoundNames *names);
@@ -961,7 +984,10 @@ public:
{ return elision ? elision->firstSourceLocation() : element->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : (element ? element->lastSourceLocation() : elision->lastSourceLocation()); }
+ {
+ auto last = lastListElement(this);
+ return last->element ? last->element->lastSourceLocation() : last->elision->lastSourceLocation();
+ }
Elision *elision = nullptr;
PatternElement *element = nullptr;
@@ -985,7 +1011,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(); }
@@ -1021,7 +1047,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
void boundNames(BoundNames *names);
@@ -1036,13 +1062,13 @@ public:
{ return property->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : property->lastSourceLocation(); }
+ { return lastListElement(this)->property->lastSourceLocation(); }
PatternProperty *property;
PatternPropertyList *next;
};
-class QML_PARSER_EXPORT IdentifierPropertyName : public PropertyName
+class QML_PARSER_EXPORT IdentifierPropertyName: public PropertyName
{
public:
QQMLJS_DECLARE_AST_NODE(IdentifierPropertyName)
@@ -1050,7 +1076,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(); }
@@ -1066,7 +1092,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(); }
@@ -1082,7 +1108,7 @@ public:
NumericLiteralPropertyName(double n):
id (n) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QString asString() const override;
@@ -1099,7 +1125,7 @@ public:
: expression(expression)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QString asString() const override { return QString(); }
@@ -1123,7 +1149,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(); }
@@ -1147,7 +1173,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(); }
@@ -1171,7 +1197,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(); }
@@ -1193,7 +1219,7 @@ public:
base (b), arguments (a)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return newToken; }
@@ -1217,7 +1243,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; }
@@ -1239,7 +1265,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(); }
@@ -1271,7 +1297,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return expression->firstSourceLocation(); }
@@ -1305,7 +1331,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(); }
@@ -1326,7 +1352,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(); }
@@ -1347,7 +1373,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; }
@@ -1368,7 +1394,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; }
@@ -1389,7 +1415,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; }
@@ -1410,7 +1436,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; }
@@ -1431,7 +1457,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; }
@@ -1452,7 +1478,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; }
@@ -1473,7 +1499,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; }
@@ -1494,7 +1520,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; }
@@ -1515,7 +1541,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; }
@@ -1539,7 +1565,7 @@ public:
BinaryExpression *binaryExpressionCast() override;
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return left->firstSourceLocation(); }
@@ -1563,7 +1589,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(); }
@@ -1587,7 +1613,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(); }
@@ -1609,7 +1635,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; }
@@ -1639,13 +1665,15 @@ public:
return n;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return statement->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : statement->lastSourceLocation(); }
+ {
+ return lastListElement(this)->statement->lastSourceLocation();
+ }
inline StatementList *finish ()
{
@@ -1676,7 +1704,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return declaration->firstSourceLocation(); }
@@ -1714,7 +1742,7 @@ public:
declarations (vlist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return declarationKindToken; }
@@ -1734,7 +1762,7 @@ public:
EmptyStatement() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return semicolonToken; }
@@ -1754,13 +1782,13 @@ 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(); }
SourceLocation lastSourceLocation() const override
- { return expression->lastSourceLocation(); }
+ { return semicolonToken; }
// attributes
ExpressionNode *expression;
@@ -1776,7 +1804,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; }
@@ -1808,7 +1836,7 @@ public:
statement (stmt), expression (e)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return doToken; }
@@ -1835,7 +1863,7 @@ public:
expression (e), statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return whileToken; }
@@ -1865,7 +1893,7 @@ public:
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return forToken; }
@@ -1903,7 +1931,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; }
@@ -1934,7 +1962,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; }
@@ -1957,7 +1985,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; }
@@ -1980,7 +2008,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; }
@@ -2002,7 +2030,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; }
@@ -2025,7 +2053,7 @@ public:
expression (e), statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return withToken; }
@@ -2050,7 +2078,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; }
@@ -2075,7 +2103,7 @@ public:
expression (e), block (b)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return switchToken; }
@@ -2100,7 +2128,7 @@ public:
expression (e), statements (slist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return caseToken; }
@@ -2132,13 +2160,15 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return clause->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : clause->lastSourceLocation(); }
+ {
+ return lastListElement(this)->clause->lastSourceLocation();
+ }
inline CaseClauses *finish ()
{
@@ -2161,7 +2191,7 @@ public:
statements (slist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return defaultToken; }
@@ -2184,7 +2214,7 @@ public:
label (l), statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
@@ -2207,7 +2237,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; }
@@ -2230,7 +2260,7 @@ public:
: patternElement(p), statement(stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return catchToken; }
@@ -2256,7 +2286,7 @@ public:
statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return finallyToken; }
@@ -2286,7 +2316,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; }
@@ -2318,7 +2348,7 @@ public:
typeAnnotation(typeAnnotation)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return functionToken; }
@@ -2352,7 +2382,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
@@ -2423,13 +2453,15 @@ public:
BoundNames boundNames() const;
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return element->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : element->lastSourceLocation(); }
+ {
+ return lastListElement(this)->element->lastSourceLocation();
+ }
FormalParameterList *finish(MemoryPool *pool);
@@ -2447,7 +2479,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; }
@@ -2476,7 +2508,7 @@ public:
: ClassExpression(n, heritage, elements)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
};
@@ -2498,7 +2530,7 @@ public:
return n;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return property->firstSourceLocation(); }
@@ -2526,7 +2558,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(); }
@@ -2555,7 +2587,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifier.isNull() ? importedBindingToken : identifierToken; }
@@ -2600,13 +2632,15 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return importSpecifierToken; }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : importSpecifierToken; }
+ {
+ return lastListElement(this)->importSpecifierToken;
+ }
// attributes
SourceLocation importSpecifierToken;
@@ -2630,7 +2664,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return leftBraceToken; }
@@ -2654,7 +2688,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
virtual SourceLocation firstSourceLocation() const override
{ return starToken; }
@@ -2704,7 +2738,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; }
@@ -2729,7 +2763,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return fromToken; }
@@ -2760,7 +2794,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return importToken; }
@@ -2793,7 +2827,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
@@ -2838,12 +2872,12 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return exportSpecifier->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : exportSpecifier->lastSourceLocation(); }
+ { return lastListElement(this)->exportSpecifier->lastSourceLocation(); }
// attributes
ExportSpecifier *exportSpecifier;
@@ -2866,7 +2900,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return leftBraceToken; }
@@ -2910,7 +2944,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return exportToken; }
@@ -2937,7 +2971,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return body ? body->firstSourceLocation() : SourceLocation(); }
@@ -2957,7 +2991,7 @@ public:
DebuggerStatement()
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return debuggerToken; }
@@ -2983,7 +3017,7 @@ public:
: importUri(uri)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return importToken; }
@@ -2997,7 +3031,6 @@ public:
QStringRef importId;
SourceLocation importToken;
SourceLocation fileNameToken;
- SourceLocation versionToken;
SourceLocation asToken;
SourceLocation importIdToken;
SourceLocation semicolonToken;
@@ -3011,6 +3044,9 @@ public:
SourceLocation lastSourceLocation() const override = 0;
UiObjectMember *uiObjectMemberCast() override;
+
+// attributes
+ UiAnnotationList *annotations = nullptr;
};
class QML_PARSER_EXPORT UiObjectMemberList: public Node
@@ -3030,13 +3066,13 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return member->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : member->lastSourceLocation(); }
+ { return lastListElement(this)->member->lastSourceLocation(); }
UiObjectMemberList *finish()
{
@@ -3059,7 +3095,7 @@ public:
: name(name)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return pragmaToken; }
@@ -3073,6 +3109,28 @@ public:
SourceLocation semicolonToken;
};
+class QML_PARSER_EXPORT UiRequired: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(UiRequired)
+
+ UiRequired(QStringRef name)
+ :name(name)
+ { kind = K; }
+
+ void accept0(BaseVisitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return requiredToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return semicolonToken; }
+
+ QStringRef name;
+ SourceLocation requiredToken;
+ SourceLocation semicolonToken;
+};
+
class QML_PARSER_EXPORT UiHeaderItemList: public Node
{
public:
@@ -3109,13 +3167,13 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return headerItem->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : headerItem->lastSourceLocation(); }
+ { return lastListElement(this)->headerItem->lastSourceLocation(); }
// attributes
Node *headerItem;
@@ -3131,7 +3189,7 @@ public:
: headers(headers), members(members)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{
@@ -3173,13 +3231,13 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return member->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : member->lastSourceLocation(); }
+ { return lastListElement(this)->member->lastSourceLocation(); }
UiArrayMemberList *finish()
{
@@ -3203,7 +3261,7 @@ public:
: members(members)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbraceToken; }
@@ -3234,13 +3292,16 @@ public:
previous->next = this;
}
- void accept0(Visitor *) override;
+ void accept0(BaseVisitor *) override;
SourceLocation firstSourceLocation() const override
{ return colonToken.isValid() ? identifierToken : propertyTypeToken; }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : (colonToken.isValid() ? propertyTypeToken : identifierToken); }
+ {
+ auto last = lastListElement(this);
+ return (last->colonToken.isValid() ? last->propertyTypeToken : last->identifierToken);
+ }
inline UiParameterList *finish ()
{
@@ -3275,7 +3336,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
{
@@ -3283,6 +3344,8 @@ public:
return defaultToken;
else if (readonlyToken.isValid())
return readonlyToken;
+ else if (requiredToken.isValid())
+ return requiredToken;
return propertyToken;
}
@@ -3306,10 +3369,13 @@ public:
UiObjectMember *binding; // initialized with a QML object or array.
bool isDefaultMember;
bool isReadonlyMember;
+ bool isRequired = false;
UiParameterList *parameters;
+ // TODO: merge source locations
SourceLocation defaultToken;
SourceLocation readonlyToken;
SourceLocation propertyToken;
+ SourceLocation requiredToken;
SourceLocation typeModifierToken;
SourceLocation typeToken;
SourceLocation identifierToken;
@@ -3327,7 +3393,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; }
@@ -3340,6 +3406,29 @@ public:
UiObjectInitializer *initializer;
};
+class QML_PARSER_EXPORT UiInlineComponent: public UiObjectMember
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(UiInlineComponent)
+
+ UiInlineComponent(const QStringRef& inlineComponentName, UiObjectDefinition* inlineComponent)
+ : name(inlineComponentName), component(inlineComponent)
+ { kind = K; }
+
+ SourceLocation lastSourceLocation() const override
+ {return component->lastSourceLocation();}
+
+ SourceLocation firstSourceLocation() const override
+ {return componentToken;}
+
+ void accept0(BaseVisitor *visitor) override;
+
+ // attributes
+ QStringRef name;
+ UiObjectDefinition* component;
+ SourceLocation componentToken;
+};
+
class QML_PARSER_EXPORT UiSourceElement: public UiObjectMember
{
public:
@@ -3369,7 +3458,7 @@ public:
return SourceLocation();
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
@@ -3401,7 +3490,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return initializer->rbraceToken; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
@@ -3429,7 +3518,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return statement->lastSourceLocation(); }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
UiQualifiedId *qualifiedId;
@@ -3454,7 +3543,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return rbracketToken; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
UiQualifiedId *qualifiedId;
@@ -3493,10 +3582,12 @@ public:
{ return memberToken; }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() :
- valueToken.isValid() ? valueToken : memberToken; }
+ {
+ auto last = lastListElement(this);
+ return last->valueToken.isValid() ? last->valueToken : last->memberToken;
+ }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
UiEnumMemberList *finish()
{
@@ -3530,7 +3621,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return rbraceToken; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
SourceLocation enumToken;
@@ -3539,8 +3630,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 05226fd043..ef37e8072f 100644
--- a/src/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/parser/qqmljsastfwd_p.h
@@ -41,7 +41,7 @@
#define QQMLJSAST_FWD_P_H
#include "qqmljsglobal_p.h"
-#include "qqmljssourcelocation_p.h"
+#include <private/qqmljssourcelocation_p.h>
#include <QtCore/qglobal.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;
@@ -169,6 +169,7 @@ class UiImport;
class UiPublicMember;
class UiParameterList;
class UiObjectDefinition;
+class UiInlineComponent;
class UiObjectInitializer;
class UiObjectBinding;
class UiScriptBinding;
@@ -182,6 +183,9 @@ class UiHeaderItemList;
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 7146cd00ac..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,333 +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 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 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(TypeAnnotation *) = 0;
+ virtual void endVisit(TypeAnnotation *) = 0;
virtual void throwRecursionDepthError() = 0;
@@ -421,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/parser/qqmljsengine_p.cpp b/src/qml/parser/qqmljsengine_p.cpp
index bb27f3992e..cb6b0375e6 100644
--- a/src/qml/parser/qqmljsengine_p.cpp
+++ b/src/qml/parser/qqmljsengine_p.cpp
@@ -123,9 +123,9 @@ void Engine::setCode(const QString &code)
{ _code = code; }
void Engine::addComment(int pos, int len, int line, int col)
-{ if (len > 0) _comments.append(QQmlJS::AST::SourceLocation(pos, len, line, col)); }
+{ if (len > 0) _comments.append(QQmlJS::SourceLocation(pos, len, line, col)); }
-QList<QQmlJS::AST::SourceLocation> Engine::comments() const
+QList<QQmlJS::SourceLocation> Engine::comments() const
{ return _comments; }
Lexer *Engine::lexer() const
diff --git a/src/qml/parser/qqmljsengine_p.h b/src/qml/parser/qqmljsengine_p.h
index 8a3e2db6a1..a34922fa1e 100644
--- a/src/qml/parser/qqmljsengine_p.h
+++ b/src/qml/parser/qqmljsengine_p.h
@@ -52,7 +52,7 @@
//
#include "qqmljsglobal_p.h"
-#include "qqmljssourcelocation_p.h"
+#include <private/qqmljssourcelocation_p.h>
#include <private/qqmljsmemorypool_p.h>
@@ -97,7 +97,7 @@ class QML_PARSER_EXPORT Engine
Lexer *_lexer;
Directives *_directives;
MemoryPool _pool;
- QList<AST::SourceLocation> _comments;
+ QList<SourceLocation> _comments;
QString _extraCode;
QString _code;
@@ -109,7 +109,7 @@ public:
const QString &code() const { return _code; }
void addComment(int pos, int len, int line, int col);
- QList<AST::SourceLocation> comments() const;
+ QList<SourceLocation> comments() const;
Lexer *lexer() const;
void setLexer(Lexer *lexer);
diff --git a/src/qml/parser/qqmljskeywords_p.h b/src/qml/parser/qqmljskeywords_p.h
index 96b3709162..5f08cc4353 100644
--- a/src/qml/parser/qqmljskeywords_p.h
+++ b/src/qml/parser/qqmljskeywords_p.h
@@ -743,6 +743,18 @@ static inline int classify8(const QChar *s, int parseModeFlags) {
}
}
}
+ } else if (s[2].unicode() == 'q') {
+ if (s[3].unicode() == 'u') {
+ if (s[4].unicode() == 'i') {
+ if (s[5].unicode() == 'r') {
+ if (s[6].unicode() == 'e') {
+ if (s[7].unicode() == 'd') {
+ return Lexer::T_REQUIRED;
+ }
+ }
+ }
+ }
+ }
}
}
}
@@ -824,6 +836,25 @@ static inline int classify9(const QChar *s, int parseModeFlags) {
}
}
}
+ else if (s[0].unicode() == 'c') {
+ if (s[1].unicode() == 'o') {
+ if (s[2].unicode() == 'm') {
+ if (s[3].unicode() == 'p') {
+ if (s[4].unicode() == 'o') {
+ if (s[5].unicode() == 'n') {
+ if (s[6].unicode() == 'e') {
+ if (s[7].unicode() == 'n') {
+ if (s[8].unicode() == 't') {
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_COMPONENT) : int(Lexer::T_IDENTIFIER);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
return Lexer::T_IDENTIFIER;
}
diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp
index 1e0ac72bd1..243fc5bd30 100644
--- a/src/qml/parser/qqmljslexer.cpp
+++ b/src/qml/parser/qqmljslexer.cpp
@@ -492,6 +492,42 @@ int Lexer::scanToken()
again:
_validTokenText = false;
+ // handle comment can be called after a '/' has been read
+ // and returns true if it actually encountered a comment
+ auto handleComment = [this](){
+ if (_char == QLatin1Char('*')) {
+ scanChar();
+ while (_codePtr <= _endPtr) {
+ if (_char == QLatin1Char('*')) {
+ scanChar();
+ if (_char == QLatin1Char('/')) {
+ scanChar();
+
+ if (_engine) {
+ _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 4,
+ tokenStartLine(), tokenStartColumn() + 2);
+ }
+
+ return true;
+ }
+ } else {
+ scanChar();
+ }
+ }
+ } else if (_char == QLatin1Char('/')) {
+ while (_codePtr <= _endPtr && !isLineTerminator()) {
+ scanChar();
+ }
+ if (_engine) {
+ _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 2,
+ tokenStartLine(), tokenStartColumn() + 2);
+ }
+ return true;
+ }
+ return false;
+ };
+
+
while (_char.isSpace()) {
if (isLineTerminator()) {
if (_restrictedKeyword) {
@@ -544,7 +580,14 @@ again:
case ']': return T_RBRACKET;
case '[': return T_LBRACKET;
- case '?': return T_QUESTION;
+ case '?': {
+ if (_char == QLatin1Char('?')) {
+ scanChar();
+ return T_QUESTION_QUESTION;
+ }
+
+ return T_QUESTION;
+ }
case '>':
if (_char == QLatin1Char('>')) {
@@ -599,35 +642,9 @@ again:
case ':': return T_COLON;
case '/':
- if (_char == QLatin1Char('*')) {
- scanChar();
- while (_codePtr <= _endPtr) {
- if (_char == QLatin1Char('*')) {
- scanChar();
- if (_char == QLatin1Char('/')) {
- scanChar();
-
- if (_engine) {
- _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 4,
- tokenStartLine(), tokenStartColumn() + 2);
- }
-
- goto again;
- }
- } else {
- scanChar();
- }
- }
- } else if (_char == QLatin1Char('/')) {
- while (_codePtr <= _endPtr && !isLineTerminator()) {
- scanChar();
- }
- if (_engine) {
- _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 2,
- tokenStartLine(), tokenStartColumn() + 2);
- }
+ if (handleComment())
goto again;
- } if (_char == QLatin1Char('=')) {
+ else if (_char == QLatin1Char('=')) {
scanChar();
return T_DIVIDE_EQ;
}
@@ -702,6 +719,8 @@ again:
case ')': return T_RPAREN;
case '(': return T_LPAREN;
+ case '@': return T_AT;
+
case '&':
if (_char == QLatin1Char('=')) {
scanChar();
@@ -829,6 +848,21 @@ again:
if (!identifierWithEscapeChars)
kind = classify(_tokenStartPtr, _tokenLength, parseModeFlags());
+ if (kind == T_FUNCTION) {
+ continue_skipping:
+ while (_codePtr < _endPtr && _char.isSpace())
+ scanChar();
+ if (_char == QLatin1Char('*')) {
+ _tokenLength = _codePtr - _tokenStartPtr - 1;
+ kind = T_FUNCTION_STAR;
+ scanChar();
+ } else if (_char == QLatin1Char('/')) {
+ scanChar();
+ if (handleComment())
+ goto continue_skipping;
+ }
+ }
+
if (_engine) {
if (kind == T_IDENTIFIER && identifierWithEscapeChars)
_tokenSpell = _engine->newStringRef(_tokenText);
@@ -1407,6 +1441,7 @@ static const int uriTokens[] = {
QQmlJSGrammar::T_FINALLY,
QQmlJSGrammar::T_FOR,
QQmlJSGrammar::T_FUNCTION,
+ QQmlJSGrammar::T_FUNCTION_STAR,
QQmlJSGrammar::T_IF,
QQmlJSGrammar::T_IN,
QQmlJSGrammar::T_OF,
@@ -1445,8 +1480,8 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
{
auto setError = [error, this](QString message) {
error->message = std::move(message);
- error->line = tokenStartLine();
- error->column = tokenStartColumn();
+ error->loc.startLine = tokenStartLine();
+ error->loc.startColumn = tokenStartColumn();
};
QScopedValueRollback<bool> directivesGuard(_handlingDirectives, true);
@@ -1561,8 +1596,8 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
else
setError(QCoreApplication::translate("QQmlParser", "Module import requires a qualifier"));
if (tokenStartLine() != lineNumber) {
- error->line = lineNumber;
- error->line = column;
+ error->loc.startLine = lineNumber;
+ error->loc.startColumn = column;
}
return false; // expected `as'
}
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index 2cbe8ec564..e39a8319b6 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -39,6 +39,7 @@ greaterThan(QT_CLANG_MAJOR_VERSION, 3)|greaterThan(QT_CLANG_MINOR_VERSION, 3)| \
WERROR += -Wno-error=unused-const-variable
HEADERS += qtqmlglobal.h \
+ inlinecomponentutils_p.h \
qtqmlglobal_p.h \
qtqmlcompilerglobal.h \
qtqmlcompilerglobal_p.h
@@ -66,4 +67,11 @@ include(../3rdparty/masm/masm.pri)
MODULE_PLUGIN_TYPES = \
qmltooling
+
+QMLTYPES_FILENAME = plugins.qmltypes
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml
+QML_IMPORT_NAME = QtQml
+IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+CONFIG += qmltypes install_qmltypes install_metatypes
+
load(qt_module)
diff --git a/src/qml/qml/ftw/qhashedstring.cpp b/src/qml/qml/ftw/qhashedstring.cpp
index 7a8fdd0a14..6c58ab87f4 100644
--- a/src/qml/qml/ftw/qhashedstring.cpp
+++ b/src/qml/qml/ftw/qhashedstring.cpp
@@ -102,6 +102,25 @@ QHashedStringRef QHashedStringRef::mid(int offset, int length) const
(length == -1 || (offset + length) > m_length)?(m_length - offset):length);
}
+QVector<QHashedStringRef> QHashedStringRef::split(const QChar sep) const
+{
+ QVector<QHashedStringRef> ret;
+ auto curLength = 0;
+ auto curOffset = m_data;
+ for (int offset = 0; offset < m_length; ++offset) {
+ if (*(m_data + offset) == sep) {
+ ret.push_back({curOffset, curLength});
+ curOffset = m_data + offset + 1;
+ curLength = 0;
+ } else {
+ ++curLength;
+ }
+ }
+ if (curLength > 0)
+ ret.push_back({curOffset, curLength});
+ return ret;
+}
+
bool QHashedStringRef::endsWith(const QString &s) const
{
return s.length() < m_length &&
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index b9f3f81219..a2e10ff143 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -125,6 +125,7 @@ public:
bool endsWith(const QString &) const;
int indexOf(const QChar &, int from=0) const;
QHashedStringRef mid(int, int) const;
+ QVector<QHashedStringRef> split(const QChar sep) const;
inline bool isEmpty() const;
inline int length() const;
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index 2e9c6f3de6..a16f3d4167 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -3,6 +3,7 @@ SOURCES += \
$$PWD/qqmldatablob.cpp \
$$PWD/qqmldirdata.cpp \
$$PWD/qqmlerror.cpp \
+ $$PWD/qqmlmoduleregistration.cpp \
$$PWD/qqmlopenmetaobject.cpp \
$$PWD/qqmlscriptblob.cpp \
$$PWD/qqmlscriptdata.cpp \
@@ -71,6 +72,7 @@ HEADERS += \
$$PWD/qqmldatablob_p.h \
$$PWD/qqmldirdata_p.h \
$$PWD/qqmlglobal_p.h \
+ $$PWD/qqmlmoduleregistration.h \
$$PWD/qqmlopenmetaobject_p.h \
$$PWD/qqmlscriptblob_p.h \
$$PWD/qqmlscriptdata_p.h \
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 5b16a3c9e2..fe4e2f4e55 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>
@@ -61,7 +62,7 @@ void qmlClearTypeRegistrations() // Declared in qqml.h
//From qqml.h
bool qmlProtectModule(const char *uri, int majVersion)
{
- return QQmlMetaType::protectModule(uri, majVersion);
+ return QQmlMetaType::protectModule(QString::fromUtf8(uri), majVersion);
}
//From qqml.h
@@ -103,33 +104,188 @@ QObject *QQmlPrivate::RegisterSingletonFunctor::operator()(QQmlEngine *qeng, QJS
return m_object;
};
+static QVector<int> availableRevisions(const QMetaObject *metaObject)
+{
+ QVector<int> revisions;
+ if (!metaObject)
+ return revisions;
+ const int propertyOffset = metaObject->propertyOffset();
+ const int propertyCount = metaObject->propertyCount();
+ for (int propertyIndex = propertyOffset, propertyEnd = propertyOffset + propertyCount;
+ propertyIndex < propertyEnd; ++propertyIndex) {
+ const QMetaProperty property = metaObject->property(propertyIndex);
+ if (int revision = property.revision())
+ revisions.append(revision);
+ }
+ const int methodOffset = metaObject->methodOffset();
+ const int methodCount = metaObject->methodCount();
+ for (int methodIndex = methodOffset, methodEnd = methodOffset + methodCount;
+ methodIndex < methodEnd; ++methodIndex) {
+ const QMetaMethod method = metaObject->method(methodIndex);
+ if (int revision = method.revision())
+ revisions.append(revision);
+ }
+
+ // Need to also check parent meta objects, as their revisions are inherited.
+ if (const QMetaObject *superMeta = metaObject->superClass())
+ revisions += availableRevisions(superMeta);
+
+ return revisions;
+}
+
/*
This method is "over generalized" to allow us to (potentially) register more types of things in
the future without adding exported symbols.
*/
int QQmlPrivate::qmlregister(RegistrationType type, void *data)
{
- if (type == AutoParentRegistration) {
+ QQmlType dtype;
+ switch (type) {
+ case AutoParentRegistration:
return QQmlMetaType::registerAutoParentFunction(
*reinterpret_cast<RegisterAutoParent *>(data));
- } else if (type == QmlUnitCacheHookRegistration) {
+ case QmlUnitCacheHookRegistration:
return QQmlMetaType::registerUnitCacheHook(
*reinterpret_cast<RegisterQmlUnitCacheHook *>(data));
+ case TypeAndRevisionsRegistration: {
+ const RegisterTypeAndRevisions &type = *reinterpret_cast<RegisterTypeAndRevisions *>(data);
+ const char *elementName = classElementName(type.classInfoMetaObject);
+ const bool creatable = (elementName != nullptr)
+ && boolClassInfo(type.classInfoMetaObject, "QML.Creatable", true);
+
+ const QString noCreateReason = creatable
+ ? QString()
+ : QString::fromUtf8(classInfo(type.classInfoMetaObject, "QML.UncreatableReason"));
+ RegisterType revisionRegistration = {
+ 1,
+ type.typeId,
+ type.listId,
+ creatable ? type.objectSize : 0,
+ nullptr,
+ noCreateReason,
+ type.uri,
+ type.versionMajor,
+ -1,
+ nullptr,
+ type.metaObject,
+ type.attachedPropertiesFunction,
+ type.attachedPropertiesMetaObject,
+ type.parserStatusCast,
+ type.valueSourceCast,
+ type.valueInterceptorCast,
+ type.extensionObjectCreate,
+ type.extensionMetaObject,
+ nullptr,
+ -1
+ };
+
+ const int added = intClassInfo(type.classInfoMetaObject, "QML.AddedInMinorVersion", 0);
+ const int removed = intClassInfo(type.classInfoMetaObject, "QML.RemovedInMinorVersion", -1);
+
+ auto revisions = availableRevisions(type.metaObject);
+ revisions.append(qMax(added, 0));
+ if (type.attachedPropertiesMetaObject)
+ revisions += availableRevisions(type.attachedPropertiesMetaObject);
+
+ std::sort(revisions.begin(), revisions.end());
+ const auto it = std::unique(revisions.begin(), revisions.end());
+ revisions.erase(it, revisions.end());
+
+ const bool typeWasRemoved = removed >= added;
+ for (int revision : revisions) {
+ if (revision < added)
+ continue;
+
+ // When removed, we still add revisions, but anonymous ones
+ if (typeWasRemoved && revision >= removed) {
+ revisionRegistration.elementName = nullptr;
+ revisionRegistration.create = nullptr;
+ } else {
+ revisionRegistration.elementName = elementName;
+ revisionRegistration.create = creatable ? type.create : nullptr;
+ }
+
+ // Equivalent of qmlRegisterRevision<T, revision>(...)
+ revisionRegistration.versionMinor = revision;
+ revisionRegistration.revision = revision;
+ revisionRegistration.customParser = type.customParserFactory();
+
+ qmlregister(TypeRegistration, &revisionRegistration);
+ }
+ break;
}
+ case SingletonAndRevisionsRegistration: {
+ const RegisterSingletonTypeAndRevisions &type
+ = *reinterpret_cast<RegisterSingletonTypeAndRevisions *>(data);
+ const char *elementName = classElementName(type.classInfoMetaObject);
+ RegisterSingletonType revisionRegistration = {
+ QmlCurrentSingletonTypeRegistrationVersion,
+ type.uri,
+ type.versionMajor,
+ -1,
+ elementName,
- QQmlType dtype;
- if (type == TypeRegistration)
+ type.scriptApi,
+ nullptr,
+ type.instanceMetaObject,
+ type.typeId,
+ -1,
+
+ type.generalizedQobjectApi
+ };
+
+ const int added = intClassInfo(type.classInfoMetaObject, "QML.AddedInMinorVersion", 0);
+ const int removed = intClassInfo(type.classInfoMetaObject, "QML.RemovedInMinorVersion", -1);
+
+ auto revisions = availableRevisions(type.instanceMetaObject);
+ revisions.append(qMax(added, 0));
+
+ std::sort(revisions.begin(), revisions.end());
+ const auto it = std::unique(revisions.begin(), revisions.end());
+ revisions.erase(it, revisions.end());
+
+ const bool typeWasRemoved = removed >= added;
+ for (int revision : qAsConst(revisions)) {
+ if (revision < added)
+ continue;
+
+ // When removed, we still add revisions, but anonymous ones
+ if (typeWasRemoved && revision >= removed) {
+ revisionRegistration.typeName = nullptr;
+ revisionRegistration.scriptApi = nullptr;
+ revisionRegistration.generalizedQobjectApi = nullptr;
+ } else {
+ revisionRegistration.typeName = elementName;
+ revisionRegistration.scriptApi = type.scriptApi;
+ revisionRegistration.generalizedQobjectApi = type.generalizedQobjectApi;
+ }
+
+ // Equivalent of qmlRegisterRevision<T, revision>(...)
+ revisionRegistration.versionMinor = revision;
+ revisionRegistration.revision = revision;
+
+ qmlregister(SingletonRegistration, &revisionRegistration);
+ }
+ break;
+ }
+ case TypeRegistration:
dtype = QQmlMetaType::registerType(*reinterpret_cast<RegisterType *>(data));
- else if (type == InterfaceRegistration)
+ break;
+ case InterfaceRegistration:
dtype = QQmlMetaType::registerInterface(*reinterpret_cast<RegisterInterface *>(data));
- else if (type == SingletonRegistration)
+ break;
+ case SingletonRegistration:
dtype = QQmlMetaType::registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data));
- else if (type == CompositeRegistration)
+ break;
+ case CompositeRegistration:
dtype = QQmlMetaType::registerCompositeType(*reinterpret_cast<RegisterCompositeType *>(data));
- else if (type == CompositeSingletonRegistration)
+ break;
+ case CompositeSingletonRegistration:
dtype = QQmlMetaType::registerCompositeSingletonType(*reinterpret_cast<RegisterCompositeSingletonType *>(data));
- else
+ break;
+ default:
return -1;
+ }
if (!dtype.isValid())
return -1;
@@ -155,6 +311,50 @@ void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data)
case CompositeSingletonRegistration:
QQmlMetaType::unregisterType(data);
break;
+ case TypeAndRevisionsRegistration:
+ case SingletonAndRevisionsRegistration:
+ // Currently unnecessary. We'd need a special data structure to hold
+ // URI + majorVersion and then we'd iterate the minor versions, look up the
+ // associated QQmlType objects by uri/elementName/major/minor and qmlunregister
+ // each of them.
+ Q_UNREACHABLE();
+ break;
+ }
+}
+
+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,
+ 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);
}
}
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 8b7457d471..5ea1d17478 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -41,9 +41,6 @@
#define QQML_H
#include <QtQml/qqmlprivate.h>
-#include <QtQml/qqmlparserstatus.h>
-#include <QtQml/qqmlpropertyvaluesource.h>
-#include <QtQml/qqmllist.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qmetaobject.h>
@@ -51,6 +48,12 @@
#define QML_VERSION 0x020000
#define QML_VERSION_STR "2.0"
+#define QML_PRIVATE_NAMESPACE \
+ QT_PREPEND_NAMESPACE(QQmlPrivate)
+
+#define QML_REGISTER_TYPES_AND_REVISIONS \
+ QT_PREPEND_NAMESPACE(qmlRegisterTypesAndRevisions)
+
#define QML_DECLARE_TYPE(TYPE) \
Q_DECLARE_METATYPE(TYPE *) \
Q_DECLARE_METATYPE(QQmlListProperty<TYPE>)
@@ -64,6 +67,62 @@
#define QML_DECLARE_INTERFACE_HASMETATYPE(INTERFACE) \
QML_DECLARE_TYPE_HASMETATYPE(INTERFACE)
+#define QML_ELEMENT \
+ Q_CLASSINFO("QML.Element", "auto")
+
+#define QML_ANONYMOUS \
+ Q_CLASSINFO("QML.Element", "anonymous")
+
+#define QML_NAMED_ELEMENT(NAME) \
+ Q_CLASSINFO("QML.Element", #NAME)
+
+#define QML_UNCREATABLE(REASON) \
+ Q_CLASSINFO("QML.Creatable", "false") \
+ Q_CLASSINFO("QML.UncreatableReason", REASON)
+
+#define QML_SINGLETON \
+ Q_CLASSINFO("QML.Singleton", "true") \
+ enum class QmlIsSingleton {yes = true}; \
+ template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSingleton; \
+ template<typename T, typename... Args> \
+ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
+
+#define QML_ADDED_IN_MINOR_VERSION(VERSION) \
+ Q_CLASSINFO("QML.AddedInMinorVersion", #VERSION)
+
+#define QML_REMOVED_IN_MINOR_VERSION(VERSION) \
+ Q_CLASSINFO("QML.RemovedInMinorVersion", #VERSION)
+
+#define QML_ATTACHED(ATTACHED_TYPE) \
+ Q_CLASSINFO("QML.Attached", #ATTACHED_TYPE) \
+ using QmlAttachedType = ATTACHED_TYPE; \
+ template<class, class, bool> friend struct QML_PRIVATE_NAMESPACE::QmlAttached; \
+ template<class> friend struct QML_PRIVATE_NAMESPACE::QmlAttachedAccessor;
+
+#define QML_EXTENDED(EXTENDED_TYPE) \
+ Q_CLASSINFO("QML.Extended", #EXTENDED_TYPE) \
+ using QmlExtendedType = EXTENDED_TYPE; \
+ template<class, class> friend struct QML_PRIVATE_NAMESPACE::QmlExtended; \
+ template<typename T, typename... Args> \
+ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
+
+#define QML_FOREIGN(FOREIGN_TYPE) \
+ Q_CLASSINFO("QML.Foreign", #FOREIGN_TYPE) \
+ using QmlForeignType = FOREIGN_TYPE; \
+ template<class, class> friend struct QML_PRIVATE_NAMESPACE::QmlResolved; \
+ 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
};
@@ -82,25 +141,11 @@ QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
-
-class QQmlPropertyValueInterceptor;
-
-#define QML_GETTYPENAMES \
- const char *className = T::staticMetaObject.className(); \
- const int nameLen = int(strlen(className)); \
- QVarLengthArray<char,48> pointerName(nameLen+2); \
- memcpy(pointerName.data(), className, size_t(nameLen)); \
- pointerName[nameLen] = '*'; \
- pointerName[nameLen+1] = '\0'; \
- const int listLen = int(strlen("QQmlListProperty<")); \
- QVarLengthArray<char,64> listName(listLen + nameLen + 2); \
- memcpy(listName.data(), "QQmlListProperty<", size_t(listLen)); \
- memcpy(listName.data()+listLen, className, size_t(nameLen)); \
- listName[listLen+nameLen] = '>'; \
- listName[listLen+nameLen+1] = '\0';
-
void Q_QML_EXPORT qmlClearTypeRegistrations();
+template<class T>
+QQmlCustomParser *qmlCreateCustomParser();
+
template<typename T>
int qmlRegisterAnonymousType(const char *uri, int versionMajor)
{
@@ -141,7 +186,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)
@@ -380,9 +426,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
@@ -395,7 +440,7 @@ int qmlRegisterExtendedType()
nullptr,
QString(),
- nullptr, 0, 0, nullptr, &T::staticMetaObject,
+ uri, versionMajor, 0, nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -413,6 +458,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)
@@ -452,7 +506,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);
@@ -461,12 +517,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 *>(),
+ "",
+ 0
+ };
+
+ 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,
+ versionMajor
};
return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface);
@@ -733,6 +810,85 @@ 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, bool Interface>
+struct QmlTypeAndRevisionsRegistration;
+
+template<class T, class Resolved, class Extended>
+struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> {
+ static void registerTypeAndRevisions(const char *uri, int versionMajor)
+ {
+ QQmlPrivate::qmlRegisterTypeAndRevisions<Resolved, Extended>(
+ uri, versionMajor, &T::staticMetaObject);
+ }
+};
+
+template<class T, class Resolved>
+struct QmlTypeAndRevisionsRegistration<T, Resolved, void, true, false> {
+ static void registerTypeAndRevisions(const char *uri, int versionMajor)
+ {
+ QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved>(
+ uri, versionMajor, &T::staticMetaObject);
+ }
+};
+
+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);
+
+template<typename T, typename... Args>
+void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor)
+{
+ QmlTypeAndRevisionsRegistration<
+ T, typename QQmlPrivate::QmlResolved<T>::Type,
+ typename QQmlPrivate::QmlExtended<T>::Type,
+ QQmlPrivate::QmlSingleton<T>::Value,
+ QQmlPrivate::QmlInterface<T>::Value>
+ ::registerTypeAndRevisions(uri, versionMajor);
+ qmlRegisterTypesAndRevisions<Args...>(uri, versionMajor);
+}
+
+template<>
+inline void qmlRegisterTypesAndRevisions<>(const char *, int) {}
+
+inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject,
+ const char *uri, int versionMajor)
+{
+ QQmlPrivate::RegisterTypeAndRevisions type = {
+ 0,
+ 0,
+ 0,
+ 0,
+ nullptr,
+
+ uri,
+ versionMajor,
+
+ metaObject,
+ metaObject,
+
+ nullptr,
+ nullptr,
+
+ -1,
+ -1,
+ -1,
+
+ nullptr,
+ nullptr,
+
+ &qmlCreateCustomParser<void>
+ };
+
+ qmlregister(QQmlPrivate::TypeAndRevisionsRegistration, &type);
+}
+
int Q_QML_EXPORT qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName);
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index 7f80fe5e1c..6ee03b39e5 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
QQmlApplicationEnginePrivate::QQmlApplicationEnginePrivate(QQmlEngine *e)
: QQmlEnginePrivate(e)
{
+ uiLanguage = QLocale().bcp47Name();
}
QQmlApplicationEnginePrivate::~QQmlApplicationEnginePrivate()
@@ -72,6 +73,7 @@ void QQmlApplicationEnginePrivate::init()
&QCoreApplication::quit, Qt::QueuedConnection);
q->connect(q, &QQmlApplicationEngine::exit, QCoreApplication::instance(),
&QCoreApplication::exit, Qt::QueuedConnection);
+ q->connect(q, SIGNAL(uiLanguageChanged()), q_func(), SLOT(_q_loadTranslations()));
#if QT_CONFIG(translation)
QTranslator* qtTranslator = new QTranslator(q);
if (qtTranslator->load(QLocale(), QLatin1String("qt"), QLatin1String("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath), QLatin1String(".qm")))
@@ -83,22 +85,27 @@ void QQmlApplicationEnginePrivate::init()
QCoreApplication::instance()->setProperty("__qml_using_qqmlapplicationengine", QVariant(true));
}
-void QQmlApplicationEnginePrivate::loadTranslations(const QUrl &rootFile)
+void QQmlApplicationEnginePrivate::_q_loadTranslations()
{
#if QT_CONFIG(translation)
- if (rootFile.scheme() != QLatin1String("file") && rootFile.scheme() != QLatin1String("qrc"))
+ if (translationsDirectory.isEmpty())
return;
- QFileInfo fi(QQmlFile::urlToLocalFileOrQrc(rootFile));
-
Q_Q(QQmlApplicationEngine);
- QTranslator *translator = new QTranslator(q);
- if (translator->load(QLocale(), QLatin1String("qml"), QLatin1String("_"), fi.path() + QLatin1String("/i18n"), QLatin1String(".qm")))
- QCoreApplication::installTranslator(translator);
- else
- delete translator;
-#else
- Q_UNUSED(rootFile)
+
+ QScopedPointer<QTranslator> translator(new QTranslator);
+ if (!uiLanguage.isEmpty()) {
+ QLocale locale(uiLanguage);
+ if (translator->load(locale, QLatin1String("qml"), QLatin1String("_"), translationsDirectory, QLatin1String(".qm"))) {
+ if (activeTranslator)
+ QCoreApplication::removeTranslator(activeTranslator.data());
+ QCoreApplication::installTranslator(translator.data());
+ activeTranslator.swap(translator);
+ }
+ } else {
+ activeTranslator.reset();
+ }
+ q->retranslate();
#endif
}
@@ -106,7 +113,14 @@ void QQmlApplicationEnginePrivate::startLoad(const QUrl &url, const QByteArray &
{
Q_Q(QQmlApplicationEngine);
- loadTranslations(url); //Translations must be loaded before the QML file is
+ if (url.scheme() == QLatin1String("file") || url.scheme() == QLatin1String("qrc")) {
+ QFileInfo fi(QQmlFile::urlToLocalFileOrQrc(url));
+ translationsDirectory = fi.path() + QLatin1String("/i18n");
+ } else {
+ translationsDirectory.clear();
+ }
+
+ _q_loadTranslations(); //Translations must be loaded before the QML file is
QQmlComponent *c = new QQmlComponent(q, q);
if (dataFlag)
@@ -181,6 +195,7 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
\list
\li Translation files must have "qml_" prefix e.g. qml_ja_JP.qm.
\endlist
+ \li Translations are reloaded when the \c QJSEngine::uiLanguage / \c Qt.uiLanguage property is changed.
\li Automatically sets an incubation controller if the scene contains a QQuickWindow.
\li Automatically sets a \c QQmlFileSelector as the url interceptor, applying file selectors to all
QML files and assets.
diff --git a/src/qml/qml/qqmlapplicationengine.h b/src/qml/qml/qqmlapplicationengine.h
index 2b4de91154..37f75d5068 100644
--- a/src/qml/qml/qqmlapplicationengine.h
+++ b/src/qml/qml/qqmlapplicationengine.h
@@ -74,6 +74,7 @@ Q_SIGNALS:
private:
Q_DISABLE_COPY(QQmlApplicationEngine)
+ Q_PRIVATE_SLOT(d_func(), void _q_loadTranslations())
Q_DECLARE_PRIVATE(QQmlApplicationEngine)
};
diff --git a/src/qml/qml/qqmlapplicationengine_p.h b/src/qml/qml/qqmlapplicationengine_p.h
index 1279e400e8..86f492510f 100644
--- a/src/qml/qml/qqmlapplicationengine_p.h
+++ b/src/qml/qml/qqmlapplicationengine_p.h
@@ -70,10 +70,14 @@ public:
void cleanUp();
void startLoad(const QUrl &url, const QByteArray &data = QByteArray(), bool dataFlag = false);
- void loadTranslations(const QUrl &rootFile);
+ void _q_loadTranslations();
void finishLoad(QQmlComponent *component);
QList<QObject *> objects;
QVariantMap initialProperties;
+ QString translationsDirectory;
+#if QT_CONFIG(translation)
+ QScopedPointer<QTranslator> activeTranslator;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 52572be2b2..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>
@@ -54,6 +58,8 @@
#include <private/qv4variantobject_p.h>
#include <private/qv4jscall_p.h>
+#include <qtqml_tracepoints_p.h>
+
#include <QVariant>
#include <QtCore/qdebug.h>
#include <QVector>
@@ -182,6 +188,8 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags)
if (canUseAccessor())
flags.setFlag(QQmlPropertyData::BypassInterceptor);
+ Q_TRACE_SCOPE(QQmlBinding, engine, function() ? function()->name()->toQString() : QString(),
+ sourceLocation().sourceFile, sourceLocation().line, sourceLocation().column);
QQmlBindingProfiler prof(QQmlEnginePrivate::get(engine)->profiler, function());
doUpdate(watcher, flags, scope);
@@ -316,7 +324,7 @@ protected:
break;
default:
if (const QV4::QQmlValueTypeWrapper *vtw = result.as<const QV4::QQmlValueTypeWrapper>()) {
- if (vtw->d()->valueType->metaType.id() == pd->propType()) {
+ if (vtw->d()->valueType()->metaType.id() == pd->propType()) {
return vtw->write(m_target.data(), pd->coreIndex());
}
}
@@ -388,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;
}
@@ -475,7 +488,7 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
if (!propertyMetaObject.isNull())
propertyType = propertyMetaObject.className();
}
- } else if (userType != QVariant::Invalid) {
+ } else if (userType != QMetaType::UnknownType) {
if (userType == QMetaType::Nullptr || userType == QMetaType::VoidStar)
valueType = "null";
else
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index ff01e737ca..b347bb3829 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -60,6 +60,7 @@
#include <QtCore/qdebug.h>
+#include <qtqml_tracepoints_p.h>
QT_BEGIN_NAMESPACE
@@ -352,6 +353,10 @@ void QQmlBoundSignal_callback(QQmlNotifierEndpoint *e, void **a)
QQmlEngine *engine;
if (s->m_expression && (engine = s->m_expression->engine())) {
+ Q_TRACE_SCOPE(QQmlHandlingSignal, engine,
+ s->m_expression->function() ? s->m_expression->function()->name()->toQString() : QString(),
+ s->m_expression->sourceLocation().sourceFile, s->m_expression->sourceLocation().line,
+ s->m_expression->sourceLocation().column);
QQmlHandlingSignalProfiler prof(QQmlEnginePrivate::get(engine)->profiler, s->m_expression);
s->m_expression->evaluate(a);
if (s->m_expression && s->m_expression->hasError()) {
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index b26b90d2aa..9ee4fdbe41 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -50,6 +50,7 @@
#include "qqmlincubator.h"
#include "qqmlincubator_p.h"
#include <private/qqmljavascriptexpression_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4script_p.h>
@@ -248,9 +249,8 @@ V4_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension);
execute script code at startup, once the full QML environment has been
established.
- The corresponding handler is \c onCompleted. It can be declared on
- any object. The order of running the \c onCompleted handlers is
- undefined.
+ The \c onCompleted signal handler can be declared on any object. The order
+ of running the handlers is undefined.
\qml
Rectangle {
@@ -269,9 +269,8 @@ V4_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension);
work done in response to the \l {completed}{completed()} signal, or other
imperative code in your application.
- The corresponding handler is \c onDestruction. It can be declared on
- any object. The order of running the \c onDestruction handlers is
- undefined.
+ The \c onDestruction signal handler can be declared on any object. The
+ order of running the handlers is undefined.
\qml
Rectangle {
@@ -340,6 +339,16 @@ void QQmlComponentPrivate::fromTypeData(const QQmlRefPointer<QQmlTypeData> &data
}
}
+RequiredProperties &QQmlComponentPrivate::requiredProperties()
+{
+ return state.creator->requiredProperties();
+}
+
+bool QQmlComponentPrivate::hadRequiredProperties() const
+{
+ return state.creator->componentHadRequiredProperties();
+}
+
void QQmlComponentPrivate::clear()
{
if (typeData) {
@@ -364,9 +373,9 @@ QObject *QQmlComponentPrivate::doBeginCreate(QQmlComponent *q, QQmlContext *cont
bool QQmlComponentPrivate::setInitialProperty(QObject *component, const QString& name, const QVariant &value)
{
- QQmlProperty prop(component, name);
- auto privProp = QQmlPropertyPrivate::get(prop);
- if (!prop.isValid() || !privProp->writeValueProperty(value, nullptr)) {
+ QQmlProperty prop = QQmlComponentPrivate::removePropertyFromRequired(component, name, requiredProperties());
+ QQmlPropertyPrivate *privProp = QQmlPropertyPrivate::get(prop);
+ if (!prop.isValid() || !privProp->writeValueProperty(value, {})) {
QQmlError error{};
error.setUrl(url);
error.setDescription(QLatin1String("Could not set property %1").arg(name));
@@ -809,6 +818,10 @@ QObject *QQmlComponent::create(QQmlContext *context)
QObject *rv = d->doBeginCreate(this, context);
if (rv)
completeCreate();
+ if (rv && !d->requiredProperties().empty()) {
+ delete rv;
+ return nullptr;
+ }
return rv;
}
@@ -829,6 +842,10 @@ QObject *QQmlComponent::createWithInitialProperties(const QVariantMap& initialPr
setInitialProperties(rv, initialProperties);
completeCreate();
}
+ if (!d->requiredProperties().empty()) {
+ d->requiredProperties().clear();
+ return nullptr;
+ }
return rv;
}
@@ -951,6 +968,7 @@ void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv,
if (!state->creator->populateDeferredProperties(object, deferredData))
state->errors << state->creator->errors;
+ deferredData->bindings.clear();
deferredState->constructionStates += state;
}
@@ -981,6 +999,57 @@ void QQmlComponentPrivate::complete(QQmlEnginePrivate *enginePriv, ConstructionS
}
/*!
+ * \internal
+ * Finds the matching toplevel property with name \a name of the component \a createdComponent.
+ * If it was a required property or an alias to a required property contained in \a
+ * requiredProperties, it is removed from it.
+ *
+ * If wasInRequiredProperties is non-null, the referenced boolean is set to true iff the property
+ * was found in requiredProperties.
+ *
+ * Returns the QQmlProperty with name \a name (which might be invalid if there is no such property),
+ * for further processing (for instance, actually setting the property value).
+ *
+ * Note: This method is used in QQmlComponent and QQmlIncubator to manage required properties. Most
+ * classes which create components should not need it and should only need to call
+ * setInitialProperties.
+ */
+QQmlProperty QQmlComponentPrivate::removePropertyFromRequired(QObject *createdComponent, const QString &name, RequiredProperties &requiredProperties, bool* wasInRequiredProperties)
+{
+ QQmlProperty prop(createdComponent, name);
+ auto privProp = QQmlPropertyPrivate::get(prop);
+ if (prop.isValid()) {
+ // resolve outstanding required properties
+ auto targetProp = &privProp->core;
+ if (targetProp->isAlias()) {
+ auto target = createdComponent;
+ QQmlPropertyIndex originalIndex(targetProp->coreIndex());
+ QQmlPropertyIndex propIndex;
+ QQmlPropertyPrivate::findAliasTarget(target, originalIndex, &target, &propIndex);
+ QQmlData *data = QQmlData::get(target);
+ Q_ASSERT(data && data->propertyCache);
+ targetProp = data->propertyCache->property(propIndex.coreIndex());
+ } else {
+ // we need to get the pointer from the property cache instead of directly using
+ // targetProp else the lookup will fail
+ QQmlData *data = QQmlData::get(createdComponent);
+ Q_ASSERT(data && data->propertyCache);
+ targetProp = data->propertyCache->property(targetProp->coreIndex());
+ }
+ auto it = requiredProperties.find(targetProp);
+ if (it != requiredProperties.end()) {
+ if (wasInRequiredProperties)
+ *wasInRequiredProperties = true;
+ requiredProperties.erase(it);
+ } else {
+ if (wasInRequiredProperties)
+ *wasInRequiredProperties = false;
+ }
+ }
+ return prop;
+}
+
+/*!
This method provides advanced control over component instance creation.
In general, programmers should use QQmlComponent::create() to create a
component.
@@ -999,6 +1068,11 @@ void QQmlComponent::completeCreate()
void QQmlComponentPrivate::completeCreate()
{
+ const RequiredProperties& unsetRequiredProperties = requiredProperties();
+ for (const auto& unsetRequiredProperty: unsetRequiredProperties) {
+ QQmlError error = unsetRequiredPropertyToQQmlError(unsetRequiredProperty);
+ state.errors.push_back(error);
+ }
if (state.completePending) {
++creationDepth.localData();
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
@@ -1186,7 +1260,7 @@ struct QmlIncubatorObject : public QV4::Object
static ReturnedValue method_forceCompletion(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
void statusChanged(QQmlIncubator::Status);
- void setInitialState(QObject *);
+ void setInitialState(QObject *, RequiredProperties &requiredProperties);
};
}
@@ -1211,7 +1285,8 @@ public:
void setInitialState(QObject *o) override {
QV4::Scope scope(incubatorObject.engine());
QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject.as<QV4::QmlIncubatorObject>());
- i->setInitialState(o);
+ auto d = QQmlIncubatorPrivate::get(this);
+ i->setInitialState(o, d->requiredProperties());
}
QV4::PersistentValue incubatorObject; // keep a strong internal reference while incubating
@@ -1283,7 +1358,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
*/
-void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v)
+void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v, RequiredProperties &requiredProperties, QObject *createdComponent)
{
QV4::Scope scope(engine);
QV4::ScopedObject object(scope);
@@ -1302,6 +1377,7 @@ void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV
break;
object = o;
const QStringList properties = name->toQString().split(QLatin1Char('.'));
+ bool isTopLevelProperty = properties.size() == 1;
for (int i = 0; i < properties.length() - 1; ++i) {
name = engine->newString(properties.at(i));
object = object->get(name);
@@ -1318,12 +1394,40 @@ void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV
if (engine->hasException) {
engine->hasException = false;
continue;
+ } else if (isTopLevelProperty) {
+ auto prop = removePropertyFromRequired(createdComponent, name->toQString(), requiredProperties);
}
}
engine->hasException = false;
}
+QQmlError QQmlComponentPrivate::unsetRequiredPropertyToQQmlError(const RequiredPropertyInfo &unsetRequiredProperty)
+{
+ QQmlError error;
+ QString description = QLatin1String("Required property %1 was not initialized").arg(unsetRequiredProperty.propertyName);
+ switch (unsetRequiredProperty.aliasesToRequired.size()) {
+ case 0:
+ break;
+ case 1: {
+ const auto info = unsetRequiredProperty.aliasesToRequired.first();
+ description += QLatin1String("\nIt can be set via the alias property %1 from %2\n").arg(info.propertyName, info.fileUrl.toString());
+ break;
+ }
+ default:
+ description += QLatin1String("\nIt can be set via one of the following alias properties:");
+ for (auto aliasInfo: unsetRequiredProperty.aliasesToRequired) {
+ description += QLatin1String("\n- %1 (%2)").arg(aliasInfo.propertyName, aliasInfo.fileUrl.toString());
+ }
+ description += QLatin1Char('\n');
+ }
+ error.setDescription(description);
+ error.setUrl(unsetRequiredProperty.fileUrl);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(unsetRequiredProperty.location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(unsetRequiredProperty.location.column));
+ return error;
+}
+
/*!
\internal
*/
@@ -1371,7 +1475,17 @@ void QQmlComponent::createObject(QQmlV4Function *args)
if (!valuemap->isUndefined()) {
QV4::Scoped<QV4::QmlContext> qmlContext(scope, v4->qmlContext());
- QQmlComponentPrivate::setInitialProperties(v4, qmlContext, object, valuemap);
+ QQmlComponentPrivate::setInitialProperties(v4, qmlContext, object, valuemap, d->requiredProperties(), rv);
+ }
+ if (!d->requiredProperties().empty()) {
+ QList<QQmlError> errors;
+ for (const auto &requiredProperty: d->requiredProperties()) {
+ errors.push_back(QQmlComponentPrivate::unsetRequiredPropertyToQQmlError(requiredProperty));
+ }
+ qmlWarning(rv, errors);
+ args->setReturnValue(QV4::Encode::null());
+ delete rv;
+ return;
}
d->completeCreate();
@@ -1503,7 +1617,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
}
// XXX used by QSGLoader
-void QQmlComponentPrivate::initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate)
+void QQmlComponentPrivate::initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate, RequiredProperties &requiredProperties)
{
QV4::ExecutionEngine *v4engine = engine->handle();
QV4::Scope scope(v4engine);
@@ -1512,7 +1626,7 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(QV4::QmlContext
Q_ASSERT(object->as<QV4::Object>());
if (!valuemap.isUndefined())
- setInitialProperties(v4engine, qmlContext, object, valuemap);
+ setInitialProperties(v4engine, qmlContext, object, valuemap, requiredProperties, toCreate);
}
QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4)
@@ -1602,7 +1716,7 @@ void QV4::Heap::QmlIncubatorObject::destroy() {
Object::destroy();
}
-void QV4::QmlIncubatorObject::setInitialState(QObject *o)
+void QV4::QmlIncubatorObject::setInitialState(QObject *o, RequiredProperties &requiredProperties)
{
QQmlComponent_setQmlParent(o, d()->parent);
@@ -1611,7 +1725,7 @@ void QV4::QmlIncubatorObject::setInitialState(QObject *o)
QV4::Scope scope(v4);
QV4::ScopedObject obj(scope, QV4::QObjectWrapper::wrap(v4, o));
QV4::Scoped<QV4::QmlContext> qmlCtxt(scope, d()->qmlContext);
- QQmlComponentPrivate::setInitialProperties(v4, qmlCtxt, obj, d()->valuemap);
+ QQmlComponentPrivate::setInitialProperties(v4, qmlCtxt, obj, d()->valuemap, requiredProperties, o);
}
}
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index f259c99b08..cb5d5a787c 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -70,6 +70,9 @@ class Q_QML_EXPORT QQmlComponent : public QObject
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(QUrl url READ url CONSTANT)
+ QML_NAMED_ELEMENT(Component)
+ QML_ATTACHED(QQmlComponentAttached)
+ Q_CLASSINFO("QML.Builtin", "QML")
public:
enum CompilationMode { PreferSynchronous, Asynchronous };
@@ -136,9 +139,29 @@ private:
friend class QQmlObjectCreator;
};
-QT_END_NAMESPACE
+// Don't do this at home.
+namespace QQmlPrivate {
+
+// Generally you cannot use QQmlComponentAttached as attached properties object in derived classes.
+// It is private.
+template<class T>
+struct OverridableAttachedType<T, QQmlComponentAttached>
+{
+ using Type = void;
+};
+
+// QQmlComponent itself is allowed to use QQmlComponentAttached, though.
+template<>
+struct OverridableAttachedType<QQmlComponent, QQmlComponentAttached>
+{
+ using Type = QQmlComponentAttached;
+};
+
+} // namespace QQmlPrivate
+
+
+QT_END_NAMESPACE
QML_DECLARE_TYPE(QQmlComponent)
-QML_DECLARE_TYPEINFO(QQmlComponent, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQMLCOMPONENT_H
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 2170646b89..a919eb45c0 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -86,8 +86,9 @@ public:
QObject *beginCreate(QQmlContextData *);
void completeCreate();
- void initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate);
- static void setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v);
+ void initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate, RequiredProperties &requiredProperties);
+ static void setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v, RequiredProperties &requiredProperties, QObject *createdComponent);
+ static QQmlError unsetRequiredPropertyToQQmlError(const RequiredPropertyInfo &unsetRequiredProperty);
virtual void incubateObject(
QQmlIncubator *incubationTask,
@@ -106,6 +107,8 @@ public:
qreal progress;
int start;
+ RequiredProperties& requiredProperties();
+ bool hadRequiredProperties() const;
QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
struct ConstructionState {
@@ -134,6 +137,7 @@ public:
static void completeDeferred(QQmlEnginePrivate *enginePriv, DeferredState *deferredState);
static void complete(QQmlEnginePrivate *enginePriv, ConstructionState *state);
+ static QQmlProperty removePropertyFromRequired(QObject *createdComponent, const QString &name, RequiredProperties& requiredProperties, bool *wasInRequiredProperties = nullptr);
QQmlEngine *engine;
QQmlGuardedContextData creationContext;
diff --git a/src/qml/qml/qqmlcomponentattached_p.h b/src/qml/qml/qqmlcomponentattached_p.h
index e3bca18857..8ecd9da17d 100644
--- a/src/qml/qml/qqmlcomponentattached_p.h
+++ b/src/qml/qml/qqmlcomponentattached_p.h
@@ -61,6 +61,11 @@ QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QQmlComponentAttached : public QObject
{
Q_OBJECT
+
+ // Used as attached object for QQmlComponent. We want qqmlcomponentattached_p.h to be #include'd
+ // when registering QQmlComponent, but we cannot #include it from qqmlcomponent.h. Therefore we
+ // force an anonymous type registration here.
+ QML_ANONYMOUS
public:
QQmlComponentAttached(QObject *parent = nullptr);
~QQmlComponentAttached();
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index f75a076bcb..9157bb95c3 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -553,7 +553,7 @@ QQmlContextData::QQmlContextData()
QQmlContextData::QQmlContextData(QQmlContext *ctxt)
: engine(nullptr), isInternal(false), isJSContext(false),
isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false),
- stronglyReferencedByParent(false), publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1),
+ stronglyReferencedByParent(false), hasExtraObject(false), publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1),
contextObject(nullptr), nextChild(nullptr), prevChild(nullptr),
expressions(nullptr), contextObjects(nullptr), idValues(nullptr), idValueCount(0),
componentAttached(nullptr)
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index 5f7316b00c..f93393a11b 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -147,11 +147,16 @@ public:
quint32 hasEmittedDestruction:1;
quint32 isRootObjectInCreation:1;
quint32 stronglyReferencedByParent:1;
- quint32 dummy:25;
+ quint32 hasExtraObject:1; // used in QQmlDelegateModelItem::dataForObject to find the corresponding QQmlDelegateModelItem of an object
+ quint32 dummy:24;
QQmlContext *publicContext;
- // The incubator that is constructing this context if any
- QQmlIncubatorPrivate *incubator;
+ union {
+ // The incubator that is constructing this context if any
+ QQmlIncubatorPrivate *incubator;
+ // a pointer to extra data, currently only used in QQmlDelegateModel
+ QObject *extraObject;
+ };
// Compilation unit for contexts that belong to a compiled type.
QQmlRefPointer<QV4::ExecutableCompilationUnit> typeCompilationUnit;
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index a5f34dafdf..5e6e1187e2 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -40,6 +40,7 @@
#include "qqmlcustomparser_p.h"
#include <private/qv4compileddata_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
#include <QtCore/qdebug.h>
@@ -100,10 +101,10 @@ void QQmlCustomParser::clearErrors()
*/
void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const QString &description)
{
- QQmlJS::DiagnosticMessage error;
- error.line = location.line;
- error.column = location.column;
- error.message = description;
+ QQmlError error;
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(location.column));
+ error.setDescription(description);
exceptions << error;
}
@@ -131,8 +132,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));
@@ -143,18 +149,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, 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, 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/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index df8cbc9072..4eb709228e 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -83,7 +83,7 @@ public:
virtual void verifyBindings(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &, const QList<const QV4::CompiledData::Binding *> &) = 0;
virtual void applyBindings(QObject *, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &, const QList<const QV4::CompiledData::Binding *> &) = 0;
- QVector<QQmlJS::DiagnosticMessage> errors() const { return exceptions; }
+ QVector<QQmlError> errors() const { return exceptions; }
protected:
void error(const QV4::CompiledData::Binding *binding, const QString& description)
@@ -97,7 +97,7 @@ protected:
const QMetaObject *resolveType(const QString&) const;
private:
- QVector<QQmlJS::DiagnosticMessage> exceptions;
+ QVector<QQmlError> exceptions;
QQmlEnginePrivate *engine;
const QQmlPropertyValidator *validator;
Flags m_flags;
@@ -107,11 +107,6 @@ private:
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlCustomParser::Flags)
-#if 0
-#define QML_REGISTER_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, TYPE, CUSTOMTYPE) \
- qmlRegisterCustomType<TYPE>(#URI, VERSION_MAJ, VERSION_MIN, #NAME, #TYPE, new CUSTOMTYPE)
-#endif
-
QT_END_NAMESPACE
#endif
diff --git a/src/qml/qml/qqmldatablob.cpp b/src/qml/qml/qqmldatablob.cpp
index 750fc6de50..b22e46b69c 100644
--- a/src/qml/qml/qqmldatablob.cpp
+++ b/src/qml/qml/qqmldatablob.cpp
@@ -42,9 +42,12 @@
#include <private/qqmlprofiler_p.h>
#include <private/qqmltypeloader_p.h>
#include <private/qqmltypeloaderthread_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
#include <QtQml/qqmlengine.h>
+#include <qtqml_tracepoints_p.h>
+
#ifdef DATABLOB_DEBUG
#define ASSERT_CALLBACK() do { if (!m_typeLoader || !m_typeLoader->m_thread->isThisThread()) qFatal("QQmlDataBlob: An API call was made outside a callback"); } while (false)
#else
@@ -304,22 +307,19 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors)
void QQmlDataBlob::setError(const QQmlJS::DiagnosticMessage &error)
{
QQmlError e;
- e.setColumn(error.column);
- e.setLine(error.line);
+ e.setColumn(qmlConvertSourceCoordinate<quint32, int>(error.loc.startColumn));
+ e.setLine(qmlConvertSourceCoordinate<quint32, int>(error.loc.startLine));
e.setDescription(error.message);
e.setUrl(url());
setError(e);
}
-void QQmlDataBlob::setError(const QVector<QQmlJS::DiagnosticMessage> &errors)
+void QQmlDataBlob::setError(const QVector<QQmlError> &errors)
{
QList<QQmlError> finalErrors;
finalErrors.reserve(errors.count());
for (const auto &error : errors) {
- QQmlError e;
- e.setColumn(error.column);
- e.setLine(error.line);
- e.setDescription(error.message);
+ QQmlError e = error;
e.setUrl(url());
finalErrors << e;
}
@@ -559,6 +559,7 @@ void QQmlDataBlob::notifyAllWaitingOnMe()
void QQmlDataBlob::notifyComplete(QQmlDataBlob *blob)
{
Q_ASSERT(blob->status() == Error || blob->status() == Complete);
+ Q_TRACE_SCOPE(QQmlCompiling, blob->url());
QQmlCompilingProfiler prof(typeLoader()->profiler(), blob);
m_inCallback = true;
diff --git a/src/qml/qml/qqmldatablob_p.h b/src/qml/qml/qqmldatablob_p.h
index 0450e94c02..cc066d29a1 100644
--- a/src/qml/qml/qqmldatablob_p.h
+++ b/src/qml/qml/qqmldatablob_p.h
@@ -132,7 +132,7 @@ protected:
void setError(const QQmlError &);
void setError(const QList<QQmlError> &errors);
void setError(const QQmlJS::DiagnosticMessage &error);
- void setError(const QVector<QQmlJS::DiagnosticMessage> &errors);
+ void setError(const QVector<QQmlError> &errors);
void setError(const QString &description);
void addDependency(QQmlDataBlob *);
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 93964ac76f..872a448bfd 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -57,6 +57,7 @@
#include "qqmlnotifier_p.h"
#include "qqmlincubator.h"
#include "qqmlabstracturlinterceptor.h"
+#include "qqmlsourcecoordinate_p.h"
#include <private/qqmldirparser_p.h>
#include <private/qqmlboundsignal_p.h>
#include <private/qqmljsdiagnosticmessage_p.h>
@@ -101,8 +102,6 @@
# endif
#endif // Q_OS_WIN
-Q_DECLARE_METATYPE(QQmlProperty)
-
QT_BEGIN_NAMESPACE
// Declared in qqml.h
@@ -197,37 +196,11 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject,
bool QQmlEnginePrivate::qml_debugging_enabled = false;
bool QQmlEnginePrivate::s_designerMode = false;
-void QQmlEnginePrivate::defineModule()
-{
- const char uri[] = "QtQml";
-
- qmlRegisterType<QQmlComponent>(uri, 2, 0, "Component");
- qmlRegisterType<QObject>(uri, 2, 0, "QtObject");
- qmlRegisterType<QQmlBind>(uri, 2, 0, "Binding");
- qmlRegisterType<QQmlBind, 8>(uri, 2, 8, "Binding"); // Only available in >= 2.8
- qmlRegisterType<QQmlBind, 14>(uri, 2, 14, "Binding");
-
- // TODO: We won't need Connections to be a custom type anymore once we can drop the
- // automatic signal handler inference from undeclared properties.
- qmlRegisterCustomType<QQmlConnections>(uri, 2, 0, "Connections", new QQmlConnectionsParser);
- qmlRegisterCustomType<QQmlConnections, 3>(uri, 2, 3, "Connections", new QQmlConnectionsParser); // Only available in QtQml >= 2.3
-
-#if QT_CONFIG(qml_animation)
- qmlRegisterType<QQmlTimer>(uri, 2, 0, "Timer");
-#endif
-
- qmlRegisterType<QQmlLoggingCategory>(uri, 2, 8, "LoggingCategory"); // Only available in >= 2.8
- qmlRegisterType<QQmlLoggingCategory, 12>(uri, 2, 12, "LoggingCategory"); // Only available in >= 2.12
-
-#if QT_CONFIG(qml_locale)
- qmlRegisterUncreatableType<QQmlLocale>(uri, 2, 2, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
-#endif
-}
-
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
void QQmlEnginePrivate::registerQuickTypes()
{
// Don't add anything here. These are only for backwards compatibility.
+ // Also, don't use qmlRegisterTypesAndRevisions as that will auto-add future revisions.
const char uri[] = "QtQuick";
@@ -236,13 +209,17 @@ void QQmlEnginePrivate::registerQuickTypes()
qmlRegisterType<QQmlBind>(uri, 2, 0, "Binding");
qmlRegisterType<QQmlBind, 8>(uri, 2, 8, "Binding");
qmlRegisterCustomType<QQmlConnections>(uri, 2, 0, "Connections", new QQmlConnectionsParser);
+
+ // Connections revision 3 was added in QtQml 2.3, but only in QtQuick 2.7.
qmlRegisterCustomType<QQmlConnections, 3>(uri, 2, 7, "Connections", new QQmlConnectionsParser);
+
#if QT_CONFIG(qml_animation)
qmlRegisterType<QQmlTimer>(uri, 2, 0,"Timer");
#endif
qmlRegisterType<QQmlLoggingCategory>(uri, 2, 8, "LoggingCategory");
qmlRegisterType<QQmlLoggingCategory, 12>(uri, 2, 12, "LoggingCategory");
#if QT_CONFIG(qml_locale)
+ // Locale was added in QtQuick 2.0 and in QtQml 2.2
qmlRegisterUncreatableType<QQmlLocale>(uri, 2, 0, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
#endif
}
@@ -445,6 +422,7 @@ The following functions are also on the Qt object.
\li \c "unix" - Other Unix-based OS
\li \c "windows" - Windows
\li \c "winrt" - WinRT / UWP
+ \li \c "wasm" - WebAssembly
\endlist
\row
@@ -707,11 +685,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;
@@ -815,10 +789,12 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
// QQmlEngine to emit signals from a different thread. These signals are then automatically
// marshalled back onto the QObject's thread and handled by QML from there. This is tested
// by the qqmlecmascript::threadSignal() autotest.
- if (ddata->notifyList &&
- QThread::currentThreadId() != QObjectPrivate::get(object)->threadData->threadId.loadRelaxed()) {
+ if (!ddata->notifyList)
+ return;
- if (!QObjectPrivate::get(object)->threadData->thread.loadAcquire())
+ auto objectThreadData = QObjectPrivate::get(object)->threadData.loadRelaxed();
+ if (QThread::currentThreadId() != objectThreadData->threadId.loadRelaxed()) {
+ if (!objectThreadData->thread.loadAcquire())
return;
QMetaMethod m = QMetaObjectPrivate::signal(object->metaObject(), index);
@@ -850,7 +826,7 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
QQmlThreadNotifierProxyObject *mpo = new QQmlThreadNotifierProxyObject;
mpo->target = object;
- mpo->moveToThread(QObjectPrivate::get(object)->threadData->thread.loadAcquire());
+ mpo->moveToThread(objectThreadData->thread.loadAcquire());
QCoreApplication::postEvent(mpo, ev.take());
} else {
@@ -1043,7 +1019,7 @@ QQmlEngine::~QQmlEngine()
// we do this here and not in the private dtor since otherwise a crash can
// occur (if we are the QObject parent of the QObject singleton instance)
// XXX TODO: performance -- store list of singleton types separately?
- QList<QQmlType> singletonTypes = QQmlMetaType::qmlSingletonTypes();
+ const QList<QQmlType> singletonTypes = QQmlMetaType::qmlSingletonTypes();
for (const QQmlType &currType : singletonTypes)
d->destroySingletonInstance(currType);
@@ -1358,6 +1334,21 @@ void QQmlEngine::setOutputWarningsToStandardError(bool enabled)
}
/*!
+ \qmlproperty string Qt::uiLanguage
+ \since 5.15
+
+ The uiLanguage holds the name of the language to be used for user interface
+ string translations. It is exposed in C++ as QQmlEngine::uiLanguage property.
+
+ You can set the value freely and use it in bindings. It is recommended to set it
+ after installing translators in your application. By convention, an empty string
+ means no translation from the language used in the source code is intended to occur.
+
+ If you're using QQmlApplicationEngine and the value changes, QQmlEngine::retranslate()
+ will be called.
+*/
+
+/*!
\fn template<typename T> T QQmlEngine::singletonInstance(int qmlTypeId)
Returns the instance of a singleton type that was registered under \a qmlTypeId.
@@ -1371,12 +1362,16 @@ void QQmlEngine::setOutputWarningsToStandardError(bool enabled)
\code
class MySingleton : public QObject {
Q_OBJECT
+
+ // Register as default constructed singleton.
+ QML_ELEMENT
+ QML_SINGLETON
+
static int typeId;
// ...
};
- // Register with QObject* callback
- MySingleton::typeId = qmlRegisterSingletonType<MySingleton>(...);
+ MySingleton::typeId = qmlTypeId(...);
// Retrieve as QObject*
QQmlEngine engine;
@@ -1393,11 +1388,10 @@ void QQmlEngine::setOutputWarningsToStandardError(bool enabled)
QJSValue instance = engine.singletonInstance<QJSValue>(typeId);
\endcode
- It is recommended to store the QML type id during registration, e.g. as a static member
- in the singleton class. Otherwise, a costly lookup via qmlTypeId() has to be performed
- at run-time.
+ It is recommended to store the QML type id, e.g. as a static member in the
+ singleton class. The lookup via qmlTypeId() is costly.
- \sa qmlRegisterSingletonType(), qmlTypeId()
+ \sa QML_SINGLETON, qmlRegisterSingletonType(), qmlTypeId()
\since 5.12
*/
template<>
@@ -2132,15 +2126,15 @@ QList<QQmlError> QQmlEnginePrivate::qmlErrorFromDiagnostics(
QList<QQmlError> errors;
for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) {
if (m.isWarning()) {
- qWarning("%s:%d : %s", qPrintable(fileName), m.line, qPrintable(m.message));
+ qWarning("%s:%d : %s", qPrintable(fileName), m.loc.startLine, qPrintable(m.message));
continue;
}
QQmlError error;
error.setUrl(QUrl(fileName));
error.setDescription(m.message);
- error.setLine(m.line);
- error.setColumn(m.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(m.loc.startLine));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(m.loc.startColumn));
errors << error;
}
return errors;
@@ -2275,7 +2269,7 @@ void QQmlEngine::setPluginPathList(const QStringList &paths)
On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
- The plugin has to be a Qt plugin which implements the QQmlExtensionPlugin interface.
+ The plugin has to be a Qt plugin which implements the QQmlEngineExtensionPlugin interface.
*/
bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors)
{
@@ -2390,12 +2384,23 @@ int QQmlEnginePrivate::listType(int t) const
return QQmlMetaType::listType(t);
}
+
+static QQmlPropertyCache *propertyCacheForPotentialInlineComponentType(int t, const QHash<int, QV4::ExecutableCompilationUnit *>::const_iterator &iter) {
+ if (t != (*iter)->metaTypeId) {
+ // this is an inline component, and what we have in the iterator is currently the parent compilation unit
+ for (auto &&icDatum: (*iter)->inlineComponentData)
+ if (icDatum.typeIds.id == t)
+ return (*iter)->propertyCaches.at(icDatum.objectIndex);
+ }
+ return (*iter)->rootPropertyCache().data();
+}
+
QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const
{
Locker locker(this);
auto iter = m_compositeTypes.constFind(t);
if (iter != m_compositeTypes.cend()) {
- return QQmlMetaObject((*iter)->rootPropertyCache().data());
+ return propertyCacheForPotentialInlineComponentType(t, iter);
} else {
QQmlType type = QQmlMetaType::qmlType(t);
return QQmlMetaObject(type.baseMetaObject());
@@ -2407,7 +2412,7 @@ QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const
Locker locker(this);
auto iter = m_compositeTypes.constFind(t);
if (iter != m_compositeTypes.cend()) {
- return QQmlMetaObject((*iter)->rootPropertyCache().data());
+ return propertyCacheForPotentialInlineComponentType(t, iter);
} else {
QQmlType type = QQmlMetaType::qmlType(t);
return QQmlMetaObject(type.metaObject());
@@ -2419,7 +2424,7 @@ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t)
Locker locker(this);
auto iter = m_compositeTypes.constFind(t);
if (iter != m_compositeTypes.cend()) {
- return (*iter)->rootPropertyCache().data();
+ return propertyCacheForPotentialInlineComponentType(t, iter);
} else {
QQmlType type = QQmlMetaType::qmlType(t);
locker.unlock();
@@ -2432,7 +2437,7 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, int minorVe
Locker locker(this);
auto iter = m_compositeTypes.constFind(t);
if (iter != m_compositeTypes.cend()) {
- return (*iter)->rootPropertyCache().data();
+ return propertyCacheForPotentialInlineComponentType(t, iter);
} else {
QQmlType type = QQmlMetaType::qmlType(t);
locker.unlock();
@@ -2452,6 +2457,9 @@ void QQmlEnginePrivate::registerInternalCompositeType(QV4::ExecutableCompilation
// The QQmlCompiledData is not referenced here, but it is removed from this
// hash in the QQmlCompiledData destructor
m_compositeTypes.insert(compilationUnit->metaTypeId, compilationUnit);
+ for (auto &&data: compilationUnit->inlineComponentData) {
+ m_compositeTypes.insert(data.typeIds.id, compilationUnit);
+ }
}
void QQmlEnginePrivate::unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit)
@@ -2460,6 +2468,14 @@ void QQmlEnginePrivate::unregisterInternalCompositeType(QV4::ExecutableCompilati
Locker locker(this);
m_compositeTypes.remove(compilationUnit->metaTypeId);
+ for (auto&& icDatum: compilationUnit->inlineComponentData)
+ m_compositeTypes.remove(icDatum.typeIds.id);
+}
+
+QV4::ExecutableCompilationUnit *QQmlEnginePrivate::obtainExecutableCompilationUnit(int typeId)
+{
+ Locker locker(this);
+ return m_compositeTypes.value(typeId, nullptr);
}
template<>
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 502e2ed3d9..263c69e2d8 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -101,6 +101,13 @@ class QQmlProfiler;
class QQmlPropertyCapture;
class QQmlMetaObject;
+struct QObjectForeign {
+ Q_GADGET
+ QML_FOREIGN(QObject)
+ QML_NAMED_ELEMENT(QtObject)
+ Q_CLASSINFO("QML.Root", "QML")
+};
+
// This needs to be declared here so that the pool for it can live in QQmlEnginePrivate.
// The inline method definitions are in qqmljavascriptexpression_p.h
class QQmlJavaScriptExpressionGuard : public QQmlNotifierEndpoint
@@ -224,6 +231,7 @@ public:
QQmlPropertyCache *rawPropertyCacheForType(int, int minorVersion = -1);
void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
+ QV4::ExecutableCompilationUnit *obtainExecutableCompilationUnit(int typeId);
bool isTypeLoaded(const QUrl &url) const;
bool isScriptLoaded(const QUrl &url) const;
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 0b94ed3b49..da585d2126 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -77,12 +77,15 @@ QT_BEGIN_NAMESPACE
\sa QQuickView::errors(), QQmlComponent::errors()
*/
-class QQmlErrorPrivate : public QQmlJS::DiagnosticMessage
+class QQmlErrorPrivate
{
public:
- QQmlErrorPrivate() { type = QtWarningMsg; }
QUrl url;
QPointer<QObject> object;
+ QString message;
+ QtMsgType type = QtWarningMsg;
+ int line = -1;
+ int column = -1;
};
/*!
@@ -185,7 +188,7 @@ void QQmlError::setDescription(const QString &description)
int QQmlError::line() const
{
if (d)
- return qmlConvertSourceCoordinate<quint32, int>(d->line);
+ return d->line;
return -1;
}
@@ -196,7 +199,7 @@ void QQmlError::setLine(int line)
{
if (!d)
d = new QQmlErrorPrivate;
- d->line = qmlConvertSourceCoordinate<int, quint32>(line);
+ d->line = line;
}
/*!
@@ -205,7 +208,7 @@ void QQmlError::setLine(int line)
int QQmlError::column() const
{
if (d)
- return qmlConvertSourceCoordinate<quint32, int>(d->column);
+ return d->column;
return -1;
}
@@ -216,7 +219,7 @@ void QQmlError::setColumn(int column)
{
if (!d)
d = new QQmlErrorPrivate;
- d->column = qmlConvertSourceCoordinate<int, quint32>(column);
+ d->column = column;
}
/*!
diff --git a/src/qml/qml/qqmlextensioninterface.h b/src/qml/qml/qqmlextensioninterface.h
index d2eb79c5c9..1490bc512e 100644
--- a/src/qml/qml/qqmlextensioninterface.h
+++ b/src/qml/qml/qqmlextensioninterface.h
@@ -62,8 +62,14 @@ public:
virtual void initializeEngine(QQmlEngine *engine, const char *uri) = 0;
};
-#define QQmlTypesExtensionInterface_iid "org.qt-project.Qt.QQmlTypesExtensionInterface"
+class Q_QML_EXPORT QQmlEngineExtensionInterface
+{
+public:
+ virtual ~QQmlEngineExtensionInterface() = default;
+ virtual void initializeEngine(QQmlEngine *engine, const char *uri) = 0;
+};
+#define QQmlTypesExtensionInterface_iid "org.qt-project.Qt.QQmlTypesExtensionInterface"
Q_DECLARE_INTERFACE(QQmlTypesExtensionInterface, "org.qt-project.Qt.QQmlTypesExtensionInterface/1.0")
// NOTE: When changing this to a new version and deciding to add backup code to
@@ -73,6 +79,9 @@ Q_DECLARE_INTERFACE(QQmlTypesExtensionInterface, "org.qt-project.Qt.QQmlTypesExt
Q_DECLARE_INTERFACE(QQmlExtensionInterface, QQmlExtensionInterface_iid)
+#define QQmlEngineExtensionInterface_iid "org.qt-project.Qt.QQmlEngineExtensionInterface"
+Q_DECLARE_INTERFACE(QQmlEngineExtensionInterface, QQmlEngineExtensionInterface_iid)
+
QT_END_NAMESPACE
#endif // QQMLEXTENSIONINTERFACE_H
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index a1087a0034..7a62c967e7 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -43,10 +43,11 @@
QT_BEGIN_NAMESPACE
/*!
- \since 5.0
+ \since 5.14
\inmodule QtQml
- \class QQmlExtensionPlugin
- \brief The QQmlExtensionPlugin class provides an abstract base for custom QML extension plugins.
+ \class QQmlEngineExtensionPlugin
+ \brief The QQmlEngineExtensionPlugin class provides an abstract base for custom QML extension
+ plugins.
\ingroup plugins
@@ -60,6 +61,7 @@ QT_BEGIN_NAMESPACE
/*!
\fn void QQmlExtensionPlugin::registerTypes(const char *uri)
+ \internal
Registers the QML types in the given \a uri. Subclasses should implement
this to call qmlRegisterType() for all types which are provided by the extension
@@ -70,26 +72,39 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \internal
+*/
+QQmlExtensionPlugin::QQmlExtensionPlugin(QObject *parent)
+ : QObject(*(new QQmlExtensionPluginPrivate), parent)
+{
+}
+
+/*!
Constructs a QML extension plugin with the given \a parent.
Note that this constructor is invoked automatically by the
Q_PLUGIN_METADATA() macro, so there is no need for calling it
explicitly.
-*/
-QQmlExtensionPlugin::QQmlExtensionPlugin(QObject *parent)
- : QObject(*(new QQmlExtensionPluginPrivate), parent)
+ */
+QQmlEngineExtensionPlugin::QQmlEngineExtensionPlugin(QObject *parent)
+ : QObject(parent)
{
}
+
/*!
\internal
*/
-QQmlExtensionPlugin::~QQmlExtensionPlugin()
-{
-}
+QQmlExtensionPlugin::~QQmlExtensionPlugin() = default;
+
+/*!
+ \internal
+ */
+QQmlEngineExtensionPlugin::~QQmlEngineExtensionPlugin() = default;
/*!
\since 5.1
+ \internal
\brief Returns the URL of the directory from which the extension is loaded.
This is useful when the plugin also needs to load QML files or other
@@ -102,11 +117,21 @@ QUrl QQmlExtensionPlugin::baseUrl() const
}
/*!
+ \internal
+*/
+
+void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
+{
+ Q_UNUSED(engine);
+ Q_UNUSED(uri);
+}
+
+/*!
Initializes the extension from the \a uri using the \a engine. Here an application
plugin might, for example, expose some data or objects to QML,
as context properties on the engine's root context.
-*/
-void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
+ */
+void QQmlEngineExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
{
Q_UNUSED(engine);
Q_UNUSED(uri);
@@ -124,6 +149,12 @@ void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
\inmodule QtQml
*/
+/*!
+ \class QQmlEngineExtensionInterface
+ \internal
+ \inmodule QtQml
+*/
+
QT_END_NAMESPACE
#include "moc_qqmlextensionplugin.cpp"
diff --git a/src/qml/qml/qqmlextensionplugin.h b/src/qml/qml/qqmlextensionplugin.h
index 55e9b89dae..ef7ff422cd 100644
--- a/src/qml/qml/qqmlextensionplugin.h
+++ b/src/qml/qml/qqmlextensionplugin.h
@@ -70,6 +70,19 @@ private:
Q_DISABLE_COPY(QQmlExtensionPlugin)
};
+class Q_QML_EXPORT QQmlEngineExtensionPlugin
+ : public QObject
+ , public QQmlEngineExtensionInterface
+{
+ Q_OBJECT
+ Q_DISABLE_COPY_MOVE(QQmlEngineExtensionPlugin)
+ Q_INTERFACES(QQmlEngineExtensionInterface)
+public:
+ explicit QQmlEngineExtensionPlugin(QObject *parent = nullptr);
+ ~QQmlEngineExtensionPlugin() override;
+ void initializeEngine(QQmlEngine *engine, const char *uri) override;
+};
+
QT_END_NAMESPACE
#endif // QQMLEXTENSIONPLUGIN_H
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index a01b07c75c..c3f6a9057d 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -58,6 +58,7 @@
#include <private/qqmltypeloaderqmldircontent_p.h>
#include <QtCore/qjsonobject.h>
#include <QtCore/qjsonarray.h>
+#include <QtQml/private/qqmltype_p_p.h>
#include <algorithm>
#include <functional>
@@ -229,8 +230,7 @@ public:
bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor,
QQmlType *type_return, QList<QQmlError> *errors,
QQmlType::RegistrationType registrationType,
- QQmlImport::RecursionRestriction recursionRestriction
- = QQmlImport::PreventRecursion);
+ bool *typeRecursionDetected = nullptr);
QUrl baseUrl;
QString base;
@@ -246,9 +246,9 @@ public:
QQmlTypeLoader *typeLoader;
- static bool locateQmldir(const QString &uri, int vmaj, int vmin,
- QQmlImportDatabase *database,
- QString *outQmldirFilePath, QString *outUrl);
+ static QQmlImports::LocalQmldirResult locateLocalQmldir(
+ const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database,
+ QString *outQmldirFilePath, QString *outUrl);
static bool validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, int vmaj, int vmin,
QList<QQmlError> *errors);
@@ -534,7 +534,7 @@ static QString joinStringRefs(const QVector<QStringRef> &refs, const QChar &sep)
*/
QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringList &basePaths, int vmaj, int vmin)
{
- const QVector<QStringRef> parts = uri.splitRef(Dot, QString::SkipEmptyParts);
+ const QVector<QStringRef> parts = uri.splitRef(Dot, Qt::SkipEmptyParts);
QStringList qmlDirPathsPaths;
// fully & partially versioned parts + 1 unversioned for each base path
@@ -594,7 +594,7 @@ bool QQmlImports::resolveType(const QHashedStringRef &type,
QQmlType *type_return, int *vmaj, int *vmin,
QQmlImportNamespace** ns_return, QList<QQmlError> *errors,
QQmlType::RegistrationType registrationType,
- QQmlImport::RecursionRestriction recursionRestriction) const
+ bool *typeRecursionDetected) const
{
QQmlImportNamespace* ns = d->findQualifiedNamespace(type);
if (ns) {
@@ -604,7 +604,7 @@ bool QQmlImports::resolveType(const QHashedStringRef &type,
}
if (type_return) {
if (d->resolveType(type, vmaj, vmin, type_return, errors, registrationType,
- recursionRestriction)) {
+ typeRecursionDetected)) {
if (qmlImportTrace()) {
#define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \
<< ')' << "::resolveType: " << type.toString() << " => "
@@ -614,6 +614,8 @@ bool QQmlImports::resolveType(const QHashedStringRef &type,
RESOLVE_TYPE_DEBUG << type_return->typeName() << ' ' << type_return->sourceUrl() << " TYPE/URL-SINGLETON";
else if (type_return->isComposite())
RESOLVE_TYPE_DEBUG << type_return->typeName() << ' ' << type_return->sourceUrl() << " TYPE/URL";
+ else if (type_return->isInlineComponentType())
+ RESOLVE_TYPE_DEBUG << type_return->typeName() << ' ' << type_return->sourceUrl() << " TYPE(INLINECOMPONENT)";
else
RESOLVE_TYPE_DEBUG << type_return->typeName() << " TYPE";
}
@@ -710,6 +712,38 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
}
const QString typeStr = type.toString();
+ if (isInlineComponent) {
+ Q_ASSERT(type_return);
+ bool ret = uri == typeStr;
+ if (ret) {
+ Q_ASSERT(!type_return->isValid());
+ auto createICType = [&]() {
+ auto typePriv = new QQmlTypePrivate {QQmlType::RegistrationType::InlineComponentType};
+ bool ok = false;
+ typePriv->extraData.id->objectId = QUrl(this->url).fragment().toInt(&ok);
+ Q_ASSERT(ok);
+ typePriv->extraData.id->url = QUrl(this->url);
+ auto icType = QQmlType(typePriv);
+ typePriv->release();
+ return icType;
+ };
+ if (containingType.isValid()) {
+ // we currently cannot reference a Singleton inside itself
+ // in that case, containingType is still invalid
+ if (int icID = containingType.lookupInlineComponentIdByName(typeStr) != -1) {
+ *type_return = containingType.lookupInlineComponentById(icID);
+ } else {
+ auto icType = createICType();
+ int placeholderId = containingType.generatePlaceHolderICId();
+ const_cast<QQmlImportInstance*>(this)->containingType.associateInlineComponent(typeStr, placeholderId, CompositeMetaTypeIds {}, icType);
+ *type_return = QQmlType(icType);
+ }
+ } else {
+ *type_return = createICType();
+ }
+ }
+ return ret;
+ }
QQmlDirComponents::ConstIterator it = qmlDirComponents.find(typeStr), end = qmlDirComponents.end();
if (it != end) {
QString componentUrl;
@@ -744,9 +778,12 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
if (resolveLocalUrl(*base, c.fileName) != componentUrl)
continue; // failed attempt to access an internal type
}
- if (recursionRestriction == QQmlImport::PreventRecursion && *base == componentUrl) {
- if (typeRecursionDetected)
- *typeRecursionDetected = true;
+
+ const bool recursion = *base == componentUrl;
+ if (typeRecursionDetected)
+ *typeRecursionDetected = recursion;
+
+ if (recursionRestriction == QQmlImport::PreventRecursion && recursion) {
continue; // no recursion
}
}
@@ -803,10 +840,10 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
}
if (exists) {
- if (recursionRestriction == QQmlImport::PreventRecursion && base && (*base == qmlUrl)) { // no recursion
- if (typeRecursionDetected)
- *typeRecursionDetected = true;
- } else {
+ const bool recursion = base && *base == qmlUrl;
+ if (typeRecursionDetected)
+ *typeRecursionDetected = recursion;
+ if (recursionRestriction == QQmlImport::AllowRecursion || !recursion) {
QQmlType returnType = QQmlMetaType::typeForUrl(
qmlUrl, type, registrationType == QQmlType::CompositeSingletonType, errors);
if (type_return)
@@ -822,49 +859,111 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor,
QQmlType *type_return, QList<QQmlError> *errors,
QQmlType::RegistrationType registrationType,
- QQmlImport::RecursionRestriction recursionRestriction)
+ bool *typeRecursionDetected)
{
- QQmlImportNamespace *s = nullptr;
- int dot = type.indexOf(Dot);
- if (dot >= 0) {
- QHashedStringRef namespaceName(type.constData(), dot);
- s = findQualifiedNamespace(namespaceName);
- if (!s) {
- if (errors) {
- QQmlError error;
- error.setDescription(QQmlImportDatabase::tr("- %1 is not a namespace").arg(namespaceName.toString()));
- errors->prepend(error);
- }
- return false;
- }
- int ndot = type.indexOf(Dot,dot+1);
- if (ndot > 0) {
- if (errors) {
- QQmlError error;
- error.setDescription(QQmlImportDatabase::tr("- nested namespaces not allowed"));
- errors->prepend(error);
- }
- return false;
- }
- } else {
- s = &unqualifiedset;
- }
- QHashedStringRef unqualifiedtype = dot < 0 ? type : QHashedStringRef(type.constData()+dot+1, type.length()-dot-1);
- if (s) {
- if (s->resolveType(typeLoader, unqualifiedtype, vmajor, vminor, type_return, &base, errors,
- registrationType, recursionRestriction))
+ const QVector<QHashedStringRef> splitName = type.split(Dot);
+ auto resolveTypeInNamespace = [&](QHashedStringRef unqualifiedtype, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors) -> bool {
+ if (nameSpace->resolveType(typeLoader, unqualifiedtype, vmajor, vminor, type_return, &base, errors,
+ registrationType, typeRecursionDetected))
return true;
- if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && type_return && s != &unqualifiedset) {
+ if (nameSpace->imports.count() == 1 && !nameSpace->imports.at(0)->isLibrary && type_return && nameSpace != &unqualifiedset) {
// qualified, and only 1 url
*type_return = QQmlMetaType::typeForUrl(
- resolveLocalUrl(s->imports.at(0)->url,
+ resolveLocalUrl(nameSpace->imports.at(0)->url,
unqualifiedtype.toString() + QLatin1String(".qml")),
type, false, errors);
return type_return->isValid();
}
+ return false;
+ };
+ switch (splitName.size()) {
+ case 1: {
+ // must be a simple type
+ return resolveTypeInNamespace(type, &unqualifiedset, errors);
}
-
- return false;
+ case 2: {
+ // either namespace + simple type OR simple type + inline component
+ QQmlImportNamespace *s = findQualifiedNamespace(splitName.at(0));
+ if (s) {
+ // namespace + simple type
+ return resolveTypeInNamespace(splitName.at(1), s, errors);
+ } else {
+ if (resolveTypeInNamespace(splitName.at(0), &unqualifiedset, nullptr)) {
+ // either simple type + inline component
+ auto const icName = splitName.at(1).toString();
+ auto objectIndex = type_return->lookupInlineComponentIdByName(icName);
+ if (objectIndex != -1) {
+ *type_return = type_return->lookupInlineComponentById(objectIndex);
+ } else {
+ auto icTypePriv = new QQmlTypePrivate(QQmlType::RegistrationType::InlineComponentType);
+ icTypePriv->setContainingType(type_return);
+ icTypePriv->extraData.id->url = type_return->sourceUrl();
+ int placeholderId = type_return->generatePlaceHolderICId();
+ icTypePriv->extraData.id->url.setFragment(QString::number(placeholderId));
+ auto icType = QQmlType(icTypePriv);
+ icTypePriv->release();
+ type_return->associateInlineComponent(icName, placeholderId, CompositeMetaTypeIds {}, icType);
+ *type_return = icType;
+ }
+ Q_ASSERT(type_return->containingType().isValid());
+ type_return->setPendingResolutionName(icName);
+ return true;
+ } else {
+ // or a failure
+ if (errors) {
+ QQmlError error;
+ error.setDescription(QQmlImportDatabase::tr("- %1 is neither a type nor a namespace").arg(splitName.at(0).toString()));
+ errors->prepend(error);
+ }
+ return false;
+ }
+ }
+ }
+ case 3: {
+ // must be namespace + simple type + inline component
+ QQmlImportNamespace *s = findQualifiedNamespace(splitName.at(0));
+ QQmlError error;
+ if (!s) {
+ error.setDescription(QQmlImportDatabase::tr("- %1 is not a namespace").arg(splitName.at(0).toString()));
+ } else {
+ if (resolveTypeInNamespace(splitName.at(1), s, nullptr)) {
+ auto const icName = splitName.at(2).toString();
+ auto objectIndex = type_return->lookupInlineComponentIdByName(icName);
+ if (objectIndex != -1)
+ *type_return = type_return->lookupInlineComponentById(objectIndex);
+ else {
+ auto icTypePriv = new QQmlTypePrivate(QQmlType::RegistrationType::InlineComponentType);
+ icTypePriv->setContainingType(type_return);
+ icTypePriv->extraData.id->url = type_return->sourceUrl();
+ int placeholderId = type_return->generatePlaceHolderICId();
+ icTypePriv->extraData.id->url.setFragment(QString::number(placeholderId));
+ auto icType = QQmlType(icTypePriv);
+ icTypePriv->release();
+ type_return->associateInlineComponent(icName, placeholderId, CompositeMetaTypeIds {}, icType);
+ *type_return = icType;
+ }
+ type_return->setPendingResolutionName(icName);
+ return true;
+ } else {
+ error.setDescription(QQmlImportDatabase::tr("- %1 is not a type").arg(splitName.at(1).toString()));
+ }
+ }
+ if (errors) {
+ errors->prepend(error);
+ }
+ return false;
+ }
+ default: {
+ // all other numbers suggest a user error
+ if (errors) {
+ QQmlError error;
+ error.setDescription(QQmlImportDatabase::tr("- nested namespaces not allowed"));
+ errors->prepend(error);
+ }
+ return false;
+ }
+ }
+ Q_UNREACHABLE();
}
QQmlImportInstance *QQmlImportNamespace::findImport(const QString &uri) const
@@ -880,13 +979,25 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS
int *vmajor, int *vminor, QQmlType *type_return,
QString *base, QList<QQmlError> *errors,
QQmlType::RegistrationType registrationType,
- QQmlImport::RecursionRestriction recursionRestriction)
+ bool *typeRecursionDetected)
{
- bool typeRecursionDetected = false;
+ QQmlImport::RecursionRestriction recursionRestriction =
+ typeRecursionDetected ? QQmlImport::AllowRecursion : QQmlImport::PreventRecursion;
+
+ bool localTypeRecursionDetected = false;
+ if (!typeRecursionDetected)
+ typeRecursionDetected = &localTypeRecursionDetected;
+
+ if (needsSorting()) {
+ std::stable_sort(imports.begin(), imports.end(), [](QQmlImportInstance *left, QQmlImportInstance *) {
+ return left->isInlineComponent;
+ });
+ setNeedsSorting(false);
+ }
for (int i=0; i<imports.count(); ++i) {
const QQmlImportInstance *import = imports.at(i);
if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, base,
- &typeRecursionDetected, registrationType, recursionRestriction, errors)) {
+ typeRecursionDetected, registrationType, recursionRestriction, errors)) {
if (qmlCheckTypes()) {
// check for type clashes
for (int j = i+1; j<imports.count(); ++j) {
@@ -933,7 +1044,7 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS
}
if (errors) {
QQmlError error;
- if (typeRecursionDetected)
+ if (*typeRecursionDetected)
error.setDescription(QQmlImportDatabase::tr("is instantiated recursively"));
else
error.setDescription(QQmlImportDatabase::tr("is not a type"));
@@ -942,6 +1053,17 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS
return false;
}
+bool QQmlImportNamespace::needsSorting() const
+{
+ return nextNamespace == this;
+}
+
+void QQmlImportNamespace::setNeedsSorting(bool needsSorting)
+{
+ Q_ASSERT(nextNamespace == this || nextNamespace == nullptr);
+ nextNamespace = needsSorting ? this : nullptr;
+}
+
QQmlImportsPrivate::QQmlImportsPrivate(QQmlTypeLoader *loader)
: ref(1), typeLoader(loader) {
}
@@ -990,7 +1112,9 @@ static QVector<QStaticPlugin> makePlugins()
const auto staticPlugins = QPluginLoader::staticPlugins();
for (const QStaticPlugin &plugin : staticPlugins) {
const QString iid = plugin.metaData().value(QLatin1String("IID")).toString();
- if (iid == QLatin1String(QQmlExtensionInterface_iid) || iid == QLatin1String(QQmlExtensionInterface_iid_old)) {
+ if (iid == QLatin1String(QQmlEngineExtensionInterface_iid)
+ || iid == QLatin1String(QQmlExtensionInterface_iid)
+ || iid == QLatin1String(QQmlExtensionInterface_iid_old)) {
plugins.append(plugin);
}
}
@@ -1008,7 +1132,9 @@ bool QQmlImportsPrivate::populatePluginPairVector(QVector<StaticPluginPair> &res
static const QVector<QStaticPlugin> plugins = makePlugins();
for (const QStaticPlugin &plugin : plugins) {
// Since a module can list more than one plugin, we keep iterating even after we found a match.
- if (QQmlExtensionPlugin *instance = qobject_cast<QQmlExtensionPlugin *>(plugin.instance())) {
+ QObject *instance = plugin.instance();
+ if (qobject_cast<QQmlEngineExtensionPlugin *>(instance)
+ || qobject_cast<QQmlExtensionPlugin *>(instance)) {
const QJsonArray metaTagsUriList = plugin.metaData().value(QLatin1String("uri")).toArray();
if (metaTagsUriList.isEmpty()) {
if (errors) {
@@ -1064,7 +1190,13 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
if (qmldirPluginCount == 0)
return true;
- if (!database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) {
+ if (database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) {
+ if ((vmaj >= 0 && vmin >= 0)
+ ? !QQmlMetaType::isModule(uri, vmaj, vmin)
+ : !QQmlMetaType::isAnyModule(uri)) {
+ QQmlMetaType::qmlRegisterModuleTypes(uri, vmaj);
+ }
+ } else {
// First search for listed qmldir plugins dynamically. If we cannot resolve them all, we continue
// searching static plugins that has correct metadata uri. Note that since we only know the uri
// for a static plugin, and not the filename, we cannot know which static plugin belongs to which
@@ -1225,8 +1357,9 @@ Locates the qmldir file for \a uri version \a vmaj.vmin. Returns true if found,
and fills in outQmldirFilePath and outQmldirUrl appropriately. Otherwise returns
false.
*/
-bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database,
- QString *outQmldirFilePath, QString *outQmldirPathUrl)
+QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir(
+ const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database,
+ QString *outQmldirFilePath, QString *outQmldirPathUrl)
{
Q_ASSERT(vmaj >= 0 && vmin >= 0); // Versions are always specified for libraries
@@ -1234,20 +1367,21 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ
QQmlImportDatabase::QmldirCache *cacheHead = nullptr;
{
- QQmlImportDatabase::QmldirCache **cachePtr = database->qmldirCache.value(uri);
- if (cachePtr) {
- cacheHead = *cachePtr;
- QQmlImportDatabase::QmldirCache *cache = cacheHead;
- while (cache) {
- if (cache->versionMajor == vmaj && cache->versionMinor == vmin) {
- *outQmldirFilePath = cache->qmldirFilePath;
- *outQmldirPathUrl = cache->qmldirPathUrl;
- return !cache->qmldirFilePath.isEmpty();
+ QQmlImportDatabase::QmldirCache **cachePtr = database->qmldirCache.value(uri);
+ if (cachePtr) {
+ cacheHead = *cachePtr;
+ QQmlImportDatabase::QmldirCache *cache = cacheHead;
+ while (cache) {
+ if (cache->versionMajor == vmaj && cache->versionMinor == vmin) {
+ *outQmldirFilePath = cache->qmldirFilePath;
+ *outQmldirPathUrl = cache->qmldirPathUrl;
+ return cache->qmldirFilePath.isEmpty() ? QQmlImports::QmldirNotFound
+ : QQmlImports::QmldirFound;
+ }
+ cache = cache->next;
}
- cache = cache->next;
}
}
- }
QQmlTypeLoader &typeLoader = QQmlEnginePrivate::get(database->engine)->typeLoader;
@@ -1257,12 +1391,17 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ
interceptor ? QQmlImportDatabase::LocalOrRemote : QQmlImportDatabase::Local);
// Search local import paths for a matching version
- const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(uri, localImportPaths, vmaj, vmin);
+ const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(
+ uri, localImportPaths, vmaj, vmin);
+ bool pathTurnedRemote = false;
for (QString qmldirPath : qmlDirPaths) {
if (interceptor) {
- qmldirPath = QQmlFile::urlToLocalFileOrQrc(
- interceptor->intercept(QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
- QQmlAbstractUrlInterceptor::QmldirFile));
+ const QUrl intercepted = interceptor->intercept(
+ QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
+ QQmlAbstractUrlInterceptor::QmldirFile);
+ qmldirPath = QQmlFile::urlToLocalFileOrQrc(intercepted);
+ if (!pathTurnedRemote && qmldirPath.isEmpty() && !QQmlFile::isLocalFile(intercepted))
+ pathTurnedRemote = true;
}
QString absoluteFilePath = typeLoader.absoluteFilePath(qmldirPath);
@@ -1285,7 +1424,7 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ
*outQmldirFilePath = absoluteFilePath;
*outQmldirPathUrl = url;
- return true;
+ return QQmlImports::QmldirFound;
}
}
@@ -1295,7 +1434,7 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ
cache->next = cacheHead;
database->qmldirCache.insert(uri, cache);
- return false;
+ return pathTurnedRemote ? QQmlImports::QmldirInterceptedToRemote : QQmlImports::QmldirNotFound;
}
bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, int vmaj, int vmin,
@@ -1627,6 +1766,22 @@ bool QQmlImports::addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlErro
}
/*!
+ \internal
+ */
+bool QQmlImports::addInlineComponentImport(QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl, QQmlType containingType)
+{
+ importInstance->url = importUrl.toString();
+ importInstance->uri = name;
+ importInstance->isInlineComponent = true;
+ importInstance->majversion = 0;
+ importInstance->minversion = 0;
+ importInstance->containingType = containingType;
+ d->unqualifiedset.imports.push_back(importInstance);
+ d->unqualifiedset.setNeedsSorting(true);
+ return true;
+}
+
+/*!
\internal
Adds information to \a imports such that subsequent calls to resolveType()
@@ -1689,11 +1844,11 @@ bool QQmlImports::updateQmldirContent(QQmlImportDatabase *importDb,
return d->updateQmldirContent(uri, prefix, qmldirIdentifier, qmldirUrl, importDb, errors);
}
-bool QQmlImports::locateQmldir(QQmlImportDatabase *importDb,
- const QString& uri, int vmaj, int vmin,
- QString *qmldirFilePath, QString *url)
+QQmlImports::LocalQmldirResult QQmlImports::locateLocalQmldir(
+ QQmlImportDatabase *importDb, const QString &uri, int vmaj, int vmin,
+ QString *qmldirFilePath, QString *url)
{
- return d->locateQmldir(uri, vmaj, vmin, importDb, qmldirFilePath, url);
+ return d->locateLocalQmldir(uri, vmaj, vmin, importDb, qmldirFilePath, url);
}
bool QQmlImports::isLocal(const QString &url)
@@ -1744,7 +1899,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
#else
QLatin1Char pathSep(':');
#endif
- QStringList paths = envImportPath.split(pathSep, QString::SkipEmptyParts);
+ QStringList paths = envImportPath.split(pathSep, Qt::SkipEmptyParts);
for (int ii = paths.count() - 1; ii >= 0; --ii)
addImportPath(paths.at(ii));
}
@@ -1756,7 +1911,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QT_BUNDLED_LIBS_PATH"))) {
const QString envImportPath = qEnvironmentVariable("QT_BUNDLED_LIBS_PATH");
QLatin1Char pathSep(':');
- QStringList paths = envImportPath.split(pathSep, QString::SkipEmptyParts);
+ QStringList paths = envImportPath.split(pathSep, Qt::SkipEmptyParts);
for (int ii = paths.count() - 1; ii >= 0; --ii)
addPluginPath(paths.at(ii));
}
@@ -2001,12 +2156,25 @@ void QQmlImportDatabase::setImportPathList(const QStringList &paths)
/*!
\internal
*/
-bool QQmlImportDatabase::registerPluginTypes(QObject *instance, const QString &basePath,
- const QString &uri, const QString &typeNamespace, int vmaj, QList<QQmlError> *errors)
+static bool registerPluginTypes(QObject *instance, const QString &basePath, const QString &uri,
+ const QString &typeNamespace, int vmaj, QList<QQmlError> *errors)
{
if (qmlImportTrace())
qDebug().nospace() << "QQmlImportDatabase::registerPluginTypes: " << uri << " from " << basePath;
- return QQmlMetaType::registerPluginTypes(instance, basePath, uri, typeNamespace, vmaj, errors);
+
+ if (!QQmlMetaType::registerPluginTypes(instance, basePath, uri, typeNamespace, vmaj, errors))
+ return false;
+
+ if (vmaj >= 0 && !typeNamespace.isEmpty() && !QQmlMetaType::protectModule(uri, vmaj)) {
+ QQmlError error;
+ error.setDescription(
+ QString::fromLatin1("Cannot protect module %1 %2 as it was never registered")
+ .arg(uri).arg(vmaj));
+ errors->append(error);
+ return false;
+ }
+
+ return true;
}
/*!
@@ -2046,17 +2214,8 @@ bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &ba
// other QML loader threads and thus not process the initializeEngine call).
}
- // The plugin's per-engine initialization does not need lock protection, as this function is
- // only called from the engine specific loader thread and importDynamicPlugin as well as
- // importStaticPlugin are the only places of access.
- if (!initializedPlugins.contains(uniquePluginID)) {
- initializedPlugins.insert(uniquePluginID);
-
- if (QQmlExtensionInterface *eiface = qobject_cast<QQmlExtensionInterface *>(instance)) {
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- ep->typeLoader.initializeEngine(eiface, uri.toUtf8().constData());
- }
- }
+ if (!initializedPlugins.contains(uniquePluginID))
+ finalizePlugin(instance, uniquePluginID, uri);
return true;
}
@@ -2131,22 +2290,46 @@ bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QStr
// other QML loader threads and thus not process the initializeEngine call).
}
+ if (!engineInitialized)
+ finalizePlugin(instance, absoluteFilePath, uri);
- if (!engineInitialized) {
- // The plugin's per-engine initialization does not need lock protection, as this function is
- // only called from the engine specific loader thread and importDynamicPlugin as well as
- // importStaticPlugin are the only places of access.
- initializedPlugins.insert(absoluteFilePath);
+ return true;
+}
- if (QQmlExtensionInterface *eiface = qobject_cast<QQmlExtensionInterface *>(instance)) {
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- ep->typeLoader.initializeEngine(eiface, uri.toUtf8().constData());
- }
+bool QQmlImportDatabase::removeDynamicPlugin(const QString &filePath)
+{
+ StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
+ QMutexLocker lock(&plugins->mutex);
+
+ auto it = plugins->find(QFileInfo(filePath).absoluteFilePath());
+ if (it == plugins->end())
+ return false;
+
+ QPluginLoader *loader = it->loader;
+ if (!loader)
+ return false;
+
+ if (!loader->unload()) {
+ qWarning("Unloading %s failed: %s", qPrintable(it->uri),
+ qPrintable(loader->errorString()));
}
+ delete loader;
+ plugins->erase(it);
return true;
}
+QStringList QQmlImportDatabase::dynamicPlugins() const
+{
+ StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
+ QMutexLocker lock(&plugins->mutex);
+ QStringList results;
+ for (auto it = plugins->constBegin(), end = plugins->constEnd(); it != end; ++it) {
+ if (it->loader != nullptr)
+ results.append(it.key());
+ }
+ return results;
+}
#endif // QT_CONFIG(library)
void QQmlImportDatabase::clearDirCache()
@@ -2165,4 +2348,20 @@ void QQmlImportDatabase::clearDirCache()
qmldirCache.clear();
}
+void QQmlImportDatabase::finalizePlugin(QObject *instance, const QString &path, const QString &uri)
+{
+ // The plugin's per-engine initialization does not need lock protection, as this function is
+ // only called from the engine specific loader thread and importDynamicPlugin as well as
+ // importStaticPlugin are the only places of access.
+
+ initializedPlugins.insert(path);
+ if (auto *extensionIface = qobject_cast<QQmlExtensionInterface *>(instance)) {
+ QQmlEnginePrivate::get(engine)->typeLoader.initializeEngine(
+ extensionIface, uri.toUtf8().constData());
+ } else if (auto *engineIface = qobject_cast<QQmlEngineExtensionInterface *>(instance)) {
+ QQmlEnginePrivate::get(engine)->typeLoader.initializeEngine(
+ engineIface, uri.toUtf8().constData());
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index ea9c2eafb5..594eae7bb4 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -80,10 +80,12 @@ struct QQmlImportInstance
QString uri; // e.g. QtQuick
QString url; // the base path of the import
QString localDirectoryPath; // the base path of the import if it's a local file
+ QQmlType containingType; // points to the containing type for inline components
int majversion; // the major version imported
int minversion; // the minor version imported
bool isLibrary; // true means that this is not a file import
bool implicitlyImported = false;
+ bool isInlineComponent = false;
QQmlDirComponents qmlDirComponents; // a copy of the components listed in the qmldir
QQmlDirScripts qmlDirScripts; // a copy of the scripts in the qmldir
@@ -114,13 +116,18 @@ public:
int *vmajor, int *vminor, QQmlType* type_return,
QString *base = nullptr, QList<QQmlError> *errors = nullptr,
QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
- QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion);
+ bool *typeRecursionDeteced = nullptr);
// Prefix when used as a qualified import. Otherwise empty.
QHashedString prefix;
// Used by QQmlImportsPrivate::qualifiedSets
+ // set to this in unqualifiedSet to indicate that the lists of imports needs
+ // to be sorted when an inline component import was added
+ // We can't use flag pointer, as that does not work with QFieldList
QQmlImportNamespace *nextNamespace;
+ bool needsSorting() const;
+ void setNeedsSorting(bool needsSorting);
};
class Q_QML_PRIVATE_EXPORT QQmlImports
@@ -142,8 +149,7 @@ public:
QQmlImportNamespace **ns_return,
QList<QQmlError> *errors = nullptr,
QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
- QQmlImport::RecursionRestriction recursionRestriction
- = QQmlImport::PreventRecursion) const;
+ bool *typeRecursionDetected = nullptr) const;
bool resolveType(QQmlImportNamespace *,
const QHashedStringRef& type,
QQmlType *type_return, int *version_major, int *version_minor,
@@ -152,6 +158,8 @@ public:
bool addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlError> *errors);
+ bool addInlineComponentImport(QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl, QQmlType containingType);
+
bool addFileImport(QQmlImportDatabase *,
const QString& uri, const QString& prefix, int vmaj, int vmin, bool incomplete,
QList<QQmlError> *errors);
@@ -164,9 +172,15 @@ public:
const QString &uri, const QString &prefix,
const QString &qmldirIdentifier, const QString &qmldirUrl, QList<QQmlError> *errors);
- bool locateQmldir(QQmlImportDatabase *,
- const QString &uri, int vmaj, int vmin,
- QString *qmldirFilePath, QString *url);
+ enum LocalQmldirResult {
+ QmldirFound,
+ QmldirNotFound,
+ QmldirInterceptedToRemote
+ };
+
+ LocalQmldirResult locateLocalQmldir(
+ QQmlImportDatabase *, const QString &uri, int vmaj, int vmin,
+ QString *qmldirFilePath, QString *url);
void populateCache(QQmlTypeNameCache *cache) const;
@@ -203,7 +217,7 @@ private:
QQmlImportsPrivate *d;
};
-class QQmlImportDatabase
+class Q_QML_PRIVATE_EXPORT QQmlImportDatabase
{
Q_DECLARE_TR_FUNCTIONS(QQmlImportDatabase)
public:
@@ -214,6 +228,8 @@ public:
#if QT_CONFIG(library)
bool importDynamicPlugin(const QString &filePath, const QString &uri, const QString &importNamespace, int vmaj, QList<QQmlError> *errors);
+ bool removeDynamicPlugin(const QString &filePath);
+ QStringList dynamicPlugins() const;
#endif
QStringList importPathList(PathType type = LocalOrRemote) const;
@@ -235,9 +251,8 @@ private:
const QString &baseName);
bool importStaticPlugin(QObject *instance, const QString &basePath, const QString &uri,
const QString &typeNamespace, int vmaj, QList<QQmlError> *errors);
- bool registerPluginTypes(QObject *instance, const QString &basePath,
- const QString &uri, const QString &typeNamespace, int vmaj, QList<QQmlError> *errors);
void clearDirCache();
+ void finalizePlugin(QObject *instance, const QString &path, const QString &uri);
struct QmldirCache {
int versionMajor;
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index bc06226cbf..0ad013e90b 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -43,6 +43,7 @@
#include "qqmlexpression_p.h"
#include "qqmlobjectcreator_p.h"
+#include <private/qqmlcomponent_p.h>
void QQmlEnginePrivate::incubate(QQmlIncubator &i, QQmlContextData *forContext)
{
@@ -60,7 +61,7 @@ void QQmlEnginePrivate::incubate(QQmlIncubator &i, QQmlContextData *forContext)
QExplicitlySharedDataPointer<QQmlIncubatorPrivate> parentIncubator;
QQmlContextData *cctxt = forContext;
while (cctxt) {
- if (cctxt->incubator) {
+ if (!cctxt->hasExtraObject && cctxt->incubator) {
parentIncubator = cctxt->incubator;
break;
}
@@ -148,7 +149,8 @@ void QQmlIncubatorPrivate::clear()
}
enginePriv = nullptr;
if (!rootContext.isNull()) {
- rootContext->incubator = nullptr;
+ if (!rootContext->hasExtraObject)
+ rootContext->incubator = nullptr;
rootContext = nullptr;
}
@@ -296,6 +298,20 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
tresult = creator->create(subComponentToCreate, /*parent*/nullptr, &i);
if (!tresult)
errors = creator->errors;
+ else {
+ RequiredProperties& requiredProperties = creator->requiredProperties();
+ for (auto it = initialProperties.cbegin(); it != initialProperties.cend(); ++it) {
+ auto component = tresult;
+ auto name = it.key();
+ QQmlProperty prop = QQmlComponentPrivate::removePropertyFromRequired(component, name, requiredProperties);
+ if (!prop.isValid() || !prop.write(it.value())) {
+ QQmlError error{};
+ error.setUrl(compilationUnit->url());
+ error.setDescription(QLatin1String("Could not set property %1").arg(name));
+ errors.push_back(error);
+ }
+ }
+ }
enginePriv->dereferenceScarceResources();
if (watcher.hasRecursed())
@@ -312,8 +328,14 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
ddata->indestructible = true;
ddata->explicitIndestructibleSet = true;
ddata->rootObjectInCreation = false;
- if (q)
+ if (q) {
q->setInitialState(result);
+ if (!creator->requiredProperties().empty()) {
+ const auto& unsetRequiredProperties = creator->requiredProperties();
+ for (const auto& unsetRequiredProperty: unsetRequiredProperties)
+ errors << QQmlComponentPrivate::unsetRequiredPropertyToQQmlError(unsetRequiredProperty);
+ }
+ }
}
if (watcher.hasRecursed())
@@ -381,26 +403,51 @@ void QQmlIncubationController::incubateFor(int msecs)
if (!d || !d->incubatorCount)
return;
- QQmlInstantiationInterrupt i(msecs * 1000000);
+ QQmlInstantiationInterrupt i(msecs * Q_INT64_C(1000000));
i.reset();
do {
static_cast<QQmlIncubatorPrivate*>(d->incubatorList.first())->incubate(i);
} while (d && d->incubatorCount != 0 && !i.shouldInterrupt());
}
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
-Incubate objects while the bool pointed to by \a flag is true, or until there are no
-more objects to incubate, or up to \a msecs if \a msecs is not zero.
+\obsolete
+
+\warning Do not use this function.
+Use the overload taking a \c{std::atomic<bool>} instead.
+*/
+void QQmlIncubationController::incubateWhile(volatile bool *flag, int msecs)
+{
+ if (!d || !d->incubatorCount)
+ return;
+
+ QQmlInstantiationInterrupt i(flag, msecs * Q_INT64_C(1000000));
+ i.reset();
+ do {
+ static_cast<QQmlIncubatorPrivate*>(d->incubatorList.first())->incubate(i);
+ } while (d && d->incubatorCount != 0 && !i.shouldInterrupt());
+}
+#endif
+
+/*!
+\since 5.15
+
+Incubate objects while the atomic bool pointed to by \a flag is true,
+or until there are no more objects to incubate, or up to \a msecs if \a
+msecs is not zero.
Generally this method is used in conjunction with a thread or a UNIX signal that sets
the bool pointed to by \a flag to false when it wants incubation to be interrupted.
+
+\note \a flag is read using acquire memory ordering.
*/
-void QQmlIncubationController::incubateWhile(volatile bool *flag, int msecs)
+void QQmlIncubationController::incubateWhile(std::atomic<bool> *flag, int msecs)
{
if (!d || !d->incubatorCount)
return;
- QQmlInstantiationInterrupt i(flag, msecs * 1000000);
+ QQmlInstantiationInterrupt i(flag, msecs * Q_INT64_C(1000000));
i.reset();
do {
static_cast<QQmlIncubatorPrivate*>(d->incubatorList.first())->incubate(i);
@@ -657,6 +704,36 @@ QObject *QQmlIncubator::object() const
}
/*!
+Return a list of properties which are required but haven't been set yet.
+This list can be modified, so that subclasses which implement special logic
+setInitialProperties can mark properties set there as no longer required.
+
+\sa QQmlIncubator::setInitialProperties
+\since 5.15
+*/
+RequiredProperties &QQmlIncubatorPrivate::requiredProperties()
+{
+ return creator->requiredProperties();
+}
+
+bool QQmlIncubatorPrivate::hadRequiredProperties() const
+{
+ return creator->componentHadRequiredProperties();
+}
+
+/*!
+Stores a mapping from property names to initial values, contained in
+\a initialProperties, with which the incubated component will be initialized.
+
+\sa QQmlComponent::setInitialProperties
+\since 5.15
+*/
+void QQmlIncubator::setInitialProperties(const QVariantMap &initialProperties)
+{
+ d->initialProperties = initialProperties;
+}
+
+/*!
Called when the status of the incubator changes. \a status is the new status.
The default implementation does nothing.
diff --git a/src/qml/qml/qqmlincubator.h b/src/qml/qml/qqmlincubator.h
index e68f6e3c45..6e47ca2173 100644
--- a/src/qml/qml/qqmlincubator.h
+++ b/src/qml/qml/qqmlincubator.h
@@ -42,11 +42,15 @@
#include <QtQml/qtqmlglobal.h>
#include <QtQml/qqmlerror.h>
+#include <atomic>
QT_BEGIN_NAMESPACE
class QQmlEngine;
+class QQmlPropertyData;
+class QVariant;
+using QVariantMap = QMap<QString, QVariant>;
class QQmlIncubatorPrivate;
class Q_QML_EXPORT QQmlIncubator
@@ -84,6 +88,8 @@ public:
QObject *object() const;
+ void setInitialProperties(const QVariantMap &initialProperties);
+
protected:
virtual void statusChanged(Status);
virtual void setInitialState(QObject *);
@@ -107,7 +113,11 @@ public:
int incubatingObjectCount() const;
void incubateFor(int msecs);
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_VERSION_X(5, 15, "Use the overload that takes a std::atomic<bool>")
void incubateWhile(volatile bool *flag, int msecs=0);
+#endif
+ void incubateWhile(std::atomic<bool> *flag, int msecs = 0);
protected:
virtual void incubatingObjectCountChanged(int);
diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h
index 57ec8249cb..a674ff274f 100644
--- a/src/qml/qml/qqmlincubator_p.h
+++ b/src/qml/qml/qqmlincubator_p.h
@@ -61,8 +61,10 @@
QT_BEGIN_NAMESPACE
+class RequiredProperties;
+
class QQmlIncubator;
-class QQmlIncubatorPrivate : public QQmlEnginePrivate::Incubator
+class Q_QML_PRIVATE_EXPORT QQmlIncubatorPrivate : public QQmlEnginePrivate::Incubator
{
public:
QQmlIncubatorPrivate(QQmlIncubator *q, QQmlIncubator::IncubationMode m);
@@ -97,11 +99,14 @@ public:
QIntrusiveList<QIPBase, &QIPBase::nextWaitingFor> waitingFor;
QRecursionNode recursion;
+ QVariantMap initialProperties;
void clear();
void forceCompletion(QQmlInstantiationInterrupt &i);
void incubate(QQmlInstantiationInterrupt &i);
+ RequiredProperties &requiredProperties();
+ bool hadRequiredProperties() const;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp
index dd401bdb20..7204d5ccd2 100644
--- a/src/qml/qml/qqmlinfo.cpp
+++ b/src/qml/qml/qqmlinfo.cpp
@@ -44,6 +44,7 @@
#include "qqmlcontext_p.h"
#include "qqmlmetatype_p.h"
#include "qqmlengine_p.h"
+#include "qqmlsourcecoordinate_p.h"
#include <QCoreApplication>
@@ -218,8 +219,8 @@ QQmlInfo::~QQmlInfo()
QQmlData *ddata = QQmlData::get(object, false);
if (ddata && ddata->outerContext) {
error.setUrl(ddata->outerContext->url());
- error.setLine(ddata->lineNumber);
- error.setColumn(ddata->columnNumber);
+ error.setLine(qmlConvertSourceCoordinate<quint16, int>(ddata->lineNumber));
+ error.setColumn(qmlConvertSourceCoordinate<quint16, int>(ddata->columnNumber));
}
}
diff --git a/src/qml/qml/qqmlirloader.cpp b/src/qml/qml/qqmlirloader.cpp
index 82cad8eba8..f66094fad7 100644
--- a/src/qml/qml/qqmlirloader.cpp
+++ b/src/qml/qml/qqmlirloader.cpp
@@ -78,14 +78,14 @@ struct FakeExpression : public QQmlJS::AST::NullExpression
: location(start, length)
{}
- virtual QQmlJS::AST::SourceLocation firstSourceLocation() const
+ virtual QQmlJS::SourceLocation firstSourceLocation() const
{ return location; }
- virtual QQmlJS::AST::SourceLocation lastSourceLocation() const
+ virtual QQmlJS::SourceLocation lastSourceLocation() const
{ return location; }
private:
- QQmlJS::AST::SourceLocation location;
+ QQmlJS::SourceLocation location;
};
QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *serializedObject)
@@ -200,6 +200,13 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
object->runtimeFunctionIndices.allocate(pool, functionIndices);
+ const QV4::CompiledData::InlineComponent *serializedInlineComponent = serializedObject->inlineComponentTable();
+ for (uint i = 0; i < serializedObject->nInlineComponents; ++i, ++serializedInlineComponent) {
+ QmlIR::InlineComponent *ic = pool->New<QmlIR::InlineComponent>();
+ *static_cast<QV4::CompiledData::InlineComponent*>(ic) = *serializedInlineComponent;
+ object->inlineComponents->append(ic);
+ }
+
return object;
}
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 8661ebcc13..6a9ef06159 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -50,6 +50,7 @@
#include <private/qqmlglobal_p.h>
#include <private/qv4qobjectwrapper_p.h>
#include <private/qqmlbuiltinfunctions_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
QT_BEGIN_NAMESPACE
@@ -72,8 +73,8 @@ bool QQmlDelayedError::addError(QQmlEnginePrivate *e)
void QQmlDelayedError::setErrorLocation(const QQmlSourceLocation &sourceLocation)
{
m_error.setUrl(QUrl(sourceLocation.sourceFile));
- m_error.setLine(sourceLocation.line);
- m_error.setColumn(sourceLocation.column);
+ m_error.setLine(qmlConvertSourceCoordinate<quint16, int>(sourceLocation.line));
+ m_error.setColumn(qmlConvertSourceCoordinate<quint16, int>(sourceLocation.column));
}
void QQmlDelayedError::setErrorDescription(const QString &description)
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index 5425bf498c..b504fdf22d 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -250,10 +250,37 @@ bool QQmlListReference::canCount() const
}
/*!
- Return true if at(), count(), append() and clear() are implemented, so you can manipulate
- the list.
+Returns true if items in the list property can be replaced, otherwise false.
+Returns false if the reference is invalid.
+
+\sa replace()
+*/
+bool QQmlListReference::canReplace() const
+{
+ return (isValid() && d->property.replace);
+}
+
+/*!
+Returns true if the last item can be removed from the list property, otherwise false.
+Returns false if the reference is invalid.
+
+\sa removeLast()
+*/
+bool QQmlListReference::canRemoveLast() const
+{
+ return (isValid() && d->property.removeLast);
+}
+
+/*!
+ Return true if at(), count(), append(), and either clear() or removeLast()
+ are implemented, so you can manipulate the list.
+
+ Mind that replace() and removeLast() can be emulated by stashing all
+ items and rebuilding the list using clear() and append(). Therefore,
+ they are not required for the list to be manipulable. Furthermore,
+ clear() can be emulated using removeLast().
-\sa isReadable(), at(), count(), append(), clear()
+\sa isReadable(), at(), count(), append(), clear(), replace(), removeLast()
*/
bool QQmlListReference::isManipulable() const
{
@@ -329,6 +356,39 @@ int QQmlListReference::count() const
}
/*!
+Replaces the item at \a index in the list with \a object.
+Returns true if the operation succeeded, otherwise false.
+
+\sa canReplace()
+*/
+bool QQmlListReference::replace(int index, QObject *object) const
+{
+ if (!canReplace())
+ return false;
+
+ if (object && !QQmlMetaObject::canConvert(object, d->elementType))
+ return false;
+
+ d->property.replace(&d->property, index, object);
+ return true;
+}
+
+/*!
+Removes the last item in the list.
+Returns true if the operation succeeded, otherwise false.
+
+\sa canRemoveLast()
+*/
+bool QQmlListReference::removeLast() const
+{
+ if (!canRemoveLast())
+ return false;
+
+ d->property.removeLast(&d->property);
+ return true;
+}
+
+/*!
\class QQmlListProperty
\since 5.0
\inmodule QtQml
@@ -375,14 +435,25 @@ QML list properties are type-safe - in this case \c {Fruit} is a QObject type th
/*!
\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(QObject *object, QList<T *> &list)
+\deprecated
Convenience constructor for making a QQmlListProperty value from an existing
QList \a list. The \a list reference must remain valid for as long as \a object
exists. \a object must be provided.
-Generally this constructor should not be used in production code, as a
-writable QList violates QML's memory management rules. However, this constructor
-can be very useful while prototyping.
+This constructor synthesizes the removeLast() and replace() methods
+introduced in Qt 5.15, using count(), at(), clear(), and append(). This is slow.
+If you intend to manipulate the list beyond clearing it, you should explicitly
+provide these methods.
+*/
+
+/*!
+\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(QObject *object, QList<T *> *list)
+\since 5.15
+
+Convenience constructor for making a QQmlListProperty value from an existing
+QList \a list. The \a list reference must remain valid for as long as \a object
+exists. \a object must be provided.
*/
/*!
@@ -408,6 +479,39 @@ remains valid while \a object exists.
Null pointers can be passed for any function. If any null pointers are passed in, the list
will be neither designable nor alterable by the debugger. It is recommended to provide valid
pointers for all functions.
+
+\note The resulting QQmlListProperty will synthesize the removeLast() and
+replace() methods using \a count, \a at, \a clear, and \a append if all of those
+are given. This is slow. If you intend to manipulate the list beyond clearing it,
+you should explicitly provide these methods.
+*/
+
+/*!
+\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(
+ QObject *object, void *data, AppendFunction append, CountFunction count,
+ AtFunction at, ClearFunction clear, ReplaceFunction replace,
+ RemoveLastFunction removeLast)
+
+Construct a QQmlListProperty from a set of operation functions \a append,
+\a count, \a at, \a clear, \a replace, and \removeLast. An opaque \a data handle
+may be passed which can be accessed from within the operation functions. The
+list property remains valid while \a object exists.
+
+Null pointers can be passed for any function, causing the respective function to
+be synthesized using the others, if possible. QQmlListProperty can synthesize
+\list
+ \li \a clear using \a count and \a removeLast
+ \li \a replace using \a count, \a at, \a clear, and \a append
+ \li \a replace using \a count, \a at, \a removeLast, and \a append
+ \li \a removeLast using \a count, \a at, \a clear, and \a append
+\endlist
+if those are given. This is slow, but if your list does not natively provide
+faster options for these primitives, you may want to use the synthesized ones.
+
+Furthermore, if either of \a count, \a at, \a append, and \a clear are neither
+given explicitly nor synthesized, the list will be neither designable nor
+alterable by the debugger. It is recommended to provide enough valid pointers
+to avoid this situation.
*/
/*!
@@ -448,4 +552,20 @@ Synonym for \c {void (*)(QQmlListProperty<T> *property)}.
Clear the list \a property.
*/
+/*!
+\typedef QQmlListProperty::ReplaceFunction
+
+Synonym for \c {void (*)(QQmlListProperty<T> *property, int index, T *value)}.
+
+Replace the element at position \a index in the list \a property with \a value.
+*/
+
+/*!
+\typedef QQmlListProperty::RemoveLastFunction
+
+Synonym for \c {void (*)(QQmlListProperty<T> *property)}.
+
+Remove the last element from the list \a property.
+*/
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h
index 90ec57c911..17333ca9e4 100644
--- a/src/qml/qml/qqmllist.h
+++ b/src/qml/qml/qqmllist.h
@@ -55,22 +55,28 @@ struct QMetaObject;
template<typename T>
class QQmlListProperty {
public:
- typedef void (*AppendFunction)(QQmlListProperty<T> *, T*);
- typedef int (*CountFunction)(QQmlListProperty<T> *);
- typedef T *(*AtFunction)(QQmlListProperty<T> *, int);
- typedef void (*ClearFunction)(QQmlListProperty<T> *);
-
- QQmlListProperty()
- : append(nullptr),
- count(nullptr),
- at(nullptr),
- clear(nullptr)
- {}
+ using AppendFunction = void (*)(QQmlListProperty<T> *, T *);
+ using CountFunction = int (*)(QQmlListProperty<T> *);
+ using AtFunction = T *(*)(QQmlListProperty<T> *, int);
+ using ClearFunction = void (*)(QQmlListProperty<T> *);
+ using ReplaceFunction = void (*)(QQmlListProperty<T> *, int, T *);
+ using RemoveLastFunction = void (*)(QQmlListProperty<T> *);
+
+ QQmlListProperty() = default;
+
+#if QT_DEPRECATED_SINCE(5,15)
+ QT_DEPRECATED_X("Use constructor taking QList pointer, and gain improved performance")
QQmlListProperty(QObject *o, QList<T *> &list)
: object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
- clear(qlist_clear)
+ clear(qlist_clear), replace(qslow_replace), removeLast(qslow_removeLast)
+ {}
+#endif
+ QQmlListProperty(QObject *o, QList<T *> *list)
+ : object(o), data(list), append(qlist_append), count(qlist_count), at(qlist_at),
+ clear(qlist_clear), replace(qlist_replace), removeLast(qlist_removeLast)
{}
+
QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t,
ClearFunction r )
: object(o),
@@ -78,37 +84,47 @@ public:
append(a),
count(c),
at(t),
- clear(r)
-
+ clear(r),
+ replace((a && c && t && r) ? qslow_replace : nullptr),
+ removeLast((a && c && t && r) ? qslow_removeLast : nullptr)
{}
- QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction t)
+
+ QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t,
+ ClearFunction r, ReplaceFunction s, RemoveLastFunction p)
: object(o),
data(d),
- append(nullptr),
- count(c), at(t),
- clear(nullptr)
+ append(a),
+ count(c),
+ at(t),
+ clear((!r && p && c) ? qslow_clear : r),
+ replace((!s && a && c && t && (r || p)) ? qslow_replace : s),
+ removeLast((!p && a && c && t && r) ? qslow_removeLast : p)
+ {}
+
+ QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction a)
+ : object(o), data(d), count(c), at(a)
{}
+
bool operator==(const QQmlListProperty &o) const {
return object == o.object &&
data == o.data &&
append == o.append &&
count == o.count &&
at == o.at &&
- clear == o.clear;
+ clear == o.clear &&
+ replace == o.replace &&
+ removeLast == o.removeLast;
}
QObject *object = nullptr;
void *data = nullptr;
- AppendFunction append;
-
- CountFunction count;
- AtFunction at;
-
- ClearFunction clear;
-
- void *dummy1 = nullptr;
- void *dummy2 = nullptr;
+ AppendFunction append = nullptr;
+ CountFunction count = nullptr;
+ AtFunction at = nullptr;
+ ClearFunction clear = nullptr;
+ ReplaceFunction replace = nullptr;
+ RemoveLastFunction removeLast = nullptr;
private:
static void qlist_append(QQmlListProperty *p, T *v) {
@@ -123,6 +139,59 @@ private:
static void qlist_clear(QQmlListProperty *p) {
return reinterpret_cast<QList<T *> *>(p->data)->clear();
}
+ static void qlist_replace(QQmlListProperty *p, int idx, T *v) {
+ return reinterpret_cast<QList<T *> *>(p->data)->replace(idx, v);
+ }
+ static void qlist_removeLast(QQmlListProperty *p) {
+ return reinterpret_cast<QList<T *> *>(p->data)->removeLast();
+ }
+
+ static void qslow_replace(QQmlListProperty<T> *list, int idx, T *v)
+ {
+ const int length = list->count(list);
+ if (idx < 0 || idx >= length)
+ return;
+
+ QVector<T *> stash;
+ if (list->clear != qslow_clear) {
+ stash.reserve(length);
+ for (int i = 0; i < length; ++i)
+ stash.append(i == idx ? v : list->at(list, i));
+ list->clear(list);
+ for (T *item : qAsConst(stash))
+ list->append(list, item);
+ } else {
+ stash.reserve(length - idx - 1);
+ for (int i = length - 1; i > idx; --i) {
+ stash.append(list->at(list, i));
+ list->removeLast(list);
+ }
+ list->removeLast(list);
+ list->append(list, v);
+ while (!stash.isEmpty())
+ list->append(list, stash.takeLast());
+ }
+ }
+
+ static void qslow_clear(QQmlListProperty<T> *list)
+ {
+ for (int i = 0, end = list->count(list); i < end; ++i)
+ list->removeLast(list);
+ }
+
+ static void qslow_removeLast(QQmlListProperty<T> *list)
+ {
+ const int length = list->count(list) - 1;
+ if (length < 0)
+ return;
+ QVector<T *> stash;
+ stash.reserve(length);
+ for (int i = 0; i < length; ++i)
+ stash.append(list->at(list, i));
+ list->clear(list);
+ for (T *item : qAsConst(stash))
+ list->append(list, item);
+ }
};
#endif
@@ -146,6 +215,8 @@ public:
bool canAt() const;
bool canClear() const;
bool canCount() const;
+ bool canReplace() const;
+ bool canRemoveLast() const;
bool isManipulable() const;
bool isReadable() const;
@@ -154,6 +225,8 @@ public:
QObject *at(int) const;
bool clear() const;
int count() const;
+ bool replace(int, QObject *) const;
+ bool removeLast() const;
private:
friend class QQmlListReferencePrivate;
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index 5349572921..e5c1cb04a9 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -119,11 +119,13 @@ ReturnedValue QmlListWrapper::virtualGet(const Managed *m, PropertyKey id, const
if (hasProperty)
*hasProperty = false;
return Value::undefinedValue().asReturnedValue();
- } else if (id.isString()) {
- if (id == v4->id_length()->propertyKey() && !w->d()->object.isNull()) {
- quint32 count = w->d()->property().count ? w->d()->property().count(&w->d()->property()) : 0;
- return Value::fromUInt32(count).asReturnedValue();
- }
+ }
+
+ if (id.isString() && id == v4->id_length()->propertyKey()) {
+ if (hasProperty)
+ *hasProperty = true;
+ quint32 count = w->d()->property().count ? w->d()->property().count(&w->d()->property()) : 0;
+ return Value::fromUInt32(count).asReturnedValue();
}
return Object::virtualGet(m, id, receiver, hasProperty);
@@ -131,12 +133,70 @@ ReturnedValue QmlListWrapper::virtualGet(const Managed *m, PropertyKey id, const
bool QmlListWrapper::virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver)
{
- // doesn't do anything. Should we throw?
- Q_UNUSED(m);
- Q_UNUSED(id);
- Q_UNUSED(value);
- Q_UNUSED(receiver);
- return false;
+ Q_ASSERT(m->as<QmlListWrapper>());
+
+ const auto *w = static_cast<const QmlListWrapper *>(m);
+ QV4::ExecutionEngine *v4 = w->engine();
+
+ QQmlListProperty<QObject> *prop = &(w->d()->property());
+
+ if (id.isArrayIndex()) {
+ if (!prop->count || !prop->replace)
+ return false;
+
+ const uint index = id.asArrayIndex();
+ const int count = prop->count(prop);
+ if (count < 0 || index >= uint(count))
+ return false;
+
+ QV4::Scope scope(v4);
+ QV4::ScopedObject so(scope, value.toObject(scope.engine));
+ if (auto *wrapper = so->as<QV4::QObjectWrapper>()) {
+ prop->replace(prop, index, wrapper->object());
+ return true;
+ }
+
+ return false;
+ }
+
+ if (id.isString() && id == v4->id_length()->propertyKey()) {
+ if (!prop->count)
+ return false;
+
+ const quint32 count = prop->count(prop);
+
+ bool ok = false;
+ const uint newLength = value.asArrayLength(&ok);
+ if (!ok)
+ return false;
+
+ if (newLength == 0) {
+ if (!prop->clear)
+ return false;
+ prop->clear(prop);
+ return true;
+ }
+
+ if (newLength < count) {
+ if (!prop->removeLast)
+ return false;
+
+ for (uint i = newLength; i < count; ++i)
+ prop->removeLast(prop);
+
+ return true;
+ }
+
+ if (!prop->append)
+ return false;
+
+ for (uint i = count; i < newLength; ++i)
+ prop->append(prop, nullptr);
+
+ return true;
+ }
+
+ return Object::virtualPut(m, id, value, receiver);
}
struct QmlListWrapperOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index dca13ac8d4..7af6af276a 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -314,7 +314,7 @@ ReturnedValue QQmlDateExtension::method_fromLocaleDateString(const QV4::Function
QLocale locale;
QString dateString = s->toQString();
QDate date = locale.toDate(dateString);
- RETURN_RESULT(engine->newDateObject(QDateTime(date)));
+ RETURN_RESULT(engine->newDateObject(date.startOfDay()));
}
}
@@ -341,7 +341,7 @@ ReturnedValue QQmlDateExtension::method_fromLocaleDateString(const QV4::Function
dt = r->d()->locale->toDate(dateString, enumFormat);
}
- RETURN_RESULT(engine->newDateObject(QDateTime(dt)));
+ RETURN_RESULT(engine->newDateObject(dt.startOfDay()));
}
ReturnedValue QQmlDateExtension::method_timeZoneUpdated(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *, int argc)
@@ -478,6 +478,23 @@ ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(const QV4::FunctionObjec
RETURN_RESULT(fdow);
}
+ReturnedValue QQmlLocaleData::method_get_numberOptions(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
+ QV4::Scope scope(b);
+ const QLocale *locale = getThisLocale(scope, thisObject);
+ if (!locale)
+ return Encode::undefined();
+ int numberOptions = int(locale->numberOptions());
+ RETURN_RESULT(numberOptions);
+}
+
+ReturnedValue QQmlLocaleData::method_set_numberOptions(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) {
+ QV4::Scope scope(b);
+ QLocale *locale = getThisLocale(scope, thisObject);
+ int const numberOptions = argc ? int(argv[0].toNumber()) : QLocale::DefaultNumberOptions;
+ locale->setNumberOptions(QLocale::NumberOptions {numberOptions});
+ return Encode::undefined();
+}
+
ReturnedValue QQmlLocaleData::method_get_measurementSystem(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
@@ -701,6 +718,7 @@ QV4LocaleDataDeletable::QV4LocaleDataDeletable(QV4::ExecutionEngine *engine)
o->defineAccessorProperty(QStringLiteral("amText"), QQmlLocaleData::method_get_amText, nullptr);
o->defineAccessorProperty(QStringLiteral("measurementSystem"), QQmlLocaleData::method_get_measurementSystem, nullptr);
o->defineAccessorProperty(QStringLiteral("exponential"), QQmlLocaleData::method_get_exponential, nullptr);
+ o->defineAccessorProperty(QStringLiteral("numberOptions"), QQmlLocaleData::method_get_numberOptions, QQmlLocaleData::method_set_numberOptions);
prototype.set(engine, o);
}
@@ -873,6 +891,16 @@ ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, con
*/
/*!
+ \qmlproperty enumeration QtQml::Locale::NumberOption
+
+ Holds a set of options for number-to-string and
+ string-to-number conversions.
+
+ \sa Number::toLocaleString()
+ \sa Number::fromLocaleString()
+*/
+
+/*!
\qmlproperty string QtQml::Locale::percent
Holds the percent character of this locale.
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 859c36e11b..1d6fdb12a7 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -94,6 +94,9 @@ private:
class Q_QML_PRIVATE_EXPORT QQmlLocale
{
Q_GADGET
+ QML_NAMED_ELEMENT(Locale)
+ QML_UNCREATABLE("Locale cannot be instantiated. Use Qt.locale().")
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
~QQmlLocale();
@@ -128,6 +131,16 @@ public:
Saturday = Qt::Saturday
};
Q_ENUM(DayOfWeek)
+ enum NumberOptions {
+ DefaultNumberOptions = QLocale::DefaultNumberOptions,
+ OmitGroupSeparator = QLocale::OmitGroupSeparator,
+ RejectGroupSeparator = QLocale::RejectGroupSeparator,
+ OmitLeadingZeroInExponent = QLocale::OmitLeadingZeroInExponent,
+ RejectLeadingZeroInExponent = QLocale::RejectLeadingZeroInExponent,
+ IncludeTrailingZeroesAfterDot = QLocale::IncludeTrailingZeroesAfterDot,
+ RejectTrailingZeroesAfterDot = QLocale::RejectTrailingZeroesAfterDot
+ };
+ Q_ENUM(NumberOptions)
static QV4::ReturnedValue locale(QV4::ExecutionEngine *engine, const QString &localeName);
static QV4::ReturnedValue wrap(QV4::ExecutionEngine *engine, const QLocale &locale);
@@ -197,6 +210,9 @@ struct QQmlLocaleData : public QV4::Object
static QV4::ReturnedValue method_get_exponential(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue method_get_amText(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue method_get_pmText(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+
+ static QV4::ReturnedValue method_get_numberOptions(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_numberOptions(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
}
diff --git a/src/qml/qml/qqmlloggingcategory_p.h b/src/qml/qml/qqmlloggingcategory_p.h
index ee5d9af2e7..c7377528b4 100644
--- a/src/qml/qml/qqmlloggingcategory_p.h
+++ b/src/qml/qml/qqmlloggingcategory_p.h
@@ -56,6 +56,7 @@
#include <QtCore/qloggingcategory.h>
#include <QtQml/qqmlparserstatus.h>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -66,6 +67,8 @@ class QQmlLoggingCategory : public QObject, public QQmlParserStatus
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(DefaultLogLevel defaultLogLevel READ defaultLogLevel WRITE setDefaultLogLevel REVISION 12)
+ QML_NAMED_ELEMENT(LoggingCategory)
+ QML_ADDED_IN_MINOR_VERSION(8)
public:
enum DefaultLogLevel {
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 4f2089b60d..b2a769cab4 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -92,8 +92,13 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data,
d->typeId = type.typeId;
d->listId = type.listId;
d->isSetup = true;
- d->version_maj = 0;
d->version_min = 0;
+ if (type.version > 0) {
+ d->module = QString::fromUtf8(type.uri);
+ d->version_maj = type.versionMajor;
+ } else {
+ d->version_maj = 0;
+ }
data->registerType(d);
return d;
}
@@ -154,7 +159,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el
d->extraData.cd->propertyValueSourceCast = type.valueSourceCast;
d->extraData.cd->propertyValueInterceptorCast = type.valueInterceptorCast;
d->extraData.cd->extFunc = type.extensionObjectCreate;
- d->extraData.cd->customParser = type.customParser;
+ d->extraData.cd->customParser = reinterpret_cast<QQmlCustomParser *>(type.customParser);
d->extraData.cd->registerEnumClassesUnscoped = true;
if (type.extensionMetaObject)
@@ -267,6 +272,48 @@ void QQmlMetaType::clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
}
}
+void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, int majorVersion,
+ void (*registerFunction)())
+{
+ const QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion);
+ QQmlMetaTypeDataPtr data;
+ if (data->moduleTypeRegistrationFunctions.contains(versionedUri))
+ qFatal("Cannot add multiple registrations for %s %d", qPrintable(uri), majorVersion);
+ else
+ data->moduleTypeRegistrationFunctions.insert(versionedUri, registerFunction);
+}
+
+void QQmlMetaType::qmlRemoveModuleRegistration(const QString &uri, int majorVersion)
+{
+ const QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion);
+ QQmlMetaTypeDataPtr data;
+
+ if (!data.isValid())
+ return; // shutdown/deletion race. Not a problem.
+
+ if (!data->moduleTypeRegistrationFunctions.contains(versionedUri))
+ qFatal("Cannot remove multiple registrations for %s %d", qPrintable(uri), majorVersion);
+ else
+ data->moduleTypeRegistrationFunctions.remove(versionedUri);
+}
+
+bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri, int majorVersion)
+{
+ QQmlMetaTypeDataPtr data;
+ return data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, majorVersion));
+}
+
+/*!
+ \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
@@ -303,7 +350,7 @@ void QQmlMetaType::unregisterAutoParentFunction(const QQmlPrivate::AutoParentFun
QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &type)
{
- if (type.version > 0)
+ if (type.version > 1)
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
QQmlMetaTypeDataPtr data;
@@ -312,9 +359,6 @@ QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &t
data->idToType.insert(priv->typeId, priv);
data->idToType.insert(priv->listId, priv);
- // XXX No insertMulti, so no multi-version interfaces?
- if (!priv->elementName.isEmpty())
- data->nameToType.insert(priv->elementName, priv);
if (data->interfaces.size() <= type.typeId)
data->interfaces.resize(type.typeId + 16);
@@ -342,7 +386,7 @@ QString registrationTypeString(QQmlType::RegistrationType typeType)
// NOTE: caller must hold a QMutexLocker on "data"
bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data,
- const char *uri, const QString &typeName, int majorVersion = -1)
+ const char *uri, const QString &typeName, int majorVersion)
{
if (!typeName.isEmpty()) {
if (typeName.at(0).isLower()) {
@@ -363,27 +407,16 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da
if (uri && !typeName.isEmpty()) {
QString nameSpace = QString::fromUtf8(uri);
-
- if (data->typeRegistrationNamespace.isEmpty() && !nameSpace.isEmpty()) {
- // Is the target namespace protected against further registrations?
- if (data->protectedNamespaces.contains(nameSpace)) {
+ QQmlMetaTypeData::VersionedUri versionedUri;
+ versionedUri.uri = nameSpace;
+ versionedUri.majorVersion = majorVersion;
+ if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)){
+ if (qqtm->isLocked()){
QString failure(QCoreApplication::translate("qmlRegisterType",
- "Cannot install %1 '%2' into protected namespace '%3'"));
- data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace));
+ "Cannot install %1 '%2' into protected module '%3' version '%4'"));
+ data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace).arg(majorVersion));
return false;
}
- } else if (majorVersion >= 0) {
- QQmlMetaTypeData::VersionedUri versionedUri;
- versionedUri.uri = nameSpace;
- versionedUri.majorVersion = majorVersion;
- if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)){
- if (qqtm->isLocked()){
- QString failure(QCoreApplication::translate("qmlRegisterType",
- "Cannot install %1 '%2' into protected module '%3' version '%4'"));
- data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace).arg(majorVersion));
- return false;
- }
- }
}
}
@@ -408,10 +441,10 @@ void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data)
Q_ASSERT(type);
if (!type->elementName.isEmpty())
- data->nameToType.insertMulti(type->elementName, type);
+ data->nameToType.insert(type->elementName, type);
if (type->baseMetaObject)
- data->metaObjectToType.insertMulti(type->baseMetaObject, type);
+ data->metaObjectToType.insert(type->baseMetaObject, type);
if (type->typeId) {
data->idToType.insert(type->typeId, type);
@@ -477,14 +510,16 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe
bool fileImport = false;
if (*(type.uri) == '\0')
fileImport = true;
- if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? nullptr : type.uri, typeName))
+ if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? nullptr : type.uri,
+ typeName, type.versionMajor)) {
return QQmlType();
+ }
QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
addTypeToData(priv, data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(QQmlTypeLoader::normalize(type.url), priv);
+ files->insert(QQmlTypeLoader::normalize(type.url), priv);
return QQmlType(priv);
}
@@ -505,17 +540,15 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit
addTypeToData(priv, data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(QQmlTypeLoader::normalize(type.url), priv);
+ files->insert(QQmlTypeLoader::normalize(type.url), priv);
return QQmlType(priv);
}
-void QQmlMetaType::registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit)
+CompositeMetaTypeIds QQmlMetaType::registerInternalCompositeType(const QByteArray &className)
{
- QByteArray name = compilationUnit->rootPropertyCache()->className();
-
- QByteArray ptr = name + '*';
- QByteArray lst = "QQmlListProperty<" + name + '>';
+ QByteArray ptr = className + '*';
+ QByteArray lst = "QQmlListProperty<" + className + '>';
int ptr_type = QMetaType::registerNormalizedType(ptr,
QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Destruct,
@@ -530,23 +563,19 @@ void QQmlMetaType::registerInternalCompositeType(QV4::ExecutableCompilationUnit
static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QQmlListProperty<QObject> >::Flags),
static_cast<QMetaObject*>(nullptr));
- compilationUnit->metaTypeId = ptr_type;
- compilationUnit->listMetaTypeId = lst_type;
-
QQmlMetaTypeDataPtr data;
data->qmlLists.insert(lst_type, ptr_type);
+
+ return {ptr_type, lst_type};
}
-void QQmlMetaType::unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit)
+void QQmlMetaType::unregisterInternalCompositeType(const CompositeMetaTypeIds &typeIds)
{
- int ptr_type = compilationUnit->metaTypeId;
- int lst_type = compilationUnit->listMetaTypeId;
-
QQmlMetaTypeDataPtr data;
- data->qmlLists.remove(lst_type);
+ data->qmlLists.remove(typeIds.listId);
- QMetaType::unregisterType(ptr_type);
- QMetaType::unregisterType(lst_type);
+ QMetaType::unregisterType(typeIds.id);
+ QMetaType::unregisterType(typeIds.listId);
}
int QQmlMetaType::registerUnitCacheHook(
@@ -560,12 +589,12 @@ int QQmlMetaType::registerUnitCacheHook(
return 0;
}
-bool QQmlMetaType::protectModule(const char *uri, int majVersion)
+bool QQmlMetaType::protectModule(const QString &uri, int majVersion)
{
QQmlMetaTypeDataPtr data;
QQmlMetaTypeData::VersionedUri versionedUri;
- versionedUri.uri = QString::fromUtf8(uri);
+ versionedUri.uri = uri;
versionedUri.majorVersion = majVersion;
if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)) {
@@ -642,17 +671,6 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat
const QString &uri, const QString &typeNamespace, int vmaj,
QList<QQmlError> *errors)
{
- QQmlTypesExtensionInterface *iface = qobject_cast<QQmlTypesExtensionInterface *>(instance);
- if (!iface) {
- if (errors) {
- QQmlError error;
- error.setDescription(QStringLiteral("Module loaded for URI '%1' does not implement "
- "QQmlTypesExtensionInterface").arg(typeNamespace));
- errors->prepend(error);
- }
- return false;
- }
-
if (!typeNamespace.isEmpty() && typeNamespace != uri) {
// This is an 'identified' module
// The namespace for type registrations must match the URI for locating the module
@@ -683,8 +701,6 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat
}
return false;
}
-
- data->protectedNamespaces.insert(uri);
} else {
// This is not an identified module - provide a warning
qWarning().nospace() << qPrintable(
@@ -692,28 +708,42 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat
"it cannot be protected from external registrations.").arg(uri));
}
- if (auto *plugin = qobject_cast<QQmlExtensionPlugin *>(instance)) {
- // basepath should point to the directory of the module, not the plugin file itself:
- QQmlExtensionPluginPrivate::get(plugin)->baseUrl
- = QQmlImports::urlFromLocalFileOrQrcOrUrl(basePath);
+ if (!qobject_cast<QQmlEngineExtensionInterface *>(instance)) {
+ QQmlTypesExtensionInterface *iface = qobject_cast<QQmlTypesExtensionInterface *>(instance);
+ if (!iface) {
+ if (errors) {
+ QQmlError error;
+ // Also does not implement QQmlTypesExtensionInterface, but we want to discourage that.
+ error.setDescription(QStringLiteral("Module loaded for URI '%1' does not implement "
+ "QQmlEngineExtensionInterface").arg(typeNamespace));
+ errors->prepend(error);
+ }
+ return false;
+ }
+
+ if (auto *plugin = qobject_cast<QQmlExtensionPlugin *>(instance)) {
+ // basepath should point to the directory of the module, not the plugin file itself:
+ QQmlExtensionPluginPrivate::get(plugin)->baseUrl
+ = QQmlImports::urlFromLocalFileOrQrcOrUrl(basePath);
+ }
+
+ const QByteArray bytes = uri.toUtf8();
+ const char *moduleId = bytes.constData();
+ iface->registerTypes(moduleId);
}
- data->typeRegistrationNamespace = typeNamespace;
- const QByteArray bytes = uri.toUtf8();
- const char *moduleId = bytes.constData();
- iface->registerTypes(moduleId);
- data->typeRegistrationNamespace.clear();
- }
+ data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, vmaj));
- if (!failures.isEmpty()) {
- if (errors) {
- for (const QString &failure : qAsConst(failures)) {
- QQmlError error;
- error.setDescription(failure);
- errors->prepend(error);
+ if (!failures.isEmpty()) {
+ if (errors) {
+ for (const QString &failure : qAsConst(failures)) {
+ QQmlError error;
+ error.setDescription(failure);
+ errors->prepend(error);
+ }
}
+ return false;
}
- return false;
}
return true;
@@ -794,7 +824,7 @@ QQmlType QQmlMetaType::typeForUrl(const QString &urlString,
data->registerType(priv);
addTypeToData(priv, data);
- data->urlToType.insertMulti(url, priv);
+ data->urlToType.insert(url, priv);
return QQmlType(priv);
}
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 6c2b0bb2a6..0c5bc043c4 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -63,6 +63,15 @@ class QQmlError;
namespace QV4 { class ExecutableCompilationUnit; }
+struct CompositeMetaTypeIds
+{
+ int id = -1;
+ int listId = -1;
+ CompositeMetaTypeIds() = default;
+ CompositeMetaTypeIds(int id, int listId) : id(id), listId(listId) {}
+ bool isValid() const { return id != -1 && listId != -1; }
+};
+
class Q_QML_PRIVATE_EXPORT QQmlMetaType
{
public:
@@ -80,11 +89,10 @@ public:
static void unregisterType(int type);
- static void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
- static void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
-
+ static CompositeMetaTypeIds registerInternalCompositeType(const QByteArray &className);
+ static void unregisterInternalCompositeType(const CompositeMetaTypeIds &typeIds);
static void registerModule(const char *uri, int versionMajor, int versionMinor);
- static bool protectModule(const char *uri, int majVersion);
+ static bool protectModule(const QString &uri, int majVersion);
static int typeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName);
@@ -188,6 +196,14 @@ public:
static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd);
+
+ static void qmlInsertModuleRegistration(const QString &uri, int majorVersion,
+ void (*registerFunction)());
+ static void qmlRemoveModuleRegistration(const QString &uri, int majorVersion);
+
+ static bool qmlRegisterModuleTypes(const QString &uri, int majorVersion);
+
+ static int qmlRegisteredListTypeCount();
};
Q_DECLARE_TYPEINFO(QQmlMetaType, Q_MOVABLE_TYPE);
diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp
index 775bc8bdb4..ed885eaa97 100644
--- a/src/qml/qml/qqmlmetatypedata.cpp
+++ b/src/qml/qml/qqmlmetatypedata.cpp
@@ -78,6 +78,16 @@ void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
priv->release();
}
+bool QQmlMetaTypeData::registerModuleTypes(const QQmlMetaTypeData::VersionedUri &versionedUri)
+{
+ auto function = moduleTypeRegistrationFunctions.constFind(versionedUri);
+ if (function != moduleTypeRegistrationFunctions.constEnd()) {
+ (*function)();
+ return true;
+ }
+ return false;
+}
+
QQmlPropertyCache *QQmlMetaTypeData::propertyCacheForMinorVersion(int index, int minorVersion) const
{
return (index < typePropertyCaches.length())
diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h
index 5239b635ce..e51d4ca1a4 100644
--- a/src/qml/qml/qqmlmetatypedata_p.h
+++ b/src/qml/qml/qqmlmetatypedata_p.h
@@ -71,7 +71,7 @@ struct QQmlMetaTypeData
QSet<QQmlType> undeletableTypes;
typedef QHash<int, QQmlTypePrivate *> Ids;
Ids idToType;
- typedef QHash<QHashedStringRef, QQmlTypePrivate *> Names;
+ typedef QMultiHash<QHashedStringRef, QQmlTypePrivate *> Names;
Names nameToType;
typedef QHash<QUrl, QQmlTypePrivate *> Files; //For file imported composite types only
Files urlToType;
@@ -79,7 +79,7 @@ struct QQmlMetaTypeData
// singleton types. This way we can locate any
// of them by url, even if it was registered as
// a module via QQmlPrivate::RegisterCompositeType
- typedef QHash<const QMetaObject *, QQmlTypePrivate *> MetaObjects;
+ typedef QMultiHash<const QMetaObject *, QQmlTypePrivate *> MetaObjects;
MetaObjects metaObjectToType;
typedef QHash<int, QQmlMetaType::StringConverter> StringConverters;
StringConverters stringConverters;
@@ -96,9 +96,13 @@ struct QQmlMetaTypeData
QHashedString uri;
int majorVersion;
};
+
typedef QHash<VersionedUri, QQmlTypeModule *> TypeModules;
TypeModules uriToModule;
+ QHash<VersionedUri, void (*)()> moduleTypeRegistrationFunctions;
+ bool registerModuleTypes(const VersionedUri &versionedUri);
+
QBitArray objects;
QBitArray interfaces;
QBitArray lists;
@@ -106,10 +110,6 @@ struct QQmlMetaTypeData
QList<QQmlPrivate::AutoParentFunction> parentFunctions;
QVector<QQmlPrivate::QmlUnitCacheLookupFunction> lookupCachedQmlUnit;
- QSet<QString> protectedNamespaces;
-
- QString typeRegistrationNamespace;
-
QHash<int, int> qmlLists;
QHash<const QMetaObject *, QQmlPropertyCache *> propertyCaches;
diff --git a/src/qml/qml/qqmlmoduleregistration.cpp b/src/qml/qml/qqmlmoduleregistration.cpp
new file mode 100644
index 0000000000..b7bc3555a6
--- /dev/null
+++ b/src/qml/qml/qqmlmoduleregistration.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 <QtQml/private/qqmlmetatype_p.h>
+#include <QtQml/qqmlmoduleregistration.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QQmlModuleRegistrationPrivate
+{
+ const QString uri;
+ const int majorVersion;
+};
+
+QQmlModuleRegistration::QQmlModuleRegistration(
+ const char *uri, int majorVersion,
+ void (*registerFunction)()) :
+ d(new QQmlModuleRegistrationPrivate { QString::fromUtf8(uri), majorVersion })
+{
+ QQmlMetaType::qmlInsertModuleRegistration(d->uri, d->majorVersion,
+ registerFunction);
+}
+
+QQmlModuleRegistration::~QQmlModuleRegistration()
+{
+ QQmlMetaType::qmlRemoveModuleRegistration(d->uri, d->majorVersion);
+ delete d;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlmoduleregistration.h b/src/qml/qml/qqmlmoduleregistration.h
new file mode 100644
index 0000000000..6f553a2823
--- /dev/null
+++ b/src/qml/qml/qqmlmoduleregistration.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 QQMLMODULEREGISTRATION_H
+#define QQMLMODULEREGISTRATION_H
+
+#include <QtQml/qtqmlglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QQmlModuleRegistrationPrivate;
+class Q_QML_EXPORT QQmlModuleRegistration
+{
+ Q_DISABLE_COPY_MOVE(QQmlModuleRegistration)
+public:
+ QQmlModuleRegistration(const char *uri, int majorVersion, void (*registerFunction)());
+ ~QQmlModuleRegistration();
+
+private:
+ QQmlModuleRegistrationPrivate *d = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLMODULEREGISTRATION_H
diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp
index 1359586b31..df3731684a 100644
--- a/src/qml/qml/qqmlnotifier.cpp
+++ b/src/qml/qml/qqmlnotifier.cpp
@@ -118,8 +118,8 @@ void QQmlNotifierEndpoint::connect(QObject *source, int sourceSignal, QQmlEngine
disconnect();
Q_ASSERT(engine);
- if (QObjectPrivate::get(source)->threadData->threadId.loadRelaxed() !=
- QObjectPrivate::get(engine)->threadData->threadId.loadRelaxed()) {
+ if (QObjectPrivate::get(source)->threadData.loadRelaxed()->threadId.loadRelaxed() !=
+ QObjectPrivate::get(engine)->threadData.loadRelaxed()->threadId.loadRelaxed()) {
QString sourceName;
QDebug(&sourceName) << source;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 836d27f245..3ca89924f9 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -56,25 +56,17 @@
#include <private/qqmldebugconnector_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qqmlscriptdata_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
#include <private/qjsvalue_p.h>
#include <private/qv4generatorobject_p.h>
+#include <QScopedValueRollback>
+
#include <qtqml_tracepoints_p.h>
+#include <QScopedValueRollback>
QT_USE_NAMESPACE
-namespace {
-struct ActiveOCRestorer
-{
- ActiveOCRestorer(QQmlObjectCreator *creator, QQmlEnginePrivate *ep)
- : ep(ep), oldCreator(ep->activeObjectCreator) { ep->activeObjectCreator = creator; }
- ~ActiveOCRestorer() { ep->activeObjectCreator = oldCreator; }
-
- QQmlEnginePrivate *ep;
- QQmlObjectCreator *oldCreator;
-};
-}
-
QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, QQmlContextData *creationContext,
QQmlIncubatorPrivate *incubator)
: phase(Startup)
@@ -87,16 +79,17 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlR
init(parentContext);
sharedState->componentAttached = nullptr;
- sharedState->allCreatedBindings.allocate(compilationUnit->totalBindingsCount);
- sharedState->allParserStatusCallbacks.allocate(compilationUnit->totalParserStatusCount);
- sharedState->allCreatedObjects.allocate(compilationUnit->totalObjectCount);
+ sharedState->allCreatedBindings.allocate(compilationUnit->totalBindingsCount());
+ sharedState->allParserStatusCallbacks.allocate(compilationUnit->totalParserStatusCount());
+ sharedState->allCreatedObjects.allocate(compilationUnit->totalObjectCount());
sharedState->allJavaScriptObjects = nullptr;
sharedState->creationContext = creationContext;
sharedState->rootContext = nullptr;
+ sharedState->hadRequiredProperties = false;
if (auto profiler = QQmlEnginePrivate::get(engine)->profiler) {
Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler,
- sharedState->profiler.init(profiler, compilationUnit->totalParserStatusCount));
+ sharedState->profiler.init(profiler, compilationUnit->totalParserStatusCount()));
} else {
Q_UNUSED(profiler);
}
@@ -154,7 +147,7 @@ QQmlObjectCreator::~QQmlObjectCreator()
}
}
-QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlInstantiationInterrupt *interrupt)
+QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlInstantiationInterrupt *interrupt, int flags)
{
if (phase == CreatingObjectsPhase2) {
phase = ObjectsCreated;
@@ -168,8 +161,14 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
if (subComponentIndex == -1) {
objectToCreate = /*root object*/0;
} else {
- const QV4::CompiledData::Object *compObj = compilationUnit->objectAt(subComponentIndex);
- objectToCreate = compObj->bindingTable()->value.objectIndex;
+ Q_ASSERT(subComponentIndex >= 0);
+ if (flags & CreationFlags::InlineComponent) {
+ objectToCreate = subComponentIndex;
+ } else {
+ Q_ASSERT(flags & CreationFlags::NormalObject);
+ const QV4::CompiledData::Object *compObj = compilationUnit->objectAt(subComponentIndex);
+ objectToCreate = compObj->bindingTable()->value.objectIndex;
+ }
}
context = new QQmlContextData;
@@ -188,7 +187,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
Q_ASSERT(sharedState->allJavaScriptObjects || topLevelCreator);
if (topLevelCreator)
- sharedState->allJavaScriptObjects = scope.alloc(compilationUnit->totalObjectCount);
+ sharedState->allJavaScriptObjects = scope.alloc(compilationUnit->totalObjectCount());
if (subComponentIndex == -1 && compilationUnit->dependentScripts.count()) {
QV4::ScopedObject scripts(scope, v4->newArrayObject(compilationUnit->dependentScripts.count()));
@@ -233,73 +232,23 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
return instance;
}
-// ### unify or keep in sync with populateDeferredBinding()
-bool QQmlObjectCreator::populateDeferredProperties(QObject *instance, QQmlData::DeferredData *deferredData)
+void QQmlObjectCreator::beginPopulateDeferred(QQmlContextData *newContext)
{
- QQmlData *declarativeData = QQmlData::get(instance);
- context = deferredData->context;
- sharedState->rootContext = context;
-
- QObject *bindingTarget = instance;
-
- QQmlRefPointer<QQmlPropertyCache> cache = declarativeData->propertyCache;
- QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(instance);
-
- QObject *scopeObject = instance;
- qSwap(_scopeObject, scopeObject);
-
- QV4::Scope valueScope(v4);
+ context = newContext;
+ sharedState->rootContext = newContext;
Q_ASSERT(topLevelCreator);
Q_ASSERT(!sharedState->allJavaScriptObjects);
- sharedState->allJavaScriptObjects = valueScope.alloc(compilationUnit->totalObjectCount);
-
- QV4::QmlContext *qmlContext = static_cast<QV4::QmlContext *>(valueScope.alloc());
-
- qSwap(_qmlContext, qmlContext);
-
- qSwap(_propertyCache, cache);
- qSwap(_qobject, instance);
-
- int objectIndex = deferredData->deferredIdx;
- qSwap(_compiledObjectIndex, objectIndex);
-
- const QV4::CompiledData::Object *obj = compilationUnit->objectAt(_compiledObjectIndex);
- qSwap(_compiledObject, obj);
-
- qSwap(_ddata, declarativeData);
- qSwap(_bindingTarget, bindingTarget);
- qSwap(_vmeMetaObject, vmeMetaObject);
-
- setupBindings(/*applyDeferredBindings=*/true);
-
- qSwap(_vmeMetaObject, vmeMetaObject);
- qSwap(_bindingTarget, bindingTarget);
- qSwap(_ddata, declarativeData);
- qSwap(_compiledObject, obj);
- qSwap(_compiledObjectIndex, objectIndex);
- qSwap(_qobject, instance);
- qSwap(_propertyCache, cache);
-
- qSwap(_qmlContext, qmlContext);
- qSwap(_scopeObject, scopeObject);
- deferredData->bindings.clear();
- phase = ObjectsCreated;
-
- return errors.isEmpty();
+ QV4::Scope valueScope(v4);
+ sharedState->allJavaScriptObjects = valueScope.alloc(compilationUnit->totalObjectCount());
}
-// ### unify or keep in sync with populateDeferredProperties()
-bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty, QQmlData::DeferredData *deferredData, const QV4::CompiledData::Binding *binding)
+void QQmlObjectCreator::populateDeferred(QObject *instance, int deferredIndex,
+ const QQmlPropertyPrivate *qmlProperty,
+ const QV4::CompiledData::Binding *binding)
{
- Q_ASSERT(binding->flags & QV4::CompiledData::Binding::IsDeferredBinding);
-
- QObject *instance = qmlProperty.object();
QQmlData *declarativeData = QQmlData::get(instance);
- context = deferredData->context;
- sharedState->rootContext = context;
-
QObject *bindingTarget = instance;
QQmlRefPointer<QQmlPropertyCache> cache = declarativeData->propertyCache;
@@ -309,11 +258,10 @@ bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty,
qSwap(_scopeObject, scopeObject);
QV4::Scope valueScope(v4);
+ QScopedValueRollback<QV4::Value*> jsObjectGuard(sharedState->allJavaScriptObjects,
+ valueScope.alloc(compilationUnit->totalObjectCount()));
Q_ASSERT(topLevelCreator);
- if (!sharedState->allJavaScriptObjects)
- sharedState->allJavaScriptObjects = valueScope.alloc(compilationUnit->totalObjectCount);
-
QV4::QmlContext *qmlContext = static_cast<QV4::QmlContext *>(valueScope.alloc());
qSwap(_qmlContext, qmlContext);
@@ -321,31 +269,37 @@ bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty,
qSwap(_propertyCache, cache);
qSwap(_qobject, instance);
- int objectIndex = deferredData->deferredIdx;
+ int objectIndex = deferredIndex;
qSwap(_compiledObjectIndex, objectIndex);
const QV4::CompiledData::Object *obj = compilationUnit->objectAt(_compiledObjectIndex);
qSwap(_compiledObject, obj);
-
qSwap(_ddata, declarativeData);
qSwap(_bindingTarget, bindingTarget);
qSwap(_vmeMetaObject, vmeMetaObject);
- QQmlListProperty<void> savedList;
- qSwap(_currentList, savedList);
+ if (binding) {
+ Q_ASSERT(qmlProperty);
+ Q_ASSERT(binding->flags & QV4::CompiledData::Binding::IsDeferredBinding);
- const QQmlPropertyData &property = QQmlPropertyPrivate::get(qmlProperty)->core;
+ QQmlListProperty<void> savedList;
+ qSwap(_currentList, savedList);
- if (property.isQList()) {
- void *argv[1] = { (void*)&_currentList };
- QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property.coreIndex(), argv);
- } else if (_currentList.object) {
- _currentList = QQmlListProperty<void>();
- }
+ const QQmlPropertyData &property = qmlProperty->core;
- setPropertyBinding(&property, binding);
+ if (property.isQList()) {
+ void *argv[1] = { (void*)&_currentList };
+ QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property.coreIndex(), argv);
+ } else if (_currentList.object) {
+ _currentList = QQmlListProperty<void>();
+ }
- qSwap(_currentList, savedList);
+ setPropertyBinding(&property, binding);
+
+ qSwap(_currentList, savedList);
+ } else {
+ setupBindings(/*applyDeferredBindings=*/true);
+ }
qSwap(_vmeMetaObject, vmeMetaObject);
qSwap(_bindingTarget, bindingTarget);
@@ -357,12 +311,29 @@ bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty,
qSwap(_qmlContext, qmlContext);
qSwap(_scopeObject, scopeObject);
+}
- phase = ObjectsCreated;
-
+bool QQmlObjectCreator::populateDeferredProperties(QObject *instance,
+ const QQmlData::DeferredData *deferredData)
+{
+ beginPopulateDeferred(deferredData->context);
+ populateDeferred(instance, deferredData->deferredIdx);
+ finalizePopulateDeferred();
return errors.isEmpty();
}
+void QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty, int deferredIndex,
+ const QV4::CompiledData::Binding *binding)
+{
+ populateDeferred(qmlProperty.object(), deferredIndex, QQmlPropertyPrivate::get(qmlProperty),
+ binding);
+}
+
+void QQmlObjectCreator::finalizePopulateDeferred()
+{
+ phase = ObjectsCreated;
+}
+
void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding)
{
QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite;
@@ -453,25 +424,25 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
}
}
break;
- case QVariant::String: {
+ case QMetaType::QString: {
assertOrNull(binding->evaluatesToString());
QString value = compilationUnit->bindingValueAsString(binding);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::StringList: {
+ case QMetaType::QStringList: {
assertOrNull(binding->evaluatesToString());
QStringList value(compilationUnit->bindingValueAsString(binding));
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::ByteArray: {
+ case QMetaType::QByteArray: {
assertType(QV4::CompiledData::Binding::Type_String);
QByteArray value(compilationUnit->bindingValueAsString(binding).toUtf8());
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::Url: {
+ case QMetaType::QUrl: {
assertType(QV4::CompiledData::Binding::Type_String);
QString string = compilationUnit->bindingValueAsString(binding);
// Encoded dir-separators defeat QUrl processing - decode them first
@@ -483,7 +454,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::UInt: {
+ case QMetaType::UInt: {
assertType(QV4::CompiledData::Binding::Type_Number);
double d = compilationUnit->bindingValueAsNumber(binding);
uint value = uint(d);
@@ -491,7 +462,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
break;
}
break;
- case QVariant::Int: {
+ case QMetaType::Int: {
assertType(QV4::CompiledData::Binding::Type_Number);
double d = compilationUnit->bindingValueAsNumber(binding);
int value = int(d);
@@ -505,13 +476,13 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::Double: {
+ case QMetaType::Double: {
assertType(QV4::CompiledData::Binding::Type_Number);
double value = compilationUnit->bindingValueAsNumber(binding);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::Color: {
+ case QMetaType::QColor: {
bool ok = false;
uint colorValue = QQmlStringConverters::rgbaFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
@@ -522,21 +493,21 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
}
break;
#if QT_CONFIG(datestring)
- case QVariant::Date: {
+ case QMetaType::QDate: {
bool ok = false;
QDate value = QQmlStringConverters::dateFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::Time: {
+ case QMetaType::QTime: {
bool ok = false;
QTime value = QQmlStringConverters::timeFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::DateTime: {
+ case QMetaType::QDateTime: {
bool ok = false;
QDateTime value = QQmlStringConverters::dateTimeFromString(compilationUnit->bindingValueAsString(binding), &ok);
// ### VME compatibility :(
@@ -550,55 +521,55 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
}
break;
#endif // datestring
- case QVariant::Point: {
+ case QMetaType::QPoint: {
bool ok = false;
QPoint value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok).toPoint();
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::PointF: {
+ case QMetaType::QPointF: {
bool ok = false;
QPointF value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::Size: {
+ case QMetaType::QSize: {
bool ok = false;
QSize value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok).toSize();
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::SizeF: {
+ case QMetaType::QSizeF: {
bool ok = false;
QSizeF value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::Rect: {
+ case QMetaType::QRect: {
bool ok = false;
QRect value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok).toRect();
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::RectF: {
+ case QMetaType::QRectF: {
bool ok = false;
QRectF value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok);
assertOrNull(ok);
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::Bool: {
+ case QMetaType::Bool: {
assertType(QV4::CompiledData::Binding::Type_Boolean);
bool value = binding->valueAsBoolean();
property->writeProperty(_qobject, &value, propertyWriteFlags);
}
break;
- case QVariant::Vector2D: {
+ case QMetaType::QVector2D: {
struct {
float xp;
float yp;
@@ -609,7 +580,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &vec, propertyWriteFlags);
}
break;
- case QVariant::Vector3D: {
+ case QMetaType::QVector3D: {
struct {
float xp;
float yp;
@@ -621,7 +592,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &vec, propertyWriteFlags);
}
break;
- case QVariant::Vector4D: {
+ case QMetaType::QVector4D: {
struct {
float xp;
float yp;
@@ -634,7 +605,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &vec, propertyWriteFlags);
}
break;
- case QVariant::Quaternion: {
+ case QMetaType::QQuaternion: {
struct {
float wp;
float xp;
@@ -647,7 +618,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
property->writeProperty(_qobject, &vec, propertyWriteFlags);
}
break;
- case QVariant::RegExp:
+ case QMetaType::QRegExp:
assertOrNull(!"not possible");
break;
default: {
@@ -712,7 +683,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
QVariant value = (*converter)(stringValue);
QMetaProperty metaProperty = _qobject->metaObject()->property(property->coreIndex());
- if (value.isNull() || ((int)metaProperty.type() != property->propType() && metaProperty.userType() != property->propType())) {
+ if (value.isNull() || metaProperty.userType() != property->propType()) {
recordError(binding->location, tr("Cannot assign value %1 to property %2").arg(stringValue).arg(QString::fromUtf8(metaProperty.name())));
break;
}
@@ -785,6 +756,23 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings)
const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable();
for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) {
+ QQmlPropertyData *const property = propertyData.at(i);
+ if (property) {
+ QQmlPropertyData* targetProperty = property;
+ if (targetProperty->isAlias()) {
+ // follow alias
+ auto target = _bindingTarget;
+ QQmlPropertyIndex originalIndex(targetProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
+ QQmlPropertyIndex propIndex;
+ QQmlPropertyPrivate::findAliasTarget(target, originalIndex, &target, &propIndex);
+ QQmlData *data = QQmlData::get(target);
+ Q_ASSERT(data && data->propertyCache);
+ targetProperty = data->propertyCache->property(propIndex.coreIndex());
+ }
+ sharedState->requiredProperties.remove(targetProperty);
+ }
+
+
if (binding->flags & QV4::CompiledData::Binding::IsCustomParserBinding)
continue;
@@ -796,8 +784,6 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings)
continue;
}
- const QQmlPropertyData *property = propertyData.at(i);
-
if (property && property->isQList()) {
if (property->coreIndex() != currentListPropertyIndex) {
void *argv[1] = { (void*)&_currentList };
@@ -1150,8 +1136,8 @@ void QQmlObjectCreator::recordError(const QV4::CompiledData::Location &location,
{
QQmlError error;
error.setUrl(compilationUnit->url());
- error.setLine(location.line);
- error.setColumn(location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(location.column));
error.setDescription(description);
errors << error;
}
@@ -1175,7 +1161,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
QString typeName;
Q_TRACE_EXIT(QQmlObjectCreator_createInstance_exit, typeName);
- ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
+ QScopedValueRollback<QQmlObjectCreator*> ocRestore(QQmlEnginePrivate::get(engine)->activeObjectCreator, this);
bool isComponent = false;
QObject *instance = nullptr;
@@ -1196,7 +1182,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
Q_ASSERT(typeRef);
installPropertyCache = !typeRef->isFullyDynamicType;
QQmlType type = typeRef->type;
- if (type.isValid()) {
+ if (type.isValid() && !type.isInlineComponentType()) {
typeName = type.qmlTypeName();
void *ddataMemory = nullptr;
@@ -1228,19 +1214,34 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
sharedState->allCreatedObjects.push(instance);
} else {
- Q_ASSERT(typeRef->compilationUnit);
- typeName = typeRef->compilationUnit->fileName();
- if (typeRef->compilationUnit->unitData()->isSingleton())
+ const auto compilationUnit = typeRef->compilationUnit();
+ Q_ASSERT(compilationUnit);
+ typeName = compilationUnit->fileName();
+ // compilation unit is shared between root type and its inline component types
+ // so isSingleton errorneously returns true for inline components
+ if (compilationUnit->unitData()->isSingleton() && !type.isInlineComponentType())
{
recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex)));
return nullptr;
}
- QQmlObjectCreator subCreator(context, typeRef->compilationUnit, sharedState.data());
- instance = subCreator.create();
- if (!instance) {
- errors += subCreator.errors;
- return nullptr;
+
+ if (!type.isInlineComponentType()) {
+ QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data());
+ instance = subCreator.create();
+ if (!instance) {
+ errors += subCreator.errors;
+ return nullptr;
+ }
+ } else {
+ int subObjectId = type.inlineComponendId();
+ QScopedValueRollback<int> rollback {compilationUnit->icRoot, subObjectId};
+ QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data());
+ instance = subCreator.create(subObjectId, nullptr, nullptr, CreationFlags::InlineComponent);
+ if (!instance) {
+ errors += subCreator.errors;
+ return nullptr;
+ }
}
}
if (instance->isWidgetType()) {
@@ -1265,7 +1266,10 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
ddata->columnNumber = obj->location.column;
ddata->setImplicitDestructible();
- if (static_cast<quint32>(index) == /*root object*/0 || ddata->rootObjectInCreation) {
+ // inline components are root objects, but their index is != 0, so we need
+ // an additional check
+ const bool isInlineComponent = obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot;
+ if (static_cast<quint32>(index) == /*root object*/0 || ddata->rootObjectInCreation || isInlineComponent) {
if (ddata->context) {
Q_ASSERT(ddata->context != context);
Q_ASSERT(ddata->outerContext);
@@ -1376,7 +1380,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
phase = Finalizing;
QQmlObjectCreatorRecursionWatcher watcher(this);
- ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
+ QScopedValueRollback<QQmlObjectCreator*> ocRestore(QQmlEnginePrivate::get(engine)->activeObjectCreator, this);
while (!sharedState->allCreatedBindings.isEmpty()) {
QQmlAbstractBinding::Ptr b = sharedState->allCreatedBindings.pop();
@@ -1506,10 +1510,73 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
if (_compiledObject->flags & QV4::CompiledData::Object::HasDeferredBindings)
_ddata->deferData(_compiledObjectIndex, compilationUnit, context);
+ QSet<QString> postHocRequired;
+ for (auto it = _compiledObject->requiredPropertyExtraDataBegin(); it != _compiledObject->requiredPropertyExtraDataEnd(); ++it)
+ postHocRequired.insert(stringAt(it->nameIndex));
+ bool hadInheritedRequiredProperties = !postHocRequired.empty();
+
+ for (int propertyIndex = 0; propertyIndex != _compiledObject->propertyCount(); ++propertyIndex) {
+ const QV4::CompiledData::Property* property = _compiledObject->propertiesBegin() + propertyIndex;
+ QQmlPropertyData *propertyData = _propertyCache->property(_propertyCache->propertyOffset() + propertyIndex);
+ // only compute stringAt if there's a chance for the lookup to succeed
+ auto postHocIt = postHocRequired.isEmpty() ? postHocRequired.end() : postHocRequired.find(stringAt(property->nameIndex));
+ if (!property->isRequired && postHocRequired.end() == postHocIt)
+ continue;
+ if (postHocIt != postHocRequired.end())
+ postHocRequired.erase(postHocIt);
+ sharedState->hadRequiredProperties = true;
+ sharedState->requiredProperties.insert(propertyData,
+ RequiredPropertyInfo {compilationUnit->stringAt(property->nameIndex), compilationUnit->finalUrl(), property->location, {}});
+
+ }
+
+ for (int i = 0; i <= _propertyCache->propertyOffset(); ++i) {
+ QQmlPropertyData *propertyData = _propertyCache->maybeUnresolvedProperty(i);
+ if (!propertyData)
+ continue;
+ if (!propertyData->isRequired() && postHocRequired.isEmpty())
+ continue;
+ QString name = propertyData->name(_qobject);
+ auto postHocIt = postHocRequired.find(name);
+ if (!propertyData->isRequired() && postHocRequired.end() == postHocIt )
+ continue;
+
+ if (postHocIt != postHocRequired.end())
+ postHocRequired.erase(postHocIt);
+
+ sharedState->hadRequiredProperties = true;
+ sharedState->requiredProperties.insert(propertyData, RequiredPropertyInfo {name, compilationUnit->finalUrl(), _compiledObject->location, {}});
+ }
+ if (!postHocRequired.isEmpty() && hadInheritedRequiredProperties)
+ recordError({}, QLatin1String("Property %1 was marked as required but does not exist").arg(*postHocRequired.begin()));
+
if (_compiledObject->nFunctions > 0)
setupFunctions();
setupBindings();
+ for (int aliasIndex = 0; aliasIndex != _compiledObject->aliasCount(); ++aliasIndex) {
+ const QV4::CompiledData::Alias* alias = _compiledObject->aliasesBegin() + aliasIndex;
+ const auto originalAlias = alias;
+ while (alias->aliasToLocalAlias)
+ alias = _compiledObject->aliasesBegin() + alias->localAliasIndex;
+ Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved);
+ if (!context->idValues->wasSet())
+ continue;
+ QObject *target = context->idValues[alias->targetObjectId].data();
+ if (!target)
+ continue;
+ QQmlData *targetDData = QQmlData::get(target, /*create*/false);
+ if (!targetDData)
+ continue;
+ int coreIndex = QQmlPropertyIndex::fromEncoded(alias->encodedMetaPropertyIndex).coreIndex();
+ QQmlPropertyData *const targetProperty = targetDData->propertyCache->property(coreIndex);
+ if (!targetProperty)
+ continue;
+ auto it = sharedState->requiredProperties.find(targetProperty);
+ if (it != sharedState->requiredProperties.end())
+ it->aliasesToRequired.push_back(AliasToRequiredInfo {compilationUnit->stringAt(originalAlias->nameIndex), compilationUnit->finalUrl()});
+ }
+
qSwap(_vmeMetaObject, vmeMetaObject);
qSwap(_bindingTarget, bindingTarget);
qSwap(_ddata, declarativeData);
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index ecdbcc56dd..bca450addb 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -66,6 +66,28 @@ class QQmlAbstractBinding;
class QQmlInstantiationInterrupt;
class QQmlIncubatorPrivate;
+struct AliasToRequiredInfo {
+ QString propertyName;
+ QUrl fileUrl;
+};
+
+/*!
+\internal
+This struct contains information solely used for displaying error messages
+\variable aliasesToRequired allows us to give the user a way to know which (aliasing) properties
+can be set to set the required property
+\sa QQmlComponentPrivate::unsetRequiredPropertyToQQmlError
+*/
+struct RequiredPropertyInfo
+{
+ QString propertyName;
+ QUrl fileUrl;
+ QV4::CompiledData::Location location;
+ QVector<AliasToRequiredInfo> aliasesToRequired;
+};
+
+class RequiredProperties : public QHash<QQmlPropertyData*, RequiredPropertyInfo> {};
+
struct QQmlObjectCreatorSharedState : public QSharedData
{
QQmlContextData *rootContext;
@@ -78,6 +100,8 @@ struct QQmlObjectCreatorSharedState : public QSharedData
QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks;
QQmlVmeProfiler profiler;
QRecursionNode recursionNode;
+ RequiredProperties requiredProperties;
+ bool hadRequiredProperties;
};
class Q_QML_PRIVATE_EXPORT QQmlObjectCreator
@@ -87,9 +111,16 @@ public:
QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, QQmlContextData *creationContext, QQmlIncubatorPrivate *incubator = nullptr);
~QQmlObjectCreator();
- QObject *create(int subComponentIndex = -1, QObject *parent = nullptr, QQmlInstantiationInterrupt *interrupt = nullptr);
- bool populateDeferredProperties(QObject *instance, QQmlData::DeferredData *deferredData);
- bool populateDeferredBinding(const QQmlProperty &qmlProperty, QQmlData::DeferredData *deferredData, const QV4::CompiledData::Binding *binding);
+ enum CreationFlags { NormalObject = 1, InlineComponent = 2 };
+ QObject *create(int subComponentIndex = -1, QObject *parent = nullptr, QQmlInstantiationInterrupt *interrupt = nullptr, int flags = NormalObject);
+
+ bool populateDeferredProperties(QObject *instance, const QQmlData::DeferredData *deferredData);
+
+ void beginPopulateDeferred(QQmlContextData *context);
+ void populateDeferredBinding(const QQmlProperty &qmlProperty, int deferredIndex,
+ const QV4::CompiledData::Binding *binding);
+ void finalizePopulateDeferred();
+
QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
void clear();
@@ -102,6 +133,9 @@ public:
QQmlContextData *parentContextData() const { return parentContext.contextData(); }
QFiniteStack<QPointer<QObject> > &allCreatedObjects() { return sharedState->allCreatedObjects; }
+ RequiredProperties &requiredProperties() {return sharedState->requiredProperties;}
+ bool componentHadRequiredProperties() const {return sharedState->hadRequiredProperties;}
+
private:
QQmlObjectCreator(QQmlContextData *contextData, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState);
@@ -112,6 +146,11 @@ private:
bool populateInstance(int index, QObject *instance,
QObject *bindingTarget, const QQmlPropertyData *valueTypeProperty);
+ // If qmlProperty and binding are null, populate all properties, otherwise only the given one.
+ void populateDeferred(QObject *instance, int deferredIndex,
+ const QQmlPropertyPrivate *qmlProperty = nullptr,
+ const QV4::CompiledData::Binding *binding = nullptr);
+
void setupBindings(bool applyDeferredBindings = false);
bool setPropertyBinding(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
void setPropertyValue(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
diff --git a/src/qml/qml/qqmlplatform.cpp b/src/qml/qml/qqmlplatform.cpp
index 0acf20bbb4..dcd7ca2d46 100644
--- a/src/qml/qml/qqmlplatform.cpp
+++ b/src/qml/qml/qqmlplatform.cpp
@@ -74,6 +74,8 @@ QString QQmlPlatform::os()
return QStringLiteral("linux");
#elif defined(Q_OS_QNX)
return QStringLiteral("qnx");
+#elif defined(Q_OS_WASM)
+ return QStringLiteral("wasm");
#elif defined(Q_OS_UNIX)
return QStringLiteral("unix");
#else
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 6d7a2569bc..d6a9e73763 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -52,18 +52,43 @@
//
#include <functional>
+#include <type_traits>
#include <QtQml/qtqmlglobal.h>
+#include <QtQml/qqmlparserstatus.h>
+#include <QtQml/qqmllist.h>
+#include <QtQml/qqmlpropertyvaluesource.h>
#include <QtCore/qglobal.h>
#include <QtCore/qvariant.h>
#include <QtCore/qurl.h>
#include <QtCore/qpointer.h>
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qdebug.h>
+
+#define QML_GETTYPENAMES \
+ const char *className = T::staticMetaObject.className(); \
+ const int nameLen = int(strlen(className)); \
+ QVarLengthArray<char,48> pointerName(nameLen+2); \
+ memcpy(pointerName.data(), className, size_t(nameLen)); \
+ pointerName[nameLen] = '*'; \
+ pointerName[nameLen+1] = '\0'; \
+ const int listLen = int(strlen("QQmlListProperty<")); \
+ QVarLengthArray<char,64> listName(listLen + nameLen + 2); \
+ memcpy(listName.data(), "QQmlListProperty<", size_t(listLen)); \
+ memcpy(listName.data()+listLen, className, size_t(nameLen)); \
+ listName[listLen+nameLen] = '>'; \
+ listName[listLen+nameLen+1] = '\0';
+
QT_BEGIN_NAMESPACE
+class QQmlPropertyValueInterceptor;
+
namespace QQmlPrivate {
struct CachedQmlUnit;
+template<typename A>
+using QQmlAttachedPropertiesFunc = A *(*)(QObject *);
}
namespace QV4 {
@@ -78,7 +103,7 @@ struct Document;
typedef void (*IRLoaderFunction)(Document *, const QQmlPrivate::CachedQmlUnit *);
}
-typedef QObject *(*QQmlAttachedPropertiesFunc)(QObject *);
+using QQmlAttachedPropertiesFunc = QQmlPrivate::QQmlAttachedPropertiesFunc<QObject>;
inline uint qHash(QQmlAttachedPropertiesFunc func, uint seed = 0)
{
@@ -99,6 +124,14 @@ class QJSValue;
class QJSEngine;
class QQmlEngine;
class QQmlCustomParser;
+class QQmlTypeNotAvailable;
+
+template<class T>
+QQmlCustomParser *qmlCreateCustomParser()
+{
+ return nullptr;
+}
+
namespace QQmlPrivate
{
void Q_QML_EXPORT qdeclarativeelement_destructor(QObject *);
@@ -124,11 +157,62 @@ namespace QQmlPrivate
};
template<typename T>
+ constexpr bool isConstructible()
+ {
+ return std::is_default_constructible<T>::value && std::is_base_of<QObject, T>::value;
+ }
+
+ template<typename T>
void createInto(void *memory) { new (memory) QQmlElement<T>; }
template<typename T>
+ QObject *createSingletonInstance(QQmlEngine *, QJSEngine *) { return new T; }
+
+ template<typename T>
QObject *createParent(QObject *p) { return new T(p); }
+ using CreateIntoFunction = void (*)(void *);
+ using CreateSingletonFunction = QObject *(*)(QQmlEngine *, QJSEngine *);
+ using CreateParentFunction = QObject *(*)(QObject *);
+
+ template<typename T, bool Constructible = isConstructible<T>()>
+ struct Constructors;
+
+ template<typename T>
+ struct Constructors<T, true>
+ {
+ static constexpr CreateIntoFunction createInto
+ = QQmlPrivate::createInto<T>;
+ static constexpr CreateSingletonFunction createSingletonInstance
+ = QQmlPrivate::createSingletonInstance<T>;
+ };
+
+ template<typename T>
+ struct Constructors<T, false>
+ {
+ static constexpr CreateIntoFunction createInto = nullptr;
+ static constexpr CreateSingletonFunction createSingletonInstance = nullptr;
+ };
+
+ template<typename T, bool IsVoid = std::is_void<T>::value>
+ struct ExtendedType;
+
+ // void means "not an extended type"
+ template<typename T>
+ struct ExtendedType<T, true>
+ {
+ static constexpr const CreateParentFunction createParent = nullptr;
+ static constexpr const QMetaObject *staticMetaObject = nullptr;
+ };
+
+ // If it's not void, we actually want an error if the ctor or the metaobject is missing.
+ template<typename T>
+ struct ExtendedType<T, false>
+ {
+ static constexpr const CreateParentFunction createParent = QQmlPrivate::createParent<T>;
+ static constexpr const QMetaObject *staticMetaObject = &T::staticMetaObject;
+ };
+
template<class From, class To, int N>
struct StaticCastSelectorClass
{
@@ -156,66 +240,103 @@ namespace QQmlPrivate
}
};
- template <typename T>
- struct has_attachedPropertiesMember
+ template<typename...>
+ using QmlVoidT = void;
+
+ // You can prevent subclasses from using the same attached type by specialzing this.
+ // This is reserved for internal types, though.
+ template<class T, class A>
+ struct OverridableAttachedType
{
- static bool const value = QQmlTypeInfo<T>::hasAttachedProperties;
+ using Type = A;
};
- template <typename T, bool hasMember>
- class has_attachedPropertiesMethod
+ template<class T, class = QmlVoidT<>, bool OldStyle = QQmlTypeInfo<T>::hasAttachedProperties>
+ struct QmlAttached
{
- public:
- typedef int yes_type;
- typedef char no_type;
-
- template<typename ReturnType>
- static yes_type checkType(ReturnType *(*)(QObject *));
- static no_type checkType(...);
-
- static bool const value = sizeof(checkType(&T::qmlAttachedProperties)) == sizeof(yes_type);
+ using Type = void;
+ using Func = QQmlAttachedPropertiesFunc<QObject>;
+ static const QMetaObject *staticMetaObject() { return nullptr; }
+ static Func attachedPropertiesFunc() { return nullptr; }
};
- template <typename T>
- class has_attachedPropertiesMethod<T, false>
+ // Defined inline via QML_ATTACHED
+ template<class T>
+ struct QmlAttached<T, QmlVoidT<typename OverridableAttachedType<T, typename T::QmlAttachedType>::Type>, false>
{
- public:
- static bool const value = false;
+ // Normal attached properties
+ template <typename Parent, typename Attached>
+ struct Properties
+ {
+ using Func = QQmlAttachedPropertiesFunc<Attached>;
+ static const QMetaObject *staticMetaObject() { return &Attached::staticMetaObject; }
+ static Func attachedPropertiesFunc() { return Parent::qmlAttachedProperties; }
+ };
+
+ // Disabled via OverridableAttachedType
+ template<typename Parent>
+ struct Properties<Parent, void>
+ {
+ using Func = QQmlAttachedPropertiesFunc<QObject>;
+ static const QMetaObject *staticMetaObject() { return nullptr; };
+ static Func attachedPropertiesFunc() { return nullptr; };
+ };
+
+ using Type = typename OverridableAttachedType<T, typename T::QmlAttachedType>::Type;
+ using Func = typename Properties<T, Type>::Func;
+
+ static const QMetaObject *staticMetaObject()
+ {
+ return Properties<T, Type>::staticMetaObject();
+ }
+
+ static Func attachedPropertiesFunc()
+ {
+ return Properties<T, Type>::attachedPropertiesFunc();
+ }
};
- template<typename T, int N>
- class AttachedPropertySelector
+ // Separately defined via QQmlTypeInfo
+ template<class T>
+ struct QmlAttached<T, QmlVoidT<decltype(T::qmlAttachedProperties)>, true>
{
- public:
- static inline QQmlAttachedPropertiesFunc func() { return nullptr; }
- static inline const QMetaObject *metaObject() { return nullptr; }
+ using Type = typename std::remove_pointer<decltype(T::qmlAttachedProperties(nullptr))>::type;
+ using Func = QQmlAttachedPropertiesFunc<Type>;
+
+ static const QMetaObject *staticMetaObject() { return &Type::staticMetaObject; }
+ static Func attachedPropertiesFunc() { return T::qmlAttachedProperties; }
};
- template<typename T>
- class AttachedPropertySelector<T, 1>
+
+ // This is necessary because both the type containing a default template parameter and the type
+ // instantiating the template need to have access to the default template parameter type. In
+ // this case that's T::QmlAttachedType. The QML_FOREIGN macro needs to befriend specific other
+ // types. Therefore we need some kind of "accessor". Because of compiler bugs in gcc and clang,
+ // we cannot befriend attachedPropertiesFunc() directly. Wrapping the actual access into another
+ // struct "fixes" that. For convenience we still want the free standing functions in addition.
+ template<class T>
+ struct QmlAttachedAccessor
{
- template<typename ReturnType>
- static inline const QMetaObject *attachedPropertiesMetaObject(ReturnType *(*)(QObject *)) {
- return &ReturnType::staticMetaObject;
- }
- public:
- static inline QQmlAttachedPropertiesFunc func() {
- return QQmlAttachedPropertiesFunc(&T::qmlAttachedProperties);
+ static QQmlAttachedPropertiesFunc<QObject> attachedPropertiesFunc()
+ {
+ return QQmlAttachedPropertiesFunc<QObject>(QmlAttached<T>::attachedPropertiesFunc());
}
- static inline const QMetaObject *metaObject() {
- return attachedPropertiesMetaObject(&T::qmlAttachedProperties);
+
+ static const QMetaObject *staticMetaObject()
+ {
+ return QmlAttached<T>::staticMetaObject();
}
};
template<typename T>
- inline QQmlAttachedPropertiesFunc attachedPropertiesFunc()
+ inline QQmlAttachedPropertiesFunc<QObject> attachedPropertiesFunc()
{
- return AttachedPropertySelector<T, has_attachedPropertiesMethod<T, has_attachedPropertiesMember<T>::value>::value>::func();
+ return QmlAttachedAccessor<T>::attachedPropertiesFunc();
}
template<typename T>
inline const QMetaObject *attachedPropertiesMetaObject()
{
- return AttachedPropertySelector<T, has_attachedPropertiesMethod<T, has_attachedPropertiesMember<T>::value>::value>::metaObject();
+ return QmlAttachedAccessor<T>::staticMetaObject();
}
enum AutoParentResult { Parented, IncompatibleObject, IncompatibleParent };
@@ -236,7 +357,7 @@ namespace QQmlPrivate
const char *elementName;
const QMetaObject *metaObject;
- QQmlAttachedPropertiesFunc attachedPropertiesFunction;
+ QQmlAttachedPropertiesFunc<QObject> attachedPropertiesFunction;
const QMetaObject *attachedPropertiesMetaObject;
int parserStatusCast;
@@ -247,10 +368,38 @@ namespace QQmlPrivate
const QMetaObject *extensionMetaObject;
QQmlCustomParser *customParser;
+
int revision;
// If this is extended ensure "version" is bumped!!!
};
+ struct RegisterTypeAndRevisions {
+ int version;
+
+ int typeId;
+ int listId;
+ int objectSize;
+ void (*create)(void *);
+
+ const char *uri;
+ int versionMajor;
+
+ const QMetaObject *metaObject;
+ const QMetaObject *classInfoMetaObject;
+
+ QQmlAttachedPropertiesFunc<QObject> attachedPropertiesFunction;
+ const QMetaObject *attachedPropertiesMetaObject;
+
+ int parserStatusCast;
+ int valueSourceCast;
+ int valueInterceptorCast;
+
+ QObject *(*extensionObjectCreate)(QObject *);
+ const QMetaObject *extensionMetaObject;
+
+ QQmlCustomParser *(*customParserFactory)();
+ };
+
struct RegisterInterface {
int version;
@@ -258,6 +407,9 @@ namespace QQmlPrivate
int listId;
const char *iid;
+
+ const char *uri;
+ int versionMajor;
};
struct RegisterAutoParent {
@@ -283,6 +435,19 @@ namespace QQmlPrivate
// If this is extended ensure "version" is bumped!!!
};
+ struct RegisterSingletonTypeAndRevisions {
+ int version;
+ const char *uri;
+ int versionMajor;
+
+ QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *);
+ const QMetaObject *instanceMetaObject;
+ const QMetaObject *classInfoMetaObject;
+
+ int typeId;
+ std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3
+ };
+
struct RegisterCompositeType {
QUrl url;
const char *uri;
@@ -318,7 +483,9 @@ namespace QQmlPrivate
SingletonRegistration = 3,
CompositeRegistration = 4,
CompositeSingletonRegistration = 5,
- QmlUnitCacheHookRegistration = 6
+ QmlUnitCacheHookRegistration = 6,
+ TypeAndRevisionsRegistration = 7,
+ SingletonAndRevisionsRegistration = 8
};
int Q_QML_EXPORT qmlregister(RegistrationType, void *);
@@ -330,7 +497,168 @@ namespace QQmlPrivate
QPointer<QObject> m_object;
bool alreadyCalled = false;
};
-}
+
+ static int indexOfOwnClassInfo(const QMetaObject *metaObject, const char *key)
+ {
+ if (!metaObject || !key)
+ return -1;
+
+ const int offset = metaObject->classInfoOffset();
+ for (int i = metaObject->classInfoCount() + offset - 1; i >= offset; --i)
+ if (qstrcmp(key, metaObject->classInfo(i).name()) == 0) {
+ return i;
+ }
+ return -1;
+ }
+
+ inline const char *classInfo(const QMetaObject *metaObject, const char *key)
+ {
+ return metaObject->classInfo(indexOfOwnClassInfo(metaObject, key)).value();
+ }
+
+ inline int intClassInfo(const QMetaObject *metaObject, const char *key, int defaultValue = 0)
+ {
+ const int index = indexOfOwnClassInfo(metaObject, key);
+ return (index == -1) ? defaultValue
+ : QByteArray(metaObject->classInfo(index).value()).toInt();
+ }
+
+ inline bool boolClassInfo(const QMetaObject *metaObject, const char *key,
+ bool defaultValue = false)
+ {
+ const int index = indexOfOwnClassInfo(metaObject, key);
+ return (index == -1) ? defaultValue
+ : (QByteArray(metaObject->classInfo(index).value()) == "true");
+ }
+
+ inline const char *classElementName(const QMetaObject *metaObject)
+ {
+ const char *elementName = classInfo(metaObject, "QML.Element");
+ if (qstrcmp(elementName, "auto") == 0)
+ return metaObject->className();
+ if (qstrcmp(elementName, "anonymous") == 0)
+ return nullptr;
+
+ if (!elementName || elementName[0] < 'A' || elementName[0] > 'Z') {
+ qWarning() << "Missing or unusable QML.Element class info \"" << elementName << "\""
+ << "for" << metaObject->className();
+ }
+
+ return elementName;
+ }
+
+ template<class T, class = QmlVoidT<>>
+ struct QmlExtended
+ {
+ using Type = void;
+ };
+
+ template<class T>
+ struct QmlExtended<T, QmlVoidT<typename T::QmlExtendedType>>
+ {
+ using Type = typename T::QmlExtendedType;
+ };
+
+ template<class T, class = QmlVoidT<>>
+ struct QmlResolved
+ {
+ using Type = T;
+ };
+
+ template<class T>
+ struct QmlResolved<T, QmlVoidT<typename T::QmlForeignType>>
+ {
+ using Type = typename T::QmlForeignType;
+ };
+
+ template<class T, class = QmlVoidT<>>
+ struct QmlSingleton
+ {
+ static constexpr bool Value = false;
+ };
+
+ template<class T>
+ struct QmlSingleton<T, QmlVoidT<typename T::QmlIsSingleton>>
+ {
+ 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)
+ {
+ QML_GETTYPENAMES
+
+ RegisterSingletonTypeAndRevisions api = {
+ 0,
+
+ uri,
+ versionMajor,
+
+ nullptr,
+
+ &T::staticMetaObject,
+ classInfoMetaObject,
+
+ qRegisterNormalizedMetaType<T *>(pointerName.constData()),
+ Constructors<T>::createSingletonInstance
+ };
+
+ qmlregister(SingletonAndRevisionsRegistration, &api);
+ }
+
+ template<typename T, typename E>
+ void qmlRegisterTypeAndRevisions(const char *uri, int versionMajor,
+ const QMetaObject *classInfoMetaObject)
+ {
+ QML_GETTYPENAMES
+
+ RegisterTypeAndRevisions type = {
+ 0,
+ qRegisterNormalizedMetaType<T *>(pointerName.constData()),
+ qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ int(sizeof(T)),
+ Constructors<T>::createInto,
+
+ uri,
+ versionMajor,
+
+ &T::staticMetaObject,
+ classInfoMetaObject,
+
+ attachedPropertiesFunc<T>(),
+ attachedPropertiesMetaObject<T>(),
+
+ StaticCastSelector<T, QQmlParserStatus>::cast(),
+ StaticCastSelector<T, QQmlPropertyValueSource>::cast(),
+ StaticCastSelector<T, QQmlPropertyValueInterceptor>::cast(),
+
+ ExtendedType<E>::createParent,
+ ExtendedType<E>::staticMetaObject,
+
+ &qmlCreateCustomParser<T>
+ };
+
+ 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 86cb606f83..8521de6ab3 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -476,7 +476,7 @@ QQmlPropertyPrivate::propertyTypeCategory() const
return QQmlProperty::Normal;
} else if (type & QQmlProperty::Property) {
int type = propertyType();
- if (type == QVariant::Invalid)
+ if (type == QMetaType::UnknownType)
return QQmlProperty::InvalidCategory;
else if (QQmlValueTypeFactory::isValueType((uint)type))
return QQmlProperty::Normal;
@@ -531,7 +531,7 @@ bool QQmlProperty::operator==(const QQmlProperty &other) const
*/
int QQmlProperty::propertyType() const
{
- return d ? d->propertyType() : int(QVariant::Invalid);
+ return d ? d->propertyType() : int(QMetaType::UnknownType);
}
bool QQmlPropertyPrivate::isValueType() const
@@ -547,7 +547,7 @@ int QQmlPropertyPrivate::propertyType() const
} else if (type & QQmlProperty::Property) {
return core.propType();
} else {
- return QVariant::Invalid;
+ return QMetaType::UnknownType;
}
}
@@ -790,7 +790,7 @@ static void removeOldBinding(QObject *object, QQmlPropertyIndex index, QQmlPrope
return;
if (!(flags & QQmlPropertyPrivate::DontEnable))
- oldBinding->setEnabled(false, nullptr);
+ oldBinding->setEnabled(false, {});
oldBinding->removeFromObject();
}
@@ -896,7 +896,7 @@ void QQmlPropertyPrivate::setBinding(QQmlAbstractBinding *binding, BindingFlags
QQmlData *data = QQmlData::get(object, true);
if (data->propertyCache) {
QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex);
- Q_ASSERT(propertyData && !propertyData->isAlias());
+ Q_ASSERT(propertyData);
}
#endif
@@ -1144,7 +1144,7 @@ bool QQmlPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx,
QVariant v = value;
if (prop.isEnumType()) {
QMetaEnum menum = prop.enumerator();
- if (v.userType() == QVariant::String
+ if (v.userType() == QMetaType::QString
#ifdef QT3_SUPPORT
|| v.userType() == QVariant::CString
#endif
@@ -1156,13 +1156,13 @@ bool QQmlPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx,
v = QVariant(menum.keyToValue(value.toByteArray(), &ok));
if (!ok)
return false;
- } else if (v.userType() != QVariant::Int && v.userType() != QVariant::UInt) {
+ } else if (v.userType() != QMetaType::Int && v.userType() != QMetaType::UInt) {
int enumMetaTypeId = QMetaType::type(QByteArray(menum.scope() + QByteArray("::") + menum.name()));
if ((enumMetaTypeId == QMetaType::UnknownType) || (v.userType() != enumMetaTypeId) || !v.constData())
return false;
v = QVariant(*reinterpret_cast<const int *>(v.constData()));
}
- v.convert(QVariant::Int);
+ v.convert(QMetaType::Int);
}
// the status variable is changed by qt_metacall to indicate what it did
@@ -1229,17 +1229,17 @@ bool QQmlPropertyPrivate::write(QObject *object,
QMetaProperty prop = object->metaObject()->property(property.coreIndex());
QVariant v = value;
// Enum values come through the script engine as doubles
- if (variantType == QVariant::Double) {
+ if (variantType == QMetaType::Double) {
double integral;
double fractional = std::modf(value.toDouble(), &integral);
if (qFuzzyIsNull(fractional))
- v.convert(QVariant::Int);
+ v.convert(QMetaType::Int);
}
return writeEnumProperty(prop, property.coreIndex(), object, v, flags);
}
QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(context);
- const bool isUrl = propertyType == QVariant::Url; // handled separately
+ const bool isUrl = propertyType == QMetaType::QUrl; // handled separately
// The cases below are in approximate order of likelyhood:
if (propertyType == variantType && !isUrl && propertyType != qMetaTypeId<QList<QUrl>>() && !property.isQList()) {
@@ -1272,7 +1272,7 @@ bool QQmlPropertyPrivate::write(QObject *object,
} else {
return false;
}
- } else if (value.canConvert(propertyType) && !isUrl && variantType != QVariant::String && propertyType != qMetaTypeId<QList<QUrl>>() && !property.isQList()) {
+ } else if (value.canConvert(propertyType) && !isUrl && variantType != QMetaType::QString && propertyType != qMetaTypeId<QList<QUrl>>() && !property.isQList()) {
// common cases:
switch (propertyType) {
case QMetaType::Bool: {
@@ -1305,14 +1305,14 @@ bool QQmlPropertyPrivate::write(QObject *object,
return property.writeProperty(object, const_cast<QVariant *>(&value), flags);
} else if (isUrl) {
QUrl u;
- if (variantType == QVariant::Url) {
+ if (variantType == QMetaType::QUrl) {
u = value.toUrl();
- } else if (variantType == QVariant::ByteArray) {
+ } else if (variantType == QMetaType::QByteArray) {
QString input(QString::fromUtf8(value.toByteArray()));
// Encoded dir-separators defeat QUrl processing - decode them first
input.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive);
u = QUrl(input);
- } else if (variantType == QVariant::String) {
+ } else if (variantType == QMetaType::QString) {
QString input(value.toString());
// Encoded dir-separators defeat QUrl processing - decode them first
input.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive);
@@ -1378,7 +1378,7 @@ bool QQmlPropertyPrivate::write(QObject *object,
bool ok = false;
QVariant v;
- if (variantType == QVariant::String)
+ if (variantType == QMetaType::QString)
v = QQmlStringConverters::variantFromString(value.toString(), propertyType, &ok);
if (!ok) {
@@ -1391,8 +1391,8 @@ bool QQmlPropertyPrivate::write(QObject *object,
// successful conversion.
Q_ASSERT(v.userType() == propertyType);
ok = true;
- } else if (static_cast<uint>(propertyType) >= QVariant::UserType &&
- variantType == QVariant::String) {
+ } else if (static_cast<uint>(propertyType) >= QMetaType::User &&
+ variantType == QMetaType::QString) {
QQmlMetaType::StringConverter con = QQmlMetaType::customStringConverter(propertyType);
if (con) {
v = con(value.toString());
@@ -1406,28 +1406,28 @@ bool QQmlPropertyPrivate::write(QObject *object,
// to a sequence type property (eg, an int to a QList<int> property).
// or that we encountered an interface type
// Note that we've already handled single-value assignment to QList<QUrl> properties.
- if (variantType == QVariant::Int && propertyType == qMetaTypeId<QList<int> >()) {
+ if (variantType == QMetaType::Int && propertyType == qMetaTypeId<QList<int> >()) {
QList<int> list;
list << value.toInt();
v = QVariant::fromValue<QList<int> >(list);
ok = true;
- } else if ((variantType == QVariant::Double || variantType == QVariant::Int)
+ } else if ((variantType == QMetaType::Double || variantType == QMetaType::Int)
&& (propertyType == qMetaTypeId<QList<qreal> >())) {
QList<qreal> list;
list << value.toReal();
v = QVariant::fromValue<QList<qreal> >(list);
ok = true;
- } else if (variantType == QVariant::Bool && propertyType == qMetaTypeId<QList<bool> >()) {
+ } else if (variantType == QMetaType::Bool && propertyType == qMetaTypeId<QList<bool> >()) {
QList<bool> list;
list << value.toBool();
v = QVariant::fromValue<QList<bool> >(list);
ok = true;
- } else if (variantType == QVariant::String && propertyType == qMetaTypeId<QList<QString> >()) {
+ } else if (variantType == QMetaType::QString && propertyType == qMetaTypeId<QList<QString> >()) {
QList<QString> list;
list << value.toString();
v = QVariant::fromValue<QList<QString> >(list);
ok = true;
- } else if (variantType == QVariant::String && propertyType == qMetaTypeId<QStringList>()) {
+ } else if (variantType == QMetaType::QString && propertyType == qMetaTypeId<QStringList>()) {
QStringList list;
list << value.toString();
v = QVariant::fromValue<QStringList>(list);
@@ -1474,7 +1474,7 @@ QQmlMetaObject QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate *engi
*/
bool QQmlProperty::write(const QVariant &value) const
{
- return QQmlPropertyPrivate::write(*this, value, nullptr);
+ return QQmlPropertyPrivate::write(*this, value, {});
}
/*!
diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h
index 285c34d7fa..8abd83d7b4 100644
--- a/src/qml/qml/qqmlproperty_p.h
+++ b/src/qml/qml/qqmlproperty_p.h
@@ -107,9 +107,9 @@ public:
static bool writeValueProperty(QObject *,
const QQmlPropertyData &, const QQmlPropertyData &valueTypeData,
const QVariant &, QQmlContextData *,
- QQmlPropertyData::WriteFlags flags = nullptr);
+ QQmlPropertyData::WriteFlags flags = {});
static bool write(QObject *, const QQmlPropertyData &, const QVariant &,
- QQmlContextData *, QQmlPropertyData::WriteFlags flags = nullptr);
+ QQmlContextData *, QQmlPropertyData::WriteFlags flags = {});
static void findAliasTarget(QObject *, QQmlPropertyIndex, QObject **, QQmlPropertyIndex *);
enum BindingFlag {
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 69957ab282..0e5534fc04 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -71,10 +71,11 @@ static QQmlPropertyData::Flags fastFlagsForProperty(const QMetaProperty &p)
{
QQmlPropertyData::Flags flags;
- flags.isConstant = p.isConstant();
- flags.isWritable = p.isWritable();
- flags.isResettable = p.isResettable();
- flags.isFinal = p.isFinal();
+ flags.setIsConstant(p.isConstant());
+ flags.setIsWritable(p.isWritable());
+ flags.setIsResettable(p.isResettable());
+ flags.setIsFinal(p.isFinal());
+ flags.setIsRequired(p.isRequired());
if (p.isEnumType())
flags.type = QQmlPropertyData::Flags::EnumType;
@@ -92,7 +93,7 @@ static void flagsForPropertyType(int propType, QQmlPropertyData::Flags &flags)
flags.type = QQmlPropertyData::Flags::QObjectDerivedType;
} else if (propType == QMetaType::QVariant) {
flags.type = QQmlPropertyData::Flags::QVariantType;
- } else if (propType < static_cast<int>(QVariant::UserType)) {
+ } else if (propType < static_cast<int>(QMetaType::User)) {
// nothing to do
} else if (propType == qMetaTypeId<QQmlBinding *>()) {
flags.type = QQmlPropertyData::Flags::QmlBindingType;
@@ -136,14 +137,14 @@ static void populate(QQmlPropertyData *data, const QMetaProperty &p)
void QQmlPropertyData::lazyLoad(const QMetaProperty &p)
{
populate(this, p);
- int type = static_cast<int>(p.type());
+ int type = static_cast<int>(p.userType());
if (type == QMetaType::QObjectStar) {
setPropType(type);
m_flags.type = Flags::QObjectDerivedType;
} else if (type == QMetaType::QVariant) {
setPropType(type);
m_flags.type = Flags::QVariantType;
- } else if (type == QVariant::UserType || type == -1) {
+ } else if (type >= QMetaType::User || type == 0) {
m_flags.notFullyResolved = true;
} else {
setPropType(type);
@@ -166,21 +167,21 @@ void QQmlPropertyData::load(const QMetaMethod &m)
m_flags.type = Flags::FunctionType;
if (m.methodType() == QMetaMethod::Signal) {
- m_flags.isSignal = true;
+ m_flags.setIsSignal(true);
} else if (m.methodType() == QMetaMethod::Constructor) {
- m_flags.isConstructor = true;
+ m_flags.setIsConstructor(true);
setPropType(QMetaType::QObjectStar);
}
const int paramCount = m.parameterCount();
if (paramCount) {
- m_flags.hasArguments = true;
+ m_flags.setHasArguments(true);
if ((paramCount == 1) && (m.parameterTypes().constFirst() == "QQmlV4Function*"))
- m_flags.isV4Function = true;
+ m_flags.setIsV4Function(true);
}
if (m.attributes() & QMetaMethod::Cloned)
- m_flags.isCloned = true;
+ m_flags.setIsCloned(true);
Q_ASSERT(m.revision() <= Q_INT16_MAX);
setRevision(m.revision());
@@ -314,13 +315,13 @@ void QQmlPropertyCache::appendSignal(const QString &name, QQmlPropertyData::Flag
const QList<QByteArray> &names)
{
QQmlPropertyData data;
- data.setPropType(QVariant::Invalid);
+ data.setPropType(QMetaType::UnknownType);
data.setCoreIndex(coreIndex);
data.setFlags(flags);
data.setArguments(nullptr);
QQmlPropertyData handler = data;
- handler.m_flags.isSignalHandler = true;
+ handler.m_flags.setIsSignalHandler(true);
if (types) {
int argumentCount = *types;
@@ -398,6 +399,19 @@ const QMetaObject *QQmlPropertyCache::createMetaObject()
return _metaObject;
}
+QQmlPropertyData *QQmlPropertyCache::maybeUnresolvedProperty(int index) const
+{
+ if (index < 0 || index >= (propertyIndexCacheStart + propertyIndexCache.count()))
+ return nullptr;
+
+ QQmlPropertyData *rv = nullptr;
+ if (index < propertyIndexCacheStart)
+ return _parent->maybeUnresolvedProperty(index);
+ else
+ rv = const_cast<QQmlPropertyData *>(&propertyIndexCache.at(index - propertyIndexCacheStart));
+ return rv;
+}
+
QQmlPropertyData *QQmlPropertyCache::defaultProperty() const
{
return property(defaultPropertyName(), nullptr, nullptr);
@@ -519,7 +533,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
data->setFlags(methodFlags);
data->lazyLoad(m);
- data->m_flags.isDirect = !dynamicMetaObject;
+ data->m_flags.setIsDirect(!dynamicMetaObject);
Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
data->setMetaObjectOffset(allowedRevisionCache.count() - 1);
@@ -527,7 +541,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
if (data->isSignal()) {
sigdata = &signalHandlerIndexCache[signalHandlerIndex - signalHandlerIndexCacheStart];
*sigdata = *data;
- sigdata->m_flags.isSignalHandler = true;
+ sigdata->m_flags.setIsSignalHandler(true);
}
QQmlPropertyData *old = nullptr;
@@ -569,7 +583,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
if (old) {
// We only overload methods in the same class, exactly like C++
if (old->isFunction() && old->coreIndex() >= methodOffset)
- data->m_flags.isOverload = true;
+ data->m_flags.setIsOverload(true);
data->markAsOverrideOf(old);
}
@@ -600,7 +614,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
data->lazyLoad(p);
data->setTypeMinorVersion(typeMinorVersion);
- data->m_flags.isDirect = !dynamicMetaObject;
+ data->m_flags.setIsDirect(!dynamicMetaObject);
Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
data->setMetaObjectOffset(allowedRevisionCache.count() - 1);
@@ -626,7 +640,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
}
if (isGadget) // always dispatch over a 'normal' meta-call so the QQmlValueType can intercept
- data->m_flags.isDirect = false;
+ data->m_flags.setIsDirect(false);
else
data->trySetStaticMetaCallFunction(metaObject->d.static_metacall, ii - propOffset);
if (old)
@@ -849,7 +863,7 @@ void QQmlPropertyData::markAsOverrideOf(QQmlPropertyData *predecessor)
setOverrideIndexIsProperty(!predecessor->isFunction());
setOverrideIndex(predecessor->coreIndex());
- predecessor->m_flags.isOverridden = true;
+ predecessor->m_flags.setIsOverridden(true);
}
QQmlPropertyCacheMethodArguments *QQmlPropertyCache::createArgumentsObject(int argc, const QList<QByteArray> &names)
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index bfd78eef88..a5340cec37 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -118,6 +118,7 @@ public:
}
QQmlPropertyData *property(int) const;
+ QQmlPropertyData *maybeUnresolvedProperty(int) const;
QQmlPropertyData *method(int) const;
QQmlPropertyData *signal(int index) const;
QQmlEnumData *qmlEnum(int) const;
diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp
index 034ebfc743..36581bda4e 100644
--- a/src/qml/qml/qqmlpropertycachecreator.cpp
+++ b/src/qml/qml/qqmlpropertycachecreator.cpp
@@ -74,6 +74,22 @@ int QQmlPropertyCacheCreatorBase::metaTypeForPropertyType(QV4::CompiledData::Bui
return QMetaType::UnknownType;
}
+QByteArray QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(const QUrl &url)
+{
+ const QString path = url.path();
+ int lastSlash = path.lastIndexOf(QLatin1Char('/'));
+ // Not a reusable type if we don't have an absolute Url
+ if (lastSlash <= -1)
+ return QByteArray();
+ // ### this might not be correct for .ui.qml files
+ const QStringRef nameBase = path.midRef(lastSlash + 1, path.length() - lastSlash - 5);
+ // Not a reusable type if it doesn't start with a upper case letter.
+ if (nameBase.isEmpty() || !nameBase.at(0).isUpper())
+ return QByteArray();
+ return nameBase.toUtf8() + "_QMLTYPE_" +
+ QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1));
+}
+
QQmlBindingInstantiationContext::QQmlBindingInstantiationContext(int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding,
const QString &instantiatingPropertyName, QQmlPropertyCache *referencingObjectPropertyCache)
: referencingObjectIndex(referencingObjectIndex)
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index 39778aa328..6b02d6fb98 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -55,16 +55,21 @@
#include <private/qqmlmetaobject_p.h>
#include <private/qqmlpropertyresolver_p.h>
#include <private/qqmltypedata_p.h>
+#include <private/inlinecomponentutils_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
+
+#include <QScopedValueRollback>
+#include <vector>
QT_BEGIN_NAMESPACE
-inline QQmlJS::DiagnosticMessage qQmlCompileError(const QV4::CompiledData::Location &location,
+inline QQmlError qQmlCompileError(const QV4::CompiledData::Location &location,
const QString &description)
{
- QQmlJS::DiagnosticMessage error;
- error.line = location.line;
- error.column = location.column;
- error.message = description;
+ QQmlError error;
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(location.column));
+ error.setDescription(description);
return error;
}
@@ -97,6 +102,8 @@ public:
static QAtomicInt classIndexCounter;
static int metaTypeForPropertyType(QV4::CompiledData::BuiltinType type);
+
+ static QByteArray createClassNameTypeByUrl(const QUrl &url);
};
template <typename ObjectContainer>
@@ -108,14 +115,19 @@ public:
QQmlPropertyCacheCreator(QQmlPropertyCacheVector *propertyCaches,
QQmlPendingGroupPropertyBindings *pendingGroupPropertyBindings,
QQmlEnginePrivate *enginePrivate,
- const ObjectContainer *objectContainer, const QQmlImports *imports);
+ const ObjectContainer *objectContainer, const QQmlImports *imports,
+ const QByteArray &typeClassName);
- QQmlJS::DiagnosticMessage buildMetaObjects();
+ QQmlError buildMetaObjects();
+ enum class VMEMetaObjectIsRequired {
+ Maybe,
+ Always
+ };
protected:
- QQmlJS::DiagnosticMessage buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context);
- QQmlRefPointer<QQmlPropertyCache> propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlJS::DiagnosticMessage *error) const;
- QQmlJS::DiagnosticMessage createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache);
+ QQmlError buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context, VMEMetaObjectIsRequired isVMERequired);
+ QQmlRefPointer<QQmlPropertyCache> propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlError *error) const;
+ QQmlError createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache);
int metaTypeForParameter(const QV4::CompiledData::ParameterType &param, QString *customTypeName = nullptr);
@@ -126,31 +138,83 @@ protected:
const QQmlImports * const imports;
QQmlPropertyCacheVector *propertyCaches;
QQmlPendingGroupPropertyBindings *pendingGroupPropertyBindings;
+ QByteArray typeClassName; // not const as we temporarily chang it for inline components
+ unsigned int currentRoot; // set to objectID of inline component root when handling inline components
};
template <typename ObjectContainer>
inline QQmlPropertyCacheCreator<ObjectContainer>::QQmlPropertyCacheCreator(QQmlPropertyCacheVector *propertyCaches,
QQmlPendingGroupPropertyBindings *pendingGroupPropertyBindings,
QQmlEnginePrivate *enginePrivate,
- const ObjectContainer *objectContainer, const QQmlImports *imports)
+ const ObjectContainer *objectContainer, const QQmlImports *imports,
+ const QByteArray &typeClassName)
: enginePrivate(enginePrivate)
, objectContainer(objectContainer)
, imports(imports)
, propertyCaches(propertyCaches)
, pendingGroupPropertyBindings(pendingGroupPropertyBindings)
+ , typeClassName(typeClassName)
+ , currentRoot(-1)
{
propertyCaches->resize(objectContainer->objectCount());
}
template <typename ObjectContainer>
-inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjects()
+inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjects()
{
+ using namespace icutils;
QQmlBindingInstantiationContext context;
- return buildMetaObjectRecursively(/*root object*/0, context);
+
+ // get a list of all inline components
+ using InlineComponent = typename std::remove_reference<decltype (*(std::declval<CompiledObject>().inlineComponentsBegin()))>::type;
+ std::vector<InlineComponent> allICs {};
+ for (int i=0; i != objectContainer->objectCount(); ++i) {
+ const CompiledObject *obj = objectContainer->objectAt(i);
+ for (auto it = obj->inlineComponentsBegin(); it != obj->inlineComponentsEnd(); ++it) {
+ allICs.push_back(*it);
+ }
+ }
+
+ // create a graph on inline components referencing inline components
+ std::vector<Node> nodes;
+ nodes.resize(allICs.size());
+ std::iota(nodes.begin(), nodes.end(), 0);
+ AdjacencyList adjacencyList;
+ adjacencyList.resize(nodes.size());
+ fillAdjacencyListForInlineComponents(objectContainer, adjacencyList, nodes, allICs);
+
+ bool hasCycle = false;
+ auto nodesSorted = topoSort(nodes, adjacencyList, hasCycle);
+
+ if (hasCycle) {
+ QQmlError diag;
+ diag.setDescription(QLatin1String("Inline components form a cycle!"));
+ return diag;
+ }
+
+ // create meta objects for inline components before compiling actual root component
+ for (auto nodeIt = nodesSorted.rbegin(); nodeIt != nodesSorted.rend(); ++nodeIt) {
+ const auto &ic = allICs[nodeIt->index];
+ QV4::ResolvedTypeReference *typeRef = objectContainer->resolvedType(ic.nameIndex);
+ Q_ASSERT(propertyCaches->at(ic.objectIndex) == nullptr);
+ Q_ASSERT(typeRef->typePropertyCache.isNull()); // not set yet
+
+ QByteArray icTypeName { objectContainer->stringAt(ic.nameIndex).toUtf8() };
+ QScopedValueRollback<QByteArray> nameChange {typeClassName, icTypeName};
+ QScopedValueRollback<unsigned int> rootChange {currentRoot, ic.objectIndex};
+ QQmlError diag = buildMetaObjectRecursively(ic.objectIndex, context, VMEMetaObjectIsRequired::Always);
+ if (diag.isValid()) {
+ return diag;
+ }
+ typeRef->typePropertyCache = propertyCaches->at(ic.objectIndex);
+ Q_ASSERT(!typeRef->typePropertyCache.isNull());
+ }
+
+ return buildMetaObjectRecursively(/*root object*/0, context, VMEMetaObjectIsRequired::Maybe);
}
template <typename ObjectContainer>
-inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context)
+inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context, VMEMetaObjectIsRequired isVMERequired)
{
auto isAddressable = [](const QUrl &url) {
const QString fileName = url.fileName();
@@ -158,7 +222,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil
};
const CompiledObject *obj = objectContainer->objectAt(objectIndex);
- bool needVMEMetaObject = obj->propertyCount() != 0 || obj->aliasCount() != 0
+ bool needVMEMetaObject = isVMERequired == VMEMetaObjectIsRequired::Always || obj->propertyCount() != 0 || obj->aliasCount() != 0
|| obj->signalCount() != 0 || obj->functionCount() != 0 || obj->enumCount() != 0
|| (((obj->flags & QV4::CompiledData::Object::IsComponent)
|| (objectIndex == 0 && isAddressable(objectContainer->url())))
@@ -179,7 +243,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil
auto *typeRef = objectContainer->resolvedType(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
QQmlRefPointer<QQmlPropertyCache> baseTypeCache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
- QQmlJS::DiagnosticMessage error = createMetaObject(context.referencingObjectIndex, obj, baseTypeCache);
+ QQmlError error = createMetaObject(context.referencingObjectIndex, obj, baseTypeCache);
if (error.isValid())
return error;
}
@@ -194,7 +258,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil
QQmlRefPointer<QQmlPropertyCache> baseTypeCache;
{
- QQmlJS::DiagnosticMessage error;
+ QQmlError error;
baseTypeCache = propertyCacheForObject(obj, context, &error);
if (error.isValid())
return error;
@@ -202,7 +266,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil
if (baseTypeCache) {
if (needVMEMetaObject) {
- QQmlJS::DiagnosticMessage error = createMetaObject(objectIndex, obj, baseTypeCache);
+ QQmlError error = createMetaObject(objectIndex, obj, baseTypeCache);
if (error.isValid())
return error;
} else {
@@ -224,23 +288,24 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil
if (!context.resolveInstantiatingProperty())
pendingGroupPropertyBindings->append(context);
- QQmlJS::DiagnosticMessage error = buildMetaObjectRecursively(binding->value.objectIndex, context);
+ QQmlError error = buildMetaObjectRecursively(binding->value.objectIndex, context, VMEMetaObjectIsRequired::Maybe);
if (error.isValid())
return error;
}
}
- QQmlJS::DiagnosticMessage noError;
+ QQmlError noError;
return noError;
}
template <typename ObjectContainer>
-inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContainer>::propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlJS::DiagnosticMessage *error) const
+inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContainer>::propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlError *error) const
{
if (context.instantiatingProperty) {
return context.instantiatingPropertyCache(enginePrivate);
} else if (obj->inheritedTypeNameIndex != 0) {
auto *typeRef = objectContainer->resolvedType(obj->inheritedTypeNameIndex);
+ QQmlType qmltype = typeRef->type;
Q_ASSERT(typeRef);
if (typeRef->isFullyDynamicType) {
@@ -280,7 +345,7 @@ inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContaine
}
template <typename ObjectContainer>
-inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache)
+inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache)
{
QQmlRefPointer<QQmlPropertyCache> cache;
cache.adopt(baseTypeCache->copyAndReserve(obj->propertyCount() + obj->aliasCount(),
@@ -292,15 +357,8 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea
QByteArray newClassName;
- if (objectIndex == /*root object*/0) {
- const QString path = objectContainer->url().path();
- int lastSlash = path.lastIndexOf(QLatin1Char('/'));
- if (lastSlash > -1) {
- const QStringRef nameBase = path.midRef(lastSlash + 1, path.length() - lastSlash - 5);
- if (!nameBase.isEmpty() && nameBase.at(0).isUpper())
- newClassName = nameBase.toUtf8() + "_QMLTYPE_" +
- QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1));
- }
+ if (objectIndex == /*root object*/0 || int(currentRoot) == objectIndex) {
+ newClassName = typeClassName;
}
if (newClassName.isEmpty()) {
newClassName = QQmlMetaObject(baseTypeCache.data()).className();
@@ -429,7 +487,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea
auto flags = QQmlPropertyData::defaultSignalFlags();
if (paramCount)
- flags.hasArguments = true;
+ flags.setHasArguments(true);
QString signalName = stringAt(s->nameIndex);
if (seenSignals.contains(signalName))
@@ -458,7 +516,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea
auto formal = function->formalsBegin();
auto end = function->formalsEnd();
for ( ; formal != end; ++formal) {
- flags.hasArguments = true;
+ flags.setHasArguments(true);
parameterNames << stringAt(formal->nameIndex).toUtf8();
int type = metaTypeForParameter(formal->type);
if (type == QMetaType::UnknownType)
@@ -499,22 +557,43 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea
Q_ASSERT(!p->isBuiltinType);
QQmlType qmltype;
- if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr, nullptr)) {
+ bool selfReference = false;
+ if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr, nullptr,
+ nullptr, QQmlType::AnyRegistrationType, &selfReference)) {
return qQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Invalid property type"));
}
- Q_ASSERT(qmltype.isValid());
- if (qmltype.isComposite()) {
- QQmlRefPointer<QQmlTypeData> tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl());
- Q_ASSERT(tdata);
- Q_ASSERT(tdata->isComplete());
+ // inline components are not necessarily valid yet
+ Q_ASSERT(qmltype.isValid() || qmltype.isInlineComponentType());
+ if (qmltype.isComposite() || qmltype.isInlineComponentType()) {
+ CompositeMetaTypeIds typeIds;
+ if (qmltype.isInlineComponentType()) {
+ auto objectId = qmltype.inlineComponendId();
+ auto containingType = qmltype.containingType();
+ if (containingType.isValid()) {
+ auto icType = containingType.lookupInlineComponentById(objectId);
+ typeIds = {icType.typeId(), icType.qListTypeId()};
+ } else {
+ typeIds = {};
+ }
+ if (!typeIds.isValid()) // type has not been registered yet, we must be in containing type
+ typeIds = objectContainer->typeIdsForComponent(objectId);
+ Q_ASSERT(typeIds.isValid());
+ } else if (selfReference) {
+ typeIds = objectContainer->typeIdsForComponent();
+ } else {
+ QQmlRefPointer<QQmlTypeData> tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl());
+ Q_ASSERT(tdata);
+ Q_ASSERT(tdata->isComplete());
- auto compilationUnit = tdata->compilationUnit();
+ auto compilationUnit = tdata->compilationUnit();
+ typeIds = compilationUnit->typeIdsForComponent();
+ }
if (p->isList) {
- propertyType = compilationUnit->listMetaTypeId;
+ propertyType = typeIds.listId;
} else {
- propertyType = compilationUnit->metaTypeId;
+ propertyType = typeIds.id;
}
} else {
if (p->isList) {
@@ -532,7 +611,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea
}
if (!p->isReadOnly && !p->isList)
- propertyFlags.isWritable = true;
+ propertyFlags.setIsWritable(true);
QString propertyName = stringAt(p->nameIndex);
@@ -544,7 +623,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea
effectiveSignalIndex++;
}
- QQmlJS::DiagnosticMessage noError;
+ QQmlError noError;
return noError;
}
@@ -562,12 +641,17 @@ inline int QQmlPropertyCacheCreator<ObjectContainer>::metaTypeForParameter(const
if (customTypeName)
*customTypeName = typeName;
QQmlType qmltype;
- if (!imports->resolveType(typeName, &qmltype, nullptr, nullptr, nullptr))
+ bool selfReference = false;
+ if (!imports->resolveType(typeName, &qmltype, nullptr, nullptr, nullptr, nullptr, QQmlType::AnyRegistrationType,
+ &selfReference))
return QMetaType::UnknownType;
if (!qmltype.isComposite())
return qmltype.typeId();
+ if (selfReference)
+ return objectContainer->typeIdsForComponent().id;
+
QQmlRefPointer<QQmlTypeData> tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl());
Q_ASSERT(tdata);
Q_ASSERT(tdata->isComplete());
@@ -587,11 +671,11 @@ public:
void appendAliasPropertiesToMetaObjects(QQmlEnginePrivate *enginePriv);
- QQmlJS::DiagnosticMessage appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex, QQmlEnginePrivate *enginePriv);
+ QQmlError appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex, QQmlEnginePrivate *enginePriv);
private:
void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex, QQmlEnginePrivate *enginePriv);
- QQmlJS::DiagnosticMessage propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv);
+ QQmlError propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv);
void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const;
@@ -702,14 +786,14 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl
}
template <typename ObjectContainer>
-inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion,
+inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion,
QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv)
{
*type = 0;
bool writable = false;
bool resettable = false;
- propertyFlags->isAlias = true;
+ propertyFlags->setIsAlias(true);
if (alias.aliasToLocalAlias) {
const QV4::CompiledData::Alias *lastAlias = &alias;
@@ -756,7 +840,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>:
if (typeRef->type.isValid())
*type = typeRef->type.typeId();
else
- *type = typeRef->compilationUnit->metaTypeId;
+ *type = typeRef->compilationUnit()->metaTypeId;
*minorVersion = typeRef->minorVersion;
@@ -794,12 +878,12 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>:
if (valueTypeIndex != -1) {
const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(*type);
if (valueTypeMetaObject->property(valueTypeIndex).isEnumType())
- *type = QVariant::Int;
+ *type = QMetaType::Int;
else
*type = valueTypeMetaObject->property(valueTypeIndex).userType();
} else {
if (targetProperty->isEnum()) {
- *type = QVariant::Int;
+ *type = QMetaType::Int;
} else {
// Copy type flags
propertyFlags->copyPropertyTypeFlags(targetProperty->flags());
@@ -811,18 +895,18 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>:
}
}
- propertyFlags->isWritable = !(alias.flags & QV4::CompiledData::Alias::IsReadOnly) && writable;
- propertyFlags->isResettable = resettable;
- return QQmlJS::DiagnosticMessage();
+ propertyFlags->setIsWritable(!(alias.flags & QV4::CompiledData::Alias::IsReadOnly) && writable);
+ propertyFlags->setIsResettable(resettable);
+ return QQmlError();
}
template <typename ObjectContainer>
-inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache(
+inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache(
const CompiledObject &component, int objectIndex, QQmlEnginePrivate *enginePriv)
{
const CompiledObject &object = *objectContainer->objectAt(objectIndex);
if (!object.aliasCount())
- return QQmlJS::DiagnosticMessage();
+ return QQmlError();
QQmlPropertyCache *propertyCache = propertyCaches->at(objectIndex);
Q_ASSERT(propertyCache);
@@ -839,7 +923,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>:
int type = 0;
int minorVersion = 0;
QQmlPropertyData::Flags propertyFlags;
- QQmlJS::DiagnosticMessage error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags, enginePriv);
+ QQmlError error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags, enginePriv);
if (error.isValid())
return error;
@@ -852,7 +936,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>:
type, minorVersion, effectiveSignalIndex++);
}
- return QQmlJS::DiagnosticMessage();
+ return QQmlError();
}
template <typename ObjectContainer>
diff --git a/src/qml/qml/qqmlpropertydata_p.h b/src/qml/qml/qqmlpropertydata_p.h
index dec696226e..7f70c34854 100644
--- a/src/qml/qml/qqmlpropertydata_p.h
+++ b/src/qml/qml/qqmlpropertydata_p.h
@@ -52,6 +52,7 @@
//
#include <private/qobject_p.h>
+#include <QtCore/qglobal.h>
QT_BEGIN_NAMESPACE
@@ -69,6 +70,7 @@ public:
typedef QObjectPrivate::StaticMetaCallFunction StaticMetaCallFunction;
struct Flags {
+ friend class QQmlPropertyData;
enum Types {
OtherType = 0,
FunctionType = 1, // Is an invokable
@@ -87,30 +89,34 @@ public:
// trySetStaticMetaCallFunction for details.
// (Note: this padding is done here, because certain compilers have surprising behavior
// when an enum is declared in-between two bit fields.)
- enum { BitsLeftInFlags = 10 };
+ enum { BitsLeftInFlags = 15 };
unsigned otherBits : BitsLeftInFlags; // align to 32 bits
- // Can apply to all properties, except IsFunction
- unsigned isConstant : 1; // Has CONST flag
- unsigned isWritable : 1; // Has WRITE function
- unsigned isResettable : 1; // Has RESET function
- unsigned isAlias : 1; // Is a QML alias to another property
- unsigned isFinal : 1; // Has FINAL flag
- unsigned isOverridden : 1; // Is overridden by a extension property
- unsigned isDirect : 1; // Exists on a C++ QMetaObject
-
+ // Members of the form aORb can only be a when type is not FunctionType, and only be
+ // b when type equals FunctionType. For that reason, the semantic meaning of the bit is
+ // overloaded, and the accessor functions are used to get the correct value
+ //
+ // Moreover, isSignalHandler, isOverload and isCloned and isConstructor make only sense
+ // for functions, too (and could at a later point be reused for flags that only make sense
+ // for non-functions)
+ //
+ // Lastly, isDirect and isOverridden apply to both functions and non-functions
+ private:
+ unsigned isConstantORisVMEFunction : 1; // Has CONST flag OR Function was added by QML
+ unsigned isWritableORhasArguments : 1; // Has WRITE function OR Function takes arguments
+ unsigned isResettableORisSignal : 1; // Has RESET function OR Function is a signal
+ unsigned isAliasORisVMESignal : 1; // Is a QML alias to another property OR Signal was added by QML
+ unsigned isFinalORisV4Function : 1; // Has FINAL flag OR Function takes QQmlV4Function* args
+ unsigned isSignalHandler : 1; // Function is a signal handler
+ unsigned isOverload : 1; // Function is an overload of another function
+ unsigned isRequiredORisCloned : 1; // Has REQUIRED flag OR The function was marked as cloned
+ unsigned isConstructor : 1; // The function was marked is a constructor
+ unsigned isDirect : 1; // Exists on a C++ QMetaObject
+ unsigned isOverridden : 1; // Is overridden by a extension property
+ public:
unsigned type : 4; // stores an entry of Types
// Apply only to IsFunctions
- unsigned isVMEFunction : 1; // Function was added by QML
- unsigned hasArguments : 1; // Function takes arguments
- unsigned isSignal : 1; // Function is a signal
- unsigned isVMESignal : 1; // Signal was added by QML
- unsigned isV4Function : 1; // Function takes QQmlV4Function* args
- unsigned isSignalHandler : 1; // Function is a signal handler
- unsigned isOverload : 1; // Function is an overload of another function
- unsigned isCloned : 1; // The function was marked as cloned
- unsigned isConstructor : 1; // The function was marked is a constructor
// Internal QQmlPropertyCache flags
unsigned notFullyResolved : 1; // True if the type data is to be lazily resolved
@@ -119,8 +125,90 @@ public:
inline Flags();
inline bool operator==(const Flags &other) const;
inline void copyPropertyTypeFlags(Flags from);
+
+ void setIsConstant(bool b) {
+ Q_ASSERT(type != FunctionType);
+ isConstantORisVMEFunction = b;
+ }
+
+ void setIsWritable(bool b) {
+ Q_ASSERT(type != FunctionType);
+ isWritableORhasArguments = b;
+ }
+
+ void setIsResettable(bool b) {
+ Q_ASSERT(type != FunctionType);
+ isResettableORisSignal = b;
+ }
+
+ void setIsAlias(bool b) {
+ Q_ASSERT(type != FunctionType);
+ isAliasORisVMESignal = b;
+ }
+
+ void setIsFinal(bool b) {
+ Q_ASSERT(type != FunctionType);
+ isFinalORisV4Function = b;
+ }
+
+ void setIsOverridden(bool b) {
+ isOverridden = b;
+ }
+
+ void setIsDirect(bool b) {
+ isDirect = b;
+ }
+
+ void setIsRequired(bool b) {
+ Q_ASSERT(type != FunctionType);
+ isRequiredORisCloned = b;
+ }
+
+ void setIsVMEFunction(bool b) {
+ Q_ASSERT(type == FunctionType);
+ isConstantORisVMEFunction = b;
+ }
+ void setHasArguments(bool b) {
+ Q_ASSERT(type == FunctionType);
+ isWritableORhasArguments = b;
+ }
+ void setIsSignal(bool b) {
+ Q_ASSERT(type == FunctionType);
+ isResettableORisSignal = b;
+ }
+ void setIsVMESignal(bool b) {
+ Q_ASSERT(type == FunctionType);
+ isAliasORisVMESignal = b;
+ }
+
+ void setIsV4Function(bool b) {
+ Q_ASSERT(type == FunctionType);
+ isFinalORisV4Function = b;
+ }
+
+ void setIsSignalHandler(bool b) {
+ Q_ASSERT(type == FunctionType);
+ isSignalHandler = b;
+ }
+
+ void setIsOverload(bool b) {
+ Q_ASSERT(type == FunctionType);
+ isOverload = b;
+ }
+
+ void setIsCloned(bool b) {
+ Q_ASSERT(type == FunctionType);
+ isRequiredORisCloned = b;
+ }
+
+ void setIsConstructor(bool b) {
+ Q_ASSERT(type == FunctionType);
+ isConstructor = b;
+ }
+
};
+
inline bool operator==(const QQmlPropertyData &) const;
Flags flags() const { return m_flags; }
@@ -133,14 +221,15 @@ public:
bool isValid() const { return coreIndex() != -1; }
- bool isConstant() const { return m_flags.isConstant; }
- bool isWritable() const { return m_flags.isWritable; }
- void setWritable(bool onoff) { m_flags.isWritable = onoff; }
- bool isResettable() const { return m_flags.isResettable; }
- bool isAlias() const { return m_flags.isAlias; }
- bool isFinal() const { return m_flags.isFinal; }
+ bool isConstant() const { return !isFunction() && m_flags.isConstantORisVMEFunction; }
+ bool isWritable() const { return !isFunction() && m_flags.isWritableORhasArguments; }
+ void setWritable(bool onoff) { Q_ASSERT(!isFunction()); m_flags.isWritableORhasArguments = onoff; }
+ bool isResettable() const { return !isFunction() && m_flags.isResettableORisSignal; }
+ bool isAlias() const { return !isFunction() && m_flags.isAliasORisVMESignal; }
+ bool isFinal() const { return !isFunction() && m_flags.isFinalORisV4Function; }
bool isOverridden() const { return m_flags.isOverridden; }
- bool isDirect() const { return m_flags.isDirect; }
+ bool isDirect() const { return m_flags.isOverload; }
+ bool isRequired() const { return !isFunction() && m_flags.isRequiredORisCloned; }
bool hasStaticMetaCallFunction() const { return staticMetaCallFunction() != nullptr; }
bool isFunction() const { return m_flags.type == Flags::FunctionType; }
bool isQObject() const { return m_flags.type == Flags::QObjectDerivedType; }
@@ -150,15 +239,15 @@ public:
bool isQJSValue() const { return m_flags.type == Flags::QJSValueType; }
bool isVarProperty() const { return m_flags.type == Flags::VarPropertyType; }
bool isQVariant() const { return m_flags.type == Flags::QVariantType; }
- bool isVMEFunction() const { return m_flags.isVMEFunction; }
- bool hasArguments() const { return m_flags.hasArguments; }
- bool isSignal() const { return m_flags.isSignal; }
- bool isVMESignal() const { return m_flags.isVMESignal; }
- bool isV4Function() const { return m_flags.isV4Function; }
+ bool isVMEFunction() const { return isFunction() && m_flags.isConstantORisVMEFunction; }
+ bool hasArguments() const { return isFunction() && m_flags.isWritableORhasArguments; }
+ bool isSignal() const { return isFunction() && m_flags.isResettableORisSignal; }
+ bool isVMESignal() const { return isFunction() && m_flags.isAliasORisVMESignal; }
+ bool isV4Function() const { return isFunction() && m_flags.isFinalORisV4Function; }
bool isSignalHandler() const { return m_flags.isSignalHandler; }
bool isOverload() const { return m_flags.isOverload; }
void setOverload(bool onoff) { m_flags.isOverload = onoff; }
- bool isCloned() const { return m_flags.isCloned; }
+ bool isCloned() const { return isFunction() && m_flags.isRequiredORisCloned; }
bool isConstructor() const { return m_flags.isConstructor; }
bool hasOverride() const { return overrideIndex() >= 0; }
@@ -294,9 +383,9 @@ public:
static Flags defaultSignalFlags()
{
Flags f;
- f.isSignal = true;
f.type = Flags::FunctionType;
- f.isVMESignal = true;
+ f.setIsSignal(true);
+ f.setIsVMESignal(true);
return f;
}
@@ -304,7 +393,7 @@ public:
{
Flags f;
f.type = Flags::FunctionType;
- f.isVMEFunction = true;
+ f.setIsVMEFunction(true);
return f;
}
@@ -348,44 +437,32 @@ bool QQmlPropertyData::operator==(const QQmlPropertyData &other) const
QQmlPropertyData::Flags::Flags()
: otherBits(0)
- , isConstant(false)
- , isWritable(false)
- , isResettable(false)
- , isAlias(false)
- , isFinal(false)
- , isOverridden(false)
- , isDirect(false)
- , type(OtherType)
- , isVMEFunction(false)
- , hasArguments(false)
- , isSignal(false)
- , isVMESignal(false)
- , isV4Function(false)
+ , isConstantORisVMEFunction(false)
+ , isWritableORhasArguments(false)
+ , isResettableORisSignal(false)
+ , isAliasORisVMESignal(false)
+ , isFinalORisV4Function(false)
, isSignalHandler(false)
, isOverload(false)
- , isCloned(false)
+ , isRequiredORisCloned(false)
, isConstructor(false)
+ , isOverridden(false)
+ , type(OtherType)
, notFullyResolved(false)
, overrideIndexIsProperty(false)
{}
bool QQmlPropertyData::Flags::operator==(const QQmlPropertyData::Flags &other) const
{
- return isConstant == other.isConstant &&
- isWritable == other.isWritable &&
- isResettable == other.isResettable &&
- isAlias == other.isAlias &&
- isFinal == other.isFinal &&
+ return isConstantORisVMEFunction == other.isConstantORisVMEFunction &&
+ isWritableORhasArguments == other.isWritableORhasArguments &&
+ isResettableORisSignal == other.isResettableORisSignal &&
+ isAliasORisVMESignal == other.isAliasORisVMESignal &&
+ isFinalORisV4Function == other.isFinalORisV4Function &&
isOverridden == other.isOverridden &&
- type == other.type &&
- isVMEFunction == other.isVMEFunction &&
- hasArguments == other.hasArguments &&
- isSignal == other.isSignal &&
- isVMESignal == other.isVMESignal &&
- isV4Function == other.isV4Function &&
isSignalHandler == other.isSignalHandler &&
- isOverload == other.isOverload &&
- isCloned == other.isCloned &&
+ isRequiredORisCloned == other.isRequiredORisCloned &&
+ type == other.type &&
isConstructor == other.isConstructor &&
notFullyResolved == other.notFullyResolved &&
overrideIndexIsProperty == other.overrideIndexIsProperty;
diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp
index c75055a3b0..3587609301 100644
--- a/src/qml/qml/qqmlpropertyvalidator.cpp
+++ b/src/qml/qml/qqmlpropertyvalidator.cpp
@@ -73,7 +73,7 @@ QQmlPropertyValidator::QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, c
bindingPropertyDataPerObject->resize(compilationUnit->objectCount());
}
-QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validate()
+QVector<QQmlError> QQmlPropertyValidator::validate()
{
return validateObject(/*root object*/0, /*instantiatingBinding*/nullptr);
}
@@ -96,12 +96,15 @@ struct BindingFinder
}
};
-QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject(
+QVector<QQmlError> QQmlPropertyValidator::validateObject(
int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding, bool populatingValueTypeGroupProperty) const
{
const QV4::CompiledData::Object *obj = compilationUnit->objectAt(objectIndex);
+ for (auto it = obj->inlineComponentsBegin(); it != obj->inlineComponentsEnd(); ++it) {
+ 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);
@@ -110,7 +113,7 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject(
QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex);
if (!propertyCache)
- return QVector<QQmlJS::DiagnosticMessage>();
+ return QVector<QQmlError>();
QQmlCustomParser *customParser = nullptr;
if (auto typeRef = resolvedType(obj->inheritedTypeNameIndex)) {
@@ -220,7 +223,7 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject(
= pd
&& QQmlValueTypeFactory::metaObjectForMetaType(pd->propType())
&& !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment);
- const QVector<QQmlJS::DiagnosticMessage> subObjectValidatorErrors
+ const QVector<QQmlError> subObjectValidatorErrors
= validateObject(binding->value.objectIndex, binding,
populatingValueTypeGroupProperty);
if (!subObjectValidatorErrors.isEmpty())
@@ -277,11 +280,11 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject(
}
if (binding->type < QV4::CompiledData::Binding::Type_Script) {
- QQmlJS::DiagnosticMessage bindingError = validateLiteralBinding(propertyCache, pd, binding);
+ QQmlError bindingError = validateLiteralBinding(propertyCache, pd, binding);
if (bindingError.isValid())
return recordError(bindingError);
} else if (binding->type == QV4::CompiledData::Binding::Type_Object) {
- QQmlJS::DiagnosticMessage bindingError = validateObjectBinding(pd, name, binding);
+ QQmlError bindingError = validateObjectBinding(pd, name, binding);
if (bindingError.isValid())
return recordError(bindingError);
} else if (binding->isGroupProperty()) {
@@ -343,24 +346,24 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject(
customParser->validator = nullptr;
customParser->engine = nullptr;
customParser->imports = (QQmlImports*)nullptr;
- QVector<QQmlJS::DiagnosticMessage> parserErrors = customParser->errors();
+ QVector<QQmlError> parserErrors = customParser->errors();
if (!parserErrors.isEmpty())
return parserErrors;
}
(*bindingPropertyDataPerObject)[objectIndex] = collectedBindingPropertyData;
- QVector<QQmlJS::DiagnosticMessage> noError;
+ QVector<QQmlError> noError;
return noError;
}
-QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding) const
+QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding) const
{
if (property->isQList()) {
return qQmlCompileError(binding->valueLocation, tr("Cannot assign primitives to lists"));
}
- QQmlJS::DiagnosticMessage noError;
+ QQmlError noError;
if (property->isEnum()) {
if (binding->flags & QV4::CompiledData::Binding::IsResolvedEnum)
@@ -384,8 +387,8 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
if (binding->type == QV4::CompiledData::Binding::Type_Null) {
QQmlError warning;
warning.setUrl(compilationUnit->url());
- warning.setLine(binding->valueLocation.line);
- warning.setColumn(binding->valueLocation.column);
+ warning.setLine(qmlConvertSourceCoordinate<quint32, int>(binding->valueLocation.line));
+ warning.setColumn(qmlConvertSourceCoordinate<quint32, int>(binding->valueLocation.column));
warning.setDescription(error + tr(" - Assigning null to incompatible properties in QML "
"is deprecated. This will become a compile error in "
"future versions of Qt."));
@@ -398,31 +401,31 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
switch (property->propType()) {
case QMetaType::QVariant:
break;
- case QVariant::String: {
+ case QMetaType::QString: {
if (!binding->evaluatesToString()) {
return warnOrError(tr("Invalid property assignment: string expected"));
}
}
break;
- case QVariant::StringList: {
+ case QMetaType::QStringList: {
if (!binding->evaluatesToString()) {
return warnOrError(tr("Invalid property assignment: string or string list expected"));
}
}
break;
- case QVariant::ByteArray: {
+ case QMetaType::QByteArray: {
if (binding->type != QV4::CompiledData::Binding::Type_String) {
return warnOrError(tr("Invalid property assignment: byte array expected"));
}
}
break;
- case QVariant::Url: {
+ case QMetaType::QUrl: {
if (binding->type != QV4::CompiledData::Binding::Type_String) {
return warnOrError(tr("Invalid property assignment: url expected"));
}
}
break;
- case QVariant::UInt: {
+ case QMetaType::UInt: {
if (binding->type == QV4::CompiledData::Binding::Type_Number) {
double d = compilationUnit->bindingValueAsNumber(binding);
if (double(uint(d)) == d)
@@ -431,7 +434,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
return warnOrError(tr("Invalid property assignment: unsigned int expected"));
}
break;
- case QVariant::Int: {
+ case QMetaType::Int: {
if (binding->type == QV4::CompiledData::Binding::Type_Number) {
double d = compilationUnit->bindingValueAsNumber(binding);
if (double(int(d)) == d)
@@ -446,13 +449,13 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::Double: {
+ case QMetaType::Double: {
if (binding->type != QV4::CompiledData::Binding::Type_Number) {
return warnOrError(tr("Invalid property assignment: number expected"));
}
}
break;
- case QVariant::Color: {
+ case QMetaType::QColor: {
bool ok = false;
QQmlStringConverters::rgbaFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@@ -461,7 +464,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
break;
#if QT_CONFIG(datestring)
- case QVariant::Date: {
+ case QMetaType::QDate: {
bool ok = false;
QQmlStringConverters::dateFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@@ -469,7 +472,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::Time: {
+ case QMetaType::QTime: {
bool ok = false;
QQmlStringConverters::timeFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@@ -477,7 +480,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::DateTime: {
+ case QMetaType::QDateTime: {
bool ok = false;
QQmlStringConverters::dateTimeFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@@ -486,7 +489,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
break;
#endif // datestring
- case QVariant::Point: {
+ case QMetaType::QPoint: {
bool ok = false;
QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@@ -494,7 +497,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::PointF: {
+ case QMetaType::QPointF: {
bool ok = false;
QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@@ -502,7 +505,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::Size: {
+ case QMetaType::QSize: {
bool ok = false;
QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@@ -510,7 +513,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::SizeF: {
+ case QMetaType::QSizeF: {
bool ok = false;
QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@@ -518,7 +521,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::Rect: {
+ case QMetaType::QRect: {
bool ok = false;
QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@@ -526,7 +529,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::RectF: {
+ case QMetaType::QRectF: {
bool ok = false;
QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok);
if (!ok) {
@@ -534,13 +537,13 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::Bool: {
+ case QMetaType::Bool: {
if (binding->type != QV4::CompiledData::Binding::Type_Boolean) {
return warnOrError(tr("Invalid property assignment: boolean expected"));
}
}
break;
- case QVariant::Vector2D: {
+ case QMetaType::QVector2D: {
struct {
float xp;
float yp;
@@ -550,7 +553,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::Vector3D: {
+ case QMetaType::QVector3D: {
struct {
float xp;
float yp;
@@ -561,7 +564,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::Vector4D: {
+ case QMetaType::QVector4D: {
struct {
float xp;
float yp;
@@ -573,7 +576,7 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::Quaternion: {
+ case QMetaType::QQuaternion: {
struct {
float wp;
float xp;
@@ -585,8 +588,8 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp
}
}
break;
- case QVariant::RegExp:
- case QVariant::RegularExpression:
+ case QMetaType::QRegExp:
+ case QMetaType::QRegularExpression:
return warnOrError(tr("Invalid property assignment: regular expression expected; use /pattern/ syntax"));
default: {
// generate single literal value assignment to a list property if required
@@ -656,23 +659,23 @@ bool QQmlPropertyValidator::canCoerce(int to, QQmlPropertyCache *fromMo) const
return false;
}
-QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::recordError(const QV4::CompiledData::Location &location, const QString &description) const
+QVector<QQmlError> QQmlPropertyValidator::recordError(const QV4::CompiledData::Location &location, const QString &description) const
{
- QVector<QQmlJS::DiagnosticMessage> errors;
+ QVector<QQmlError> errors;
errors.append(qQmlCompileError(location, description));
return errors;
}
-QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::recordError(const QQmlJS::DiagnosticMessage &error) const
+QVector<QQmlError> QQmlPropertyValidator::recordError(const QQmlError &error) const
{
- QVector<QQmlJS::DiagnosticMessage> errors;
+ QVector<QQmlError> errors;
errors.append(error);
return errors;
}
-QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, const QString &propertyName, const QV4::CompiledData::Binding *binding) const
+QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, const QString &propertyName, const QV4::CompiledData::Binding *binding) const
{
- QQmlJS::DiagnosticMessage noError;
+ QQmlError noError;
if (binding->flags & QV4::CompiledData::Binding::IsOnAssignment) {
Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Object);
@@ -727,11 +730,11 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateObjectBinding(QQmlPrope
} else if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject && property->isFunction()) {
return noError;
} else if (isPrimitiveType(propType)) {
- auto typeName = QMetaType::typeName(propType);
+ auto typeName = QString::fromUtf8(QMetaType::typeName(propType));
return qQmlCompileError(binding->location, tr("Cannot assign value of type \"%1\" to property \"%2\", expecting \"%3\"")
.arg(rhsType())
.arg(propertyName)
- .arg(QString::fromUtf8(typeName)));
+ .arg(typeName));
} else if (QQmlValueTypeFactory::isValueType(propType)) {
return qQmlCompileError(binding->location, tr("Cannot assign value of type \"%1\" to property \"%2\", expecting an object")
.arg(rhsType()).arg(propertyName));
diff --git a/src/qml/qml/qqmlpropertyvalidator_p.h b/src/qml/qml/qqmlpropertyvalidator_p.h
index 74a1281927..281472981c 100644
--- a/src/qml/qml/qqmlpropertyvalidator_p.h
+++ b/src/qml/qml/qqmlpropertyvalidator_p.h
@@ -66,25 +66,24 @@ class QQmlPropertyValidator
public:
QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, const QQmlImports &imports, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit);
- QVector<QQmlJS::DiagnosticMessage> validate();
+ QVector<QQmlError> validate();
private:
- QVector<QQmlJS::DiagnosticMessage> validateObject(
+ QVector<QQmlError> validateObject(
int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding,
bool populatingValueTypeGroupProperty = false) const;
- QQmlJS::DiagnosticMessage validateLiteralBinding(
+ QQmlError validateLiteralBinding(
QQmlPropertyCache *propertyCache, QQmlPropertyData *property,
const QV4::CompiledData::Binding *binding) const;
- QQmlJS::DiagnosticMessage validateObjectBinding(
+ QQmlError validateObjectBinding(
QQmlPropertyData *property, const QString &propertyName,
const QV4::CompiledData::Binding *binding) const;
bool canCoerce(int to, QQmlPropertyCache *fromMo) const;
- Q_REQUIRED_RESULT QVector<QQmlJS::DiagnosticMessage> recordError(
+ Q_REQUIRED_RESULT QVector<QQmlError> recordError(
const QV4::CompiledData::Location &location, const QString &description) const;
- Q_REQUIRED_RESULT QVector<QQmlJS::DiagnosticMessage> recordError(
- const QQmlJS::DiagnosticMessage &error) const;
+ Q_REQUIRED_RESULT QVector<QQmlError> recordError(const QQmlError &error) const;
QString stringAt(int index) const { return compilationUnit->stringAt(index); }
QV4::ResolvedTypeReference *resolvedType(int id) const
{
diff --git a/src/qml/qml/qqmlscriptblob.cpp b/src/qml/qml/qqmlscriptblob.cpp
index eb103dc434..dac21f7ee7 100644
--- a/src/qml/qml/qqmlscriptblob.cpp
+++ b/src/qml/qml/qqmlscriptblob.cpp
@@ -41,6 +41,7 @@
#include <private/qqmlirbuilder_p.h>
#include <private/qqmlscriptblob_p.h>
#include <private/qqmlscriptdata_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
#include <private/qv4runtimecodegen_p.h>
#include <private/qv4script_p.h>
@@ -167,8 +168,8 @@ void QQmlScriptBlob::done()
QList<QQmlError> errors = script.script->errors();
QQmlError error;
error.setUrl(url());
- error.setLine(script.location.line);
- error.setColumn(script.location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(script.location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(script.location.column));
error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->urlString()));
errors.prepend(error);
setError(errors);
diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp
index 97fcba5009..317d3c7ef5 100644
--- a/src/qml/qml/qqmltype.cpp
+++ b/src/qml/qml/qqmltype.cpp
@@ -84,6 +84,9 @@ QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
case QQmlType::CompositeType:
extraData.fd = new QQmlCompositeTypeData;
break;
+ case QQmlType::InlineComponentType:
+ extraData.id = new QQmlInlineTypeData;
+ break;
default: qFatal("QQmlTypePrivate Internal Error.");
}
}
@@ -106,6 +109,9 @@ QQmlTypePrivate::~QQmlTypePrivate()
case QQmlType::CompositeType:
delete extraData.fd;
break;
+ case QQmlType::InlineComponentType:
+ delete extraData.id;
+ break;
default: //Also InterfaceType, because it has no extra data
break;
}
@@ -426,6 +432,12 @@ void QQmlTypePrivate::insertEnumsFromPropertyCache(const QQmlPropertyCache *cach
insertEnums(cppMetaObject);
}
+void QQmlTypePrivate::setContainingType(QQmlType *containingType)
+{
+ Q_ASSERT(regType == QQmlType::InlineComponentType);
+ extraData.id->containingType = containingType->d.data();
+}
+
void QQmlTypePrivate::setName(const QString &uri, const QString &element)
{
module = uri;
@@ -440,6 +452,8 @@ QByteArray QQmlType::typeName() const
return d->extraData.sd->singletonInstanceInfo->typeName.toUtf8();
else if (d->baseMetaObject)
return d->baseMetaObject->className();
+ else if (d->regType == InlineComponentType)
+ return d->extraData.id->inlineComponentName.toUtf8();
}
return QByteArray();
}
@@ -561,7 +575,11 @@ bool QQmlType::isComposite() const
bool QQmlType::isCompositeSingleton() const
{
- return d && d->regType == CompositeSingletonType;
+ // if the outer type is a composite singleton, d->regType will indicate that even for
+ // the inline component type
+ // however, inline components can -at least for now- never be singletons
+ // so we just do one additional check
+ return d && d->regType == CompositeSingletonType && !isInlineComponentType();
}
bool QQmlType::isQObjectSingleton() const
@@ -618,14 +636,14 @@ int QQmlType::metaObjectRevision() const
QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlEnginePrivate *engine) const
{
- if (const QQmlTypePrivate *base = d->attachedPropertiesBase(engine))
+ if (const QQmlTypePrivate *base = d ? d->attachedPropertiesBase(engine) : nullptr)
return base->extraData.cd->attachedPropertiesFunc;
return nullptr;
}
const QMetaObject *QQmlType::attachedPropertiesType(QQmlEnginePrivate *engine) const
{
- if (const QQmlTypePrivate *base = d->attachedPropertiesBase(engine))
+ if (const QQmlTypePrivate *base = d ? d->attachedPropertiesBase(engine) : nullptr)
return base->extraData.cd->attachedPropertiesType;
return nullptr;
}
@@ -677,9 +695,28 @@ int QQmlType::index() const
return d ? d->index : -1;
}
+bool QQmlType::isInlineComponentType() const {
+ return d ? d->regType == QQmlType::InlineComponentType : false;
+}
+
+int QQmlType::inlineComponendId() const {
+ bool ok = false;
+ if (d->regType == QQmlType::RegistrationType::InlineComponentType) {
+ Q_ASSERT(d->extraData.id->objectId != -1);
+ return d->extraData.id->objectId;
+ }
+ int subObjectId = sourceUrl().fragment().toInt(&ok);
+ return ok ? subObjectId : -1;
+}
+
QUrl QQmlType::sourceUrl() const
{
- return d ? d->sourceUrl() : QUrl();
+ auto url = d ? d->sourceUrl() : QUrl();
+ if (url.isValid() && d->regType == QQmlType::RegistrationType::InlineComponentType && d->extraData.id->objectId) {
+ Q_ASSERT(url.hasFragment());
+ url.setFragment(QString::number(inlineComponendId()));
+ }
+ return url;
}
int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &name, bool *ok) const
@@ -845,6 +882,19 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &scope
return -1;
}
+int QQmlType::inlineComponentObjectId()
+{
+ if (!isInlineComponentType())
+ return -1;
+ return d->extraData.id->objectId;
+}
+
+void QQmlType::setInlineComponentObjectId(int id) const
+{
+ Q_ASSERT(d && d->regType == QQmlType::InlineComponentType);
+ d->extraData.id->objectId = id;
+}
+
void QQmlType::refHandle(const QQmlTypePrivate *priv)
{
if (priv)
@@ -864,4 +914,66 @@ int QQmlType::refCount(const QQmlTypePrivate *priv)
return -1;
}
+int QQmlType::lookupInlineComponentIdByName(const QString &name) const
+{
+ Q_ASSERT(d);
+ return d->namesToInlineComponentObjectIndex.value(name, -1);
+}
+
+QQmlType QQmlType::containingType() const
+{
+ Q_ASSERT(d && d->regType == QQmlType::RegistrationType::InlineComponentType);
+ auto ret = QQmlType {d->extraData.id->containingType};
+ Q_ASSERT(!ret.isInlineComponentType());
+ return ret;
+}
+
+QQmlType QQmlType::lookupInlineComponentById(int objectid) const
+{
+ Q_ASSERT(d);
+ return d->objectIdToICType.value(objectid, QQmlType(nullptr));
+}
+
+int QQmlType::generatePlaceHolderICId() const
+{
+ Q_ASSERT(d);
+ int id = -2;
+ for (auto it = d->objectIdToICType.keyBegin(); it != d->objectIdToICType.keyEnd(); ++it)
+ if (*it < id)
+ id = *it;
+ return id;
+}
+
+void QQmlType::associateInlineComponent(const QString &name, int objectID, const CompositeMetaTypeIds &metaTypeIds, QQmlType existingType)
+{
+ bool const reuseExistingType = existingType.isValid();
+ auto priv = reuseExistingType ? const_cast<QQmlTypePrivate *>(existingType.d.data()) : new QQmlTypePrivate { RegistrationType::InlineComponentType } ;
+ priv->setName( QString::fromUtf8(typeName()), name);
+ auto icUrl = QUrl(sourceUrl());
+ icUrl.setFragment(QString::number(objectID));
+ priv->extraData.id->url = icUrl;
+ priv->extraData.id->containingType = d.data();
+ priv->extraData.id->objectId = objectID;
+ priv->typeId = metaTypeIds.id;
+ priv->listId = metaTypeIds.listId;
+ d->namesToInlineComponentObjectIndex.insert(name, objectID);
+ QQmlType icType(priv);
+ d->objectIdToICType.insert(objectID, icType);
+ if (!reuseExistingType)
+ priv->release();
+}
+
+void QQmlType::setPendingResolutionName(const QString &name)
+{
+ Q_ASSERT(d && d->regType == QQmlType::RegistrationType::InlineComponentType);
+ Q_ASSERT(d->extraData.id->inlineComponentName == name|| d->extraData.id->inlineComponentName.isEmpty());
+ d->extraData.id->inlineComponentName = name;
+}
+
+QString QQmlType::pendingResolutionName() const
+{
+ Q_ASSERT(d && d->regType == QQmlType::RegistrationType::InlineComponentType);
+ return d->extraData.id->inlineComponentName;
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h
index af134b21f1..387baa74bb 100644
--- a/src/qml/qml/qqmltype_p.h
+++ b/src/qml/qml/qqmltype_p.h
@@ -74,6 +74,7 @@ class QQmlPropertyCache;
namespace QV4 {
struct String;
}
+struct CompositeMetaTypeIds;
class Q_QML_PRIVATE_EXPORT QQmlType
{
@@ -144,6 +145,9 @@ public:
int index() const;
+ bool isInlineComponentType() const;
+ int inlineComponendId() const;
+
struct Q_QML_PRIVATE_EXPORT SingletonInstanceInfo
{
QJSValue (*scriptCallback)(QQmlEngine *, QJSEngine *) = nullptr;
@@ -166,6 +170,8 @@ public:
int scopedEnumValue(QQmlEnginePrivate *engine, int index, const QString &, bool *ok) const;
int scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &, const QByteArray &, bool *ok) const;
int scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &, const QStringRef &, bool *ok) const;
+ int inlineComponentObjectId();
+ void setInlineComponentObjectId(int id) const; // TODO: const setters are BAD
const QQmlTypePrivate *priv() const { return d.data(); }
static void refHandle(const QQmlTypePrivate *priv);
@@ -178,9 +184,19 @@ public:
InterfaceType = 2,
CompositeType = 3,
CompositeSingletonType = 4,
+ InlineComponentType = 5,
AnyRegistrationType = 255
};
+ QQmlType containingType() const;
+ int lookupInlineComponentIdByName(const QString &name) const;
+ QQmlType lookupInlineComponentById(int objectid) const;
+ int generatePlaceHolderICId() const;
+
+ void associateInlineComponent(const QString &name, int objectID, const CompositeMetaTypeIds &metaTypeIds, QQmlType existingType);
+ void setPendingResolutionName(const QString &name);
+ QString pendingResolutionName() const;
+
private:
friend class QQmlTypePrivate;
friend uint qHash(const QQmlType &t, uint seed);
diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h
index 51f776178c..43344827db 100644
--- a/src/qml/qml/qqmltype_p_p.h
+++ b/src/qml/qml/qqmltype_p_p.h
@@ -56,6 +56,7 @@
#include <private/qqmlproxymetaobject_p.h>
#include <private/qqmlrefcount_p.h>
#include <private/qqmlpropertycache_p.h>
+#include <private/qqmlmetatype_p.h>
QT_BEGIN_NAMESPACE
@@ -69,6 +70,7 @@ public:
void initEnums(QQmlEnginePrivate *engine) const;
void insertEnums(const QMetaObject *metaObject) const;
void insertEnumsFromPropertyCache(const QQmlPropertyCache *cache) const;
+ void setContainingType(QQmlType *containingType);
QUrl sourceUrl() const
{
@@ -77,6 +79,8 @@ public:
return extraData.fd->url;
case QQmlType::CompositeSingletonType:
return extraData.sd->singletonInstanceInfo->url;
+ case QQmlType::InlineComponentType:
+ return extraData.id->url;
default:
return QUrl();
}
@@ -130,10 +134,23 @@ public:
QUrl url;
};
+ struct QQmlInlineTypeData
+ {
+ QUrl url = QUrl();
+ // The containing type stores a pointer to the inline component type
+ // Using QQmlType here would create a reference cycle
+ // As the inline component type cannot outlive the containing type
+ // this should still be fine
+ QQmlTypePrivate const * containingType = nullptr;
+ QString inlineComponentName = QString();
+ int objectId = -1;
+ };
+
union extraData {
QQmlCppTypeData* cd;
QQmlSingletonTypeData* sd;
QQmlCompositeTypeData* fd;
+ QQmlInlineTypeData* id;
} extraData;
const char *iid;
@@ -160,6 +177,8 @@ public:
mutable QList<QStringHash<int>*> scopedEnums;
void setName(const QString &uri, const QString &element);
+ mutable QHash<QString, int> namesToInlineComponentObjectIndex;
+ mutable QHash<int, QQmlType> objectIdToICType;
private:
~QQmlTypePrivate() override;
diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp
index 9ff0e3fb9e..058bf8848c 100644
--- a/src/qml/qml/qqmltypecompiler.cpp
+++ b/src/qml/qml/qqmltypecompiler.cpp
@@ -58,10 +58,10 @@ QQmlTypeCompiler::QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *type
QV4::ResolvedTypeReferenceMap *resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
: resolvedTypes(resolvedTypeCache)
, engine(engine)
- , typeData(typeData)
, dependencyHasher(dependencyHasher)
- , typeNameCache(typeNameCache)
, document(parsedQML)
+ , typeNameCache(typeNameCache)
+ , typeData(typeData)
{
}
@@ -81,8 +81,8 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile()
{
QQmlPropertyCacheCreator<QQmlTypeCompiler> propertyCacheBuilder(&m_propertyCaches, &pendingGroupPropertyBindings,
- engine, this, imports());
- QQmlJS::DiagnosticMessage error = propertyCacheBuilder.buildMetaObjects();
+ engine, this, imports(), typeData->typeClassName());
+ QQmlError error = propertyCacheBuilder.buildMetaObjects();
if (error.isValid()) {
recordError(error);
return nullptr;
@@ -174,8 +174,8 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile()
void QQmlTypeCompiler::recordError(const QV4::CompiledData::Location &location, const QString &description)
{
QQmlError error;
- error.setLine(location.line);
- error.setColumn(location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(location.column));
error.setDescription(description);
error.setUrl(url());
errors << error;
@@ -185,8 +185,15 @@ void QQmlTypeCompiler::recordError(const QQmlJS::DiagnosticMessage &message)
{
QQmlError error;
error.setDescription(message.message);
- error.setLine(message.line);
- error.setColumn(message.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(message.loc.startLine));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(message.loc.startColumn));
+ error.setUrl(url());
+ errors << error;
+}
+
+void QQmlTypeCompiler::recordError(const QQmlError &e)
+{
+ QQmlError error = e;
error.setUrl(url());
errors << error;
}
@@ -279,6 +286,11 @@ void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier
document->imports.append(import);
}
+CompositeMetaTypeIds QQmlTypeCompiler::typeIdsForComponent(int objectId) const
+{
+ return typeData->typeIds(objectId);
+}
+
QQmlCompilePass::QQmlCompilePass(QQmlTypeCompiler *typeCompiler)
: compiler(typeCompiler)
{
@@ -801,8 +813,8 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
const QMetaObject *firstMetaObject = nullptr;
if (tr->type.isValid())
firstMetaObject = tr->type.metaObject();
- else if (tr->compilationUnit)
- firstMetaObject = tr->compilationUnit->rootPropertyCache()->firstCppMetaObject();
+ else if (const auto compilationUnit = tr->compilationUnit())
+ firstMetaObject = compilationUnit->rootPropertyCache()->firstCppMetaObject();
if (isUsableComponent(firstMetaObject))
continue;
// if here, not a QQmlComponent, so needs wrapping
@@ -876,6 +888,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;
@@ -931,7 +947,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);
@@ -1007,7 +1023,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex)
for (int objectIndex: qAsConst(_objectsWithAliases)) {
- QQmlJS::DiagnosticMessage error;
+ QQmlError error;
const auto result = resolveAliasesInObject(objectIndex, &error);
if (error.isValid()) {
@@ -1016,7 +1032,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex)
}
if (result == AllAliasesResolved) {
- QQmlJS::DiagnosticMessage error = aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex, enginePrivate);
+ QQmlError error = aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex, enginePrivate);
if (error.isValid()) {
recordError(error);
return false;
@@ -1047,7 +1063,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex)
QQmlComponentAndAliasResolver::AliasResolutionResult
QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex,
- QQmlJS::DiagnosticMessage *error)
+ QQmlError *error)
{
const QmlIR::Object * const obj = qmlObjects->at(objectIndex);
if (!obj->aliasCount())
@@ -1216,7 +1232,7 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex)
if (obj->idNameIndex != 0)
_seenObjectWithId = true;
- if (obj->flags & QV4::CompiledData::Object::IsComponent) {
+ if (obj->flags & QV4::CompiledData::Object::IsComponent && !obj->isInlineComponent) {
Q_ASSERT(obj->bindingCount() == 1);
const QV4::CompiledData::Binding *componentBinding = obj->firstBinding();
Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object);
diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h
index 40b0337848..057dd012c6 100644
--- a/src/qml/qml/qqmltypecompiler_p.h
+++ b/src/qml/qml/qqmltypecompiler_p.h
@@ -79,7 +79,9 @@ struct QQmlTypeCompiler
{
Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler)
public:
- QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document,
+ QQmlTypeCompiler(QQmlEnginePrivate *engine,
+ QQmlTypeData *typeData,
+ QmlIR::Document *document,
const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
QV4::ResolvedTypeReferenceMap *resolvedTypeCache,
const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
@@ -98,7 +100,8 @@ public:
QList<QQmlError> compilationErrors() const { return errors; }
void recordError(const QV4::CompiledData::Location &location, const QString &description);
- void recordError(const QQmlJS::DiagnosticMessage &error);
+ void recordError(const QQmlJS::DiagnosticMessage &message);
+ void recordError(const QQmlError &e);
int registerString(const QString &str);
int registerConstant(QV4::ReturnedValue v);
@@ -129,12 +132,12 @@ public:
return resolvedTypes->value(id);
}
+ CompositeMetaTypeIds typeIdsForComponent(int objectId = 0) const;
+
private:
QList<QQmlError> errors;
QQmlEnginePrivate *engine;
- QQmlTypeData *typeData;
const QV4::CompiledData::DependentTypesHasher &dependencyHasher;
- QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
QmlIR::Document *document;
// index is string index of type name (use obj->inheritedTypeNameIndex)
QHash<int, QQmlCustomParser*> customParsers;
@@ -142,6 +145,9 @@ private:
// index in first hash is component index, vector inside contains object indices of objects with id property
QVector<quint32> m_componentRoots;
QQmlPropertyCacheVector m_propertyCaches;
+
+ QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
+ QQmlTypeData *typeData;
};
struct QQmlCompilePass
@@ -152,7 +158,7 @@ struct QQmlCompilePass
protected:
void recordError(const QV4::CompiledData::Location &location, const QString &description) const
{ compiler->recordError(location, description); }
- void recordError(const QQmlJS::DiagnosticMessage &error)
+ void recordError(const QQmlError &error)
{ compiler->recordError(error); }
QV4::ResolvedTypeReference *resolvedType(int id) const
@@ -275,7 +281,7 @@ protected:
AllAliasesResolved
};
- AliasResolutionResult resolveAliasesInObject(int objectIndex, QQmlJS::DiagnosticMessage *error);
+ AliasResolutionResult resolveAliasesInObject(int objectIndex, QQmlError *error);
QQmlEnginePrivate *enginePrivate;
QQmlJS::MemoryPool *pool;
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index 0fd5bc83e6..fc1d0cfbcf 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -92,6 +92,25 @@ QV4::ExecutableCompilationUnit *QQmlTypeData::compilationUnit() const
return m_compiledData.data();
}
+QV4::ExecutableCompilationUnit *QQmlTypeData::compilationUnitForInlineComponent(unsigned int icObjectId) const
+{
+ Q_ASSERT(m_document || m_compiledData);
+ if (m_compiledData)
+ return m_compiledData.data();
+ for (auto it = m_document->objects.begin(); it != m_document->objects.end(); ++it) {
+ auto object = *it;
+ auto icIt = std::find_if(object->inlineComponentsBegin(), object->inlineComponentsEnd(), [&](const QV4::CompiledData::InlineComponent &ic) {
+ return ic.objectIndex == icObjectId;
+ });
+ if (icIt != object->inlineComponentsEnd()) {
+ Q_ASSERT(m_inlineComponentToCompiledData.contains(icIt->nameIndex));
+ return m_inlineComponentToCompiledData[icIt->nameIndex].data();
+ }
+ }
+ Q_UNREACHABLE();
+ return nullptr; // make integrity happy
+}
+
void QQmlTypeData::registerCallback(TypeDataCallback *callback)
{
Q_ASSERT(!m_callbacks.contains(callback));
@@ -105,6 +124,13 @@ void QQmlTypeData::unregisterCallback(TypeDataCallback *callback)
Q_ASSERT(!m_callbacks.contains(callback));
}
+CompositeMetaTypeIds QQmlTypeData::typeIds(int objectId) const
+{
+ if (objectId != 0)
+ return m_inlineComponentData[objectId].typeIds;
+ return m_typeIds;
+}
+
bool QQmlTypeData::tryLoadFromDiskCache()
{
if (!diskCacheEnabled())
@@ -130,8 +156,15 @@ bool QQmlTypeData::tryLoadFromDiskCache()
m_compiledData = unit;
- for (int i = 0, count = m_compiledData->objectCount(); i < count; ++i)
- m_typeReferences.collectFromObject(m_compiledData->objectAt(i));
+ QVector<QV4::CompiledData::InlineComponent> ics;
+ for (int i = 0, count = m_compiledData->objectCount(); i < count; ++i) {
+ auto object = m_compiledData->objectAt(i);
+ m_typeReferences.collectFromObject(object);
+ const auto inlineComponentTable = object->inlineComponentTable();
+ for (auto i = 0; i != object->nInlineComponents; ++i) {
+ ics.push_back(inlineComponentTable[i]);
+ }
+ }
m_importCache.setBaseUrl(finalUrl(), finalUrlString());
@@ -170,14 +203,28 @@ bool QQmlTypeData::tryLoadFromDiskCache()
Q_ASSERT(errors.size());
QQmlError error(errors.takeFirst());
error.setUrl(m_importCache.baseUrl());
- error.setLine(import->location.line);
- error.setColumn(import->location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column));
errors.prepend(error); // put it back on the list after filling out information.
setError(errors);
return false;
}
}
+ QQmlType containingType;
+ auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first();
+ int major = -1, minor = -1;
+ QQmlImportNamespace *ns = nullptr;
+ m_importCache.resolveType(containingTypeName, &containingType, &major, &minor, &ns);
+ for (auto&& ic: ics) {
+ QString const nameString = m_compiledData->stringAt(ic.nameIndex);
+ QByteArray const name = nameString.toUtf8();
+ auto importUrl = finalUrl();
+ importUrl.setFragment(QString::number(ic.objectIndex));
+ auto import = new QQmlImportInstance();
+ m_importCache.addInlineComponentImport(import, nameString, importUrl, containingType);
+ }
+
return true;
}
@@ -196,8 +243,8 @@ void QQmlTypeData::createTypeAndPropertyCaches(
{
QQmlPropertyCacheCreator<QV4::ExecutableCompilationUnit> propertyCacheCreator(
&m_compiledData->propertyCaches, &pendingGroupPropertyBindings, engine,
- m_compiledData.data(), &m_importCache);
- QQmlJS::DiagnosticMessage error = propertyCacheCreator.buildMetaObjects();
+ m_compiledData.data(), &m_importCache, typeClassName());
+ QQmlError error = propertyCacheCreator.buildMetaObjects();
if (error.isValid()) {
setError(error);
return;
@@ -228,6 +275,43 @@ static bool addTypeReferenceChecksumsToHash(const QList<QQmlTypeData::TypeRefere
return true;
}
+// local helper function for inline components
+namespace {
+template<typename ObjectContainer>
+void setupICs(const ObjectContainer &container, QHash<int, InlineComponentData> *icData, const QUrl &finalUrl) {
+ Q_ASSERT(icData->empty());
+ for (int i = 0; i != container->objectCount(); ++i) {
+ auto root = container->objectAt(i);
+ for (auto it = root->inlineComponentsBegin(); it != root->inlineComponentsEnd(); ++it) {
+ auto url = finalUrl;
+ url.setFragment(QString::number(it->objectIndex));
+ const QByteArray &className = QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(url);
+ InlineComponentData icDatum(QQmlMetaType::registerInternalCompositeType(className), int(it->objectIndex), int(it->nameIndex), 0, 0, 0);
+ icData->insert(it->objectIndex, icDatum);
+ }
+ }
+};
+}
+
+template<typename Container>
+void QQmlTypeData::setCompileUnit(const Container &container)
+{
+ for (int i = 0; i != container->objectCount(); ++i) {
+ auto const root = container->objectAt(i);
+ for (auto it = root->inlineComponentsBegin(); it != root->inlineComponentsEnd(); ++it) {
+ auto *typeRef = m_compiledData->resolvedType(it->nameIndex);
+
+ // We don't want the type reference to keep a strong reference to the compilation unit
+ // here. The compilation unit owns the type reference, and having a strong reference
+ // would prevent the compilation unit from ever getting deleted. We can still be sure
+ // that the compilation unit outlives the type reference, due to ownership.
+ typeRef->setReferencesCompilationUnit(false);
+
+ typeRef->setCompilationUnit(m_compiledData); // share compilation unit
+ }
+ }
+}
+
void QQmlTypeData::done()
{
auto cleanup = qScopeGuard([this]{
@@ -248,8 +332,8 @@ void QQmlTypeData::done()
QList<QQmlError> errors = script.script->errors();
QQmlError error;
error.setUrl(url());
- error.setLine(script.location.line);
- error.setColumn(script.location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(script.location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(script.location.column));
error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->urlString()));
errors.prepend(error);
setError(errors);
@@ -258,18 +342,38 @@ void QQmlTypeData::done()
}
// Check all type dependencies for errors
- for (auto it = m_resolvedTypes.constBegin(), end = m_resolvedTypes.constEnd(); it != end;
+ for (auto it = qAsConst(m_resolvedTypes).begin(), end = qAsConst(m_resolvedTypes).end(); it != end;
++it) {
const TypeReference &type = *it;
- Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError());
+ Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError() || type.type.isInlineComponentType());
+ if (type.type.isInlineComponentType() && !type.type.pendingResolutionName().isEmpty()) {
+ auto containingType = type.type.containingType();
+ auto objectId = containingType.lookupInlineComponentIdByName(type.type.pendingResolutionName());
+ if (objectId < 0) { // can be any negative number if we tentatively resolved it in QQmlImport but it actually was not an inline component
+ const QString typeName = stringAt(it.key());
+ int lastDot = typeName.lastIndexOf('.');
+
+ QList<QQmlError> errors = type.typeData ? type.typeData->errors() : QList<QQmlError>{};
+ QQmlError error;
+ error.setUrl(url());
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(type.location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(type.location.column));
+ error.setDescription(QQmlTypeLoader::tr("Type %1 has no inline component type called %2").arg(typeName.leftRef(lastDot), type.type.pendingResolutionName()));
+ errors.prepend(error);
+ setError(errors);
+ return;
+ } else {
+ type.type.setInlineComponentObjectId(objectId);
+ }
+ }
if (type.typeData && type.typeData->isError()) {
const QString typeName = stringAt(it.key());
QList<QQmlError> errors = type.typeData->errors();
QQmlError error;
error.setUrl(url());
- error.setLine(type.location.line);
- error.setColumn(type.location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(type.location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(type.location.column));
error.setDescription(QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName));
errors.prepend(error);
setError(errors);
@@ -287,8 +391,8 @@ void QQmlTypeData::done()
QList<QQmlError> errors = type.typeData->errors();
QQmlError error;
error.setUrl(url());
- error.setLine(type.location.line);
- error.setColumn(type.location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(type.location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(type.location.column));
error.setDescription(QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName));
errors.prepend(error);
setError(errors);
@@ -296,10 +400,28 @@ void QQmlTypeData::done()
}
}
- QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
+ m_typeClassName = QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(finalUrl());
+ if (!m_typeClassName.isEmpty())
+ m_typeIds = QQmlMetaType::registerInternalCompositeType(m_typeClassName);
+
+ if (m_document) {
+ setupICs(m_document, &m_inlineComponentData, finalUrl());
+ } else {
+ setupICs(m_compiledData, &m_inlineComponentData, finalUrl());
+ }
+ auto typeCleanupGuard = qScopeGuard([&]() {
+ if (isError() && m_typeIds.isValid()) {
+ QQmlMetaType::unregisterInternalCompositeType(m_typeIds);
+ for (auto&& icData: qAsConst(m_inlineComponentData)) {
+ QQmlMetaType::unregisterInternalCompositeType(icData.typeIds);
+ }
+ }
+ });
+
QV4::ResolvedTypeReferenceMap resolvedTypeCache;
+ QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
{
- QQmlJS::DiagnosticMessage error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache);
+ QQmlError error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache);
if (error.isValid()) {
setError(error);
qDeleteAll(resolvedTypeCache);
@@ -329,8 +451,12 @@ void QQmlTypeData::done()
if (!m_document.isNull()) {
// Compile component
compile(typeNameCache, &resolvedTypeCache, dependencyHasher);
+ if (!isError())
+ setCompileUnit(m_document);
} else {
createTypeAndPropertyCaches(typeNameCache, resolvedTypeCache);
+ if (!isError())
+ setCompileUnit(m_compiledData);
}
if (isError())
@@ -338,17 +464,18 @@ void QQmlTypeData::done()
{
QQmlEnginePrivate *const enginePrivate = QQmlEnginePrivate::get(engine);
+ m_compiledData->inlineComponentData = m_inlineComponentData;
{
// Sanity check property bindings
QQmlPropertyValidator validator(enginePrivate, m_importCache, m_compiledData);
- QVector<QQmlJS::DiagnosticMessage> errors = validator.validate();
+ QVector<QQmlError> errors = validator.validate();
if (!errors.isEmpty()) {
setError(errors);
return;
}
}
- m_compiledData->finalizeCompositeType(enginePrivate);
+ m_compiledData->finalizeCompositeType(enginePrivate, typeIds());
}
{
@@ -376,6 +503,26 @@ void QQmlTypeData::done()
}
}
+ // associate inline components to root component
+ {
+ auto typeName = finalUrlString().splitRef('/').last().split('.').first().toString();
+ // typeName can be empty if a QQmlComponent was constructed with an empty QUrl parameter
+ if (!typeName.isEmpty() && typeName.at(0).isUpper() && !m_inlineComponentData.isEmpty()) {
+ QHashedStringRef const hashedStringRef { typeName };
+ QList<QQmlError> errors;
+ auto type = QQmlMetaType::typeForUrl(finalUrlString(), hashedStringRef, false, &errors);
+ Q_ASSERT(errors.empty());
+ if (type.isValid()) {
+ for (auto const &icDatum : m_inlineComponentData) {
+ Q_ASSERT(icDatum.typeIds.isValid());
+ QQmlType existingType = type.lookupInlineComponentById(type.lookupInlineComponentIdByName(m_compiledData->stringAt(icDatum.nameIndex)));
+ type.associateInlineComponent(m_compiledData->stringAt(icDatum.nameIndex),
+ icDatum.objectIndex, icDatum.typeIds, existingType);
+ }
+ }
+ }
+ }
+
{
// Collect imported scripts
m_compiledData->dependentScripts.reserve(m_scripts.count());
@@ -485,8 +632,8 @@ bool QQmlTypeData::loadFromSource()
for (const QQmlJS::DiagnosticMessage &msg : qAsConst(compiler.errors)) {
QQmlError e;
e.setUrl(url());
- e.setLine(msg.line);
- e.setColumn(msg.column);
+ e.setLine(qmlConvertSourceCoordinate<quint32, int>(msg.loc.startLine));
+ e.setColumn(qmlConvertSourceCoordinate<quint32, int>(msg.loc.startColumn));
e.setDescription(msg.message);
errors << e;
}
@@ -509,6 +656,22 @@ void QQmlTypeData::restoreIR(QV4::CompiledData::CompilationUnit &&unit)
void QQmlTypeData::continueLoadFromIR()
{
+ QQmlType containingType;
+ auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first();
+ int major = -1, minor = -1;
+ QQmlImportNamespace *ns = nullptr;
+ m_importCache.resolveType(containingTypeName, &containingType, &major, &minor, &ns);
+ for (auto const& object: m_document->objects) {
+ for (auto it = object->inlineComponentsBegin(); it != object->inlineComponentsEnd(); ++it) {
+ QString const nameString = m_document->stringAt(it->nameIndex);
+ QByteArray const name = nameString.toUtf8();
+ auto importUrl = finalUrl();
+ importUrl.setFragment(QString::number(it->objectIndex));
+ auto import = new QQmlImportInstance(); // Note: The cache takes ownership of the QQmlImportInstance
+ m_importCache.addInlineComponentImport(import, nameString, importUrl, containingType);
+ }
+ }
+
m_typeReferences.collectFromObjects(m_document->objects.constBegin(), m_document->objects.constEnd());
m_importCache.setBaseUrl(finalUrl(), finalUrlString());
@@ -541,8 +704,8 @@ void QQmlTypeData::continueLoadFromIR()
Q_ASSERT(errors.size());
QQmlError error(errors.takeFirst());
error.setUrl(m_importCache.baseUrl());
- error.setLine(import->location.line);
- error.setColumn(import->location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column));
errors.prepend(error); // put it back on the list after filling out information.
setError(errors);
return;
@@ -568,8 +731,8 @@ void QQmlTypeData::allDependenciesDone()
QQmlError error;
error.setDescription(QQmlTypeLoader::tr("module \"%1\" is not installed").arg(import->uri));
error.setUrl(m_importCache.baseUrl());
- error.setLine(import->location.line);
- error.setColumn(import->location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column));
errors.prepend(error);
}
}
@@ -677,8 +840,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());
@@ -700,15 +864,28 @@ void QQmlTypeData::resolveTypes()
const QString name = stringAt(unresolvedRef.key());
+ bool *selfReferenceDetection = unresolvedRef->needsCreation ? nullptr : &ref.selfReference;
+
if (!resolveType(name, majorVersion, minorVersion, ref, unresolvedRef->location.line,
unresolvedRef->location.column, reportErrors,
- QQmlType::AnyRegistrationType) && reportErrors)
+ QQmlType::AnyRegistrationType, selfReferenceDetection) && reportErrors)
return;
- if (ref.type.isComposite()) {
+ if (ref.type.isComposite() && !ref.selfReference) {
ref.typeData = typeLoader()->getType(ref.type.sourceUrl());
addDependency(ref.typeData.data());
}
+ if (ref.type.isInlineComponentType()) {
+ auto containingType = ref.type.containingType();
+ if (containingType.isValid()) {
+ auto const url = containingType.sourceUrl();
+ if (url.isValid()) {
+ auto typeData = typeLoader()->getType(url);
+ ref.typeData = typeData;
+ addDependency(typeData.data());
+ }
+ }
+ }
ref.majorVersion = majorVersion;
ref.minorVersion = minorVersion;
@@ -716,7 +893,6 @@ void QQmlTypeData::resolveTypes()
ref.location.column = unresolvedRef->location.column;
ref.needsCreation = unresolvedRef->needsCreation;
-
m_resolvedTypes.insert(unresolvedRef.key(), ref);
}
@@ -725,7 +901,7 @@ void QQmlTypeData::resolveTypes()
loadImplicitImport();
}
-QQmlJS::DiagnosticMessage QQmlTypeData::buildTypeResolutionCaches(
+QQmlError QQmlTypeData::buildTypeResolutionCaches(
QQmlRefPointer<QQmlTypeNameCache> *typeNameCache,
QV4::ResolvedTypeReferenceMap *resolvedTypeCache
) const
@@ -750,8 +926,40 @@ QQmlJS::DiagnosticMessage QQmlTypeData::buildTypeResolutionCaches(
if (resolvedType->needsCreation && qmlType.isCompositeSingleton()) {
return qQmlCompileError(resolvedType->location, tr("Composite Singleton Type %1 is not creatable.").arg(qmlType.qmlTypeName()));
}
- ref->compilationUnit = resolvedType->typeData->compilationUnit();
- } else if (qmlType.isValid()) {
+ ref->setCompilationUnit(resolvedType->typeData->compilationUnit());
+ if (resolvedType->type.isInlineComponentType()) {
+ // Inline component which is part of an already resolved type
+ int objectId = -1;
+ if (qmlType.containingType().isValid()) {
+ objectId = qmlType.containingType().lookupInlineComponentIdByName(QString::fromUtf8(qmlType.typeName()));
+ qmlType.setInlineComponentObjectId(objectId);
+ } else {
+ objectId = resolvedType->type.inlineComponendId();
+ }
+ Q_ASSERT(objectId != -1);
+ ref->typePropertyCache = resolvedType->typeData->compilationUnit()->propertyCaches.at(objectId);
+ ref->type = qmlType;
+ Q_ASSERT(ref->type.isInlineComponentType());
+ }
+ } else if (resolvedType->type.isInlineComponentType()) {
+ // Inline component, defined in the file we are currently compiling
+ if (!m_inlineComponentToCompiledData.contains(resolvedType.key())) {
+ ref->type = qmlType;
+ if (qmlType.isValid()) {
+ // this is required for inline components in singletons
+ auto typeID = qmlType.lookupInlineComponentById(qmlType.inlineComponendId()).typeId();
+ auto exUnit = engine->obtainExecutableCompilationUnit(typeID);
+ if (exUnit) {
+ ref->setCompilationUnit(exUnit);
+ ref->typePropertyCache = engine->propertyCacheForType(typeID);
+ }
+ }
+ } else {
+ ref->setCompilationUnit(m_inlineComponentToCompiledData[resolvedType.key()]);
+ ref->typePropertyCache = m_inlineComponentToCompiledData[resolvedType.key()]->rootPropertyCache();
+ }
+
+ } else if (qmlType.isValid() && !resolvedType->selfReference) {
ref->type = qmlType;
Q_ASSERT(ref->type.isValid());
@@ -772,26 +980,29 @@ QQmlJS::DiagnosticMessage QQmlTypeData::buildTypeResolutionCaches(
ref->doDynamicTypeCheck();
resolvedTypeCache->insert(resolvedType.key(), ref.take());
}
- QQmlJS::DiagnosticMessage noError;
+ QQmlError noError;
return noError;
}
bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion,
TypeReference &ref, int lineNumber, int columnNumber,
- bool reportErrors, QQmlType::RegistrationType registrationType)
+ bool reportErrors, QQmlType::RegistrationType registrationType,
+ bool *typeRecursionDetected)
{
QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
bool typeFound = m_importCache.resolveType(typeName, &ref.type, &majorVersion, &minorVersion,
- &typeNamespace, &errors, registrationType);
+ &typeNamespace, &errors, registrationType,
+ typeRecursionDetected);
if (!typeNamespace && !typeFound && !m_implicitImportLoaded) {
// Lazy loading of implicit import
if (loadImplicitImport()) {
// Try again to find the type
errors.clear();
typeFound = m_importCache.resolveType(typeName, &ref.type, &majorVersion, &minorVersion,
- &typeNamespace, &errors, registrationType);
+ &typeNamespace, &errors, registrationType,
+ typeRecursionDetected);
} else {
return false; //loadImplicitImport() hit an error, and called setError already
}
diff --git a/src/qml/qml/qqmltypedata_p.h b/src/qml/qml/qqmltypedata_p.h
index e1d0c900ea..906a0ee171 100644
--- a/src/qml/qml/qqmltypedata_p.h
+++ b/src/qml/qml/qqmltypedata_p.h
@@ -69,6 +69,7 @@ public:
int majorVersion;
int minorVersion;
QQmlRefPointer<QQmlTypeData> typeData;
+ bool selfReference = false;
QString prefix; // used by CompositeSingleton types
QString qualifiedName() const;
bool needsCreation;
@@ -85,6 +86,8 @@ private:
friend class QQmlTypeLoader;
QQmlTypeData(const QUrl &, QQmlTypeLoader *);
+ template<typename Container>
+ void setCompileUnit(const Container &container);
public:
~QQmlTypeData() override;
@@ -92,6 +95,7 @@ public:
const QList<ScriptReference> &resolvedScripts() const;
QV4::ExecutableCompilationUnit *compilationUnit() const;
+ QV4::ExecutableCompilationUnit *compilationUnitForInlineComponent(unsigned int icObjectId) const;
// Used by QQmlComponent to get notifications
struct TypeDataCallback {
@@ -102,6 +106,9 @@ public:
void registerCallback(TypeDataCallback *);
void unregisterCallback(TypeDataCallback *);
+ CompositeMetaTypeIds typeIds(int objectId = 0) const;
+ QByteArray typeClassName() const { return m_typeClassName; }
+
protected:
void done() override;
void completed() override;
@@ -118,7 +125,7 @@ private:
void restoreIR(QV4::CompiledData::CompilationUnit &&unit);
void continueLoadFromIR();
void resolveTypes();
- QQmlJS::DiagnosticMessage buildTypeResolutionCaches(
+ QQmlError buildTypeResolutionCaches(
QQmlRefPointer<QQmlTypeNameCache> *typeNameCache,
QV4::ResolvedTypeReferenceMap *resolvedTypeCache
) const;
@@ -130,11 +137,11 @@ private:
bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion,
TypeReference &ref, int lineNumber = -1, int columnNumber = -1,
bool reportErrors = true,
- QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType);
+ QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
+ bool *typeRecursionDetected = nullptr);
void scriptImported(const QQmlRefPointer<QQmlScriptBlob> &blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace) override;
-
SourceCodeData m_backupSourceCode; // used when cache verification fails.
QScopedPointer<QmlIR::Document> m_document;
QV4::CompiledData::TypeReferenceMap m_typeReferences;
@@ -150,7 +157,16 @@ private:
QMap<int, TypeReference> m_resolvedTypes;
bool m_typesResolved:1;
- QQmlRefPointer<QV4::ExecutableCompilationUnit> m_compiledData;
+ // Used for self-referencing types, otherwise -1.
+ CompositeMetaTypeIds m_typeIds;
+ QByteArray m_typeClassName; // used for meta-object later
+
+ using ExecutableCompilationUnitPtr = QQmlRefPointer<QV4::ExecutableCompilationUnit>;
+
+ QHash<int, InlineComponentData> m_inlineComponentData;
+
+ ExecutableCompilationUnitPtr m_compiledData;
+ QHash<int, ExecutableCompilationUnitPtr> m_inlineComponentToCompiledData;
QList<TypeDataCallback *> m_callbacks;
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 6c12de926c..1d66e756fa 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -45,12 +45,15 @@
#include <private/qqmltypedata_p.h>
#include <private/qqmltypeloaderqmldircontent_p.h>
#include <private/qqmltypeloaderthread_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
#include <QtQml/qqmlabstracturlinterceptor.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlextensioninterface.h>
#include <QtQml/qqmlfile.h>
+#include <qtqml_tracepoints_p.h>
+
#include <QtCore/qdir.h>
#include <QtCore/qdiriterator.h>
#include <QtCore/qfile.h>
@@ -391,23 +394,33 @@ QQmlEngine *QQmlTypeLoader::engine() const
return m_engine;
}
-/*!
+/*! \internal
Call the initializeEngine() method on \a iface. Used by QQmlImportDatabase to ensure it
gets called in the correct thread.
*/
-void QQmlTypeLoader::initializeEngine(QQmlExtensionInterface *iface,
- const char *uri)
+template<class Interface>
+void doInitializeEngine(Interface *iface, QQmlTypeLoaderThread *thread, QQmlEngine *engine,
+ const char *uri)
{
- Q_ASSERT(m_thread->isThisThread() || engine()->thread() == QThread::currentThread());
+ Q_ASSERT(thread->isThisThread() || engine->thread() == QThread::currentThread());
- if (m_thread->isThisThread()) {
- m_thread->initializeEngine(iface, uri);
+ if (thread->isThisThread()) {
+ thread->initializeEngine(iface, uri);
} else {
- Q_ASSERT(engine()->thread() == QThread::currentThread());
- iface->initializeEngine(engine(), uri);
+ Q_ASSERT(engine->thread() == QThread::currentThread());
+ iface->initializeEngine(engine, uri);
}
}
+void QQmlTypeLoader::initializeEngine(QQmlEngineExtensionInterface *iface, const char *uri)
+{
+ doInitializeEngine(iface, m_thread, engine(), uri);
+}
+
+void QQmlTypeLoader::initializeEngine(QQmlExtensionInterface *iface, const char *uri)
+{
+ doInitializeEngine(iface, m_thread, engine(), uri);
+}
void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QByteArray &data)
{
@@ -426,6 +439,7 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QString &fileName)
void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeData &d)
{
+ Q_TRACE_SCOPE(QQmlCompiling, blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
blob->m_inCallback = true;
@@ -445,6 +459,7 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeD
void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit)
{
+ Q_TRACE_SCOPE(QQmlCompiling, blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
blob->m_inCallback = true;
@@ -563,14 +578,10 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo
QString qmldirFilePath;
QString qmldirUrl;
- if (QQmlMetaType::isLockedModule(import->uri, import->majorVersion)) {
- //Locked modules are checked first, to save on filesystem checks
- if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
- import->minorVersion, QString(), QString(), false, errors))
- return false;
-
- } else if (m_importCache.locateQmldir(importDatabase, import->uri, import->majorVersion, import->minorVersion,
- &qmldirFilePath, &qmldirUrl)) {
+ const QQmlImports::LocalQmldirResult qmldirResult = m_importCache.locateLocalQmldir(
+ importDatabase, import->uri, import->majorVersion, import->minorVersion,
+ &qmldirFilePath, &qmldirUrl);
+ if (qmldirResult == QQmlImports::QmldirFound) {
// This is a local library import
if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
import->minorVersion, qmldirFilePath, qmldirUrl, false, errors))
@@ -592,46 +603,57 @@ 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->majorVersion)
+
+ // Otherwise, try to register further module types.
+ || (qmldirResult != QQmlImports::QmldirInterceptedToRemote
+ && QQmlMetaType::qmlRegisterModuleTypes(import->uri, import->majorVersion))
+
+ // 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->majorVersion,
+ import->minorVersion, QString(), QString(), false, errors)) {
+ return false;
+ }
} else {
- // Is this a module?
- if (QQmlMetaType::isAnyModule(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->majorVersion,
- import->minorVersion, QString(), QString(), false, errors))
+ import->minorVersion, 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->majorVersion,
- import->minorVersion, QString(), QString(), true, errors))
- return false;
- // Probe for all possible locations
- int priority = 0;
- const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(import->uri, remotePathList, import->majorVersion, import->minorVersion);
- 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->majorVersion, import->minorVersion);
+ 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;
}
+
}
}
}
@@ -675,8 +697,8 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob)
Q_ASSERT(errors.size());
QQmlError error(errors.takeFirst());
error.setUrl(m_importCache.baseUrl());
- error.setLine(import->location.line);
- error.setColumn(import->location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column));
errors.prepend(error); // put it back on the list after filling out information.
setError(errors);
}
@@ -705,7 +727,7 @@ bool QQmlTypeLoader::Blob::isDebugging() const
bool QQmlTypeLoader::Blob::diskCacheEnabled() const
{
- return (!disableDiskCache() || forceDiskCache()) && !isDebugging();
+ return (!disableDiskCache() && !isDebugging()) || forceDiskCache();
}
bool QQmlTypeLoader::Blob::qmldirDataAvailable(const QQmlRefPointer<QQmlQmldirData> &data, QList<QQmlError> *errors)
@@ -964,48 +986,56 @@ bool QQmlTypeLoader::fileExists(const QString &path, const QString &file)
return false;
Q_ASSERT(path.endsWith(QLatin1Char('/')));
+
+ LockHolder<QQmlTypeLoader> holder(this);
+ QCache<QString, bool> *fileSet = m_importDirCache.object(path);
+ if (fileSet) {
+ if (bool *value = fileSet->object(file))
+ return *value;
+ } else if (m_importDirCache.contains(path)) {
+ // explicit nullptr in cache
+ return false;
+ }
+
+ auto addToCache = [&](const QFileInfo &fileInfo) {
+ if (!fileSet) {
+ fileSet = fileInfo.dir().exists() ? new QCache<QString, bool> : nullptr;
+ m_importDirCache.insert(path, fileSet);
+ if (!fileSet)
+ return false;
+ }
+
+ const bool exists = fileInfo.exists();
+ fileSet->insert(file, new bool(exists));
+ return exists;
+ };
+
if (path.at(0) == QLatin1Char(':')) {
// qrc resource
- QFileInfo fileInfo(path + file);
- return fileInfo.isFile();
- } else if (path.count() > 3 && path.at(3) == QLatin1Char(':') &&
- path.startsWith(QLatin1String("qrc"), Qt::CaseInsensitive)) {
+ return addToCache(QFileInfo(path + file));
+ }
+
+ if (path.count() > 3 && path.at(3) == QLatin1Char(':')
+ && path.startsWith(QLatin1String("qrc"), Qt::CaseInsensitive)) {
// qrc resource url
- QFileInfo fileInfo(QQmlFile::urlToLocalFileOrQrc(path + file));
- return fileInfo.isFile();
+ return addToCache(QFileInfo(QQmlFile::urlToLocalFileOrQrc(path + file)));
}
+
#if defined(Q_OS_ANDROID)
- else if (path.count() > 7 && path.at(6) == QLatin1Char(':') && path.at(7) == QLatin1Char('/') &&
- path.startsWith(QLatin1String("assets"), Qt::CaseInsensitive)) {
+ if (path.count() > 7 && path.at(6) == QLatin1Char(':') && path.at(7) == QLatin1Char('/')
+ && path.startsWith(QLatin1String("assets"), Qt::CaseInsensitive)) {
// assets resource url
- QFileInfo fileInfo(QQmlFile::urlToLocalFileOrQrc(path + file));
- return fileInfo.isFile();
- } else if (path.count() > 8 && path.at(7) == QLatin1Char(':') && path.at(8) == QLatin1Char('/') &&
- path.startsWith(QLatin1String("content"), Qt::CaseInsensitive)) {
- // content url
- QFileInfo fileInfo(QQmlFile::urlToLocalFileOrQrc(path + file));
- return fileInfo.isFile();
+ return addToCache(QFileInfo(QQmlFile::urlToLocalFileOrQrc(path + file)));
}
-#endif
- LockHolder<QQmlTypeLoader> holder(this);
- if (!m_importDirCache.contains(path)) {
- bool exists = QDir(path).exists();
- QCache<QString, bool> *entry = exists ? new QCache<QString, bool> : nullptr;
- m_importDirCache.insert(path, entry);
+ if (path.count() > 8 && path.at(7) == QLatin1Char(':') && path.at(8) == QLatin1Char('/')
+ && path.startsWith(QLatin1String("content"), Qt::CaseInsensitive)) {
+ // content url
+ return addToCache(QFileInfo(QQmlFile::urlToLocalFileOrQrc(path + file)));
}
- QCache<QString, bool> *fileSet = m_importDirCache.object(path);
- if (!fileSet)
- return false;
+#endif
- bool *value = fileSet->object(file);
- if (value) {
- return *value;
- } else {
- bool exists = QFile::exists(path + file);
- fileSet->insert(file, new bool(exists));
- return exists;
- }
+ return addToCache(QFileInfo(path + file));
}
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 38a7e05961..adecf61896 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -68,6 +68,7 @@ QT_BEGIN_NAMESPACE
class QQmlScriptBlob;
class QQmlQmldirData;
class QQmlTypeData;
+class QQmlEngineExtensionInterface;
class QQmlExtensionInterface;
class QQmlProfiler;
class QQmlTypeLoaderThread;
@@ -170,6 +171,7 @@ public:
void loadWithCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit, Mode mode = PreferSynchronous);
QQmlEngine *engine() const;
+ void initializeEngine(QQmlEngineExtensionInterface *, const char *);
void initializeEngine(QQmlExtensionInterface *, const char *);
void invalidate();
diff --git a/src/qml/qml/qqmltypeloaderqmldircontent.cpp b/src/qml/qml/qqmltypeloaderqmldircontent.cpp
index 860971d296..714ea79e67 100644
--- a/src/qml/qml/qqmltypeloaderqmldircontent.cpp
+++ b/src/qml/qml/qqmltypeloaderqmldircontent.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include <private/qqmltypeloaderqmldircontent_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
#include <QtQml/qqmlerror.h>
QT_BEGIN_NAMESPACE
@@ -59,8 +60,8 @@ QList<QQmlError> QQmlTypeLoaderQmldirContent::errors(const QString &uri) const
for (const auto &parseError : parseErrors) {
QQmlError error;
error.setUrl(url);
- error.setLine(parseError.line);
- error.setColumn(parseError.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(parseError.loc.startLine));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(parseError.loc.startColumn));
error.setDescription(parseError.message);
errors.append(error);
}
@@ -83,8 +84,8 @@ void QQmlTypeLoaderQmldirContent::setContent(const QString &location, const QStr
void QQmlTypeLoaderQmldirContent::setError(const QQmlError &error)
{
QQmlJS::DiagnosticMessage parseError;
- parseError.line = error.line();
- parseError.column = error.column();
+ parseError.loc.startLine = error.line();
+ parseError.loc.startColumn = error.column();
parseError.message = error.description();
m_parser.setError(parseError);
}
diff --git a/src/qml/qml/qqmltypeloaderthread.cpp b/src/qml/qml/qqmltypeloaderthread.cpp
index 0e1cecd1e5..618bb09039 100644
--- a/src/qml/qml/qqmltypeloaderthread.cpp
+++ b/src/qml/qml/qqmltypeloaderthread.cpp
@@ -138,7 +138,13 @@ void QQmlTypeLoaderThread::callDownloadProgressChanged(QQmlDataBlob *b, qreal p)
void QQmlTypeLoaderThread::initializeEngine(QQmlExtensionInterface *iface,
const char *uri)
{
- callMethodInMain(&This::initializeEngineMain, iface, uri);
+ callMethodInMain(&This::initializeExtensionMain, iface, uri);
+}
+
+void QQmlTypeLoaderThread::initializeEngine(QQmlEngineExtensionInterface *iface,
+ const char *uri)
+{
+ callMethodInMain(&This::initializeEngineExtensionMain, iface, uri);
}
void QQmlTypeLoaderThread::shutdownThread()
@@ -188,7 +194,14 @@ void QQmlTypeLoaderThread::callDownloadProgressChangedMain(QQmlDataBlob *b, qrea
b->release();
}
-void QQmlTypeLoaderThread::initializeEngineMain(QQmlExtensionInterface *iface,
+void QQmlTypeLoaderThread::initializeExtensionMain(QQmlExtensionInterface *iface,
+ const char *uri)
+{
+ Q_ASSERT(m_loader->engine()->thread() == QThread::currentThread());
+ iface->initializeEngine(m_loader->engine(), uri);
+}
+
+void QQmlTypeLoaderThread::initializeEngineExtensionMain(QQmlEngineExtensionInterface *iface,
const char *uri)
{
Q_ASSERT(m_loader->engine()->thread() == QThread::currentThread());
diff --git a/src/qml/qml/qqmltypeloaderthread_p.h b/src/qml/qml/qqmltypeloaderthread_p.h
index 67e47e86de..9fb441e6e2 100644
--- a/src/qml/qml/qqmltypeloaderthread_p.h
+++ b/src/qml/qml/qqmltypeloaderthread_p.h
@@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE
class QQmlDataBlob;
class QQmlTypeLoader;
+class QQmlEngineExtensionInterface;
class QQmlExtensionInterface;
class QQmlTypeLoaderThread : public QQmlThread
@@ -86,6 +87,7 @@ public:
void callCompleted(QQmlDataBlob *b);
void callDownloadProgressChanged(QQmlDataBlob *b, qreal p);
void initializeEngine(QQmlExtensionInterface *, const char *);
+ void initializeEngine(QQmlEngineExtensionInterface *, const char *);
protected:
void shutdownThread() override;
@@ -96,7 +98,8 @@ private:
void loadWithCachedUnitThread(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit);
void callCompletedMain(QQmlDataBlob *b);
void callDownloadProgressChangedMain(QQmlDataBlob *b, qreal p);
- void initializeEngineMain(QQmlExtensionInterface *iface, const char *uri);
+ void initializeExtensionMain(QQmlExtensionInterface *iface, const char *uri);
+ void initializeEngineExtensionMain(QQmlEngineExtensionInterface *iface, const char *uri);
QQmlTypeLoader *m_loader;
#if QT_CONFIG(qml_network)
diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp
index 9c9bf3e48f..9d6f269030 100644
--- a/src/qml/qml/qqmltypemodule.cpp
+++ b/src/qml/qml/qqmltypemodule.cpp
@@ -97,10 +97,14 @@ void QQmlTypeModule::add(QQmlTypePrivate *type)
QList<QQmlTypePrivate *> &list = d->typeHash[type->elementName];
for (int ii = 0; ii < list.count(); ++ii) {
- Q_ASSERT(list.at(ii));
- if (list.at(ii)->version_min < type->version_min) {
+ QQmlTypePrivate *in_list = list.at(ii);
+ Q_ASSERT(in_list);
+ if (in_list->version_min < type->version_min) {
list.insert(ii, type);
return;
+ } else if (in_list->version_min == type->version_min) {
+ list[ii] = type;
+ return;
}
}
list.append(type);
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index 8f1a61e6ad..1015403226 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -154,8 +154,10 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, QQml
QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
QQmlType t;
+ bool typeRecursionDetected = false;
bool typeFound = m_imports.resolveType(typeName, &t, nullptr, nullptr, &typeNamespace, &errors,
- QQmlType::AnyRegistrationType, recursionRestriction);
+ QQmlType::AnyRegistrationType,
+ recursionRestriction == QQmlImport::AllowRecursion ? &typeRecursionDetected : nullptr);
if (typeFound) {
return Result(t);
}
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 33630bf507..d8427f2961 100644
--- a/src/qml/qml/qqmltypenotavailable_p.h
+++ b/src/qml/qml/qqmltypenotavailable_p.h
@@ -55,11 +55,11 @@
QT_BEGIN_NAMESPACE
-
class QQmlTypeNotAvailable : public QObject {
Q_OBJECT
-public:
- QQmlTypeNotAvailable();
+ QML_NAMED_ELEMENT(TypeNotAvailable)
+ QML_UNCREATABLE("Type not available.")
+ QML_ADDED_IN_MINOR_VERSION(15)
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index ef4a628a04..fa5d36503d 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -400,7 +400,7 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const
// can only compare a QObject* against a QML type
const QObjectWrapper *wrapper = var.as<QObjectWrapper>();
if (!wrapper)
- return engine->throwTypeError();
+ return QV4::Encode(false);
// in case the wrapper outlived the QObject*
const QObject *wrapperObject = wrapper->object();
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index a8fe4ec2c6..a86564a49a 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -48,6 +48,8 @@
#include <private/qqmlmodelindexvaluetype_p.h>
#endif
+Q_DECLARE_METATYPE(QQmlProperty)
+
QT_BEGIN_NAMESPACE
namespace {
@@ -62,7 +64,7 @@ struct QQmlValueTypeFactoryImpl
const QMetaObject *metaObjectForMetaType(int);
QQmlValueType *valueType(int);
- QQmlValueType *valueTypes[QVariant::UserType];
+ QQmlValueType *valueTypes[QMetaType::User];
QHash<int, QQmlValueType *> userTypes;
QMutex mutex;
@@ -71,7 +73,7 @@ struct QQmlValueTypeFactoryImpl
QQmlValueTypeFactoryImpl::QQmlValueTypeFactoryImpl()
{
- std::fill_n(valueTypes, int(QVariant::UserType), &invalidValueType);
+ std::fill_n(valueTypes, int(QMetaType::User), &invalidValueType);
#if QT_CONFIG(qml_itemmodel)
// See types wrapped in qqmlmodelindexvaluetype_p.h
@@ -118,24 +120,24 @@ bool QQmlValueTypeFactoryImpl::isValueType(int idx)
const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
{
switch (t) {
- case QVariant::Point:
+ case QMetaType::QPoint:
return &QQmlPointValueType::staticMetaObject;
- case QVariant::PointF:
+ case QMetaType::QPointF:
return &QQmlPointFValueType::staticMetaObject;
- case QVariant::Size:
+ case QMetaType::QSize:
return &QQmlSizeValueType::staticMetaObject;
- case QVariant::SizeF:
+ case QMetaType::QSizeF:
return &QQmlSizeFValueType::staticMetaObject;
- case QVariant::Rect:
+ case QMetaType::QRect:
return &QQmlRectValueType::staticMetaObject;
- case QVariant::RectF:
+ case QMetaType::QRectF:
return &QQmlRectFValueType::staticMetaObject;
- case QVariant::EasingCurve:
+ case QMetaType::QEasingCurve:
return &QQmlEasingValueType::staticMetaObject;
#if QT_CONFIG(qml_itemmodel)
- case QVariant::ModelIndex:
+ case QMetaType::QModelIndex:
return &QQmlModelIndexValueType::staticMetaObject;
- case QVariant::PersistentModelIndex:
+ case QMetaType::QPersistentModelIndex:
return &QQmlPersistentModelIndexValueType::staticMetaObject;
#endif
default:
@@ -143,7 +145,8 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
if (t == qMetaTypeId<QItemSelectionRange>())
return &QQmlItemSelectionRangeValueType::staticMetaObject;
#endif
-
+ if (t == qMetaTypeId<QQmlProperty>())
+ return &QQmlPropertyValueType::staticMetaObject;
if (const QMetaObject *mo = QQml_valueTypeProvider()->metaObjectForMetaType(t))
return mo;
break;
@@ -157,7 +160,7 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
{
- if (idx >= (int)QVariant::UserType) {
+ if (idx >= (int)QMetaType::User) {
// Protect the hash with a mutex
mutex.lock();
@@ -598,6 +601,16 @@ void QQmlEasingValueType::setBezierCurve(const QVariantList &customCurveVariant)
v = newEasingCurve;
}
+QObject *QQmlPropertyValueType::object() const
+{
+ return v.object();
+}
+
+QString QQmlPropertyValueType::name() const
+{
+ return v.name();
+}
+
QVariantList QQmlEasingValueType::bezierCurve() const
{
QVariantList rv;
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index fec942fcbb..29fa999725 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -242,6 +242,8 @@ struct QQmlEasingValueType
{
QEasingCurve v;
Q_GADGET
+ QML_NAMED_ELEMENT(Easing)
+ QML_UNCREATABLE("Use the Type enum.")
Q_PROPERTY(QQmlEasingValueType::Type type READ type WRITE setType FINAL)
Q_PROPERTY(qreal amplitude READ amplitude WRITE setAmplitude FINAL)
@@ -289,6 +291,17 @@ public:
QVariantList bezierCurve() const;
};
+struct QQmlPropertyValueType
+{
+ QQmlProperty v;
+ Q_PROPERTY(QObject *object READ object CONSTANT FINAL)
+ Q_PROPERTY(QString name READ name CONSTANT FINAL)
+ Q_GADGET
+public:
+ QObject *object() const;
+ QString name() const;
+};
+
template<typename T>
int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index cf6553d129..110288faf7 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -96,29 +96,29 @@ using namespace QV4;
void Heap::QQmlValueTypeWrapper::destroy()
{
- if (gadgetPtr) {
- valueType->metaType.destruct(gadgetPtr);
- ::operator delete(gadgetPtr);
+ if (m_gadgetPtr) {
+ m_valueType->metaType.destruct(m_gadgetPtr);
+ ::operator delete(m_gadgetPtr);
}
- if (_propertyCache)
- _propertyCache->release();
+ if (m_propertyCache)
+ m_propertyCache->release();
Object::destroy();
}
void Heap::QQmlValueTypeWrapper::setValue(const QVariant &value) const
{
- Q_ASSERT(valueType->metaType.id() == value.userType());
- if (gadgetPtr)
- valueType->metaType.destruct(gadgetPtr);
- if (!gadgetPtr)
- gadgetPtr = ::operator new(valueType->metaType.sizeOf());
- valueType->metaType.construct(gadgetPtr, value.constData());
+ Q_ASSERT(valueType()->metaType.id() == value.userType());
+ if (auto *gadget = gadgetPtr())
+ valueType()->metaType.destruct(gadget);
+ if (!gadgetPtr())
+ setGadgetPtr(::operator new(valueType()->metaType.sizeOf()));
+ valueType()->metaType.construct(gadgetPtr(), value.constData());
}
QVariant Heap::QQmlValueTypeWrapper::toVariant() const
{
- Q_ASSERT(gadgetPtr);
- return QVariant(valueType->metaType.id(), gadgetPtr);
+ Q_ASSERT(gadgetPtr());
+ return QVariant(valueType()->metaType.id(), gadgetPtr());
}
@@ -146,13 +146,13 @@ bool QQmlValueTypeReference::readReferenceValue() const
QQmlPropertyCache *cache = nullptr;
if (const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(variantReferenceType))
cache = QJSEnginePrivate::get(engine())->cache(mo);
- if (d()->gadgetPtr) {
- d()->valueType->metaType.destruct(d()->gadgetPtr);
- ::operator delete(d()->gadgetPtr);
+ if (d()->gadgetPtr()) {
+ d()->valueType()->metaType.destruct(d()->gadgetPtr());
+ ::operator delete(d()->gadgetPtr());
}
- d()->gadgetPtr =nullptr;
+ d()->setGadgetPtr(nullptr);
d()->setPropertyCache(cache);
- d()->valueType = QQmlValueTypeFactory::valueType(variantReferenceType);
+ d()->setValueType(QQmlValueTypeFactory::valueType(variantReferenceType));
if (!cache)
return false;
} else {
@@ -161,12 +161,12 @@ bool QQmlValueTypeReference::readReferenceValue() const
}
d()->setValue(variantReferenceValue);
} else {
- if (!d()->gadgetPtr) {
- d()->gadgetPtr = ::operator new(d()->valueType->metaType.sizeOf());
- d()->valueType->metaType.construct(d()->gadgetPtr, nullptr);
+ if (!d()->gadgetPtr()) {
+ d()->setGadgetPtr(::operator new(d()->valueType()->metaType.sizeOf()));
+ d()->valueType()->metaType.construct(d()->gadgetPtr(), nullptr);
}
// value-type reference
- void *args[] = { d()->gadgetPtr, nullptr };
+ void *args[] = { d()->gadgetPtr(), nullptr };
QMetaObject::metacall(d()->object, QMetaObject::ReadProperty, d()->property, args);
}
return true;
@@ -192,8 +192,13 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *obj
r->d()->object = object;
r->d()->property = property;
r->d()->setPropertyCache(QJSEnginePrivate::get(engine)->cache(metaObject));
- r->d()->valueType = QQmlValueTypeFactory::valueType(typeId);
- r->d()->gadgetPtr = nullptr;
+ auto valueType = QQmlValueTypeFactory::valueType(typeId);
+ if (!valueType) {
+ return engine->throwTypeError(QLatin1String("Type %1 is not a value type")
+ .arg(QString::fromUtf8(QMetaType(typeId).name())));
+ }
+ r->d()->setValueType(valueType);
+ r->d()->setGadgetPtr(nullptr);
return r->asReturnedValue();
}
@@ -204,8 +209,13 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, const QVaria
Scoped<QQmlValueTypeWrapper> r(scope, engine->memoryManager->allocate<QQmlValueTypeWrapper>());
r->d()->setPropertyCache(QJSEnginePrivate::get(engine)->cache(metaObject));
- r->d()->valueType = QQmlValueTypeFactory::valueType(typeId);
- r->d()->gadgetPtr = nullptr;
+ auto valueType = QQmlValueTypeFactory::valueType(typeId);
+ if (!valueType) {
+ return engine->throwTypeError(QLatin1String("Type %1 is not a value type")
+ .arg(QString::fromUtf8(QMetaType(typeId).name())));
+ }
+ r->d()->setValueType(valueType);
+ r->d()->setGadgetPtr(nullptr);
r->d()->setValue(value);
return r->asReturnedValue();
}
@@ -223,9 +233,9 @@ bool QQmlValueTypeWrapper::toGadget(void *data) const
if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>())
if (!ref->readReferenceValue())
return false;
- const int typeId = d()->valueType->metaType.id();
+ const int typeId = d()->valueType()->metaType.id();
QMetaType::destruct(typeId, data);
- QMetaType::construct(typeId, data, d()->gadgetPtr);
+ QMetaType::construct(typeId, data, d()->gadgetPtr());
return true;
}
@@ -307,7 +317,7 @@ bool QQmlValueTypeWrapper::isEqual(const QVariant& value) const
int QQmlValueTypeWrapper::typeId() const
{
- return d()->valueType->metaType.id();
+ return d()->valueType()->metaType.id();
}
bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
@@ -315,10 +325,10 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
bool destructGadgetOnExit = false;
Q_ALLOCA_DECLARE(void, gadget);
if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>()) {
- if (!d()->gadgetPtr) {
- Q_ALLOCA_ASSIGN(void, gadget, d()->valueType->metaType.sizeOf());
- d()->gadgetPtr = gadget;
- d()->valueType->metaType.construct(d()->gadgetPtr, nullptr);
+ if (!d()->gadgetPtr()) {
+ Q_ALLOCA_ASSIGN(void, gadget, d()->valueType()->metaType.sizeOf());
+ d()->setGadgetPtr(gadget);
+ d()->valueType()->metaType.construct(d()->gadgetPtr(), nullptr);
destructGadgetOnExit = true;
}
if (!ref->readReferenceValue())
@@ -327,12 +337,12 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
int flags = 0;
int status = -1;
- void *a[] = { d()->gadgetPtr, nullptr, &status, &flags };
+ void *a[] = { d()->gadgetPtr(), nullptr, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty, propertyIndex, a);
if (destructGadgetOnExit) {
- d()->valueType->metaType.destruct(d()->gadgetPtr);
- d()->gadgetPtr = nullptr;
+ d()->valueType()->metaType.destruct(d()->gadgetPtr());
+ d()->setGadgetPtr(nullptr);
}
return true;
}
@@ -354,16 +364,16 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(const FunctionObject *b, con
// Prepare a buffer to pass to QMetaType::convert()
QString convertResult;
convertResult.~QString();
- if (QMetaType::convert(w->d()->gadgetPtr, w->d()->valueType->metaType.id(), &convertResult, QMetaType::QString)) {
+ if (QMetaType::convert(w->d()->gadgetPtr(), w->d()->valueType()->metaType.id(), &convertResult, QMetaType::QString)) {
result = convertResult;
} else {
- result += QString::fromUtf8(QMetaType::typeName(w->d()->valueType->metaType.id()))
+ result += QString::fromUtf8(QMetaType::typeName(w->d()->valueType()->metaType.id()))
+ QLatin1Char('(');
const QMetaObject *mo = w->d()->propertyCache()->metaObject();
const int propCount = mo->propertyCount();
for (int i = 0; i < propCount; ++i) {
if (mo->property(i).isDesignable()) {
- QVariant value = mo->property(i).readOnGadget(w->d()->gadgetPtr);
+ QVariant value = mo->property(i).readOnGadget(w->d()->gadgetPtr());
if (i > 0)
result += QLatin1String(", ");
result += value.toString();
@@ -387,7 +397,7 @@ Q_ALWAYS_INLINE static ReturnedValue getGadgetProperty(ExecutionEngine *engine,
if (property->propType() == metatype) { \
cpptype v; \
void *args[] = { &v, nullptr }; \
- metaObject->d.static_metacall(reinterpret_cast<QObject*>(valueTypeWrapper->gadgetPtr), \
+ metaObject->d.static_metacall(reinterpret_cast<QObject*>(valueTypeWrapper->gadgetPtr()), \
QMetaObject::ReadProperty, index, args); \
return QV4::Encode(constructor(v)); \
}
@@ -412,7 +422,7 @@ Q_ALWAYS_INLINE static ReturnedValue getGadgetProperty(ExecutionEngine *engine,
v = QVariant(property->propType(), static_cast<void *>(nullptr));
args[0] = v.data();
}
- metaObject->d.static_metacall(reinterpret_cast<QObject*>(valueTypeWrapper->gadgetPtr), QMetaObject::ReadProperty,
+ metaObject->d.static_metacall(reinterpret_cast<QObject*>(valueTypeWrapper->gadgetPtr()), QMetaObject::ReadProperty,
index, args);
return engine->fromVariant(v);
#undef VALUE_TYPE_LOAD
@@ -601,10 +611,10 @@ bool QQmlValueTypeWrapper::virtualPut(Managed *m, PropertyKey id, const Value &v
QVariant v = v4->toVariant(value, property.userType());
- if (property.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
+ if (property.isEnumType() && (QMetaType::Type)v.userType() == QMetaType::Double)
v = v.toInt();
- void *gadget = r->d()->gadgetPtr;
+ void *gadget = r->d()->gadgetPtr();
property.writeOnGadget(gadget, v);
@@ -620,7 +630,7 @@ bool QQmlValueTypeWrapper::virtualPut(Managed *m, PropertyKey id, const Value &v
} else {
int flags = 0;
int status = -1;
- void *a[] = { r->d()->gadgetPtr, nullptr, &status, &flags };
+ void *a[] = { r->d()->gadgetPtr(), nullptr, &status, &flags };
QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a);
}
}
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index baac129afa..60079aa623 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -69,22 +69,45 @@ namespace Heap {
struct QQmlValueTypeWrapper : Object {
void init() { Object::init(); }
void destroy();
- QQmlPropertyCache *propertyCache() const { return _propertyCache; }
+
+ QQmlPropertyCache *propertyCache() const { return m_propertyCache; }
void setPropertyCache(QQmlPropertyCache *c) {
if (c)
c->addref();
- if (_propertyCache)
- _propertyCache->release();
- _propertyCache = c;
+ if (m_propertyCache)
+ m_propertyCache->release();
+ m_propertyCache = c;
+ }
+
+ void setValueType(QQmlValueType *valueType)
+ {
+ Q_ASSERT(valueType != nullptr);
+ m_valueType = valueType;
+ }
+
+ QQmlValueType *valueType() const
+ {
+ Q_ASSERT(m_valueType != nullptr);
+ return m_valueType;
+ }
+
+ void setGadgetPtr(void *gadgetPtr) const
+ {
+ m_gadgetPtr = gadgetPtr;
+ }
+
+ void *gadgetPtr() const
+ {
+ return m_gadgetPtr;
}
- mutable void *gadgetPtr;
- QQmlValueType *valueType;
void setValue(const QVariant &value) const;
QVariant toVariant() const;
private:
- QQmlPropertyCache *_propertyCache;
+ mutable void *m_gadgetPtr;
+ QQmlValueType *m_valueType;
+ QQmlPropertyCache *m_propertyCache;
};
}
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index 13c5524d96..05a78a17fe 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -64,6 +64,8 @@
#include <private/qqmlengine_p.h>
#include <private/qfinitestack_p.h>
+#include <atomic>
+
QT_BEGIN_NAMESPACE
class QObject;
@@ -97,17 +99,20 @@ class QTypeInfo<QQmlVMETypes::State> : public QTypeInfoMerger<QQmlVMETypes::Stat
class QQmlInstantiationInterrupt {
public:
inline QQmlInstantiationInterrupt();
- inline QQmlInstantiationInterrupt(volatile bool *runWhile, int nsecs=0);
- inline QQmlInstantiationInterrupt(int nsecs);
+ // ### Qt 6: remove
+ inline QQmlInstantiationInterrupt(volatile bool *runWhile, qint64 nsecs=0);
+ inline QQmlInstantiationInterrupt(std::atomic<bool> *runWhile, qint64 nsecs = 0);
+ inline QQmlInstantiationInterrupt(qint64 nsecs);
inline void reset();
inline bool shouldInterrupt() const;
private:
- enum Mode { None, Time, Flag };
+ enum Mode { None, Time, LegacyFlag, Flag }; // ### Qt 6: remove LegacyFlag
Mode mode;
QElapsedTimer timer;
- int nsecs;
- volatile bool *runWhile;
+ qint64 nsecs = 0;
+ volatile bool *runWhileLegacy = nullptr; // ### Qt 6: remove
+ std::atomic<bool> *runWhile = nullptr;
};
class Q_QML_PRIVATE_EXPORT QQmlVME
@@ -147,17 +152,22 @@ private:
};
QQmlInstantiationInterrupt::QQmlInstantiationInterrupt()
- : mode(None), nsecs(0), runWhile(nullptr)
+ : mode(None)
{
}
-QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(volatile bool *runWhile, int nsecs)
+QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(volatile bool *runWhile, qint64 nsecs)
+ : mode(LegacyFlag), nsecs(nsecs), runWhileLegacy(runWhile)
+{
+}
+
+QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(std::atomic<bool> *runWhile, qint64 nsecs)
: mode(Flag), nsecs(nsecs), runWhile(runWhile)
{
}
-QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(int nsecs)
- : mode(Time), nsecs(nsecs), runWhile(nullptr)
+QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(qint64 nsecs)
+ : mode(Time), nsecs(nsecs)
{
}
@@ -169,15 +179,18 @@ void QQmlInstantiationInterrupt::reset()
bool QQmlInstantiationInterrupt::shouldInterrupt() const
{
- if (mode == None) {
+ switch (mode) {
+ case None:
return false;
- } else if (mode == Time) {
+ case Time:
return timer.nsecsElapsed() > nsecs;
- } else if (mode == Flag) {
- return !*runWhile || (nsecs && timer.nsecsElapsed() > nsecs);
- } else {
- return false;
+ case LegacyFlag:
+ return !*runWhileLegacy || (nsecs && timer.nsecsElapsed() > nsecs);
+ case Flag:
+ return !runWhile->load(std::memory_order_acquire) || (nsecs && timer.nsecsElapsed() > nsecs);
}
+ Q_UNREACHABLE();
+ return false;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 69215b1304..aa9f4bc1bd 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -48,6 +48,7 @@
#include "qqmlcontext_p.h"
#include "qqmlbinding_p.h"
#include "qqmlpropertyvalueinterceptor_p.h"
+#include <qqmlinfo.h>
#include <private/qqmlglobal_p.h>
@@ -60,32 +61,105 @@
#include <private/qqmlpropertycachecreator_p.h>
#include <private/qqmlpropertycachemethodarguments_p.h>
+#include <climits> // for CHAR_BIT
+
QT_BEGIN_NAMESPACE
+class ResolvedList
+{
+ Q_DISABLE_COPY_MOVE(ResolvedList)
+
+public:
+ ResolvedList(QQmlListProperty<QObject> *prop)
+ {
+ // see QQmlVMEMetaObject::metaCall for how this was constructed
+ auto encodedIndex = quintptr(prop->data);
+ constexpr quintptr usableBits = sizeof(quintptr) * CHAR_BIT;
+ quintptr inheritanceDepth = encodedIndex >> (usableBits / 2);
+ m_id = encodedIndex & ((quintptr(1) << (usableBits / 2)) - 1);
+
+ // walk up to the correct meta object if necessary
+ auto mo = prop->object->metaObject();
+ while (inheritanceDepth--)
+ mo = mo->superClass();
+ m_metaObject = static_cast<QQmlVMEMetaObject *>(const_cast<QMetaObject *>(mo));
+ Q_ASSERT(m_metaObject);
+ Q_ASSERT( ::strstr(m_metaObject->property(m_metaObject->propOffset() + m_id).typeName(), "QQmlListProperty") );
+ Q_ASSERT(m_metaObject->object == prop->object);
+
+ // readPropertyAsList() with checks transformed into Q_ASSERT
+ // and without allocation.
+ if (m_metaObject->propertyAndMethodStorage.isUndefined() &&
+ m_metaObject->propertyAndMethodStorage.valueRef()) {
+ return;
+ }
+
+ if (auto *md = static_cast<QV4::MemberData *>(
+ m_metaObject->propertyAndMethodStorage.asManaged())) {
+ const auto *v = (md->data() + m_id)->as<QV4::VariantObject>();
+ Q_ASSERT(v);
+ Q_ASSERT(v->d());
+ QVariant &data = v->d()->data();
+ Q_ASSERT(data.userType() == qMetaTypeId<QVector<QQmlGuard<QObject>>>());
+ m_list = static_cast<QVector<QQmlGuard<QObject>> *>(data.data());
+ Q_ASSERT(m_list);
+ }
+ }
+
+ ~ResolvedList() = default;
+
+ QQmlVMEMetaObject *metaObject() const { return m_metaObject; }
+ QVector<QQmlGuard<QObject>> *list() const { return m_list; }
+ quintptr id() const { return m_id; }
+
+ void activateSignal() const
+ {
+ m_metaObject->activate(m_metaObject->object, int(m_id + m_metaObject->methodOffset()),
+ nullptr);
+ }
+
+private:
+ QQmlVMEMetaObject *m_metaObject = nullptr;
+ QVector<QQmlGuard<QObject>> *m_list = nullptr;
+ quintptr m_id = 0;
+};
+
static void list_append(QQmlListProperty<QObject> *prop, QObject *o)
{
- QList<QObject *> *list = static_cast<QList<QObject *> *>(prop->data);
- list->append(o);
- static_cast<QQmlVMEMetaObject *>(prop->dummy1)->activate(prop->object, reinterpret_cast<quintptr>(prop->dummy2), nullptr);
+ const ResolvedList resolved(prop);
+ resolved.list()->append(o);
+ resolved.activateSignal();
}
static int list_count(QQmlListProperty<QObject> *prop)
{
- QList<QObject *> *list = static_cast<QList<QObject *> *>(prop->data);
- return list->count();
+ return ResolvedList(prop).list()->count();
}
static QObject *list_at(QQmlListProperty<QObject> *prop, int index)
{
- QList<QObject *> *list = static_cast<QList<QObject *> *>(prop->data);
- return list->at(index);
+ return ResolvedList(prop).list()->at(index);
}
static void list_clear(QQmlListProperty<QObject> *prop)
{
- QList<QObject *> *list = static_cast<QList<QObject *> *>(prop->data);
- list->clear();
- static_cast<QQmlVMEMetaObject *>(prop->dummy1)->activate(prop->object, reinterpret_cast<quintptr>(prop->dummy2), nullptr);
+ const ResolvedList resolved(prop);
+ resolved.list()->clear();
+ 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()
@@ -244,7 +318,7 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a)
const QQmlData *data = QQmlData::get(object);
const int type = data->propertyCache->property(id)->propType();
- if (type != QVariant::Invalid) {
+ if (type != QMetaType::UnknownType) {
if (valueIndex != -1) {
QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
data->context->engine, type);
@@ -488,7 +562,7 @@ QUrl QQmlVMEMetaObject::readPropertyAsUrl(int id) const
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
- if (!v || v->d()->data().type() != QVariant::Url)
+ if (!v || v->d()->data().userType() != QMetaType::QUrl)
return QUrl();
return v->d()->data().value<QUrl>();
}
@@ -502,7 +576,7 @@ QDate QQmlVMEMetaObject::readPropertyAsDate(int id) const
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
- if (!v || v->d()->data().type() != QVariant::Date)
+ if (!v || v->d()->data().userType() != QMetaType::QDate)
return QDate();
return v->d()->data().value<QDate>();
}
@@ -516,7 +590,7 @@ QDateTime QQmlVMEMetaObject::readPropertyAsDateTime(int id)
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
- if (!v || v->d()->data().type() != QVariant::DateTime)
+ if (!v || v->d()->data().userType() != QMetaType::QDateTime)
return QDateTime();
return v->d()->data().value<QDateTime>();
}
@@ -530,7 +604,7 @@ QSizeF QQmlVMEMetaObject::readPropertyAsSizeF(int id) const
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
- if (!v || v->d()->data().type() != QVariant::SizeF)
+ if (!v || v->d()->data().userType() != QMetaType::QSizeF)
return QSizeF();
return v->d()->data().value<QSizeF>();
}
@@ -544,7 +618,7 @@ QPointF QQmlVMEMetaObject::readPropertyAsPointF(int id) const
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
- if (!v || v->d()->data().type() != QVariant::PointF)
+ if (!v || v->d()->data().userType() != QMetaType::QPointF)
return QPointF();
return v->d()->data().value<QPointF>();
}
@@ -563,7 +637,7 @@ QObject* QQmlVMEMetaObject::readPropertyAsQObject(int id) const
return wrapper->object();
}
-QList<QObject *> *QQmlVMEMetaObject::readPropertyAsList(int id) const
+QVector<QQmlGuard<QObject>> *QQmlVMEMetaObject::readPropertyAsList(int id) const
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (!md)
@@ -571,12 +645,12 @@ QList<QObject *> *QQmlVMEMetaObject::readPropertyAsList(int id) const
QV4::Scope scope(engine);
QV4::Scoped<QV4::VariantObject> v(scope, *(md->data() + id));
- if (!v || (int)v->d()->data().userType() != qMetaTypeId<QList<QObject *> >()) {
- QVariant variant(QVariant::fromValue(QList<QObject*>()));
+ if (!v || (int)v->d()->data().userType() != qMetaTypeId<QVector<QQmlGuard<QObject>> >()) {
+ QVariant variant(QVariant::fromValue(QVector<QQmlGuard<QObject>>()));
v = engine->newVariantObject(variant);
md->set(engine, id, v);
}
- return static_cast<QList<QObject *> *>(v->d()->data().data());
+ return static_cast<QVector<QQmlGuard<QObject>> *>(v->d()->data().data());
}
QRectF QQmlVMEMetaObject::readPropertyAsRectF(int id) const
@@ -588,7 +662,7 @@ QRectF QQmlVMEMetaObject::readPropertyAsRectF(int id) const
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::VariantObject *v = sv->as<QV4::VariantObject>();
- if (!v || v->d()->data().type() != QVariant::RectF)
+ if (!v || v->d()->data().userType() != QMetaType::QRectF)
return QRectF();
return v->d()->data().value<QRectF>();
}
@@ -685,13 +759,37 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
break;
case QV4::CompiledData::BuiltinType::InvalidBuiltin:
if (property.isList) {
- QList<QObject *> *list = readPropertyAsList(id);
- QQmlListProperty<QObject> *p = static_cast<QQmlListProperty<QObject> *>(a[0]);
- *p = QQmlListProperty<QObject>(object, list,
- list_append, list_count, list_at,
- list_clear);
- p->dummy1 = this;
- p->dummy2 = reinterpret_cast<void *>(quintptr(methodOffset() + id));
+ // when reading from the list, we need to find the correct MetaObject,
+ // namely this. However, obejct->metaObject might point to any MetaObject
+ // down the inheritance hierarchy, so we need to store how far we have
+ // to go down
+ // To do this, we encode the hierarchy depth together with the id of the
+ // property in a single quintptr, with the first half storing the depth
+ // and the second half storing the property id
+ auto mo = object->metaObject();
+ quintptr inheritanceDepth = 0u;
+ while (mo && mo != this) {
+ mo = mo->superClass();
+ ++inheritanceDepth;
+ }
+ constexpr quintptr usableBits = sizeof(quintptr) * CHAR_BIT;
+ if (Q_UNLIKELY(inheritanceDepth >= (quintptr(1) << quintptr(usableBits / 2u) ) )) {
+ qmlWarning(object) << "Too many objects in inheritance hierarchy for list property";
+ return -1;
+ }
+ if (Q_UNLIKELY(quintptr(id) >= (quintptr(1) << quintptr(usableBits / 2) ) )) {
+ qmlWarning(object) << "Too many properties in object for list property";
+ return -1;
+ }
+ quintptr encodedIndex = (inheritanceDepth << (usableBits/2)) + id;
+
+
+ readPropertyAsList(id); // Initializes if necessary
+ *static_cast<QQmlListProperty<QObject> *>(a[0])
+ = QQmlListProperty<QObject>(
+ object, reinterpret_cast<void *>(quintptr(encodedIndex)),
+ list_append, list_count, list_at,
+ list_clear, list_replace, list_removeLast);
} else {
*reinterpret_cast<QObject **>(a[0]) = readPropertyAsQObject(id);
}
@@ -842,7 +940,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
if (c == QMetaObject::WriteProperty)
- valueType->write(target, coreIndex, nullptr);
+ valueType->write(target, coreIndex, {});
return rv;
} else {
@@ -1140,7 +1238,7 @@ void QQmlVMEMetaObject::ensureQObjectWrapper()
void QQmlVMEMetaObject::mark(QV4::MarkStack *markStack)
{
- if (engine != markStack->engine)
+ if (engine != markStack->engine())
return;
propertyAndMethodStorage.markOnce(markStack);
@@ -1162,6 +1260,8 @@ bool QQmlVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex,
const int aliasId = index - propOffset() - compiledObject->nProperties;
const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[aliasId];
+ while (aliasData->aliasToLocalAlias)
+ aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex];
*target = ctxt->idValues[aliasData->targetObjectId].data();
if (!*target)
return false;
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index 58332ff7a8..e17701a968 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -188,7 +188,7 @@ public:
QDateTime readPropertyAsDateTime(int id);
QRectF readPropertyAsRectF(int id) const;
QObject *readPropertyAsQObject(int id) const;
- QList<QObject *> *readPropertyAsList(int id) const;
+ QVector<QQmlGuard<QObject> > *readPropertyAsList(int id) const;
void writeProperty(int id, int v);
void writeProperty(int id, bool v);
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 021aa369fa..86e6282e53 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -54,6 +54,7 @@
#include <QtCore/qobject.h>
#include <QtQml/qjsvalue.h>
#include <QtQml/qjsengine.h>
+#include <QtQml/qqmlfile.h>
#include <QtNetwork/qnetworkreply.h>
#include <QtCore/qtextcodec.h>
#include <QtCore/qxmlstream.h>
@@ -77,6 +78,8 @@ using namespace QV4;
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(xhrDump, QML_XHR_DUMP);
+DEFINE_BOOL_CONFIG_OPTION(xhrFileWrite, QML_XHR_ALLOW_FILE_WRITE);
+DEFINE_BOOL_CONFIG_OPTION(xhrFileRead, QML_XHR_ALLOW_FILE_READ);
struct QQmlXMLHttpRequestData {
QQmlXMLHttpRequestData();
@@ -1195,6 +1198,37 @@ void QQmlXMLHttpRequest::fillHeadersList()
void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
{
QNetworkRequest request = m_request;
+
+ if (QQmlFile::isLocalFile(url)) {
+ if (m_method == QLatin1String("PUT"))
+ {
+ if (!xhrFileWrite()) {
+ if (qEnvironmentVariableIsSet("QML_XHR_ALLOW_FILE_WRITE")) {
+ qWarning("XMLHttpRequest: Tried to use PUT on a local file despite being disabled.");
+ return;
+ } else {
+ qWarning("XMLHttpRequest: Using PUT on a local file is dangerous "
+ "and will be disabled by default in a future Qt version."
+ "Set QML_XHR_ALLOW_FILE_WRITE to 1 if you wish to continue using this feature.");
+ }
+ }
+ } else if (m_method == QLatin1String("GET")) {
+ if (!xhrFileRead()) {
+ if (qEnvironmentVariableIsSet("QML_XHR_ALLOW_FILE_READ")) {
+ qWarning("XMLHttpRequest: Tried to use GET on a local file despite being disabled.");
+ return;
+ } else {
+ qWarning("XMLHttpRequest: Using GET on a local file is dangerous "
+ "and will be disabled by default in a future Qt version."
+ "Set QML_XHR_ALLOW_FILE_READ to 1 if you wish to continue using this feature.");
+ }
+ }
+ } else {
+ qWarning("XMLHttpRequest: Unsupported method used on a local file");
+ return;
+ }
+ }
+
request.setUrl(url);
if(m_method == QLatin1String("POST") ||
m_method == QLatin1String("PUT")) {
@@ -1266,7 +1300,7 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
} else {
QObject::connect(m_network, SIGNAL(readyRead()),
this, SLOT(readyRead()));
- QObject::connect(m_network, SIGNAL(error(QNetworkReply::NetworkError)),
+ QObject::connect(m_network, SIGNAL(errorOccurred(QNetworkReply::NetworkError)),
this, SLOT(error(QNetworkReply::NetworkError)));
QObject::connect(m_network, SIGNAL(finished()),
this, SLOT(finished()));
@@ -1389,13 +1423,17 @@ void QQmlXMLHttpRequest::finished()
QVariant redirect = m_network->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirect.isValid()) {
QUrl url = m_network->url().resolved(redirect.toUrl());
- if (url.scheme() != QLatin1String("file")) {
+ if (!QQmlFile::isLocalFile(url)) {
// See http://www.ietf.org/rfc/rfc2616.txt, section 10.3.4 "303 See Other":
// Result of 303 redirection should be a new "GET" request.
const QVariant code = m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (code.isValid() && code.toInt() == 303 && m_method != QLatin1String("GET"))
m_method = QStringLiteral("GET");
destroyNetwork();
+
+ // Discard redirect response body
+ m_responseEntityBody = QByteArray();
+
requestFromUrl(url);
return;
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index f5e723419e..02628a9810 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -346,22 +346,22 @@ ReturnedValue QtObject::method_colorEqual(const FunctionObject *b, const Value *
bool ok = false;
QVariant lhs = scope.engine->toVariant(argv[0], -1);
- if (lhs.userType() == QVariant::String) {
+ if (lhs.userType() == QMetaType::QString) {
lhs = QQmlStringConverters::colorFromString(lhs.toString(), &ok);
if (!ok) {
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name");
}
- } else if (lhs.userType() != QVariant::Color) {
+ } else if (lhs.userType() != QMetaType::QColor) {
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
}
QVariant rhs = scope.engine->toVariant(argv[1], -1);
- if (rhs.userType() == QVariant::String) {
+ if (rhs.userType() == QMetaType::QString) {
rhs = QQmlStringConverters::colorFromString(rhs.toString(), &ok);
if (!ok) {
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name");
}
- } else if (rhs.userType() != QVariant::Color) {
+ } else if (rhs.userType() != QMetaType::QColor) {
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
}
@@ -612,13 +612,13 @@ ReturnedValue QtObject::method_lighter(const FunctionObject *b, const Value *, c
THROW_GENERIC_ERROR("Qt.lighter(): Invalid arguments");
QVariant v = scope.engine->toVariant(argv[0], -1);
- if (v.userType() == QVariant::String) {
+ if (v.userType() == QMetaType::QString) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
return QV4::Encode::null();
}
- } else if (v.userType() != QVariant::Color) {
+ } else if (v.userType() != QMetaType::QColor) {
return QV4::Encode::null();
}
@@ -652,13 +652,13 @@ ReturnedValue QtObject::method_darker(const FunctionObject *b, const Value *, co
THROW_GENERIC_ERROR("Qt.darker(): Invalid arguments");
QVariant v = scope.engine->toVariant(argv[0], -1);
- if (v.userType() == QVariant::String) {
+ if (v.userType() == QMetaType::QString) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
return QV4::Encode::null();
}
- } else if (v.userType() != QVariant::Color) {
+ } else if (v.userType() != QMetaType::QColor) {
return QV4::Encode::null();
}
@@ -703,143 +703,187 @@ ReturnedValue QtObject::method_tint(const FunctionObject *b, const Value *, cons
// base color
QVariant v1 = scope.engine->toVariant(argv[0], -1);
- if (v1.userType() == QVariant::String) {
+ if (v1.userType() == QMetaType::QString) {
bool ok = false;
v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok);
if (!ok) {
return QV4::Encode::null();
}
- } else if (v1.userType() != QVariant::Color) {
+ } else if (v1.userType() != QMetaType::QColor) {
return QV4::Encode::null();
}
// tint color
QVariant v2 = scope.engine->toVariant(argv[1], -1);
- if (v2.userType() == QVariant::String) {
+ if (v2.userType() == QMetaType::QString) {
bool ok = false;
v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok);
if (!ok) {
return QV4::Encode::null();
}
- } else if (v2.userType() != QVariant::Color) {
+ } else if (v2.userType() != QMetaType::QColor) {
return QV4::Encode::null();
}
return scope.engine->fromVariant(QQml_colorProvider()->tint(v1, v2));
}
+namespace {
+template <typename T>
+QString formatDateTimeObjectUsingDateFormat(T formatThis, Qt::DateFormat format) {
+ switch (format) {
+ case Qt::TextDate:
+ case Qt::ISODate:
+ case Qt::RFC2822Date:
+ case Qt::ISODateWithMs:
+ return formatThis.toString(format);
+ // ### Qt 6: Remove all locale dependent cases
+ QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ case Qt::SystemLocaleDate:
+ // case Qt::LocalDate: covered by SystemLocaleDate
+ return QLocale::system().toString(formatThis);
+ case Qt::LocaleDate:
+ case Qt::DefaultLocaleShortDate:
+ return QLocale().toString(formatThis, QLocale::ShortFormat);
+ case Qt::SystemLocaleShortDate:
+ return QLocale::system().toString(formatThis, QLocale::ShortFormat);
+ case Qt::SystemLocaleLongDate:
+ return QLocale::system().toString(formatThis, QLocale::LongFormat);
+ case Qt::DefaultLocaleLongDate:
+ return QLocale().toString(formatThis, QLocale::LongFormat);
+ }
+ QT_WARNING_POP
+ Q_UNREACHABLE();
+ return QString();
+}
+
+template <typename T>
+ReturnedValue formatDateTimeObject(const T &formatThis, const QV4::Scope &scope, const QString &functionName, int argc, const Value *argv) {
+
+ QString formatted;
+ if (argc >= 2) {
+ QV4::ScopedString s(scope, argv[1]);
+ if (s) {
+ if (argc == 3)
+ scope.engine->throwError(QLatin1String("%1(): Stay argument, third argument can only be used if second argument is a locale").arg(functionName));
+ QString format = s->toQString();
+ formatted = formatThis.toString(format);
+ } else if (argv[1].isNumber()) {
+ if (argc == 3)
+ scope.engine->throwError(QLatin1String("%1(): Stay argument, third argument can only be used if second argument is a locale").arg(functionName));
+ quint32 intFormat = argv[1].asDouble();
+ Qt::DateFormat format = Qt::DateFormat(intFormat);
+ formatted = formatDateTimeObjectUsingDateFormat(formatThis, format);
+ } else {
+ QLocale::FormatType formatOptions = QLocale::ShortFormat;
+ if (argc == 3) {
+ if (argv[2].isNumber())
+ formatOptions = QLocale::FormatType(quint32(argv[2].asDouble()));
+ else
+ scope.engine->throwError(QLatin1String("%1(): Third argument must be a Locale format option").arg(functionName));
+ }
+ auto enginePriv = QQmlEnginePrivate::get(scope.engine->qmlEngine());
+ auto localeMetaTypeId = qMetaTypeId<QLocale>();
+ QVariant locale = enginePriv->v4engine()->toVariant(argv[1], localeMetaTypeId);
+ if (!locale.canConvert(localeMetaTypeId))
+ scope.engine->throwError(QLatin1String("%1(): Bad second argument (must be either string, number or locale)").arg(functionName));
+ formatted = locale.value<QLocale>().toString(formatThis, formatOptions);
+ }
+ } else {
+ formatted = QLocale().toString(formatThis, QLocale::ShortFormat);
+ }
+
+ return Encode(scope.engine->newString(formatted));
+}
+
+}
+
/*!
-\qmlmethod string Qt::formatDate(datetime date, variant format)
+\qmlmethod string Qt::formatDate(datetime date, variant format, variant localeFormatOption)
-Returns a string representation of \a date, optionally formatted according
-to \a format.
+Returns a string representation of \a date, optionally formatted using \a format.
The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
-property, a QDate, or QDateTime value. The \a format parameter may be any of
-the possible format values as described for
+property, a QDate, or QDateTime value. The \a format and \a localeFormatOption
+parameter may be any of the possible format values as described for
\l{QtQml::Qt::formatDateTime()}{Qt.formatDateTime()}.
If \a format is not specified, \a date is formatted using
-\l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
+\l {QLocale::FormatType}{Locale.ShortFormat} using the
+default locale.
\sa Locale
*/
ReturnedValue QtObject::method_formatDate(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (argc < 1 || argc > 2)
- THROW_GENERIC_ERROR("Qt.formatDate(): Invalid arguments");
+ if (argc < 1)
+ THROW_GENERIC_ERROR("Qt.formatDate(): Missing argument");
+ if (argc > 3)
+ THROW_GENERIC_ERROR("Qt.formatDate(): Stray arguments; formatDate takes at most 3 arguments.");
- Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
QDate date = scope.engine->toVariant(argv[0], -1).toDateTime().date();
- QString formattedDate;
- if (argc == 2) {
- QV4::ScopedString s(scope, argv[1]);
- if (s) {
- QString format = s->toQString();
- formattedDate = date.toString(format);
- } else if (argv[1].isNumber()) {
- quint32 intFormat = argv[1].asDouble();
- Qt::DateFormat format = Qt::DateFormat(intFormat);
- formattedDate = date.toString(format);
- } else {
- THROW_GENERIC_ERROR("Qt.formatDate(): Invalid date format");
- }
- } else {
- formattedDate = date.toString(enumFormat);
- }
-
- return Encode(scope.engine->newString(formattedDate));
+ return formatDateTimeObject(date, scope, QLatin1String("Qt.formatDate"), argc, argv);
}
/*!
-\qmlmethod string Qt::formatTime(datetime time, variant format)
+\qmlmethod string Qt::formatTime(datetime time, variant format, variant localeFormatOption)
-Returns a string representation of \a time, optionally formatted according to
-\a format.
+Returns a string representation of \a time, optionally formatted using
+\a format, and, if provided, \a localeFormatOption.
The \a time parameter may be a JavaScript \c Date object, a QTime, or QDateTime
-value. The \a format parameter may be any of the possible format values as
-described for \l{QtQml::Qt::formatDateTime()}{Qt.formatDateTime()}.
+value. The \a format and \a localeFormatOption parameter may be any of the
+possible format values as described for
+\l{QtQml::Qt::formatDateTime()}{Qt.formatDateTime()}.
If \a format is not specified, \a time is formatted using
-\l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
+\l {QLocale::FormatType}{Locale.ShortFormat} using the default locale.
\sa Locale
*/
ReturnedValue QtObject::method_formatTime(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (argc < 1 || argc > 2)
- THROW_GENERIC_ERROR("Qt.formatTime(): Invalid arguments");
+ if (argc < 1)
+ THROW_GENERIC_ERROR("Qt.formatTime(): Missing argument");
+ if (argc > 3)
+ THROW_GENERIC_ERROR("Qt.formatTime(): Stray arguments; formatTime takes at most 3 arguments.");
QVariant argVariant = scope.engine->toVariant(argv[0], -1);
QTime time;
- if (argv[0].as<DateObject>() || (argVariant.type() == QVariant::String))
+ if (argv[0].as<DateObject>() || (argVariant.userType() == QMetaType::QString))
time = argVariant.toDateTime().time();
else // if (argVariant.type() == QVariant::Time), or invalid.
time = argVariant.toTime();
-
- Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QString formattedTime;
- if (argc == 2) {
- QV4::ScopedString s(scope, argv[1]);
- if (s) {
- QString format = s->toQString();
- formattedTime = time.toString(format);
- } else if (argv[1].isNumber()) {
- quint32 intFormat = argv[1].asDouble();
- Qt::DateFormat format = Qt::DateFormat(intFormat);
- formattedTime = time.toString(format);
- } else {
- THROW_GENERIC_ERROR("Qt.formatTime(): Invalid time format");
- }
- } else {
- formattedTime = time.toString(enumFormat);
- }
-
- return Encode(scope.engine->newString(formattedTime));
+ return formatDateTimeObject(time, scope, QLatin1String("Qt.formatTime"), argc, argv);
}
/*!
-\qmlmethod string Qt::formatDateTime(datetime dateTime, variant format)
+\qmlmethod string Qt::formatDateTime(datetime dateTime, variant format, variant localeFormatOption)
-Returns a string representation of \a dateTime, optionally formatted according to
-\a format.
+Returns a string representation of \a dateTime, optionally formatted using
+\a format and \a localeFormatOption.
The \a dateTime parameter may be a JavaScript \c Date object, a \l{date}{date}
property, a QDate, QTime, or QDateTime value.
If \a format is not provided, \a dateTime is formatted using
-\l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. Otherwise,
-\a format should be either:
+\l {QLocale::FormatType}{Locale.ShortFormat} using the
+default locale. Otherwise, \a format should be either:
\list
\li One of the Qt::DateFormat enumeration values, such as
- \c Qt.DefaultLocaleShortDate or \c Qt.ISODate
+ \c Qt.RFC2822Date or \c Qt.ISODate.
\li A string that specifies the format of the returned string, as detailed below.
+\li A \c locale object.
\endlist
+If \a format specifies a locale object, \dateTime is formatted
+with \l{QLocale::toString}. In this case, \a localeFormatOption can hold a value
+of type \l {QLocale::FormatType} to further tune the formatting. If none is
+provided, \l {QLocale::FormatType}{Locale.ShortFormat} is used.
+
If \a format specifies a format string, it should use the following expressions
to specify the date:
@@ -916,29 +960,13 @@ with the \a format values below to produce the following results:
ReturnedValue QtObject::method_formatDateTime(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (argc < 1 || argc > 2)
- THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid arguments");
+ if (argc < 1)
+ THROW_GENERIC_ERROR("Qt.formatDateTime(): Missing argument");
+ if (argc > 3)
+ THROW_GENERIC_ERROR("Qt.formatDateTime(): Stray arguments; formatDate takes at most 3 arguments.");
- Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
QDateTime dt = scope.engine->toVariant(argv[0], -1).toDateTime();
- QString formattedDt;
- if (argc == 2) {
- QV4::ScopedString s(scope, argv[1]);
- if (s) {
- QString format = s->toQString();
- formattedDt = dt.toString(format);
- } else if (argv[1].isNumber()) {
- quint32 intFormat = argv[1].asDouble();
- Qt::DateFormat format = Qt::DateFormat(intFormat);
- formattedDt = dt.toString(format);
- } else {
- THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid datetime format");
- }
- } else {
- formattedDt = dt.toString(enumFormat);
- }
-
- return Encode(scope.engine->newString(formattedDt));
+ return formatDateTimeObject(dt, scope, QLatin1String("Qt.formatDateTime"), argc, argv);
}
/*!
@@ -1338,6 +1366,41 @@ ReturnedValue QtObject::method_createComponent(const FunctionObject *b, const Va
return QV4::QObjectWrapper::wrap(scope.engine, c);
}
+ReturnedValue QtObject::method_get_uiLanguage(const FunctionObject *b, const Value * /*thisObject*/, const Value * /*argv*/, int /*argc*/)
+{
+ QV4::Scope scope(b);
+ QJSEngine *jsEngine = scope.engine->jsEngine();
+ if (!jsEngine)
+ return Encode::null();
+
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(scope.engine);
+ if (ep && ep->propertyCapture) {
+ static int propertyIndex = -1;
+ static int notifySignalIndex = -1;
+ if (propertyIndex < 0) {
+ QMetaProperty metaProperty =
+ QQmlEngine::staticMetaObject.property(QQmlEngine::staticMetaObject.indexOfProperty("uiLanguage"));
+ propertyIndex = metaProperty.propertyIndex();
+ notifySignalIndex = metaProperty.notifySignalIndex();
+ }
+ ep->propertyCapture->captureProperty(QQmlEnginePrivate::get(ep), propertyIndex, notifySignalIndex);
+ }
+
+ return Encode(scope.engine->newString(QJSEnginePrivate::get(jsEngine)->uiLanguage));
+}
+
+ReturnedValue QtObject::method_set_uiLanguage(const FunctionObject *b, const Value * /*thisObject*/, const Value *argv, int argc)
+{
+ Scope scope(b);
+ if (!argc)
+ THROW_TYPE_ERROR();
+ QJSEngine *jsEngine = scope.engine->jsEngine();
+ if (!jsEngine)
+ THROW_TYPE_ERROR();
+ jsEngine->setUiLanguage(argv[0].toQString());
+ return Encode::undefined();
+}
+
#if QT_CONFIG(qml_locale)
/*!
\qmlmethod Qt::locale(name)
@@ -1835,6 +1898,14 @@ void QV4::GlobalExtensions::init(Object *globalObject, QJSEngine::Extensions ext
globalObject->defineDefaultProperty(QStringLiteral("qsTrId"), QV4::GlobalExtensions::method_qsTrId);
globalObject->defineDefaultProperty(QStringLiteral("QT_TRID_NOOP"), QV4::GlobalExtensions::method_qsTrIdNoOp);
+ ScopedString qtName(scope, v4->newString(QStringLiteral("Qt")));
+ ScopedObject qt(scope, globalObject->get(qtName));
+ if (!qt) {
+ qt = v4->newObject();
+ globalObject->defineDefaultProperty(qtName, qt);
+ }
+ qt->defineAccessorProperty(QStringLiteral("uiLanguage"), QV4::QtObject::method_get_uiLanguage, QV4::QtObject::method_set_uiLanguage);
+
// string prototype extension
scope.engine->stringPrototype()->defineDefaultProperty(QStringLiteral("arg"), QV4::GlobalExtensions::method_string_arg);
#endif
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index d87b83ba10..5cbb52471d 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -126,6 +126,8 @@ struct QtObject : Object
static ReturnedValue method_resolvedUrl(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_createQmlObject(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_createComponent(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_uiLanguage(const FunctionObject *b, const Value *, const Value *, int);
+ static ReturnedValue method_set_uiLanguage(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
#if QT_CONFIG(qml_locale)
static ReturnedValue method_locale(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
#endif
diff --git a/src/qml/qmldirparser/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp
index 047323a3d4..152e840318 100644
--- a/src/qml/qmldirparser/qqmldirparser.cpp
+++ b/src/qml/qmldirparser/qqmldirparser.cpp
@@ -205,7 +205,7 @@ bool QQmlDirParser::parse(const QString &source)
}
Component entry(sections[1], sections[2], -1, -1);
entry.internal = true;
- _components.insertMulti(entry.typeName, entry);
+ _components.insert(entry.typeName, entry);
} else if (sections[0] == QLatin1String("singleton")) {
if (sectionCount < 3 || sectionCount > 4) {
reportError(lineNumber, 0,
@@ -216,7 +216,7 @@ bool QQmlDirParser::parse(const QString &source)
// singleton TestSingletonType TestSingletonType.qml
Component entry(sections[1], sections[2], -1, -1);
entry.singleton = true;
- _components.insertMulti(entry.typeName, entry);
+ _components.insert(entry.typeName, entry);
} else {
// handle qmldir module listing case where singleton is defined in the following pattern:
// singleton TestSingletonType 2.0 TestSingletonType20.qml
@@ -225,7 +225,7 @@ bool QQmlDirParser::parse(const QString &source)
const QString &fileName = sections[3];
Component entry(sections[1], fileName, major, minor);
entry.singleton = true;
- _components.insertMulti(entry.typeName, entry);
+ _components.insert(entry.typeName, entry);
} else {
reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").arg(sections[2]));
}
@@ -271,7 +271,7 @@ bool QQmlDirParser::parse(const QString &source)
} else if (sectionCount == 2) {
// No version specified (should only be used for relative qmldir files)
const Component entry(sections[0], sections[1], -1, -1);
- _components.insertMulti(entry.typeName, entry);
+ _components.insert(entry.typeName, entry);
} else if (sectionCount == 3) {
int major, minor;
if (parseVersion(sections[1], &major, &minor)) {
@@ -283,7 +283,7 @@ bool QQmlDirParser::parse(const QString &source)
_scripts.append(entry);
} else {
const Component entry(sections[0], fileName, major, minor);
- _components.insertMulti(entry.typeName, entry);
+ _components.insert(entry.typeName, entry);
}
} else {
reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").arg(sections[1]));
@@ -302,8 +302,8 @@ bool QQmlDirParser::parse(const QString &source)
void QQmlDirParser::reportError(quint16 line, quint16 column, const QString &description)
{
QQmlJS::DiagnosticMessage error;
- error.line = line;
- error.column = column;
+ error.loc.startLine = line;
+ error.loc.startColumn = column;
error.message = description;
_errors.append(error);
}
@@ -319,7 +319,7 @@ bool QQmlDirParser::hasError() const
void QQmlDirParser::setError(const QQmlJS::DiagnosticMessage &e)
{
_errors.clear();
- reportError(e.line, e.column, e.message);
+ reportError(e.loc.startLine, e.loc.startColumn, e.message);
}
QList<QQmlJS::DiagnosticMessage> QQmlDirParser::errors(const QString &uri) const
@@ -350,7 +350,7 @@ QList<QQmlDirParser::Plugin> QQmlDirParser::plugins() const
return _plugins;
}
-QHash<QString, QQmlDirParser::Component> QQmlDirParser::components() const
+QMultiHash<QString, QQmlDirParser::Component> QQmlDirParser::components() const
{
return _components;
}
diff --git a/src/qml/qmldirparser/qqmldirparser_p.h b/src/qml/qmldirparser/qqmldirparser_p.h
index 9fdeadfb0e..3696a1aa12 100644
--- a/src/qml/qmldirparser/qqmldirparser_p.h
+++ b/src/qml/qmldirparser/qqmldirparser_p.h
@@ -85,7 +85,7 @@ public:
struct Plugin
{
- Plugin() {}
+ Plugin() = default;
Plugin(const QString &name, const QString &path)
: name(name), path(path)
@@ -99,7 +99,7 @@ public:
struct Component
{
- Component() {}
+ Component() = default;
Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
: typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
@@ -118,7 +118,7 @@ public:
struct Script
{
- Script() {}
+ Script() = default;
Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion)
: nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion)
@@ -132,7 +132,7 @@ public:
int minorVersion = 0;
};
- QHash<QString,Component> components() const;
+ QMultiHash<QString,Component> components() const;
QHash<QString,Component> dependencies() const;
QStringList imports() const;
QList<Script> scripts() const;
@@ -141,7 +141,7 @@ public:
struct TypeInfo
{
- TypeInfo() {}
+ TypeInfo() = default;
TypeInfo(const QString &fileName)
: fileName(fileName) {}
@@ -159,7 +159,7 @@ private:
private:
QList<QQmlJS::DiagnosticMessage> _errors;
QString _typeNamespace;
- QHash<QString,Component> _components; // multi hash
+ QMultiHash<QString,Component> _components;
QHash<QString,Component> _dependencies;
QStringList _imports;
QList<Script> _scripts;
@@ -169,9 +169,9 @@ private:
QString _className;
};
-typedef QHash<QString,QQmlDirParser::Component> QQmlDirComponents;
-typedef QList<QQmlDirParser::Script> QQmlDirScripts;
-typedef QList<QQmlDirParser::Plugin> QQmlDirPlugins;
+using QQmlDirComponents = QMultiHash<QString,QQmlDirParser::Component>;
+using QQmlDirScripts = QList<QQmlDirParser::Script>;
+using QQmlDirPlugins = QList<QQmlDirParser::Plugin>;
QDebug &operator<< (QDebug &, const QQmlDirParser::Component &);
QDebug &operator<< (QDebug &, const QQmlDirParser::Script &);
diff --git a/src/qml/qtqml.tracepoints b/src/qml/qtqml.tracepoints
index 841748f201..1043d3bae3 100644
--- a/src/qml/qtqml.tracepoints
+++ b/src/qml/qtqml.tracepoints
@@ -6,9 +6,16 @@ class CompilationUnit;
class Object;
} // CompiledData
} // QV4
+class QQmlEngine;
}
QQmlObjectCreator_createInstance_entry(const QV4::CompiledData::CompilationUnit *compilationUnit, const QV4::CompiledData::Object *object, const QUrl &url)
QQmlObjectCreator_createInstance_exit(const QString &typeName)
+QQmlCompiling_entry(const QUrl &url)
+QQmlCompiling_exit()
QQmlV4_function_call_entry(const QV4::ExecutionEngine *engine, const QString &function, const QString &fileName, int line, int column)
QQmlV4_function_call_exit()
+QQmlBinding_entry(const QQmlEngine *engine, const QString &function, const QString &fileName, int line, int column)
+QQmlBinding_exit()
+QQmlHandlingSignal_entry(const QQmlEngine *engine, const QString &function, const QString &fileName, int line, int column)
+QQmlHandlingSignal_exit()
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/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index 02c3b71806..6d6553259e 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -486,7 +486,7 @@ void QQmlBind::eval()
qmlWarning(this)
<< "Not restoring previous value because restoreMode has not been set.\n"
<< "This behavior is deprecated.\n"
- << "You have to import QtQml 2.14 after any QtQuick imports and set\n"
+ << "You have to import QtQml 2.15 after any QtQuick imports and set\n"
<< "the restoreMode of the binding to fix this warning.\n"
<< "In Qt < 6.0 the default is Binding.RestoreBinding.\n"
<< "In Qt >= 6.0 the default is Binding.RestoreBindingOrValue.";
@@ -499,7 +499,7 @@ void QQmlBind::eval()
qmlWarning(this)
<< "Not restoring previous value because restoreMode has not been set.\n"
<< "This behavior is deprecated.\n"
- << "You have to import QtQml 2.14 after any QtQuick imports and set\n"
+ << "You have to import QtQml 2.15 after any QtQuick imports and set\n"
<< "the restoreMode of the binding to fix this warning.\n"
<< "In Qt < 6.0 the default is Binding.RestoreBinding.\n"
<< "In Qt >= 6.0 the default is Binding.RestoreBindingOrValue.\n";
diff --git a/src/qml/types/qqmlbind_p.h b/src/qml/types/qqmlbind_p.h
index 7bf4fc4dfd..c709224c23 100644
--- a/src/qml/types/qqmlbind_p.h
+++ b/src/qml/types/qqmlbind_p.h
@@ -81,6 +81,7 @@ private:
Q_PROPERTY(RestorationMode restoreMode READ restoreMode WRITE setRestoreMode
NOTIFY restoreModeChanged REVISION 14)
Q_ENUM(RestorationMode)
+ QML_NAMED_ELEMENT(Binding)
public:
QQmlBind(QObject *parent=nullptr);
diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h
index 5d28e8e8be..7bf688cf75 100644
--- a/src/qml/types/qqmlconnections_p.h
+++ b/src/qml/types/qqmlconnections_p.h
@@ -71,6 +71,7 @@ class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatu
Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged REVISION 3)
Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals)
+ QML_NAMED_ELEMENT(Connections)
public:
QQmlConnections(QObject *parent=nullptr);
@@ -106,6 +107,13 @@ public:
void applyBindings(QObject *object, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
};
+// TODO: We won't need Connections to be a custom type anymore once we can drop the
+// automatic signal handler inference from undeclared properties.
+template<>
+inline QQmlCustomParser *qmlCreateCustomParser<QQmlConnections>()
+{
+ return new QQmlConnectionsParser;
+}
QT_END_NAMESPACE
diff --git a/src/qml/types/qqmltimer.cpp b/src/qml/types/qqmltimer.cpp
index af2ff56f2a..bf2c414cb4 100644
--- a/src/qml/types/qqmltimer.cpp
+++ b/src/qml/types/qqmltimer.cpp
@@ -313,8 +313,6 @@ void QQmlTimer::componentComplete()
\qmlsignal QtQml::Timer::triggered()
This signal is emitted when the Timer times out.
-
- The corresponding handler is \c onTriggered.
*/
void QQmlTimer::ticked()
{
diff --git a/src/qml/types/qqmltimer_p.h b/src/qml/types/qqmltimer_p.h
index 0160e97a2f..0cd93e4659 100644
--- a/src/qml/types/qqmltimer_p.h
+++ b/src/qml/types/qqmltimer_p.h
@@ -72,6 +72,7 @@ class Q_QML_PRIVATE_EXPORT QQmlTimer : public QObject, public QQmlParserStatus
Q_PROPERTY(bool repeat READ isRepeating WRITE setRepeating NOTIFY repeatChanged)
Q_PROPERTY(bool triggeredOnStart READ triggeredOnStart WRITE setTriggeredOnStart NOTIFY triggeredOnStartChanged)
Q_PROPERTY(QObject *parent READ parent CONSTANT)
+ QML_NAMED_ELEMENT(Timer)
public:
QQmlTimer(QObject *parent=nullptr);
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/qqmldebugconnection.cpp b/src/qmldebug/qqmldebugconnection.cpp
index 4e087ee6db..b32ecc3d06 100644
--- a/src/qmldebug/qqmldebugconnection.cpp
+++ b/src/qmldebug/qqmldebugconnection.cpp
@@ -388,7 +388,7 @@ void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port)
connect(socket, &QAbstractSocket::disconnected, this, &QQmlDebugConnection::socketDisconnected);
connect(socket, &QAbstractSocket::connected, this, &QQmlDebugConnection::socketConnected);
connect(socket, static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(
- &QAbstractSocket::error), this, &QQmlDebugConnection::socketError);
+ &QAbstractSocket::errorOccurred), this, &QQmlDebugConnection::socketError);
connect(socket, &QAbstractSocket::stateChanged, this, &QQmlDebugConnection::socketStateChanged);
socket->connectToHost(hostName, port);
}
@@ -415,8 +415,7 @@ public:
{
connect(parent, &QLocalSocket::stateChanged,
this, &LocalSocketSignalTranslator::onStateChanged);
- connect(parent, static_cast<void(QLocalSocket::*)(QLocalSocket::LocalSocketError)>(
- &QLocalSocket::error), this, &LocalSocketSignalTranslator::onError);
+ connect(parent, &QLocalSocket::errorOccurred, this, &LocalSocketSignalTranslator::onError);
}
void onError(QLocalSocket::LocalSocketError error)
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/imports/models/dependencies.json b/src/qmlmodels/dependencies.json
index 0d4f101c7a..0d4f101c7a 100644
--- a/src/imports/models/dependencies.json
+++ b/src/qmlmodels/dependencies.json
diff --git a/src/qmlmodels/qmlmodels.pro b/src/qmlmodels/qmlmodels.pro
index 1d733f5bdb..4ac093556d 100644
--- a/src/qmlmodels/qmlmodels.pro
+++ b/src/qmlmodels/qmlmodels.pro
@@ -28,14 +28,10 @@ qtConfig(qml-object-model) {
qtConfig(qml-table-model) {
SOURCES += \
- $$PWD/qqmltableinstancemodel.cpp \
- $$PWD/qqmltablemodel.cpp \
- $$PWD/qqmltablemodelcolumn.cpp
+ $$PWD/qqmltableinstancemodel.cpp
HEADERS += \
- $$PWD/qqmltableinstancemodel_p.h \
- $$PWD/qqmltablemodel_p.h \
- $$PWD/qqmltablemodelcolumn_p.h
+ $$PWD/qqmltableinstancemodel_p.h
}
qtConfig(qml-list-model) {
@@ -51,21 +47,27 @@ qtConfig(qml-list-model) {
qtConfig(qml-delegate-model) {
SOURCES += \
+ $$PWD/qqmlabstractdelegatecomponent.cpp \
$$PWD/qqmladaptormodel.cpp \
$$PWD/qqmldelegatemodel.cpp \
- $$PWD/qqmldelegatecomponent.cpp \
$$PWD/qqmllistaccessor.cpp \
$$PWD/qqmllistcompositor.cpp \
$$PWD/qquickpackage.cpp
HEADERS += \
+ $$PWD/qqmlabstractdelegatecomponent_p.h \
$$PWD/qqmladaptormodel_p.h \
$$PWD/qqmldelegatemodel_p.h \
$$PWD/qqmldelegatemodel_p_p.h \
- $$PWD/qqmldelegatecomponent_p.h \
$$PWD/qqmllistaccessor_p.h \
$$PWD/qqmllistcompositor_p.h \
$$PWD/qquickpackage_p.h
}
+QMLTYPES_FILENAME = plugins.qmltypes
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/Models.2
+QML_IMPORT_NAME = QtQml.Models
+IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+CONFIG += qmltypes install_qmltypes install_metatypes
+
load(qt_module)
diff --git a/src/qmlmodels/qqmlabstractdelegatecomponent.cpp b/src/qmlmodels/qqmlabstractdelegatecomponent.cpp
new file mode 100644
index 0000000000..1058d87485
--- /dev/null
+++ b/src/qmlmodels/qqmlabstractdelegatecomponent.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 <QtQmlModels/private/qqmlabstractdelegatecomponent_p.h>
+#include <QtQmlModels/private/qqmladaptormodel_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQmlAbstractDelegateComponent::QQmlAbstractDelegateComponent(QObject *parent)
+ : QQmlComponent(parent)
+{
+}
+
+QQmlAbstractDelegateComponent::~QQmlAbstractDelegateComponent()
+{
+}
+
+QVariant QQmlAbstractDelegateComponent::value(QQmlAdaptorModel *adaptorModel, int row, int column, const QString &role) const
+{
+ if (!adaptorModel)
+ return QVariant();
+ return adaptorModel->value(adaptorModel->indexAt(row, column), role);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmlmodels/qqmlabstractdelegatecomponent_p.h b/src/qmlmodels/qqmlabstractdelegatecomponent_p.h
new file mode 100644
index 0000000000..07cae6b092
--- /dev/null
+++ b/src/qmlmodels/qqmlabstractdelegatecomponent_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 QQMLABSTRACTDELEGATECOMPONENT_P_H
+#define QQMLABSTRACTDELEGATECOMPONENT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qtqmlmodelsglobal_p.h>
+#include <private/qqmlcomponentattached_p.h>
+#include <qqmlcomponent.h>
+
+QT_REQUIRE_CONFIG(qml_delegate_model);
+
+QT_BEGIN_NAMESPACE
+
+// TODO: consider making QQmlAbstractDelegateComponent public API
+class QQmlAdaptorModel;
+class Q_QMLMODELS_PRIVATE_EXPORT QQmlAbstractDelegateComponent : public QQmlComponent
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(AbstractDelegateComponent)
+ QML_UNCREATABLE("Cannot create instance of abstract class AbstractDelegateComponent.")
+
+public:
+ QQmlAbstractDelegateComponent(QObject *parent = nullptr);
+ ~QQmlAbstractDelegateComponent() override;
+
+ virtual QQmlComponent *delegate(QQmlAdaptorModel *adaptorModel, int row, int column = 0) const = 0;
+
+signals:
+ void delegateChanged();
+
+protected:
+ QVariant value(QQmlAdaptorModel *adaptorModel,int row, int column, const QString &role) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLABSTRACTDELEGATECOMPONENT_P_H
diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp
index 64d9723a6d..2126ad3dc5 100644
--- a/src/qmlmodels/qqmladaptormodel.cpp
+++ b/src/qmlmodels/qqmladaptormodel.cpp
@@ -93,7 +93,7 @@ class QQmlDMCachedModelData : public QQmlDelegateModelItem
{
public:
QQmlDMCachedModelData(
- QQmlDelegateModelItemMetaType *metaType,
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
VDMModelDelegateDataType *dataType,
int index, int row, int column);
@@ -255,7 +255,9 @@ public:
bool hasModelData;
};
-QQmlDMCachedModelData::QQmlDMCachedModelData(QQmlDelegateModelItemMetaType *metaType, VDMModelDelegateDataType *dataType, int index, int row, int column)
+QQmlDMCachedModelData::QQmlDMCachedModelData(
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
+ VDMModelDelegateDataType *dataType, int index, int row, int column)
: QQmlDelegateModelItem(metaType, dataType, index, row, column)
, type(dataType)
{
@@ -367,10 +369,10 @@ QV4::ReturnedValue QQmlDMCachedModelData::set_property(const QV4::FunctionObject
QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
if (!modelData->cachedData.isEmpty()) {
if (modelData->cachedData.count() > 1) {
- modelData->cachedData[propertyId] = scope.engine->toVariant(argv[0], QVariant::Invalid);
+ modelData->cachedData[propertyId] = scope.engine->toVariant(argv[0], QMetaType::UnknownType);
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), propertyId, nullptr);
} else if (modelData->cachedData.count() == 1) {
- modelData->cachedData[0] = scope.engine->toVariant(argv[0], QVariant::Invalid);
+ modelData->cachedData[0] = scope.engine->toVariant(argv[0], QMetaType::UnknownType);
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 0, nullptr);
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 1, nullptr);
}
@@ -390,7 +392,7 @@ class QQmlDMAbstractItemModelData : public QQmlDMCachedModelData
public:
QQmlDMAbstractItemModelData(
- QQmlDelegateModelItemMetaType *metaType,
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
VDMModelDelegateDataType *dataType,
int index, int row, int column)
: QQmlDMCachedModelData(metaType, dataType, index, row, column)
@@ -463,6 +465,11 @@ public:
QVariant value(const QQmlAdaptorModel &model, int index, const QString &role) const override
{
+ if (!metaObject) {
+ VDMAbstractItemModelDataType *dataType = const_cast<VDMAbstractItemModelDataType *>(this);
+ dataType->initializeMetaType(model);
+ }
+
if (const QAbstractItemModel *aim = model.aim()) {
QHash<QByteArray, int>::const_iterator it = roleNames.find(role.toUtf8());
if (it != roleNames.end()) {
@@ -507,7 +514,7 @@ public:
QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &model,
- QQmlDelegateModelItemMetaType *metaType,
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
int index, int row, int column) const override
{
VDMAbstractItemModelDataType *dataType = const_cast<VDMAbstractItemModelDataType *>(this);
@@ -516,7 +523,7 @@ public:
return new QQmlDMAbstractItemModelData(metaType, dataType, index, row, column);
}
- void initializeMetaType(QQmlAdaptorModel &model)
+ void initializeMetaType(const QQmlAdaptorModel &model)
{
QMetaObjectBuilder builder;
setModelDataType<QQmlDMAbstractItemModelData>(&builder, this);
@@ -555,7 +562,7 @@ class QQmlDMListAccessorData : public QQmlDelegateModelItem
Q_OBJECT
Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
public:
- QQmlDMListAccessorData(QQmlDelegateModelItemMetaType *metaType,
+ QQmlDMListAccessorData(const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
QQmlAdaptorModel::Accessors *accessor,
int index, int row, int column, const QVariant &value)
: QQmlDelegateModelItem(metaType, accessor, index, row, column)
@@ -596,7 +603,7 @@ public:
if (!argc)
return v4->throwTypeError();
- static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(v4->toVariant(argv[0], QVariant::Invalid));
+ static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(v4->toVariant(argv[0], QMetaType::UnknownType));
return QV4::Encode::undefined();
}
@@ -671,7 +678,7 @@ public:
QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &model,
- QQmlDelegateModelItemMetaType *metaType,
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
int index, int row, int column) const override
{
VDMListDelegateDataType *dataType = const_cast<VDMListDelegateDataType *>(this);
@@ -714,7 +721,7 @@ class QQmlDMObjectData : public QQmlDelegateModelItem, public QQmlAdaptorModelPr
Q_INTERFACES(QQmlAdaptorModelProxyInterface)
public:
QQmlDMObjectData(
- QQmlDelegateModelItemMetaType *metaType,
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
VDMObjectDelegateDataType *dataType,
int index, int row, int column,
QObject *object);
@@ -785,7 +792,7 @@ public:
QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &model,
- QQmlDelegateModelItemMetaType *metaType,
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
int index, int row, int column) const override
{
VDMObjectDelegateDataType *dataType = const_cast<VDMObjectDelegateDataType *>(this);
@@ -925,7 +932,7 @@ public:
VDMObjectDelegateDataType *m_type;
};
-QQmlDMObjectData::QQmlDMObjectData(QQmlDelegateModelItemMetaType *metaType,
+QQmlDMObjectData::QQmlDMObjectData(const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
VDMObjectDelegateDataType *dataType,
int index, int row, int column,
QObject *object)
@@ -970,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 a4549127af..ba54c864c6 100644
--- a/src/qmlmodels/qqmladaptormodel_p.h
+++ b/src/qmlmodels/qqmladaptormodel_p.h
@@ -87,7 +87,7 @@ public:
virtual QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &,
- QQmlDelegateModelItemMetaType *,
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &,
int, int, int) const { return nullptr; }
virtual bool notify(
@@ -140,10 +140,16 @@ public:
inline QVariant value(int index, const QString &role) const {
return accessors->value(*this, index, role); }
- inline QQmlDelegateModelItem *createItem(QQmlDelegateModelItemMetaType *metaType, int index) {
- return accessors->createItem(*this, metaType, index, rowAt(index), columnAt(index)); }
+ inline QQmlDelegateModelItem *createItem(
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, int index)
+ {
+ 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 d5b30df45b..cee096035a 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -38,17 +38,16 @@
****************************************************************************/
#include "qqmldelegatemodel_p_p.h"
-#include "qqmldelegatecomponent_p.h"
#include <QtQml/qqmlinfo.h>
+#include <private/qqmlabstractdelegatecomponent_p.h>
#include <private/qquickpackage_p.h>
#include <private/qmetaobjectbuilder_p.h>
#include <private/qqmladaptormodel_p.h>
#include <private/qqmlchangeset_p.h>
#include <private/qqmlengine_p.h>
#include <private/qqmlcomponent_p.h>
-#include <private/qqmlincubator_p.h>
#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
@@ -56,6 +55,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcItemViewDelegateRecycling, "qt.quick.itemview.delegaterecycling")
+
class QQmlDelegateModelItem;
namespace QV4 {
@@ -206,6 +207,9 @@ QQmlDelegateModelPrivate::~QQmlDelegateModelPrivate()
{
qDeleteAll(m_finishedIncubating);
+ // Free up all items in the pool
+ drainReusableItemsPool(0);
+
if (m_cacheMetaType)
m_cacheMetaType->release();
}
@@ -265,13 +269,23 @@ QQmlDelegateModel::~QQmlDelegateModel()
Q_ASSERT(cacheItem->contextData->refCount == 1);
cacheItem->contextData = nullptr;
cacheItem->scriptRef -= 1;
+ } else if (cacheItem->incubationTask) {
+ // Both the incubationTask and the object may hold a scriptRef,
+ // but if both are present, only one scriptRef is held in total.
+ cacheItem->scriptRef -= 1;
}
+
cacheItem->groups &= ~Compositor::UnresolvedFlag;
cacheItem->objectRef = 0;
+
+ if (cacheItem->incubationTask) {
+ d->releaseIncubator(cacheItem->incubationTask);
+ cacheItem->incubationTask->vdm = nullptr;
+ cacheItem->incubationTask = nullptr;
+ }
+
if (!cacheItem->isReferenced())
delete cacheItem;
- else if (cacheItem->incubationTask)
- cacheItem->incubationTask->vdm = nullptr;
}
}
@@ -589,36 +603,47 @@ int QQmlDelegateModel::count() const
return d->m_compositor.count(d->m_compositorGroup);
}
-QQmlDelegateModel::ReleaseFlags QQmlDelegateModelPrivate::release(QObject *object)
+QQmlDelegateModel::ReleaseFlags QQmlDelegateModelPrivate::release(QObject *object, QQmlInstanceModel::ReusableFlag reusableFlag)
{
if (!object)
- return QQmlDelegateModel::ReleaseFlags(0);
+ return QQmlDelegateModel::ReleaseFlags{};
QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(object);
if (!cacheItem)
- return QQmlDelegateModel::ReleaseFlags(0);
+ return QQmlDelegateModel::ReleaseFlags{};
if (!cacheItem->releaseObject())
return QQmlDelegateModel::Referenced;
+ if (reusableFlag == QQmlInstanceModel::Reusable) {
+ removeCacheItem(cacheItem);
+ m_reusableItemsPool.insertItem(cacheItem);
+ emit q_func()->itemPooled(cacheItem->index, cacheItem->object);
+ return QQmlInstanceModel::Pooled;
+ }
+
+ destroyCacheItem(cacheItem);
+ return QQmlInstanceModel::Destroyed;
+}
+
+void QQmlDelegateModelPrivate::destroyCacheItem(QQmlDelegateModelItem *cacheItem)
+{
+ emitDestroyingItem(cacheItem->object);
cacheItem->destroyObject();
- emitDestroyingItem(object);
if (cacheItem->incubationTask) {
releaseIncubator(cacheItem->incubationTask);
cacheItem->incubationTask = nullptr;
}
cacheItem->Dispose();
- return QQmlInstanceModel::Destroyed;
}
/*
Returns ReleaseStatus flags.
*/
-
-QQmlDelegateModel::ReleaseFlags QQmlDelegateModel::release(QObject *item)
+QQmlDelegateModel::ReleaseFlags QQmlDelegateModel::release(QObject *item, QQmlInstanceModel::ReusableFlag reusableFlag)
{
Q_D(QQmlDelegateModel);
- QQmlInstanceModel::ReleaseFlags stat = d->release(item);
+ QQmlInstanceModel::ReleaseFlags stat = d->release(item, reusableFlag);
return stat;
}
@@ -626,7 +651,7 @@ QQmlDelegateModel::ReleaseFlags QQmlDelegateModel::release(QObject *item)
void QQmlDelegateModel::cancel(int index)
{
Q_D(QQmlDelegateModel);
- if (!d->m_delegate || index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) {
+ if (index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) {
qWarning() << "DelegateModel::cancel: index out range" << index << d->m_compositor.count(d->m_compositorGroup);
return;
}
@@ -716,7 +741,7 @@ QQmlListProperty<QQmlDelegateModelGroup> QQmlDelegateModel::groups()
QQmlDelegateModelPrivate::group_append,
QQmlDelegateModelPrivate::group_count,
QQmlDelegateModelPrivate::group_at,
- nullptr);
+ nullptr, nullptr, nullptr);
}
/*!
@@ -892,6 +917,125 @@ static bool isDoneIncubating(QQmlIncubator::Status status)
return status == QQmlIncubator::Ready || status == QQmlIncubator::Error;
}
+PropertyUpdater::PropertyUpdater(QObject *parent) :
+ QObject(parent) {}
+
+void PropertyUpdater::doUpdate()
+{
+ auto sender = QObject::sender();
+ auto mo = sender->metaObject();
+ auto signalIndex = QObject::senderSignalIndex();
+ ++updateCount;
+ auto property = mo->property(changeSignalIndexToPropertyIndex[signalIndex]);
+ // we synchronize between required properties and model rolenames by name
+ // that's why the QQmlProperty and the metaobject property must have the same name
+ QQmlProperty qmlProp(parent(), QString::fromLatin1(property.name()));
+ qmlProp.write(property.read(QObject::sender()));
+}
+
+void PropertyUpdater::breakBinding()
+{
+ auto it = senderToConnection.find(QObject::senderSignalIndex());
+ if (it == senderToConnection.end())
+ return;
+ if (updateCount == 0) {
+ QObject::disconnect(*it);
+ senderToConnection.erase(it);
+ QQmlError warning;
+ if (auto context = qmlContext(QObject::sender()))
+ warning.setUrl(context->baseUrl());
+ else
+ return;
+ auto signalName = QString::fromLatin1(QObject::sender()->metaObject()->method(QObject::senderSignalIndex()).name());
+ signalName.chop(sizeof("changed")-1);
+ QString propName = signalName;
+ propName[0] = propName[0].toLower();
+ warning.setDescription(QString::fromUtf8("Writing to \"%1\" broke the binding to the underlying model").arg(propName));
+ qmlWarning(this, warning);
+ } else {
+ --updateCount;
+ }
+}
+
+void QQDMIncubationTask::initializeRequiredProperties(QQmlDelegateModelItem *modelItemToIncubate, QObject *object)
+{
+ auto incubatorPriv = QQmlIncubatorPrivate::get(this);
+ if (incubatorPriv->hadRequiredProperties()) {
+ QQmlData *d = QQmlData::get(object);
+ auto contextData = d ? d->context : nullptr;
+ if (contextData) {
+ contextData->hasExtraObject = true;
+ contextData->extraObject = modelItemToIncubate;
+ }
+
+ if (incubatorPriv->requiredProperties().empty())
+ return;
+ RequiredProperties &requiredProperties = incubatorPriv->requiredProperties();
+
+ auto qmlMetaObject = modelItemToIncubate->metaObject();
+ // if a required property was not in the model, it might still be a static property of the
+ // QQmlDelegateModelItem or one of its derived classes this is the case for index, row,
+ // column, model and more
+ // the most derived subclass of QQmlDelegateModelItem is QQmlDMAbstractModelData at depth 2,
+ // so 4 should be plenty
+ QVarLengthArray<QPair<const QMetaObject *, QObject *>, 4> mos;
+ // we first check the dynamic meta object for properties originating from the model
+ // contains abstractitemmodelproperties
+ mos.push_back(qMakePair(qmlMetaObject, modelItemToIncubate));
+ auto delegateModelItemSubclassMO = qmlMetaObject->superClass();
+ mos.push_back(qMakePair(delegateModelItemSubclassMO, modelItemToIncubate));
+
+ while (strcmp(delegateModelItemSubclassMO->className(),
+ modelItemToIncubate->staticMetaObject.className())) {
+ delegateModelItemSubclassMO = delegateModelItemSubclassMO->superClass();
+ mos.push_back(qMakePair(delegateModelItemSubclassMO, modelItemToIncubate));
+ }
+ if (proxiedObject)
+ mos.push_back(qMakePair(proxiedObject->metaObject(), proxiedObject));
+
+ auto updater = new PropertyUpdater(object);
+ for (const auto &metaObjectAndObject : mos) {
+ const QMetaObject *mo = metaObjectAndObject.first;
+ QObject *itemOrProxy = metaObjectAndObject.second;
+ for (int i = mo->propertyOffset(); i < mo->propertyCount() + mo->propertyOffset(); ++i) {
+ auto prop = mo->property(i);
+ if (!prop.name())
+ continue;
+ auto propName = QString::fromUtf8(prop.name());
+ bool wasInRequired = false;
+ QQmlProperty componentProp = QQmlComponentPrivate::removePropertyFromRequired(
+ object, propName, requiredProperties, &wasInRequired);
+ // only write to property if it was actually requested by the component
+ if (wasInRequired && prop.hasNotifySignal()) {
+ QMetaMethod changeSignal = prop.notifySignal();
+ static QMetaMethod updateSlot = PropertyUpdater::staticMetaObject.method(
+ PropertyUpdater::staticMetaObject.indexOfSlot("doUpdate()"));
+
+ QMetaObject::Connection conn = QObject::connect(itemOrProxy, changeSignal,
+ updater, updateSlot);
+ updater->changeSignalIndexToPropertyIndex[changeSignal.methodIndex()] = i;
+ auto propIdx = object->metaObject()->indexOfProperty(propName.toUtf8());
+ QMetaMethod writeToPropSignal
+ = object->metaObject()->property(propIdx).notifySignal();
+ updater->senderToConnection[writeToPropSignal.methodIndex()] = conn;
+ static QMetaMethod breakBinding = PropertyUpdater::staticMetaObject.method(
+ PropertyUpdater::staticMetaObject.indexOfSlot("breakBinding()"));
+ componentProp.write(prop.read(itemOrProxy));
+ // the connection needs to established after the write,
+ // else the signal gets triggered by it and breakBinding will remove the connection
+ QObject::connect(object, writeToPropSignal, updater, breakBinding);
+ }
+ else if (wasInRequired) // we still have to write, even if there is no change signal
+ componentProp.write(prop.read(itemOrProxy));
+ }
+ }
+ } else {
+ modelItemToIncubate->contextData->contextObject = modelItemToIncubate;
+ if (proxiedObject)
+ proxyContext->contextObject = proxiedObject;
+ }
+}
+
void QQDMIncubationTask::statusChanged(Status status)
{
if (vdm) {
@@ -923,6 +1067,71 @@ void QQmlDelegateModelPrivate::releaseIncubator(QQDMIncubationTask *incubationTa
}
}
+void QQmlDelegateModelPrivate::reuseItem(QQmlDelegateModelItem *item, int newModelIndex, int newGroups)
+{
+ Q_ASSERT(item->object);
+
+ // Update/reset which groups the item belongs to
+ item->groups = newGroups;
+
+ // Update context property index (including row and column) on the delegate
+ // item, and inform the application about it. For a list, the row is the same
+ // as the index, and the column is always 0. We set alwaysEmit to true, to
+ // force all bindings to be reevaluated, even if the index didn't change.
+ const bool alwaysEmit = true;
+ item->setModelIndex(newModelIndex, newModelIndex, 0, alwaysEmit);
+
+ // Notify the application that all 'dynamic'/role-based context data has
+ // changed as well (their getter function will use the updated index).
+ auto const itemAsList = QList<QQmlDelegateModelItem *>() << item;
+ auto const updateAllRoles = QVector<int>();
+ m_adaptorModel.notify(itemAsList, newModelIndex, 1, updateAllRoles);
+
+ if (QQmlDelegateModelAttached *att = static_cast<QQmlDelegateModelAttached *>(
+ qmlAttachedPropertiesObject<QQmlDelegateModel>(item->object, false))) {
+ // Update currentIndex of the attached DelegateModel object
+ // to the index the item has in the cache.
+ att->resetCurrentIndex();
+ // emitChanges will emit both group-, and index changes to the application
+ att->emitChanges();
+ }
+
+ // Inform the view that the item is recycled. This will typically result
+ // in the view updating its own attached delegate item properties.
+ emit q_func()->itemReused(newModelIndex, item->object);
+}
+
+void QQmlDelegateModelPrivate::drainReusableItemsPool(int maxPoolTime)
+{
+ m_reusableItemsPool.drain(maxPoolTime, [=](QQmlDelegateModelItem *cacheItem){ destroyCacheItem(cacheItem); });
+}
+
+void QQmlDelegateModel::drainReusableItemsPool(int maxPoolTime)
+{
+ d_func()->drainReusableItemsPool(maxPoolTime);
+}
+
+int QQmlDelegateModel::poolSize()
+{
+ return d_func()->m_reusableItemsPool.size();
+}
+
+QQmlComponent *QQmlDelegateModelPrivate::resolveDelegate(int index)
+{
+ if (!m_delegateChooser)
+ return m_delegate;
+
+ QQmlComponent *delegate = nullptr;
+ QQmlAbstractDelegateComponent *chooser = m_delegateChooser;
+
+ do {
+ delegate = chooser->delegate(&m_adaptorModel, index);
+ chooser = qobject_cast<QQmlAbstractDelegateComponent *>(delegate);
+ } while (chooser);
+
+ return delegate;
+}
+
void QQmlDelegateModelPrivate::addCacheItem(QQmlDelegateModelItem *item, Compositor::iterator it)
{
m_cache.insert(it.cacheIndex, item);
@@ -992,6 +1201,7 @@ void QQDMIncubationTask::setInitialState(QObject *o)
void QQmlDelegateModelPrivate::setInitialState(QQDMIncubationTask *incubationTask, QObject *o)
{
QQmlDelegateModelItem *cacheItem = incubationTask->incubating;
+ incubationTask->initializeRequiredProperties(incubationTask->incubating, o);
cacheItem->object = o;
if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object))
@@ -1010,16 +1220,38 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ
}
Compositor::iterator it = m_compositor.find(group, index);
+ const auto flags = it->flags;
+ const auto modelIndex = it.modelIndex();
QQmlDelegateModelItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0;
- if (!cacheItem) {
- cacheItem = m_adaptorModel.createItem(m_cacheMetaType, it.modelIndex());
- if (!cacheItem)
+ if (!cacheItem || !cacheItem->delegate) {
+ QQmlComponent *delegate = resolveDelegate(modelIndex);
+ if (!delegate)
return nullptr;
- cacheItem->groups = it->flags;
- addCacheItem(cacheItem, it);
+ if (!cacheItem) {
+ cacheItem = m_reusableItemsPool.takeItem(delegate, index);
+ if (cacheItem) {
+ // Move the pooled item back into the cache, update
+ // all related properties, and return the object (which
+ // has already been incubated, otherwise it wouldn't be in the pool).
+ addCacheItem(cacheItem, it);
+ reuseItem(cacheItem, index, flags);
+ cacheItem->referenceObject();
+ return cacheItem->object;
+ }
+
+ // Since we could't find an available item in the pool, we create a new one
+ cacheItem = m_adaptorModel.createItem(m_cacheMetaType, modelIndex);
+ if (!cacheItem)
+ return nullptr;
+
+ cacheItem->groups = flags;
+ addCacheItem(cacheItem, it);
+ }
+
+ cacheItem->delegate = delegate;
}
// Bump the reference counts temporarily so neither the content data or the delegate object
@@ -1034,18 +1266,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ
cacheItem->incubationTask->forceCompletion();
}
} else if (!cacheItem->object) {
- QQmlComponent *delegate = m_delegate;
- if (m_delegateChooser) {
- QQmlAbstractDelegateComponent *chooser = m_delegateChooser;
- do {
- delegate = chooser->delegate(&m_adaptorModel, cacheItem->index);
- chooser = qobject_cast<QQmlAbstractDelegateComponent *>(delegate);
- } while (chooser);
- if (!delegate)
- return nullptr;
- }
-
- QQmlContext *creationContext = delegate->creationContext();
+ QQmlContext *creationContext = cacheItem->delegate->creationContext();
cacheItem->scriptRef += 1;
@@ -1058,7 +1279,6 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ
QQmlContextData *ctxt = new QQmlContextData;
ctxt->setParent(QQmlContextData::get(creationContext ? creationContext : m_context.data()));
- ctxt->contextObject = cacheItem;
cacheItem->contextData = ctxt;
if (m_adaptorModel.hasProxyObject()) {
@@ -1067,17 +1287,18 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ
ctxt = new QQmlContextData;
ctxt->setParent(cacheItem->contextData, /*stronglyReferencedByParent*/true);
QObject *proxied = proxy->proxiedObject();
- ctxt->contextObject = proxied;
+ cacheItem->incubationTask->proxiedObject = proxied;
+ cacheItem->incubationTask->proxyContext = ctxt;
// We don't own the proxied object. We need to clear it if it goes away.
QObject::connect(proxied, &QObject::destroyed,
cacheItem, &QQmlDelegateModelItem::childContextObjectDestroyed);
}
}
- QQmlComponentPrivate *cp = QQmlComponentPrivate::get(delegate);
+ QQmlComponentPrivate *cp = QQmlComponentPrivate::get(cacheItem->delegate);
cp->incubateObject(
cacheItem->incubationTask,
- delegate,
+ cacheItem->delegate,
m_context->engine(),
ctxt,
QQmlContextData::get(m_context));
@@ -1801,7 +2022,7 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
propertyName = it.nextPropertyNameAsString(v);
if (propertyName->isNull())
break;
- cacheItem->setValue(propertyName->toQStringNoThrow(), scope.engine->toVariant(v, QVariant::Invalid));
+ cacheItem->setValue(propertyName->toQStringNoThrow(), scope.engine->toVariant(v, QMetaType::UnknownType));
}
cacheItem->groups = groups | Compositor::UnresolvedFlag | Compositor::CacheFlag;
@@ -2057,9 +2278,10 @@ void QV4::Heap::QQmlDelegateModelItemObject::destroy()
}
-QQmlDelegateModelItem::QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType,
- QQmlAdaptorModel::Accessors *accessor,
- int modelIndex, int row, int column)
+QQmlDelegateModelItem::QQmlDelegateModelItem(
+ const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
+ QQmlAdaptorModel::Accessors *accessor,
+ int modelIndex, int row, int column)
: v4(metaType->v4Engine)
, metaType(metaType)
, contextData(nullptr)
@@ -2075,8 +2297,6 @@ QQmlDelegateModelItem::QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *meta
, row(row)
, column(column)
{
- metaType->addref();
-
if (accessor->propertyCache) {
// The property cache in the accessor is common for all the model
// items in the model it wraps. It describes available model roles,
@@ -2105,9 +2325,6 @@ QQmlDelegateModelItem::~QQmlDelegateModelItem()
else
delete incubationTask;
}
-
- metaType->release();
-
}
void QQmlDelegateModelItem::Dispose()
@@ -2171,6 +2388,8 @@ QQmlDelegateModelItem *QQmlDelegateModelItem::dataForObject(QObject *object)
{
QQmlData *d = QQmlData::get(object);
QQmlContextData *context = d ? d->context : nullptr;
+ if (context && context->hasExtraObject)
+ return qobject_cast<QQmlDelegateModelItem *>(context->extraObject);
for (context = context ? context->parent : nullptr; context; context = context->parent) {
if (QQmlDelegateModelItem *cacheItem = qobject_cast<QQmlDelegateModelItem *>(
context->contextObject)) {
@@ -3182,8 +3401,6 @@ void QQmlDelegateModelGroup::move(QQmlV4Function *args)
Each index is adjusted for previous changes with all removed items preceding any inserted
items.
-
- The corresponding handler is \c onChanged.
*/
//============================================================================
@@ -3324,7 +3541,7 @@ QObject *QQmlPartsModel::object(int index, QQmlIncubator::IncubationMode incubat
QObject *part = package->part(m_part);
if (!part)
return nullptr;
- m_packaged.insertMulti(part, package);
+ m_packaged.insert(part, package);
return part;
}
@@ -3338,11 +3555,11 @@ QObject *QQmlPartsModel::object(int index, QQmlIncubator::IncubationMode incubat
return nullptr;
}
-QQmlInstanceModel::ReleaseFlags QQmlPartsModel::release(QObject *item)
+QQmlInstanceModel::ReleaseFlags QQmlPartsModel::release(QObject *item, ReusableFlag)
{
- QQmlInstanceModel::ReleaseFlags flags = nullptr;
+ QQmlInstanceModel::ReleaseFlags flags;
- QHash<QObject *, QQuickPackage *>::iterator it = m_packaged.find(item);
+ auto it = m_packaged.find(item);
if (it != m_packaged.end()) {
QQuickPackage *package = *it;
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
@@ -3383,7 +3600,7 @@ QQmlIncubator::Status QQmlPartsModel::incubationStatus(int index)
int QQmlPartsModel::indexOf(QObject *item, QObject *) const
{
- QHash<QObject *, QQuickPackage *>::const_iterator it = m_packaged.find(item);
+ auto it = m_packaged.find(item);
if (it != m_packaged.end()) {
if (QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(*it))
return cacheItem->groupIndex(m_compositorGroup);
@@ -3431,6 +3648,121 @@ void QQmlPartsModel::emitModelUpdated(const QQmlChangeSet &changeSet, bool reset
}
}
+void QQmlReusableDelegateModelItemsPool::insertItem(QQmlDelegateModelItem *modelItem)
+{
+ // Currently, the only way for a view to reuse items is to call release()
+ // in the model class with the second argument explicitly set to
+ // QQmlReuseableDelegateModelItemsPool::Reusable. If the released item is
+ // no longer referenced, it will be added to the pool. Reusing of items can
+ // be specified per item, in case certain items cannot be recycled. A
+ // QQmlDelegateModelItem knows which delegate its object was created from.
+ // So when we are about to create a new item, we first check if the pool
+ // contains an item based on the same delegate from before. If so, we take
+ // it out of the pool (instead of creating a new item), and update all its
+ // context properties and attached properties.
+
+ // When a view is recycling items, it should call drain() regularly. As
+ // there is currently no logic to 'hibernate' items in the pool, they are
+ // only meant to rest there for a short while, ideally only from the time
+ // e.g a row is unloaded on one side of the view, and until a new row is
+ // loaded on the opposite side. Between these times, the application will
+ // see the item as fully functional and 'alive' (just not visible on
+ // screen). Since this time is supposed to be short, we don't take any
+ // action to notify the application about it, since we don't want to
+ // trigger any bindings that can disturb performance.
+
+ // A recommended time for calling drain() is each time a view has finished
+ // loading e.g a new row or column. If there are more items in the pool
+ // after that, it means that the view most likely doesn't need them anytime
+ // soon. Those items should be destroyed to reduce resource consumption.
+
+ // Depending on if a view is a list or a table, it can sometimes be
+ // performant to keep items in the pool for a bit longer than one "row
+ // out/row in" cycle. E.g for a table, if the number of visible rows in a
+ // view is much larger than the number of visible columns. In that case, if
+ // you flick out a row, and then flick in a column, you would throw away a
+ // lot of items in the pool if completely draining it. The reason is that
+ // unloading a row places more items in the pool than what ends up being
+ // recycled when loading a new column. And then, when you next flick in a
+ // new row, you would need to load all those drained items again from
+ // scratch. For that reason, you can specify a maxPoolTime to the
+ // drainReusableItemsPool() that allows you to keep items in the pool for a
+ // bit longer, effectively keeping more items in circulation. A recommended
+ // maxPoolTime would be equal to the number of dimensions in the view,
+ // which means 1 for a list view and 2 for a table view. If you specify 0,
+ // all items will be drained.
+
+ Q_ASSERT(!modelItem->incubationTask);
+ Q_ASSERT(!modelItem->isObjectReferenced());
+ Q_ASSERT(modelItem->object);
+ Q_ASSERT(modelItem->delegate);
+
+ modelItem->poolTime = 0;
+ m_reusableItemsPool.append(modelItem);
+
+ qCDebug(lcItemViewDelegateRecycling)
+ << "item:" << modelItem
+ << "delegate:" << modelItem->delegate
+ << "index:" << modelItem->modelIndex()
+ << "row:" << modelItem->modelRow()
+ << "column:" << modelItem->modelColumn()
+ << "pool size:" << m_reusableItemsPool.size();
+}
+
+QQmlDelegateModelItem *QQmlReusableDelegateModelItemsPool::takeItem(const QQmlComponent *delegate, int newIndexHint)
+{
+ // Find the oldest item in the pool that was made from the same delegate as
+ // the given argument, remove it from the pool, and return it.
+ for (auto it = m_reusableItemsPool.begin(); it != m_reusableItemsPool.end(); ++it) {
+ if ((*it)->delegate != delegate)
+ continue;
+ auto modelItem = *it;
+ m_reusableItemsPool.erase(it);
+
+ qCDebug(lcItemViewDelegateRecycling)
+ << "item:" << modelItem
+ << "delegate:" << delegate
+ << "old index:" << modelItem->modelIndex()
+ << "old row:" << modelItem->modelRow()
+ << "old column:" << modelItem->modelColumn()
+ << "new index:" << newIndexHint
+ << "pool size:" << m_reusableItemsPool.size();
+
+ return modelItem;
+ }
+
+ qCDebug(lcItemViewDelegateRecycling)
+ << "no available item for delegate:" << delegate
+ << "new index:" << newIndexHint
+ << "pool size:" << m_reusableItemsPool.size();
+
+ return nullptr;
+}
+
+void QQmlReusableDelegateModelItemsPool::drain(int maxPoolTime, std::function<void(QQmlDelegateModelItem *cacheItem)> releaseItem)
+{
+ // Rather than releasing all pooled items upon a call to this function, each
+ // item has a poolTime. The poolTime specifies for how many loading cycles an item
+ // has been resting in the pool. And for each invocation of this function, poolTime
+ // will increase. If poolTime is equal to, or exceeds, maxPoolTime, it will be removed
+ // from the pool and released. This way, the view can tweak a bit for how long
+ // items should stay in "circulation", even if they are not recycled right away.
+ qCDebug(lcItemViewDelegateRecycling) << "pool size before drain:" << m_reusableItemsPool.size();
+
+ for (auto it = m_reusableItemsPool.begin(); it != m_reusableItemsPool.end();) {
+ auto modelItem = *it;
+ modelItem->poolTime++;
+ if (modelItem->poolTime <= maxPoolTime) {
+ ++it;
+ } else {
+ it = m_reusableItemsPool.erase(it);
+ releaseItem(modelItem);
+ }
+ }
+
+ qCDebug(lcItemViewDelegateRecycling) << "pool size after drain:" << m_reusableItemsPool.size();
+}
+
//============================================================================
struct QQmlDelegateModelGroupChange : QV4::Object
diff --git a/src/qmlmodels/qqmldelegatemodel_p.h b/src/qmlmodels/qqmldelegatemodel_p.h
index 9e846ccc3e..8aab4badca 100644
--- a/src/qmlmodels/qqmldelegatemodel_p.h
+++ b/src/qmlmodels/qqmldelegatemodel_p.h
@@ -85,7 +85,11 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, p
Q_PROPERTY(QObject *parts READ parts CONSTANT)
Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged)
Q_CLASSINFO("DefaultProperty", "delegate")
+ QML_NAMED_ELEMENT(DelegateModel)
+ QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ATTACHED(QQmlDelegateModelAttached)
Q_INTERFACES(QQmlParserStatus)
+
public:
QQmlDelegateModel();
QQmlDelegateModel(QQmlContext *, QObject *parent=nullptr);
@@ -109,12 +113,15 @@ public:
int count() const override;
bool isValid() const override { return delegate() != nullptr; }
QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
- ReleaseFlags release(QObject *object) override;
+ ReleaseFlags release(QObject *object, ReusableFlag reusableFlag = NotReusable) override;
void cancel(int index) override;
QVariant variantValue(int index, const QString &role) override;
void setWatchedRoles(const QList<QByteArray> &roles) override;
QQmlIncubator::Status incubationStatus(int index) override;
+ void drainReusableItemsPool(int maxPoolTime) override;
+ int poolSize() override;
+
int indexOf(QObject *object, QObject *objectContext) const override;
QString filterGroup() const;
@@ -164,6 +171,8 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModelGroup : public QObject
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged)
+ QML_NAMED_ELEMENT(DelegateModelGroup)
+ QML_ADDED_IN_MINOR_VERSION(1)
public:
QQmlDelegateModelGroup(QObject *parent = nullptr);
QQmlDelegateModelGroup(const QString &name, QQmlDelegateModel *model, int compositorType, QObject *parent = nullptr);
@@ -241,7 +250,6 @@ public:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQmlDelegateModel)
-QML_DECLARE_TYPEINFO(QQmlDelegateModel, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQmlDelegateModelGroup)
#endif // QQMLDATAMODEL_P_H
diff --git a/src/qmlmodels/qqmldelegatemodel_p_p.h b/src/qmlmodels/qqmldelegatemodel_p_p.h
index 3c8af5ca43..2dc409b222 100644
--- a/src/qmlmodels/qqmldelegatemodel_p_p.h
+++ b/src/qmlmodels/qqmldelegatemodel_p_p.h
@@ -49,6 +49,8 @@
#include <private/qqmladaptormodel_p.h>
#include <private/qqmlopenmetaobject_p.h>
+#include <QtCore/qloggingcategory.h>
+
//
// W A R N I N G
// -------------
@@ -64,6 +66,8 @@ QT_REQUIRE_CONFIG(qml_delegate_model);
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcItemViewDelegateRecycling)
+
typedef QQmlListCompositor Compositor;
class QQmlDelegateModelAttachedMetaObject;
@@ -100,7 +104,7 @@ class QQmlDelegateModelItem : public QObject
Q_PROPERTY(int column READ modelColumn NOTIFY columnChanged REVISION 12)
Q_PROPERTY(QObject *model READ modelObject CONSTANT)
public:
- QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType,
+ QQmlDelegateModelItem(const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
QQmlAdaptorModel::Accessors *accessor, int modelIndex,
int row, int column);
~QQmlDelegateModelItem();
@@ -144,7 +148,7 @@ public:
static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
QV4::ExecutionEngine *v4;
- QQmlDelegateModelItemMetaType * const metaType;
+ QQmlRefPointer<QQmlDelegateModelItemMetaType> const metaType;
QQmlContextDataRef contextData;
QPointer<QObject> object;
QPointer<QQmlDelegateModelAttached> attached;
@@ -190,7 +194,18 @@ void QV4::Heap::QQmlDelegateModelItemObject::init(QQmlDelegateModelItem *item)
this->item = item;
}
+class QQmlReusableDelegateModelItemsPool
+{
+public:
+ void insertItem(QQmlDelegateModelItem *modelItem);
+ QQmlDelegateModelItem *takeItem(const QQmlComponent *delegate, int newIndexHint);
+ void reuseItem(QQmlDelegateModelItem *item, int newModelIndex);
+ void drain(int maxPoolTime, std::function<void(QQmlDelegateModelItem *cacheItem)> releaseItem);
+ int size() { return m_reusableItemsPool.size(); }
+private:
+ QList<QQmlDelegateModelItem *> m_reusableItemsPool;
+};
class QQmlDelegateModelPrivate;
class QQDMIncubationTask : public QQmlIncubator
@@ -201,11 +216,14 @@ public:
, incubating(nullptr)
, vdm(l) {}
+ void initializeRequiredProperties(QQmlDelegateModelItem *modelItemToIncubate, QObject* object);
void statusChanged(Status) override;
void setInitialState(QObject *) override;
QQmlDelegateModelItem *incubating = nullptr;
QQmlDelegateModelPrivate *vdm = nullptr;
+ QQmlContextData *proxyContext = nullptr;
+ QPointer<QObject> proxiedObject = nullptr; // the proxied object might disapear, so we use a QPointer instead of a raw one
int index[QQmlListCompositor::MaximumGroupCount];
};
@@ -275,7 +293,7 @@ public:
void requestMoreIfNecessary();
QObject *object(Compositor::Group group, int index, QQmlIncubator::IncubationMode incubationMode);
- QQmlDelegateModel::ReleaseFlags release(QObject *object);
+ QQmlDelegateModel::ReleaseFlags release(QObject *object, QQmlInstanceModel::ReusableFlag reusable = QQmlInstanceModel::NotReusable);
QVariant variantValue(Compositor::Group group, int index, const QString &name);
void emitCreatedPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
void emitInitPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
@@ -287,9 +305,13 @@ public:
void emitDestroyingItem(QObject *item) { Q_EMIT q_func()->destroyingItem(item); }
void addCacheItem(QQmlDelegateModelItem *item, Compositor::iterator it);
void removeCacheItem(QQmlDelegateModelItem *cacheItem);
-
+ void destroyCacheItem(QQmlDelegateModelItem *cacheItem);
void updateFilterGroup();
+ void reuseItem(QQmlDelegateModelItem *item, int newModelIndex, int newGroups);
+ void drainReusableItemsPool(int maxPoolTime);
+ QQmlComponent *resolveDelegate(int index);
+
void addGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
void removeGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
void setGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
@@ -334,6 +356,7 @@ public:
QQmlDelegateModelGroupEmitterList m_pendingParts;
QList<QQmlDelegateModelItem *> m_cache;
+ QQmlReusableDelegateModelItemsPool m_reusableItemsPool;
QList<QQDMIncubationTask *> m_finishedIncubating;
QList<QByteArray> m_watchedRoles;
@@ -377,7 +400,7 @@ public:
int count() const override;
bool isValid() const override;
QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
- ReleaseFlags release(QObject *item) override;
+ ReleaseFlags release(QObject *item, ReusableFlag reusable = NotReusable) override;
QVariant variantValue(int index, const QString &role) override;
QList<QByteArray> watchedRoles() const { return m_watchedRoles; }
void setWatchedRoles(const QList<QByteArray> &roles) override;
@@ -396,7 +419,7 @@ Q_SIGNALS:
private:
QQmlDelegateModel *m_model;
- QHash<QObject *, QQuickPackage *> m_packaged;
+ QMultiHash<QObject *, QQuickPackage *> m_packaged;
QString m_part;
QString m_filterGroup;
QList<QByteArray> m_watchedRoles;
@@ -445,6 +468,20 @@ private:
const int indexPropertyOffset;
};
+class PropertyUpdater : public QObject
+{
+ Q_OBJECT
+
+public:
+ PropertyUpdater(QObject *parent);
+ QHash<int, QMetaObject::Connection> senderToConnection;
+ QHash<int, int> changeSignalIndexToPropertyIndex;
+ int updateCount = 0;
+public Q_SLOTS:
+ void doUpdate();
+ void breakBinding();
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/qmlmodels/qqmlinstantiator.cpp b/src/qmlmodels/qqmlinstantiator.cpp
index f9d5762f6e..3a0d746eb6 100644
--- a/src/qmlmodels/qqmlinstantiator.cpp
+++ b/src/qmlmodels/qqmlinstantiator.cpp
@@ -250,8 +250,6 @@ QQmlInstantiator::~QQmlInstantiator()
This signal is emitted when an object is added to the Instantiator. The \a index
parameter holds the index which the object has been given, and the \a object
parameter holds the \l QtObject that has been added.
-
- The corresponding handler is \c onObjectAdded.
*/
/*!
@@ -263,8 +261,6 @@ QQmlInstantiator::~QQmlInstantiator()
Do not keep a reference to \a object if it was created by this Instantiator, as
in these cases it will be deleted shortly after the signal is handled.
-
- The corresponding handler is \c onObjectRemoved.
*/
/*!
\qmlproperty bool QtQml::Instantiator::active
diff --git a/src/qmlmodels/qqmlinstantiator_p.h b/src/qmlmodels/qqmlinstantiator_p.h
index 87accc304f..60b611128d 100644
--- a/src/qmlmodels/qqmlinstantiator_p.h
+++ b/src/qmlmodels/qqmlinstantiator_p.h
@@ -72,6 +72,8 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlInstantiator : public QObject, public QQmlP
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(QObject *object READ object NOTIFY objectChanged)
Q_CLASSINFO("DefaultProperty", "delegate")
+ QML_NAMED_ELEMENT(Instantiator)
+ QML_ADDED_IN_MINOR_VERSION(14)
public:
QQmlInstantiator(QObject *parent = nullptr);
diff --git a/src/qmlmodels/qqmllistaccessor.cpp b/src/qmlmodels/qqmllistaccessor.cpp
index 46a11e2bc2..69427df184 100644
--- a/src/qmlmodels/qqmllistaccessor.cpp
+++ b/src/qmlmodels/qqmllistaccessor.cpp
@@ -76,11 +76,13 @@ void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine)
if (!d.isValid()) {
m_type = Invalid;
- } else if (d.userType() == QVariant::StringList) {
+ } else if (d.userType() == QMetaType::QStringList) {
m_type = StringList;
} else if (d.userType() == QMetaType::QVariantList) {
m_type = VariantList;
- } else if (d.canConvert(QVariant::Int)) {
+ } 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:
// QVector<QPointer<QQuickItem>> something;
@@ -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/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp
index 083e80a0a3..e07951cab3 100644
--- a/src/qmlmodels/qqmllistmodel.cpp
+++ b/src/qmlmodels/qqmllistmodel.cpp
@@ -219,14 +219,14 @@ const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QV
{
Role::DataType type;
- switch (data.type()) {
- case QVariant::Double: type = Role::Number; break;
- case QVariant::Int: type = Role::Number; break;
- case QVariant::Bool: type = Role::Bool; break;
- case QVariant::String: type = Role::String; break;
- case QVariant::Map: type = Role::VariantMap; break;
- case QVariant::DateTime: type = Role::DateTime; break;
- case QVariant::UserType: {
+ switch (data.userType()) {
+ case QMetaType::Double: type = Role::Number; break;
+ case QMetaType::Int: type = Role::Number; break;
+ case QMetaType::Bool: type = Role::Bool; break;
+ case QMetaType::QString: type = Role::String; break;
+ case QMetaType::QVariantMap: type = Role::VariantMap; break;
+ case QMetaType::QDateTime: type = Role::DateTime; break;
+ default: {
if (data.userType() == qMetaTypeId<QJSValue>() &&
data.value<QJSValue>().isCallable()) {
type = Role::Function;
@@ -235,12 +235,14 @@ const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QV
&& data.value<const QV4::CompiledData::Binding*>()->isTranslationBinding()) {
type = Role::String;
break;
- } else {
+ } else if (data.userType() >= QMetaType::User) {
type = Role::List;
break;
+ } else {
+ type = Role::Invalid;
+ break;
}
}
- default: type = Role::Invalid; break;
}
if (type == Role::Invalid) {
@@ -1740,7 +1742,7 @@ void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector<int>
if (value.userType() == qMetaTypeId<QJSValue>())
value = value.value<QJSValue>().toVariant();
- if (value.type() == QVariant::List) {
+ if (value.userType() == QMetaType::QVariantList) {
QQmlListModel *subModel = QQmlListModel::createWithOwner(m_owner);
QVariantList subArray = value.toList();
@@ -1803,7 +1805,7 @@ void DynamicRoleModelNodeMetaObject::propertyWritten(int index)
if (v.userType() == qMetaTypeId<QJSValue>())
v= v.value<QJSValue>().toVariant();
- if (v.type() == QVariant::List) {
+ if (v.userType() == QMetaType::QVariantList) {
QQmlListModel *subModel = QQmlListModel::createWithOwner(parentModel);
QVariantList subArray = v.toList();
diff --git a/src/qmlmodels/qqmllistmodel_p.h b/src/qmlmodels/qqmllistmodel_p.h
index 10d67c1c6f..9a4358ac6f 100644
--- a/src/qmlmodels/qqmllistmodel_p.h
+++ b/src/qmlmodels/qqmllistmodel_p.h
@@ -83,6 +83,8 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles)
Q_PROPERTY(QObject *agent READ agent CONSTANT REVISION(14))
+ QML_NAMED_ELEMENT(ListModel)
+ QML_ADDED_IN_MINOR_VERSION(1)
public:
QQmlListModel(QObject *parent=nullptr);
@@ -171,7 +173,9 @@ private:
// ### FIXME
class QQmlListElement : public QObject
{
-Q_OBJECT
+ Q_OBJECT
+ QML_NAMED_ELEMENT(ListElement)
+ QML_ADDED_IN_MINOR_VERSION(1)
};
class QQmlListModelParser : public QQmlCustomParser
@@ -201,6 +205,12 @@ private:
QString listElementTypeName;
};
+template<>
+inline QQmlCustomParser *qmlCreateCustomParser<QQmlListModel>()
+{
+ return new QQmlListModelParser;
+}
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQmlListModel)
diff --git a/src/qmlmodels/qqmllistmodelworkeragent_p.h b/src/qmlmodels/qqmllistmodelworkeragent_p.h
index 1ef27cea3f..f65909dcec 100644
--- a/src/qmlmodels/qqmllistmodelworkeragent_p.h
+++ b/src/qmlmodels/qqmllistmodelworkeragent_p.h
@@ -56,6 +56,7 @@
#include <QEvent>
#include <QMutex>
#include <QWaitCondition>
+#include <QtQml/qqml.h>
#include <private/qv4engine_p.h>
@@ -71,6 +72,7 @@ class QQmlListModelWorkerAgent : public QObject
Q_OBJECT
Q_PROPERTY(int count READ count)
Q_PROPERTY(QV4::ExecutionEngine *engine READ engine WRITE setEngine NOTIFY engineChanged)
+ QML_ANONYMOUS
public:
QQmlListModelWorkerAgent(QQmlListModel *);
diff --git a/src/qmlmodels/qqmlmodelsmodule.cpp b/src/qmlmodels/qqmlmodelsmodule.cpp
index d569d8e23c..155ded6c65 100644
--- a/src/qmlmodels/qqmlmodelsmodule.cpp
+++ b/src/qmlmodels/qqmlmodelsmodule.cpp
@@ -40,25 +40,20 @@
#include "qqmlmodelsmodule_p.h"
#include <private/qtqmlmodelsglobal_p.h>
-#if QT_CONFIG(itemmodel)
-#include <QtCore/qitemselectionmodel.h>
-#endif
#if QT_CONFIG(qml_list_model)
#include <private/qqmllistmodel_p.h>
+#include <private/qqmllistmodelworkeragent_p.h>
#endif
#if QT_CONFIG(qml_delegate_model)
+#include <private/qqmlabstractdelegatecomponent_p.h>
#include <private/qqmldelegatemodel_p.h>
-#include <private/qqmldelegatecomponent_p.h>
#include <private/qquickpackage_p.h>
+#include <private/qqmlcomponentattached_p.h>
#endif
#if QT_CONFIG(qml_object_model)
#include <private/qqmlobjectmodel_p.h>
#include <private/qqmlinstantiator_p.h>
#endif
-#if QT_CONFIG(qml_table_model)
-#include <private/qqmltablemodel_p.h>
-#include <private/qqmltablemodelcolumn_p.h>
-#endif
QT_BEGIN_NAMESPACE
@@ -67,6 +62,8 @@ QT_BEGIN_NAMESPACE
void QQmlModelsModule::registerQmlTypes()
{
// Don't add anything here. These are only for backwards compatibility.
+ // Don't convert these to qmlRegisterTypesAndRevisions!
+ // -> the annotations in the headers are for the QtQml.Models module <-
#if QT_CONFIG(qml_object_model)
qmlRegisterType<QQmlInstantiator>("QtQml", 2, 1, "Instantiator"); // Only available in >= 2.1
qmlRegisterAnonymousType<QQmlInstanceModel>("QtQml", 2);
@@ -76,6 +73,8 @@ void QQmlModelsModule::registerQmlTypes()
void QQmlModelsModule::registerQuickTypes()
{
// Don't add anything here. These are only for backwards compatibility.
+ // Don't convert these to qmlRegisterTypesAndRevisions!
+ // -> the annotations in the headers are for the QtQml.Models module <-
const char uri[] = "QtQuick";
@@ -97,43 +96,4 @@ void QQmlModelsModule::registerQuickTypes()
#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-void QQmlModelsModule::defineModule()
-{
- const char uri[] = "QtQml.Models";
-
-#if QT_CONFIG(qml_list_model)
- qmlRegisterType<QQmlListElement>(uri, 2, 1, "ListElement");
- qmlRegisterCustomType<QQmlListModel>(uri, 2, 1, "ListModel", new QQmlListModelParser);
-#endif
-#if QT_CONFIG(qml_delegate_model)
- qmlRegisterType<QQmlDelegateModel>(uri, 2, 1, "DelegateModel");
- qmlRegisterType<QQmlDelegateModelGroup>(uri, 2, 1, "DelegateModelGroup");
- qmlRegisterType<QQuickPackage>(uri, 2, 14, "Package");
-#endif
-#if QT_CONFIG(qml_object_model)
- qmlRegisterType<QQmlObjectModel>(uri, 2, 1, "ObjectModel");
- qmlRegisterType<QQmlObjectModel,3>(uri, 2, 3, "ObjectModel");
- qmlRegisterType<QQmlInstantiator>(uri, 2, 14, "Instantiator");
- qmlRegisterAnonymousType<QQmlInstanceModel>(uri, 2);
-#endif
-#if QT_CONFIG(itemmodel)
- qmlRegisterType<QItemSelectionModel>(uri, 2, 2, "ItemSelectionModel");
-#endif
-}
-
-void QQmlModelsModule::defineLabsModule()
-{
- const char uri[] = "Qt.labs.qmlmodels";
-
-#if QT_CONFIG(qml_delegate_model)
- qmlRegisterUncreatableType<QQmlAbstractDelegateComponent>(uri, 1, 0, "AbstractDelegateComponent", QQmlAbstractDelegateComponent::tr("Cannot create instance of abstract class AbstractDelegateComponent."));
- qmlRegisterType<QQmlDelegateChooser>(uri, 1, 0, "DelegateChooser");
- qmlRegisterType<QQmlDelegateChoice>(uri, 1, 0, "DelegateChoice");
-#endif
-#if QT_CONFIG(qml_table_model)
- qmlRegisterType<QQmlTableModel>(uri, 1, 0, "TableModel");
- qmlRegisterType<QQmlTableModelColumn>(uri, 1, 0, "TableModelColumn");
-#endif
-}
-
QT_END_NAMESPACE
diff --git a/src/qmlmodels/qqmlmodelsmodule_p.h b/src/qmlmodels/qqmlmodelsmodule_p.h
index 7e02578db9..feed0f88fe 100644
--- a/src/qmlmodels/qqmlmodelsmodule_p.h
+++ b/src/qmlmodels/qqmlmodelsmodule_p.h
@@ -51,6 +51,12 @@
// We mean it.
//
+#include <QtQml/qqml.h>
+
+#if QT_CONFIG(itemmodel)
+#include <QtCore/qitemselectionmodel.h>
+#endif
+
#include <private/qtqmlmodelsglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -62,10 +68,17 @@ public:
static void registerQmlTypes();
static void registerQuickTypes();
#endif
+};
- static void defineModule();
- static void defineLabsModule();
+#if QT_CONFIG(itemmodel)
+struct QItemSelectionModelForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QItemSelectionModel)
+ QML_NAMED_ELEMENT(ItemSelectionModel)
+ QML_ADDED_IN_MINOR_VERSION(2)
};
+#endif
QT_END_NAMESPACE
diff --git a/src/qmlmodels/qqmlobjectmodel.cpp b/src/qmlmodels/qqmlobjectmodel.cpp
index 7409178616..90469d06c2 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) {
@@ -226,12 +247,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);
}
/*!
@@ -262,7 +284,7 @@ QObject *QQmlObjectModel::object(int index, QQmlIncubator::IncubationMode)
return item.item;
}
-QQmlInstanceModel::ReleaseFlags QQmlObjectModel::release(QObject *item)
+QQmlInstanceModel::ReleaseFlags QQmlObjectModel::release(QObject *item, ReusableFlag)
{
Q_D(QQmlObjectModel);
int idx = d->indexOf(item);
@@ -270,7 +292,7 @@ QQmlInstanceModel::ReleaseFlags QQmlObjectModel::release(QObject *item)
if (!d->children[idx].deref())
return QQmlInstanceModel::Referenced;
}
- return nullptr;
+ return {};
}
QVariant QQmlObjectModel::variantValue(int index, const QString &role)
@@ -278,7 +300,7 @@ QVariant QQmlObjectModel::variantValue(int index, const QString &role)
Q_D(QQmlObjectModel);
if (index < 0 || index >= d->children.count())
return QString();
- return QQmlEngine::contextForObject(d->children.at(index).item)->contextProperty(role);
+ return d->children.at(index).item->property(role.toUtf8().constData());
}
QQmlIncubator::Status QQmlObjectModel::incubationStatus(int)
diff --git a/src/qmlmodels/qqmlobjectmodel_p.h b/src/qmlmodels/qqmlobjectmodel_p.h
index 78a5615ae2..866d010cd3 100644
--- a/src/qmlmodels/qqmlobjectmodel_p.h
+++ b/src/qmlmodels/qqmlobjectmodel_p.h
@@ -69,23 +69,32 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlInstanceModel : public QObject
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
+ QML_ANONYMOUS
public:
+ enum ReusableFlag {
+ NotReusable,
+ Reusable
+ };
+
virtual ~QQmlInstanceModel() {}
- enum ReleaseFlag { Referenced = 0x01, Destroyed = 0x02 };
+ enum ReleaseFlag { Referenced = 0x01, Destroyed = 0x02, Pooled = 0x04 };
Q_DECLARE_FLAGS(ReleaseFlags, ReleaseFlag)
virtual int count() const = 0;
virtual bool isValid() const = 0;
virtual QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) = 0;
- virtual ReleaseFlags release(QObject *object) = 0;
+ virtual ReleaseFlags release(QObject *object, ReusableFlag reusableFlag = NotReusable) = 0;
virtual void cancel(int) {}
QString stringValue(int index, const QString &role) { return variantValue(index, role).toString(); }
virtual QVariant variantValue(int, const QString &) = 0;
virtual void setWatchedRoles(const QList<QByteArray> &roles) = 0;
virtual QQmlIncubator::Status incubationStatus(int index) = 0;
+ virtual void drainReusableItemsPool(int maxPoolTime) { Q_UNUSED(maxPoolTime) }
+ virtual int poolSize() { return 0; }
+
virtual int indexOf(QObject *object, QObject *objectContext) const = 0;
virtual const QAbstractItemModel *abstractItemModel() const { return nullptr; }
@@ -95,6 +104,8 @@ Q_SIGNALS:
void createdItem(int index, QObject *object);
void initItem(int index, QObject *object);
void destroyingItem(QObject *object);
+ Q_REVISION(15) void itemPooled(int index, QObject *object);
+ Q_REVISION(15) void itemReused(int index, QObject *object);
protected:
QQmlInstanceModel(QObjectPrivate &dd, QObject *parent = nullptr)
@@ -113,6 +124,9 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlObjectModel : public QQmlInstanceModel
Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged DESIGNABLE false)
Q_CLASSINFO("DefaultProperty", "children")
+ QML_NAMED_ELEMENT(ObjectModel)
+ QML_ADDED_IN_MINOR_VERSION(1)
+ QML_ATTACHED(QQmlObjectModelAttached)
public:
QQmlObjectModel(QObject *parent=nullptr);
@@ -121,7 +135,7 @@ public:
int count() const override;
bool isValid() const override;
QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
- ReleaseFlags release(QObject *object) override;
+ ReleaseFlags release(QObject *object, ReusableFlag reusable = NotReusable) override;
QVariant variantValue(int index, const QString &role) override;
void setWatchedRoles(const QList<QByteArray> &) override {}
QQmlIncubator::Status incubationStatus(int index) override;
@@ -191,6 +205,5 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QQmlInstanceModel)
QML_DECLARE_TYPE(QQmlObjectModel)
-QML_DECLARE_TYPEINFO(QQmlObjectModel, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQMLINSTANCEMODEL_P_H
diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp
index e2cecfef79..6e21f2f389 100644
--- a/src/qmlmodels/qqmltableinstancemodel.cpp
+++ b/src/qmlmodels/qqmltableinstancemodel.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qqmltableinstancemodel_p.h"
-#include "qqmldelegatecomponent_p.h"
+#include "qqmlabstractdelegatecomponent_p.h"
#include <QtCore/QTimer>
@@ -78,10 +78,8 @@ void QQmlTableInstanceModel::deleteModelItemLater(QQmlDelegateModelItem *modelIt
QQmlTableInstanceModel::QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent)
: QQmlInstanceModel(*(new QObjectPrivate()), parent)
, m_qmlContext(qmlContext)
- , m_metaType(
- new QQmlDelegateModelItemMetaType(m_qmlContext->engine()->handle(), nullptr,
- QStringList()),
- QQmlRefPointer<QQmlDelegateModelItemMetaType>::Adopt)
+ , m_metaType(new QQmlDelegateModelItemMetaType(m_qmlContext->engine()->handle(), nullptr, QStringList()),
+ QQmlRefPointer<QQmlDelegateModelItemMetaType>::Adopt)
{
}
@@ -144,7 +142,7 @@ QQmlDelegateModelItem *QQmlTableInstanceModel::resolveModelItem(int index)
return nullptr;
// Check if the pool contains an item that can be reused
- modelItem = takeFromReusableItemsPool(delegate);
+ modelItem = m_reusableItemsPool.takeItem(delegate, index);
if (modelItem) {
reuseItem(modelItem, index);
m_modelItems.insert(index, modelItem);
@@ -228,16 +226,24 @@ QQmlInstanceModel::ReleaseFlags QQmlTableInstanceModel::release(QObject *object,
m_modelItems.remove(modelItem->index);
if (reusable == Reusable) {
- insertIntoReusableItemsPool(modelItem);
- return QQmlInstanceModel::Referenced;
+ m_reusableItemsPool.insertItem(modelItem);
+ emit itemPooled(modelItem->index, modelItem->object);
+ return QQmlInstanceModel::Pooled;
}
// The item is not reused or referenced by anyone, so just delete it
- modelItem->destroyObject();
- emit destroyingItem(object);
+ destroyModelItem(modelItem, Deferred);
+ return QQmlInstanceModel::Destroyed;
+}
+void QQmlTableInstanceModel::destroyModelItem(QQmlDelegateModelItem *modelItem, DestructionMode mode)
+{
+ emit destroyingItem(modelItem->object);
+ if (mode == Deferred)
+ modelItem->destroyObject();
+ else
+ delete modelItem->object;
delete modelItem;
- return QQmlInstanceModel::Destroyed;
}
void QQmlTableInstanceModel::dispose(QObject *object)
@@ -279,92 +285,11 @@ void QQmlTableInstanceModel::cancel(int index)
delete modelItem;
}
-void QQmlTableInstanceModel::insertIntoReusableItemsPool(QQmlDelegateModelItem *modelItem)
-{
- // Currently, the only way for a view to reuse items is to call QQmlTableInstanceModel::release()
- // with the second argument explicitly set to QQmlTableInstanceModel::Reusable. If the released
- // item is no longer referenced, it will be added to the pool. Reusing of items can be specified
- // per item, in case certain items cannot be recycled.
- // A QQmlDelegateModelItem knows which delegate its object was created from. So when we are
- // about to create a new item, we first check if the pool contains an item based on the same
- // delegate from before. If so, we take it out of the pool (instead of creating a new item), and
- // update all its context-, and attached properties.
- // When a view is recycling items, it should call QQmlTableInstanceModel::drainReusableItemsPool()
- // regularly. As there is currently no logic to 'hibernate' items in the pool, they are only
- // meant to rest there for a short while, ideally only from the time e.g a row is unloaded
- // on one side of the view, and until a new row is loaded on the opposite side. In-between
- // this time, the application will see the item as fully functional and 'alive' (just not
- // visible on screen). Since this time is supposed to be short, we don't take any action to
- // notify the application about it, since we don't want to trigger any bindings that can
- // disturb performance.
- // A recommended time for calling drainReusableItemsPool() is each time a view has finished
- // loading e.g a new row or column. If there are more items in the pool after that, it means
- // that the view most likely doesn't need them anytime soon. Those items should be destroyed to
- // not consume resources.
- // Depending on if a view is a list or a table, it can sometimes be performant to keep
- // items in the pool for a bit longer than one "row out/row in" cycle. E.g for a table, if the
- // number of visible rows in a view is much larger than the number of visible columns.
- // In that case, if you flick out a row, and then flick in a column, you would throw away a lot
- // of items in the pool if completely draining it. The reason is that unloading a row places more
- // items in the pool than what ends up being recycled when loading a new column. And then, when you
- // next flick in a new row, you would need to load all those drained items again from scratch. For
- // that reason, you can specify a maxPoolTime to the drainReusableItemsPool() that allows you to keep
- // items in the pool for a bit longer, effectively keeping more items in circulation.
- // A recommended maxPoolTime would be equal to the number of dimenstions in the view, which
- // means 1 for a list view and 2 for a table view. If you specify 0, all items will be drained.
- Q_ASSERT(!modelItem->incubationTask);
- Q_ASSERT(!modelItem->isObjectReferenced());
- Q_ASSERT(!modelItem->isReferenced());
- Q_ASSERT(modelItem->object);
-
- modelItem->poolTime = 0;
- m_reusableItemsPool.append(modelItem);
- emit itemPooled(modelItem->index, modelItem->object);
-}
-
-QQmlDelegateModelItem *QQmlTableInstanceModel::takeFromReusableItemsPool(const QQmlComponent *delegate)
-{
- // Find the oldest item in the pool that was made from the same delegate as
- // the given argument, remove it from the pool, and return it.
- if (m_reusableItemsPool.isEmpty())
- return nullptr;
-
- for (auto it = m_reusableItemsPool.begin(); it != m_reusableItemsPool.end(); ++it) {
- if ((*it)->delegate != delegate)
- continue;
- auto modelItem = *it;
- m_reusableItemsPool.erase(it);
- return modelItem;
- }
-
- return nullptr;
-}
-
void QQmlTableInstanceModel::drainReusableItemsPool(int maxPoolTime)
{
- // Rather than releasing all pooled items upon a call to this function, each
- // item has a poolTime. The poolTime specifies for how many loading cycles an item
- // has been resting in the pool. And for each invocation of this function, poolTime
- // will increase. If poolTime is equal to, or exceeds, maxPoolTime, it will be removed
- // from the pool and released. This way, the view can tweak a bit for how long
- // items should stay in "circulation", even if they are not recycled right away.
- for (auto it = m_reusableItemsPool.begin(); it != m_reusableItemsPool.end();) {
- auto modelItem = *it;
- modelItem->poolTime++;
- if (modelItem->poolTime <= maxPoolTime) {
- ++it;
- } else {
- it = m_reusableItemsPool.erase(it);
-
- Q_ASSERT(!modelItem->incubationTask);
- Q_ASSERT(!modelItem->isObjectReferenced());
- Q_ASSERT(!modelItem->isReferenced());
- Q_ASSERT(modelItem->object);
- emit destroyingItem(modelItem->object);
- delete modelItem->object;
- delete modelItem;
- }
- }
+ m_reusableItemsPool.drain(maxPoolTime, [this](QQmlDelegateModelItem *modelItem) {
+ destroyModelItem(modelItem, Immediate);
+ });
}
void QQmlTableInstanceModel::reuseItem(QQmlDelegateModelItem *item, int newModelIndex)
@@ -558,8 +483,13 @@ const QAbstractItemModel *QQmlTableInstanceModel::abstractItemModel() const
void QQmlTableInstanceModelIncubationTask::setInitialState(QObject *object)
{
- modelItemToIncubate->object = object;
- emit tableInstanceModel->initItem(modelItemToIncubate->index, object);
+ initializeRequiredProperties(modelItemToIncubate, object);
+ if (QQmlIncubatorPrivate::get(this)->requiredProperties().empty()) {
+ modelItemToIncubate->object = object;
+ emit tableInstanceModel->initItem(modelItemToIncubate->index, object);
+ } else {
+ object->deleteLater();
+ }
}
void QQmlTableInstanceModelIncubationTask::statusChanged(QQmlIncubator::Status status)
diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h
index 4ea1d85d16..0d96d35a5e 100644
--- a/src/qmlmodels/qqmltableinstancemodel_p.h
+++ b/src/qmlmodels/qqmltableinstancemodel_p.h
@@ -86,12 +86,6 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlTableInstanceModel : public QQmlInstanceMod
Q_OBJECT
public:
-
- enum ReusableFlag {
- NotReusable,
- Reusable
- };
-
QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent = nullptr);
~QQmlTableInstanceModel() override;
@@ -115,15 +109,12 @@ public:
const QAbstractItemModel *abstractItemModel() const override;
QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
- ReleaseFlags release(QObject *object) override { return release(object, NotReusable); }
- ReleaseFlags release(QObject *object, ReusableFlag reusable);
+ ReleaseFlags release(QObject *object, ReusableFlag reusable = NotReusable) override;
void dispose(QObject *object);
void cancel(int) override;
- void insertIntoReusableItemsPool(QQmlDelegateModelItem *modelItem);
- QQmlDelegateModelItem *takeFromReusableItemsPool(const QQmlComponent *delegate);
- void drainReusableItemsPool(int maxPoolTime);
- int poolSize() { return m_reusableItemsPool.size(); }
+ void drainReusableItemsPool(int maxPoolTime) override;
+ int poolSize() override { return m_reusableItemsPool.size(); }
void reuseItem(QQmlDelegateModelItem *item, int newModelIndex);
QQmlIncubator::Status incubationStatus(int index) override;
@@ -132,11 +123,12 @@ 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:
+ enum DestructionMode {
+ Deferred,
+ Immediate
+ };
+
QQmlComponent *resolveDelegate(int index);
QQmlAdaptorModel m_adaptorModel;
@@ -146,7 +138,7 @@ private:
QQmlRefPointer<QQmlDelegateModelItemMetaType> m_metaType;
QHash<int, QQmlDelegateModelItem *> m_modelItems;
- QList<QQmlDelegateModelItem *> m_reusableItemsPool;
+ QQmlReusableDelegateModelItemsPool m_reusableItemsPool;
QList<QQmlIncubator *> m_finishedIncubationTasks;
void incubateModelItem(QQmlDelegateModelItem *modelItem, QQmlIncubator::IncubationMode incubationMode);
@@ -154,6 +146,7 @@ private:
void deleteIncubationTaskLater(QQmlIncubator *incubationTask);
void deleteAllFinishedIncubationTasks();
QQmlDelegateModelItem *resolveModelItem(int index);
+ void destroyModelItem(QQmlDelegateModelItem *modelItem, DestructionMode mode);
void dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles);
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/qquickpackage_p.h b/src/qmlmodels/qquickpackage_p.h
index 97f7818fee..97f3bab9bc 100644
--- a/src/qmlmodels/qquickpackage_p.h
+++ b/src/qmlmodels/qquickpackage_p.h
@@ -66,6 +66,9 @@ class Q_AUTOTEST_EXPORT QQuickPackage : public QObject
Q_DECLARE_PRIVATE(QQuickPackage)
Q_CLASSINFO("DefaultProperty", "data")
+ QML_NAMED_ELEMENT(Package)
+ QML_ADDED_IN_MINOR_VERSION(14)
+ QML_ATTACHED(QQuickPackageAttached)
Q_PROPERTY(QQmlListProperty<QObject> data READ data)
public:
@@ -99,6 +102,5 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickPackage)
-QML_DECLARE_TYPEINFO(QQuickPackage, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKPACKAGE_H
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/qmltest/qmldir b/src/qmltest/qmldir
new file mode 100644
index 0000000000..5e9d5e2c95
--- /dev/null
+++ b/src/qmltest/qmldir
@@ -0,0 +1,2 @@
+module Qt.test.qtestroot
+typeinfo plugins.qmltypes
diff --git a/src/qmltest/qmltest.pro b/src/qmltest/qmltest.pro
index 0bf05093be..c2e8068fc6 100644
--- a/src/qmltest/qmltest.pro
+++ b/src/qmltest/qmltest.pro
@@ -4,7 +4,7 @@ QMAKE_DOCS = $$PWD/doc/qtqmltest.qdocconf
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_FOREACH
QT = core testlib-private
-QT_PRIVATE = quick quick-private qml-private gui core-private gui-private
+QT_PRIVATE = quick quick-private qml-private gui core-private
# Testlib is only a private dependency, which results in our users not
# inheriting testlibs's MODULE_CONFIG transitively. Make it explicit.
@@ -17,15 +17,28 @@ qtHaveModule(widgets) {
SOURCES += \
$$PWD/quicktest.cpp \
- $$PWD/quicktestevent.cpp \
$$PWD/quicktestresult.cpp
+
HEADERS += \
$$PWD/quicktestglobal.h \
$$PWD/quicktest.h \
- $$PWD/quicktestevent_p.h \
+ $$PWD/quicktest_p.h \
$$PWD/quicktestresult_p.h \
$$PWD/qtestoptions_p.h
qtConfig(qml-debug): DEFINES += QT_QML_DEBUG_NO_WARNING
load(qt_module)
+
+QMLTYPES_FILENAME = plugins.qmltypes
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/Qt/test/qtestroot
+QML_IMPORT_NAME = Qt.test.qtestroot
+QML_IMPORT_VERSION = 1.0
+CONFIG += qmltypes install_qmltypes install_metatypes
+
+# Install qmldir
+qmldir.files = $$PWD/qmldir
+qmldir.path = $$QMLTYPES_INSTALL_DIR
+
+prefix_build: INSTALLS += qmldir
+else: COPIES += qmldir
diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp
index 470b3c0f7a..cfc9221b20 100644
--- a/src/qmltest/quicktest.cpp
+++ b/src/qmltest/quicktest.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
-#include "quicktest.h"
+#include "quicktest_p.h"
#include "quicktestresult_p.h"
#include <QtTest/qtestsystem.h>
#include "qtestoptions_p.h"
@@ -133,53 +133,6 @@ bool QQuickTest::qWaitForItemPolished(const QQuickItem *item, int timeout)
return QTest::qWaitFor([&]() { return !QQuickItemPrivate::get(item)->polishScheduled; }, timeout);
}
-class QTestRootObject : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(bool windowShown READ windowShown NOTIFY windowShownChanged)
- Q_PROPERTY(bool hasTestCase READ hasTestCase WRITE setHasTestCase NOTIFY hasTestCaseChanged)
- Q_PROPERTY(QObject *defined READ defined)
-public:
- QTestRootObject(QObject *parent = nullptr)
- : QObject(parent), hasQuit(false), m_windowShown(false), m_hasTestCase(false) {
- m_defined = new QQmlPropertyMap(this);
-#if defined(QT_OPENGL_ES_2_ANGLE)
- m_defined->insert(QLatin1String("QT_OPENGL_ES_2_ANGLE"), QVariant(true));
-#endif
- }
-
- static QTestRootObject *instance() {
- static QPointer<QTestRootObject> object = new QTestRootObject;
- if (!object) {
- // QTestRootObject was deleted when previous test ended, create a new one
- object = new QTestRootObject;
- }
- return object;
- }
-
- bool hasQuit:1;
- bool hasTestCase() const { return m_hasTestCase; }
- void setHasTestCase(bool value) { m_hasTestCase = value; emit hasTestCaseChanged(); }
-
- bool windowShown() const { return m_windowShown; }
- void setWindowShown(bool value) { m_windowShown = value; emit windowShownChanged(); }
- QQmlPropertyMap *defined() const { return m_defined; }
-
- void init() { setWindowShown(false); setHasTestCase(false); hasQuit = false; }
-
-Q_SIGNALS:
- void windowShownChanged();
- void hasTestCaseChanged();
-
-private Q_SLOTS:
- void quit() { hasQuit = true; }
-
-private:
- bool m_windowShown : 1;
- bool m_hasTestCase :1;
- QQmlPropertyMap *m_defined;
-};
-
static QObject *testRootObject(QQmlEngine *engine, QJSEngine *jsEngine)
{
Q_UNUSED(engine);
@@ -332,8 +285,9 @@ private:
}
};
- TestCaseEnumerationResult enumerateTestCases(QV4::ExecutableCompilationUnit *compilationUnit,
- const Object *object = nullptr)
+ TestCaseEnumerationResult enumerateTestCases(
+ const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
+ const Object *object = nullptr)
{
QQmlType testCaseType;
for (quint32 i = 0, count = compilationUnit->importCount(); i < count; ++i) {
@@ -356,9 +310,8 @@ private:
if (!object) // Start at root of compilation unit if not enumerating a specific child
object = compilationUnit->objectAt(0);
- if (QV4::ExecutableCompilationUnit *superTypeUnit
- = compilationUnit->resolvedTypes.value(object->inheritedTypeNameIndex)
- ->compilationUnit.data()) {
+ if (const auto superTypeUnit = compilationUnit->resolvedTypes.value(
+ object->inheritedTypeNameIndex)->compilationUnit()) {
// We have a non-C++ super type, which could indicate we're a subtype of a TestCase
if (testCaseType.isValid() && superTypeUnit->url() == testCaseType.sourceUrl())
result.isTestCase = true;
@@ -556,7 +509,7 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch
qputenv("QT_QTESTLIB_RUNNING", "1");
- // Register the test object
+ // Register the custom factory function
qmlRegisterSingletonType<QTestRootObject>("Qt.test.qtestroot", 1, 0, "QTestRootObject", testRootObject);
QSet<QString> commandLineTestFunctions(QTest::testFunctions.cbegin(), QTest::testFunctions.cend());
@@ -688,5 +641,3 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch
}
QT_END_NAMESPACE
-
-#include "quicktest.moc"
diff --git a/src/qmltest/quicktest_p.h b/src/qmltest/quicktest_p.h
new file mode 100644
index 0000000000..50fc3be050
--- /dev/null
+++ b/src/qmltest/quicktest_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** 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: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 QUICKTEST_P_H
+#define QUICKTEST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQuickTest/quicktest.h>
+
+#include <QtQml/qqmlpropertymap.h>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTestRootObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool windowShown READ windowShown NOTIFY windowShownChanged)
+ Q_PROPERTY(bool hasTestCase READ hasTestCase WRITE setHasTestCase NOTIFY hasTestCaseChanged)
+ Q_PROPERTY(QObject *defined READ defined)
+ QML_SINGLETON
+ QML_ELEMENT
+
+public:
+ QTestRootObject(QObject *parent = nullptr)
+ : QObject(parent), hasQuit(false), m_windowShown(false), m_hasTestCase(false) {
+ m_defined = new QQmlPropertyMap(this);
+#if defined(QT_OPENGL_ES_2_ANGLE)
+ m_defined->insert(QLatin1String("QT_OPENGL_ES_2_ANGLE"), QVariant(true));
+#endif
+ }
+
+ static QTestRootObject *instance() {
+ static QPointer<QTestRootObject> object = new QTestRootObject;
+ if (!object) {
+ // QTestRootObject was deleted when previous test ended, create a new one
+ object = new QTestRootObject;
+ }
+ return object;
+ }
+
+ bool hasQuit:1;
+ bool hasTestCase() const { return m_hasTestCase; }
+ void setHasTestCase(bool value) { m_hasTestCase = value; emit hasTestCaseChanged(); }
+
+ bool windowShown() const { return m_windowShown; }
+ void setWindowShown(bool value) { m_windowShown = value; emit windowShownChanged(); }
+ QQmlPropertyMap *defined() const { return m_defined; }
+
+ void init() { setWindowShown(false); setHasTestCase(false); hasQuit = false; }
+
+Q_SIGNALS:
+ void windowShownChanged();
+ void hasTestCaseChanged();
+
+private Q_SLOTS:
+ void quit() { hasQuit = true; }
+
+private:
+ bool m_windowShown : 1;
+ bool m_hasTestCase :1;
+ QQmlPropertyMap *m_defined;
+};
+
+QT_END_NAMESPACE
+
+#endif // QUICKTEST_P_H
diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp
index cddf21c7ed..f3a6fea193 100644
--- a/src/qmltest/quicktestresult.cpp
+++ b/src/qmltest/quicktestresult.cpp
@@ -500,8 +500,8 @@ bool QuickTestResult::verify
bool QuickTestResult::fuzzyCompare(const QVariant &actual, const QVariant &expected, qreal delta)
{
- if (actual.type() == QVariant::Color || expected.type() == QVariant::Color) {
- if (!actual.canConvert(QVariant::Color) || !expected.canConvert(QVariant::Color))
+ if (actual.userType() == QMetaType::QColor || expected.userType() == QMetaType::QColor) {
+ if (!actual.canConvert(QMetaType::QColor) || !expected.canConvert(QMetaType::QColor))
return false;
//fuzzy color comparison
@@ -556,20 +556,20 @@ void QuickTestResult::stringify(QQmlV4Function *args)
&& !value->as<QV4::ArrayObject>()) {
QVariant v = scope.engine->toVariant(value, QMetaType::UnknownType);
if (v.isValid()) {
- switch (v.type()) {
- case QVariant::Vector3D:
+ switch (v.userType()) {
+ case QMetaType::QVector3D:
{
QVector3D v3d = v.value<QVector3D>();
result = QString::fromLatin1("Qt.vector3d(%1, %2, %3)").arg(v3d.x()).arg(v3d.y()).arg(v3d.z());
break;
}
- case QVariant::Url:
+ case QMetaType::QUrl:
{
QUrl url = v.value<QUrl>();
result = QString::fromLatin1("Qt.url(%1)").arg(url.toString());
break;
}
- case QVariant::DateTime:
+ case QMetaType::QDateTime:
{
QDateTime dt = v.value<QDateTime>();
result = dt.toString(Qt::ISODateWithMs);
diff --git a/src/qmltest/quicktestresult_p.h b/src/qmltest/quicktestresult_p.h
index 0d229ad713..81b9d78830 100644
--- a/src/qmltest/quicktestresult_p.h
+++ b/src/qmltest/quicktestresult_p.h
@@ -76,6 +76,7 @@ class Q_QUICK_TEST_EXPORT QuickTestResult : public QObject
Q_PROPERTY(int skipCount READ skipCount)
Q_PROPERTY(QStringList functionsToRun READ functionsToRun)
Q_PROPERTY(QStringList tagsToRun READ tagsToRun)
+
public:
QuickTestResult(QObject *parent = nullptr);
~QuickTestResult() override;
diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp
new file mode 100644
index 0000000000..c3ab61e621
--- /dev/null
+++ b/src/qmltyperegistrar/qmltyperegistrar.cpp
@@ -0,0 +1,463 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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: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$
+**
+****************************************************************************/
+
+#include "qmltypescreator.h"
+
+#include <QCoreApplication>
+#include <QCommandLineParser>
+#include <QtDebug>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonValue>
+#include <QJsonObject>
+#include <QFile>
+#include <QScopedPointer>
+#include <QSaveFile>
+#include <QQueue>
+
+#include <cstdlib>
+
+struct ScopedPointerFileCloser
+{
+ static inline void cleanup(FILE *handle) { if (handle) fclose(handle); }
+};
+
+enum RegistrationMode {
+ NoRegistration,
+ ObjectRegistration,
+ GadgetRegistration,
+ NamespaceRegistration
+};
+
+static RegistrationMode qmlTypeRegistrationMode(const QJsonObject &classDef)
+{
+ const QJsonArray classInfos = classDef[QLatin1String("classInfos")].toArray();
+ for (const QJsonValue &info: classInfos) {
+ const QString name = info[QLatin1String("name")].toString();
+ if (name == QLatin1String("QML.Element")) {
+ if (classDef[QLatin1String("object")].toBool())
+ return ObjectRegistration;
+ if (classDef[QLatin1String("gadget")].toBool())
+ return GadgetRegistration;
+ if (classDef[QLatin1String("namespace")].toBool())
+ return NamespaceRegistration;
+ qWarning() << "Not registering classInfo which is neither an object, "
+ "nor a gadget, nor a namespace:"
+ << name;
+ break;
+ }
+ }
+ return NoRegistration;
+}
+
+static QVector<QJsonObject> foreignRelatedTypes(const QVector<QJsonObject> &types,
+ const QVector<QJsonObject> &foreignTypes)
+{
+ const QLatin1String classInfosKey("classInfos");
+ const QLatin1String nameKey("name");
+ const QLatin1String qualifiedClassNameKey("qualifiedClassName");
+ const QLatin1String qmlNamePrefix("QML.");
+ const QLatin1String qmlForeignName("QML.Foreign");
+ const QLatin1String qmlAttachedName("QML.Attached");
+ const QLatin1String valueKey("value");
+ const QLatin1String superClassesKey("superClasses");
+ const QLatin1String accessKey("access");
+ const QLatin1String publicAccess("public");
+
+ QSet<QString> processedRelatedNames;
+ QQueue<QJsonObject> typeQueue;
+ typeQueue.append(types.toList());
+ QVector<QJsonObject> relatedTypes;
+
+ // First mark all classes registered from this module as already processed.
+ for (const QJsonObject &type : types) {
+ processedRelatedNames.insert(type.value(qualifiedClassNameKey).toString());
+ const auto classInfos = type.value(classInfosKey).toArray();
+ for (const QJsonValue &classInfo : classInfos) {
+ const QJsonObject obj = classInfo.toObject();
+ if (obj.value(nameKey).toString() == qmlForeignName) {
+ processedRelatedNames.insert(obj.value(valueKey).toString());
+ break;
+ }
+ }
+ }
+
+ // Then mark all classes registered from other modules as already processed.
+ // We don't want to generate them again for this module.
+ for (const QJsonObject &foreignType : foreignTypes) {
+ const auto classInfos = foreignType.value(classInfosKey).toArray();
+ bool seenQmlPrefix = false;
+ for (const QJsonValue &classInfo : classInfos) {
+ const QJsonObject obj = classInfo.toObject();
+ const QString name = obj.value(nameKey).toString();
+ if (!seenQmlPrefix && name.startsWith(qmlNamePrefix)) {
+ processedRelatedNames.insert(foreignType.value(qualifiedClassNameKey).toString());
+ seenQmlPrefix = true;
+ }
+ if (name == qmlForeignName) {
+ processedRelatedNames.insert(obj.value(valueKey).toString());
+ break;
+ }
+ }
+ }
+
+ auto addType = [&](const QString &typeName) {
+ if (processedRelatedNames.contains(typeName))
+ return;
+ processedRelatedNames.insert(typeName);
+ if (const QJsonObject *other = QmlTypesClassDescription::findType(foreignTypes, typeName)) {
+ relatedTypes.append(*other);
+ typeQueue.enqueue(*other);
+ }
+ };
+
+ // Then recursively iterate the super types and attached types, marking the
+ // ones we are interested in as related.
+ while (!typeQueue.isEmpty()) {
+ const QJsonObject classDef = typeQueue.dequeue();
+
+ const auto classInfos = classDef.value(classInfosKey).toArray();
+ for (const QJsonValue &classInfo : classInfos) {
+ const QJsonObject obj = classInfo.toObject();
+ if (obj.value(nameKey).toString() == qmlAttachedName) {
+ addType(obj.value(valueKey).toString());
+ } else if (obj.value(nameKey).toString() == qmlForeignName) {
+ const QString foreignClassName = obj.value(valueKey).toString();
+ if (const QJsonObject *other = QmlTypesClassDescription::findType(
+ foreignTypes, foreignClassName)) {
+ const auto otherSupers = other->value(superClassesKey).toArray();
+ if (!otherSupers.isEmpty()) {
+ const QJsonObject otherSuperObject = otherSupers.first().toObject();
+ if (otherSuperObject.value(accessKey).toString() == publicAccess)
+ addType(otherSuperObject.value(nameKey).toString());
+ }
+
+ const auto otherClassInfos = other->value(classInfosKey).toArray();
+ for (const QJsonValue &otherClassInfo : otherClassInfos) {
+ const QJsonObject obj = otherClassInfo.toObject();
+ if (obj.value(nameKey).toString() == qmlAttachedName) {
+ addType(obj.value(valueKey).toString());
+ break;
+ }
+ // No, you cannot chain QML_FOREIGN declarations. Sorry.
+ }
+ break;
+ }
+ }
+ }
+
+ const auto supers = classDef.value(superClassesKey).toArray();
+ if (!supers.isEmpty()) {
+ const QJsonObject superObject = supers.first().toObject();
+ if (superObject.value(accessKey).toString() == publicAccess)
+ addType(superObject.value(nameKey).toString());
+ }
+ }
+
+ return relatedTypes;
+}
+
+int main(int argc, char **argv)
+{
+ // Produce reliably the same output for the same input by disabling QHash's random seeding.
+ qSetGlobalQHashSeed(0);
+
+ QCoreApplication app(argc, argv);
+ QCoreApplication::setApplicationName(QStringLiteral("qmltyperegistrar"));
+ QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
+
+ QCommandLineParser parser;
+ parser.addHelpOption();
+ parser.addVersionOption();
+
+ QCommandLineOption outputOption(QStringLiteral("o"));
+ outputOption.setDescription(QStringLiteral("Write output to specified file."));
+ outputOption.setValueName(QStringLiteral("file"));
+ outputOption.setFlags(QCommandLineOption::ShortOptionStyle);
+ parser.addOption(outputOption);
+
+ QCommandLineOption privateIncludesOption(
+ QStringLiteral("private-includes"),
+ QStringLiteral("Include headers ending in \"_p.h\" using \"#include <private/foo_p.h>\""
+ "rather than \"#include <foo_p.h>\"."));
+ parser.addOption(privateIncludesOption);
+
+ QCommandLineOption importNameOption(QStringLiteral("import-name"));
+ importNameOption.setDescription(QStringLiteral("Name of the module to use for type and module "
+ "registrations."));
+ importNameOption.setValueName(QStringLiteral("module name"));
+ parser.addOption(importNameOption);
+
+ QCommandLineOption majorVersionOption(QStringLiteral("major-version"));
+ majorVersionOption.setDescription(QStringLiteral("Major version to use for type and module "
+ "registrations."));
+ majorVersionOption.setValueName(QStringLiteral("major version"));
+ parser.addOption(majorVersionOption);
+
+ QCommandLineOption minorVersionOption(QStringLiteral("minor-version"));
+ minorVersionOption.setDescription(QStringLiteral("Minor version to use for module "
+ "registration."));
+ minorVersionOption.setValueName(QStringLiteral("minor version"));
+ parser.addOption(minorVersionOption);
+
+ QCommandLineOption pluginTypesOption(QStringLiteral("generate-qmltypes"));
+ pluginTypesOption.setDescription(QStringLiteral("Generate qmltypes into specified file."));
+ pluginTypesOption.setValueName(QStringLiteral("qmltypes file"));
+ parser.addOption(pluginTypesOption);
+
+ QCommandLineOption foreignTypesOption(QStringLiteral("foreign-types"));
+ foreignTypesOption.setDescription(QStringLiteral(
+ "Comma separated list of other modules' metatypes files "
+ "to consult for foreign types when generating "
+ "qmltypes file."));
+ foreignTypesOption.setValueName(QStringLiteral("foreign types"));
+ parser.addOption(foreignTypesOption);
+
+ QCommandLineOption dependenciesOption(QStringLiteral("dependencies"));
+ dependenciesOption.setDescription(QStringLiteral("JSON file with dependencies to be stated in "
+ "qmltypes file."));
+ dependenciesOption.setValueName(QStringLiteral("dependencies.json"));
+ parser.addOption(dependenciesOption);
+
+ parser.addPositionalArgument(QStringLiteral("[MOC generated json file]"),
+ QStringLiteral("MOC generated json output."));
+
+ parser.process(app);
+
+ FILE *output = stdout;
+ QScopedPointer<FILE, ScopedPointerFileCloser> outputFile;
+
+ if (parser.isSet(outputOption)) {
+ QString outputName = parser.value(outputOption);
+#if defined(_MSC_VER)
+ if (_wfopen_s(&output, reinterpret_cast<const wchar_t *>(outputName.utf16()), L"w") != 0) {
+#else
+ output = fopen(QFile::encodeName(outputName).constData(), "w"); // create output file
+ if (!output) {
+#endif
+ fprintf(stderr, "Error: Cannot open %s for writing\n", qPrintable(outputName));
+ return EXIT_FAILURE;
+ }
+ outputFile.reset(output);
+ }
+
+ fprintf(output,
+ "/****************************************************************************\n"
+ "** Generated QML type registration code\n**\n");
+ fprintf(output,
+ "** WARNING! All changes made in this file will be lost!\n"
+ "*****************************************************************************/\n\n");
+ fprintf(output,
+ "#include <QtQml/qqml.h>\n"
+ "#include <QtQml/qqmlmoduleregistration.h>\n");
+
+ QStringList includes;
+ QVector<QJsonObject> types;
+ QVector<QJsonObject> foreignTypes;
+
+ const QString module = parser.value(importNameOption);
+ const QStringList files = parser.positionalArguments();
+ for (const QString &source: files) {
+ QJsonDocument metaObjects;
+ {
+ QFile f(source);
+ if (!f.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Error opening %s for reading\n", qPrintable(source));
+ return EXIT_FAILURE;
+ }
+ QJsonParseError error = {0, QJsonParseError::NoError};
+ metaObjects = QJsonDocument::fromJson(f.readAll(), &error);
+ if (error.error != QJsonParseError::NoError) {
+ fprintf(stderr, "Error parsing %s\n", qPrintable(source));
+ return EXIT_FAILURE;
+ }
+ }
+
+ const bool privateIncludes = parser.isSet(privateIncludesOption);
+ auto resolvedInclude = [&](const QString &include) {
+ return (privateIncludes && include.endsWith(QLatin1String("_p.h")))
+ ? QLatin1String("private/") + include
+ : include;
+ };
+
+ auto processMetaObject = [&](const QJsonObject &metaObject) {
+ const QString include = resolvedInclude(metaObject[QLatin1String("inputFile")].toString());
+ const QJsonArray classes = metaObject[QLatin1String("classes")].toArray();
+ for (const auto &cls : classes) {
+ QJsonObject classDef = cls.toObject();
+ classDef.insert(QLatin1String("inputFile"), include);
+
+ switch (qmlTypeRegistrationMode(classDef)) {
+ case NamespaceRegistration:
+ case GadgetRegistration:
+ case ObjectRegistration: {
+ if (!include.endsWith(QLatin1String(".h"))
+ && !include.endsWith(QLatin1String(".hpp"))
+ && !include.endsWith(QLatin1String(".hxx"))
+ && include.contains(QLatin1Char('.'))) {
+ fprintf(stderr,
+ "Class %s is declared in %s, which appears not to be a header.\n"
+ "The compilation of its registration to QML may fail.\n",
+ qPrintable(classDef.value(QLatin1String("qualifiedClassName"))
+ .toString()),
+ qPrintable(include));
+ }
+ includes.append(include);
+ classDef.insert(QLatin1String("registerable"), true);
+
+ types.append(classDef);
+ break;
+ }
+ case NoRegistration:
+ foreignTypes.append(classDef);
+ break;
+ }
+ }
+ };
+
+ if (metaObjects.isArray()) {
+ const QJsonArray metaObjectsArray = metaObjects.array();
+ for (const auto &metaObject : metaObjectsArray) {
+ if (!metaObject.isObject()) {
+ fprintf(stderr, "Error parsing %s: JSON is not an object\n",
+ qPrintable(source));
+ return EXIT_FAILURE;
+ }
+
+ processMetaObject(metaObject.toObject());
+ }
+ } else if (metaObjects.isObject()) {
+ processMetaObject(metaObjects.object());
+ } else {
+ fprintf(stderr, "Error parsing %s: JSON is not an object or an array\n",
+ qPrintable(source));
+ return EXIT_FAILURE;
+ }
+ }
+
+ const QLatin1String qualifiedClassNameKey("qualifiedClassName");
+ auto sortTypes = [&](QVector<QJsonObject> &types) {
+ std::sort(types.begin(), types.end(), [&](const QJsonObject &a, const QJsonObject &b) {
+ return a.value(qualifiedClassNameKey).toString() <
+ b.value(qualifiedClassNameKey).toString();
+ });
+ };
+
+ sortTypes(types);
+
+ std::sort(includes.begin(), includes.end());
+ const auto newEnd = std::unique(includes.begin(), includes.end());
+ includes.erase(newEnd, includes.end());
+
+ for (const QString &include : qAsConst(includes))
+ fprintf(output, "\n#include <%s>", qPrintable(include));
+
+ fprintf(output, "\n\n");
+
+ QString moduleAsSymbol = module;
+ moduleAsSymbol.replace(QLatin1Char('.'), QLatin1Char('_'));
+
+ const QString functionName = QStringLiteral("qml_register_types_") + moduleAsSymbol;
+
+ fprintf(output, "void %s()\n{", qPrintable(functionName));
+ const auto majorVersion = parser.value(majorVersionOption);
+
+ for (const QJsonObject &classDef : qAsConst(types)) {
+ if (!classDef.value(QLatin1String("registerable")).toBool())
+ continue;
+
+ const QString className = classDef[QLatin1String("qualifiedClassName")].toString();
+
+ if (classDef.value(QLatin1String("namespace")).toBool()) {
+ fprintf(output, "\n qmlRegisterNamespaceAndRevisions(&%s::staticMetaObject, \"%s\", %s);",
+ qPrintable(className), qPrintable(module), qPrintable(majorVersion));
+ } else {
+ fprintf(output, "\n qmlRegisterTypesAndRevisions<%s>(\"%s\", %s);",
+ qPrintable(className), qPrintable(module), qPrintable(majorVersion));
+ }
+ }
+
+ fprintf(output, "\n qmlRegisterModule(\"%s\", %s, %s);",
+ qPrintable(module), qPrintable(majorVersion),
+ qPrintable(parser.value(minorVersionOption)));
+ fprintf(output, "\n}\n");
+ fprintf(output, "\nstatic const QQmlModuleRegistration registration(\"%s\", %s, %s);\n",
+ qPrintable(module), qPrintable(majorVersion), qPrintable(functionName));
+
+ if (!parser.isSet(pluginTypesOption))
+ return EXIT_SUCCESS;
+
+ if (parser.isSet(foreignTypesOption)) {
+ const QStringList foreignTypesFiles = parser.value(foreignTypesOption)
+ .split(QLatin1Char(','));
+ for (const QString &types : foreignTypesFiles) {
+ QFile typesFile(types);
+ if (!typesFile.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Cannot open foreign types file %s\n", qPrintable(types));
+ continue;
+ }
+
+ QJsonParseError error = {0, QJsonParseError::NoError};
+ QJsonDocument foreignMetaObjects = QJsonDocument::fromJson(typesFile.readAll(), &error);
+ if (error.error != QJsonParseError::NoError) {
+ fprintf(stderr, "Error parsing %s\n", qPrintable(types));
+ continue;
+ }
+
+ const QJsonArray foreignObjectsArray = foreignMetaObjects.array();
+ for (const auto &metaObject : foreignObjectsArray) {
+ if (!metaObject.isObject()) {
+ fprintf(stderr, "Error parsing %s: JSON is not an object\n",
+ qPrintable(types));
+ continue;
+ }
+
+ const QString include = metaObject[QLatin1String("inputFile")].toString();
+ const QJsonArray classes = metaObject[QLatin1String("classes")].toArray();
+ for (const auto &cls : classes) {
+ QJsonObject classDef = cls.toObject();
+ classDef.insert(QLatin1String("inputFile"), include);
+ foreignTypes.append(classDef);
+ }
+ }
+ }
+ }
+
+ sortTypes(foreignTypes);
+ types += foreignRelatedTypes(types, foreignTypes);
+ sortTypes(types);
+
+ QmlTypesCreator creator;
+ creator.setOwnTypes(std::move(types));
+ creator.setForeignTypes(std::move(foreignTypes));
+ creator.setModule(module);
+ creator.setMajorVersion(parser.value(majorVersionOption).toInt());
+
+ creator.generate(parser.value(pluginTypesOption), parser.value(dependenciesOption));
+ return EXIT_SUCCESS;
+}
diff --git a/src/qmltyperegistrar/qmltyperegistrar.pro b/src/qmltyperegistrar/qmltyperegistrar.pro
new file mode 100644
index 0000000000..dff8f00ca3
--- /dev/null
+++ b/src/qmltyperegistrar/qmltyperegistrar.pro
@@ -0,0 +1,32 @@
+option(host_build)
+
+QT = core-private
+DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
+
+QMAKE_TARGET_DESCRIPTION = QML Types Registrar
+
+include(../../tools/shared/shared.pri)
+
+SOURCES += \
+ qmltyperegistrar.cpp \
+ qmltypesclassdescription.cpp \
+ qmltypescreator.cpp
+
+HEADERS += \
+ qmltypesclassdescription.h \
+ qmltypescreator.h
+
+build_integration.files = qmltypes.prf
+build_integration.path = $$[QT_HOST_DATA]/mkspecs/features
+
+prefix_build {
+ load(qt_build_paths)
+ qmltypes_to_builddir.files = qmltypes.prf
+ qmltypes_to_builddir.path = $$MODULE_BASE_OUTDIR/mkspecs/features
+ COPIES += qmltypes_to_builddir
+ INSTALLS += build_integration
+} else {
+ COPIES += build_integration
+}
+
+load(qt_tool)
diff --git a/src/qmltyperegistrar/qmltypes.prf b/src/qmltyperegistrar/qmltypes.prf
new file mode 100644
index 0000000000..0d5a6ded24
--- /dev/null
+++ b/src/qmltyperegistrar/qmltypes.prf
@@ -0,0 +1,97 @@
+CONFIG += metatypes
+
+qtPrepareTool(QML_TYPEREGISTRAR, qmltyperegistrar)
+
+isEmpty(QML_IMPORT_VERSION): \
+ QML_IMPORT_VERSION = $$IMPORT_VERSION
+
+# from moc.prf
+isEmpty(QML_IMPORT_MAJOR_VERSION):!isEmpty(QML_IMPORT_VERSION): \
+ QML_IMPORT_MAJOR_VERSION = $$section(QML_IMPORT_VERSION, ., 0, 0)
+
+isEmpty(QML_IMPORT_MINOR_VERSION):!isEmpty(QML_IMPORT_VERSION): \
+ QML_IMPORT_MINOR_VERSION = $$section(QML_IMPORT_VERSION, ., 1, 1)
+
+isEmpty(QML_IMPORT_NAME):!isEmpty(TARGETPATH) {
+ QML_IMPORT_NAME = $$replace(TARGETPATH, "/", ".")
+ QML_IMPORT_NAME = $$replace(QML_IMPORT_NAME, .$${QML_IMPORT_MAJOR_VERSION}$, '')
+}
+
+isEmpty(QML_IMPORT_NAME) {
+ error("Need TARGET_PATH or QML_IMPORT_NAME in order to generate qml types.");
+}
+
+isEmpty(QML_IMPORT_MAJOR_VERSION) {
+ error("Need IMPORT_VERSION, QML_IMPORT_VERSION, or QML_IMPORT_MAJOR_VERSION in order to generate qml types.");
+}
+
+isEmpty(QML_IMPORT_MINOR_VERSION) {
+ QML_IMPORT_MINOR_VERSION = 0
+}
+
+isEmpty(QMLTYPES_FILENAME) {
+ plugin: QMLTYPES_FILENAME = plugins.qmltypes
+ else: QMLTYPES_FILENAME = $${TARGET}.qmltypes
+}
+
+qt_module_deps = $$replace(QT, -private$, '')
+qt_module_deps += $$replace(QT_PRIVATE, -private$, '')
+qt_module_deps = $$resolve_depends(qt_module_deps, "QT.", ".depends" ".run_depends")
+qt_module_deps = $$replace(qt_module_deps, _private$, '')
+qt_module_deps = $$unique(qt_module_deps)
+
+for(dep, qt_module_deps) {
+ METATYPES_FILENAME = $$lower($$eval(QT.$${dep}.module))_metatypes.json
+ INSTALLED_METATYPES = $$[QT_INSTALL_LIBS]/metatypes/$$METATYPES_FILENAME
+ isEmpty(MODULE_BASE_OUTDIR) {
+ QML_FOREIGN_METATYPES += $$INSTALLED_METATYPES
+ } else {
+ MODULE_BASE_METATYPES = $$MODULE_BASE_OUTDIR/lib/metatypes/$$METATYPES_FILENAME
+ exists($$MODULE_BASE_METATYPES): QML_FOREIGN_METATYPES += $$MODULE_BASE_METATYPES
+ else: QML_FOREIGN_METATYPES += $$INSTALLED_METATYPES
+ }
+}
+
+
+QML_TYPEREGISTRAR_FLAGS = \
+ --generate-qmltypes=$$QMLTYPES_FILENAME \
+ --import-name=$$QML_IMPORT_NAME \
+ --major-version=$$QML_IMPORT_MAJOR_VERSION \
+ --minor-version=$$QML_IMPORT_MINOR_VERSION \
+ --foreign-types=$$join(QML_FOREIGN_METATYPES, ',')
+
+DEPENDENCIESFILE = $$_PRO_FILE_PWD_/dependencies.json
+exists($$DEPENDENCIESFILE): QML_TYPEREGISTRAR_FLAGS += --dependencies=$$DEPENDENCIESFILE
+
+!isEmpty(MODULE_PRIVATE_INCLUDES): QML_TYPEREGISTRAR_FLAGS += --private-includes
+
+METATYPES_JSON = $$lower($$basename(TARGET))_metatypes.json
+
+TYPEREGISTRATIONS = $$lower($$basename(TARGET))_qmltyperegistrations$${first(QMAKE_EXT_CPP)}
+
+qmltyperegistrar_compiler.CONFIG += combine
+qmltyperegistrar_compiler.commands = \
+ $$QML_TYPEREGISTRAR $$QML_TYPEREGISTRAR_FLAGS -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
+qmltyperegistrar_compiler.input = METATYPES_JSON
+qmltyperegistrar_compiler.output = $$TYPEREGISTRATIONS
+qmltyperegistrar_compiler.variable_out = SOURCES
+qmltyperegistrar_compiler.name = Automatic QML type registration
+qmltyperegistrar_compiler.dependency_type = TYPE_C
+
+qmltyperegistrar_qmltypes.input = METATYPES_JSON
+qmltyperegistrar_qmltypes.depends = $$TYPEREGISTRATIONS
+qmltyperegistrar_qmltypes.output = $$QMLTYPES_FILENAME
+qmltyperegistrar_qmltypes.CONFIG = no_link
+qmltyperegistrar_qmltypes.commands = $$escape_expand(\\n) # force creation of rule
+
+install_qmltypes {
+ isEmpty(QMLTYPES_INSTALL_DIR): \
+ QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/$$TARGETPATH
+ do_install_qmltypes.files = $$OUT_PWD/$$QMLTYPES_FILENAME
+ do_install_qmltypes.path = $$QMLTYPES_INSTALL_DIR
+ do_install_qmltypes.CONFIG += no_check_exist
+ prefix_build: INSTALLS += do_install_qmltypes
+ else: COPIES += do_install_qmltypes
+}
+
+QMAKE_EXTRA_COMPILERS += qmltyperegistrar_compiler qmltyperegistrar_qmltypes
diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp
new file mode 100644
index 0000000000..9aadd75acc
--- /dev/null
+++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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: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$
+**
+****************************************************************************/
+
+#include "qmltypesclassdescription.h"
+
+#include <QtCore/qjsonarray.h>
+
+static void collectExtraVersions(const QJsonObject *component, const QString &key,
+ QList<int> &extraVersions)
+{
+ const QJsonArray &items = component->value(key).toArray();
+ for (const QJsonValue &item : items) {
+ const QJsonObject obj = item.toObject();
+ const auto revision = obj.find(QLatin1String("revision"));
+ if (revision != obj.end()) {
+ const int extraVersion = revision.value().toInt();
+ if (!extraVersions.contains(extraVersion))
+ extraVersions.append(extraVersion);
+ }
+ }
+}
+
+const QJsonObject *QmlTypesClassDescription::findType(const QVector<QJsonObject> &types,
+ const QString &name)
+{
+ static const QLatin1String qualifiedClassNameKey("qualifiedClassName");
+ auto it = std::lower_bound(types.begin(), types.end(), name,
+ [&](const QJsonObject &type, const QString &typeName) {
+ return type.value(qualifiedClassNameKey).toString() < typeName;
+ });
+
+ return (it != types.end() && it->value(qualifiedClassNameKey) == name) ? &(*it) : nullptr;
+}
+
+void QmlTypesClassDescription::collect(const QJsonObject *classDef,
+ const QVector<QJsonObject> &types,
+ const QVector<QJsonObject> &foreign,
+ CollectMode mode)
+{
+ const QJsonObject *origClassDef = classDef; // if we find QML.Foreign, classDef changes.
+ if (file.isEmpty() && classDef->value(QLatin1String("registerable")).toBool())
+ file = classDef->value(QLatin1String("inputFile")).toString();
+ const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray();
+ for (const QJsonValue &classInfo : classInfos) {
+ const QJsonObject obj = classInfo.toObject();
+ const QString name = obj[QLatin1String("name")].toString();
+ const QString value = obj[QLatin1String("value")].toString();
+
+ if (name == QLatin1String("DefaultProperty")) {
+ if (mode != AttachedType && defaultProp.isEmpty())
+ defaultProp = value;
+ } else if (name == QLatin1String("QML.AddedInMinorVersion")) {
+ if (mode == TopLevel) {
+ addedInRevision = value.toInt();
+ revisions.append(value.toInt());
+ } else if (!elementName.isEmpty()) {
+ revisions.append(value.toInt());
+ }
+ }
+
+ if (mode != TopLevel)
+ continue;
+
+ // These only apply to the original class
+ if (name == QLatin1String("QML.Element")) {
+ if (value == QLatin1String("auto"))
+ elementName = classDef->value(QLatin1String("className")).toString();
+ else if (value != QLatin1String("anonymous"))
+ elementName = value;
+ } else if (name == QLatin1String("QML.RemovedInMinorVersion")) {
+ removedInRevision = value.toInt();
+ } else if (name == QLatin1String("QML.Creatable")) {
+ isCreatable = (value != QLatin1String("false"));
+ } else if (name == QLatin1String("QML.Attached")) {
+ collectAttached(value, types, foreign);
+ } else if (name == QLatin1String("QML.Singleton")) {
+ if (value == QLatin1String("true"))
+ isSingleton = true;
+ } else if (name == QLatin1String("QML.Foreign")) {
+ if (const QJsonObject *other = findType(foreign, value)) {
+ classDef = other;
+ // Foreign type can have a default property or an attached types
+ const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray();
+ for (const QJsonValue &classInfo : classInfos) {
+ const QJsonObject obj = classInfo.toObject();
+ const QString foreignName = obj[QLatin1String("name")].toString();
+ const QString foreignValue = obj[QLatin1String("value")].toString();
+ if (defaultProp.isEmpty() && foreignName == QLatin1String("DefaultProperty"))
+ defaultProp = foreignValue;
+ else if (foreignName == QLatin1String("QML.Attached"))
+ collectAttached(foreignValue, types, foreign);
+ }
+ }
+ } else if (name == QLatin1String("QML.Root")) {
+ isRootClass = true;
+ isBuiltin = true;
+ } else if (name == QLatin1String("QML.Builtin")) {
+ isBuiltin = true;
+ }
+ }
+
+ if (mode == AttachedType || !elementName.isEmpty()) {
+ collectExtraVersions(classDef, QString::fromLatin1("properties"), revisions);
+ collectExtraVersions(classDef, QString::fromLatin1("slots"), revisions);
+ collectExtraVersions(classDef, QString::fromLatin1("methods"), revisions);
+ collectExtraVersions(classDef, QString::fromLatin1("signals"), revisions);
+ }
+
+ auto supers = classDef->value(QLatin1String("superClasses")).toArray();
+ if (classDef != origClassDef) {
+ const QJsonArray origSupers = origClassDef->value(QLatin1String("superClasses")).toArray();
+ for (const QJsonValue &origSuper : origSupers)
+ supers.append(origSuper);
+ }
+
+ for (const QJsonValue &superValue : qAsConst(supers)) {
+ const QJsonObject superObject = superValue.toObject();
+ if (superObject[QLatin1String("access")].toString() == QLatin1String("public")) {
+ const QString superName = superObject[QLatin1String("name")].toString();
+
+ if (const QJsonObject *other = findType(types, superName))
+ collect(other, types, foreign, mode == TopLevel ? SuperClass : AttachedType);
+ else if (const QJsonObject *other = findType(foreign, superName))
+ collect(other, types, foreign, mode == TopLevel ? SuperClass : AttachedType);
+ else // If we cannot locate a type for it, there is no point in recording the superClass
+ continue;
+
+ if (mode == TopLevel && superClass.isEmpty())
+ superClass = superName;
+ }
+ }
+
+ if (mode != TopLevel)
+ return;
+
+ if (addedInRevision == -1) {
+ revisions.append(0);
+ addedInRevision = 0;
+ }
+
+ std::sort(revisions.begin(), revisions.end(),
+ [](int a, int b) { return QByteArray::number(a) < QByteArray::number(b); });
+ const auto end = std::unique(revisions.begin(), revisions.end());
+ revisions.erase(end, revisions.end());
+
+ resolvedClass = classDef;
+
+ // If it's not a QObject, it's not creatable
+ isCreatable = isCreatable && classDef->value(QLatin1String("object")).toBool();
+}
+
+void QmlTypesClassDescription::collectAttached(const QString &attached,
+ const QVector<QJsonObject> &types,
+ const QVector<QJsonObject> &foreign)
+{
+ attachedType = attached;
+ if (const QJsonObject *other = findType(types, attachedType))
+ collect(other, types, foreign, AttachedType);
+ else if (const QJsonObject *other = findType(foreign, attachedType))
+ collect(other, types, foreign, AttachedType);
+}
diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h
new file mode 100644
index 0000000000..32313a490d
--- /dev/null
+++ b/src/qmltyperegistrar/qmltypesclassdescription.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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: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 QMLTYPESCLASSDESCRIPTION_H
+#define QMLTYPESCLASSDESCRIPTION_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qjsonobject.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qset.h>
+
+struct QmlTypesClassDescription
+{
+ const QJsonObject *resolvedClass = nullptr;
+ QString file;
+ QString elementName;
+ QString defaultProp;
+ QString superClass;
+ QString attachedType;
+ QList<int> revisions;
+ int addedInRevision = -1;
+ int removedInRevision = -1;
+ bool isCreatable = true;
+ bool isSingleton = false;
+ bool isRootClass = false;
+ bool isBuiltin = false;
+
+ enum CollectMode {
+ TopLevel,
+ SuperClass,
+ AttachedType
+ };
+
+ void collect(const QJsonObject *classDef, const QVector<QJsonObject> &types,
+ const QVector<QJsonObject> &foreign, CollectMode mode);
+ void collectAttached(const QString &attached, const QVector<QJsonObject> &types,
+ const QVector<QJsonObject> &foreign);
+
+ static const QJsonObject *findType(const QVector<QJsonObject> &types, const QString &name);
+};
+
+#endif // QMLTYPESCLASSDESCRIPTION_H
diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp
new file mode 100644
index 0000000000..e74550c6c2
--- /dev/null
+++ b/src/qmltyperegistrar/qmltypescreator.cpp
@@ -0,0 +1,381 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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: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$
+**
+****************************************************************************/
+
+#include "qmltypescreator.h"
+#include "qmlstreamwriter.h"
+#include "qmltypesclassdescription.h"
+
+#include <QtCore/qset.h>
+#include <QtCore/qjsonarray.h>
+#include <QtCore/qsavefile.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qjsondocument.h>
+
+static QString enquote(const QString &string)
+{
+ QString s = string;
+ return QString::fromLatin1("\"%1\"").arg(s.replace(QLatin1Char('\\'), QLatin1String("\\\\"))
+ .replace(QLatin1Char('"'),QLatin1String("\\\"")));
+}
+
+void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &collector)
+{
+ if (!collector.file.isEmpty())
+ m_qml.writeScriptBinding(QLatin1String("file"), enquote(collector.file));
+ m_qml.writeScriptBinding(
+ QLatin1String("name"),
+ enquote(collector.resolvedClass->value(
+ QLatin1String("qualifiedClassName")).toString()));
+
+ if (!collector.defaultProp.isEmpty())
+ m_qml.writeScriptBinding(QLatin1String("defaultProperty"), enquote(collector.defaultProp));
+
+ if (!collector.superClass.isEmpty())
+ m_qml.writeScriptBinding(QLatin1String("prototype"), enquote(collector.superClass));
+
+ if (collector.elementName.isEmpty())
+ return;
+
+ QStringList exports;
+ QStringList metaObjects;
+
+ for (auto it = collector.revisions.begin(), end = collector.revisions.end(); it != end; ++it) {
+ const int revision = *it;
+ if (revision < collector.addedInRevision)
+ continue;
+ if (collector.removedInRevision > collector.addedInRevision
+ && revision >= collector.removedInRevision) {
+ break;
+ }
+
+ if (collector.isBuiltin) {
+ exports.append(enquote(QString::fromLatin1("QML/%1 1.0").arg(collector.elementName)));
+ metaObjects.append(QLatin1String("0"));
+ }
+
+ exports.append(enquote(QString::fromLatin1("%1/%2 %3.%4")
+ .arg(m_module).arg(collector.elementName)
+ .arg(m_majorVersion).arg(revision)));
+ metaObjects.append(QString::number(revision));
+ }
+
+ m_qml.writeArrayBinding(QLatin1String("exports"), exports);
+
+ if (!collector.isCreatable || collector.isSingleton)
+ m_qml.writeScriptBinding(QLatin1String("isCreatable"), QLatin1String("false"));
+
+ if (collector.isSingleton)
+ m_qml.writeScriptBinding(QLatin1String("isSingleton"), QLatin1String("true"));
+
+ m_qml.writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), metaObjects);
+
+ if (!collector.attachedType.isEmpty())
+ m_qml.writeScriptBinding(QLatin1String("attachedType"), enquote(collector.attachedType));
+}
+
+void QmlTypesCreator::writeType(const QJsonObject &property, const QString &key, bool isReadonly,
+ bool parsePointer)
+{
+ auto it = property.find(key);
+ if (it == property.end())
+ return;
+
+ QString type = (*it).toString();
+ if (type.isEmpty() || type == QLatin1String("void"))
+ return;
+
+ const QLatin1String typeKey("type");
+
+ bool isList = false;
+ bool isPointer = false;
+
+ if (type == QLatin1String("QString")) {
+ type = QLatin1String("string");
+ } else if (type == QLatin1String("qreal")) {
+ type = QLatin1String("double");
+ } else if (type == QLatin1String("qint32")) {
+ type = QLatin1String("int");
+ } else if (type == QLatin1String("quint32")) {
+ type = QLatin1String("uint");
+ } else if (type == QLatin1String("qint64")) {
+ type = QLatin1String("qlonglong");
+ } else if (type == QLatin1String("quint64")) {
+ type = QLatin1String("qulonglong");
+ } else {
+
+ const QLatin1String listProperty("QQmlListProperty<");
+ if (type.startsWith(listProperty)) {
+ isList = true;
+ const int listPropertySize = listProperty.size();
+ type = type.mid(listPropertySize, type.size() - listPropertySize - 1);
+ }
+
+ if (parsePointer && type.endsWith(QLatin1Char('*'))) {
+ isPointer = true;
+ type = type.left(type.size() - 1);
+ }
+ }
+
+ m_qml.writeScriptBinding(typeKey, enquote(type));
+ const QLatin1String trueString("true");
+ if (isList)
+ m_qml.writeScriptBinding(QLatin1String("isList"), trueString);
+ if (isReadonly)
+ m_qml.writeScriptBinding(QLatin1String("isReadonly"), trueString);
+ if (isPointer)
+ m_qml.writeScriptBinding(QLatin1String("isPointer"), trueString);
+}
+
+void QmlTypesCreator::writeProperties(const QJsonArray &properties, QSet<QString> &notifySignals)
+{
+ for (const QJsonValue &property : properties) {
+ const QJsonObject obj = property.toObject();
+ const QString name = obj[QLatin1String("name")].toString();
+ m_qml.writeStartObject(QLatin1String("Property"));
+ m_qml.writeScriptBinding(QLatin1String("name"), enquote(name));
+ const auto it = obj.find(QLatin1String("revision"));
+ if (it != obj.end())
+ m_qml.writeScriptBinding(QLatin1String("revision"), QString::number(it.value().toInt()));
+ writeType(obj, QLatin1String("type"), !obj.contains(QLatin1String("write")), true);
+ m_qml.writeEndObject();
+
+ const QString notify = obj[QLatin1String("notify")].toString();
+ if (notify == name + QLatin1String("Changed"))
+ notifySignals.insert(notify);
+ }
+}
+
+void QmlTypesCreator::writeMethods(const QJsonArray &methods, const QString &type,
+ const QSet<QString> &notifySignals)
+{
+ for (const QJsonValue &method : methods) {
+ const QJsonObject obj = method.toObject();
+ const QString name = obj[QLatin1String("name")].toString();
+ if (name.isEmpty())
+ continue;
+ const QJsonArray arguments = method[QLatin1String("arguments")].toArray();
+ const auto revision = obj.find(QLatin1String("revision"));
+ if (notifySignals.contains(name) && arguments.isEmpty() && revision == obj.end())
+ continue;
+ m_qml.writeStartObject(type);
+ m_qml.writeScriptBinding(QLatin1String("name"), enquote(name));
+ if (revision != obj.end())
+ m_qml.writeScriptBinding(QLatin1String("revision"), QString::number(revision.value().toInt()));
+ writeType(obj, QLatin1String("returnType"), false, false);
+ for (const QJsonValue &argument : arguments) {
+ const QJsonObject obj = argument.toObject();
+ m_qml.writeStartObject(QLatin1String("Parameter"));
+ const QString name = obj[QLatin1String("name")].toString();
+ if (!name.isEmpty())
+ m_qml.writeScriptBinding(QLatin1String("name"), enquote(name));
+ writeType(obj, QLatin1String("type"), false, true);
+ m_qml.writeEndObject();
+ }
+ m_qml.writeEndObject();
+ }
+}
+
+void QmlTypesCreator::writeEnums(const QJsonArray &enums)
+{
+ for (const auto &item : enums) {
+ const QJsonObject obj = item.toObject();
+ const QJsonArray values = obj.value(QLatin1String("values")).toArray();
+ QStringList valueList;
+
+ for (const QJsonValue &value : values)
+ valueList.append(enquote(value.toString()));
+
+ m_qml.writeStartObject(QLatin1String("Enum"));
+ m_qml.writeScriptBinding(QLatin1String("name"),
+ enquote(obj.value(QLatin1String("name")).toString()));
+ auto alias = obj.find(QLatin1String("alias"));
+ if (alias != obj.end())
+ m_qml.writeScriptBinding(alias.key(), enquote(alias->toString()));
+ auto isFlag = obj.find(QLatin1String("isFlag"));
+ if (isFlag != obj.end() && isFlag->toBool())
+ m_qml.writeBooleanBinding(isFlag.key(), true);
+ m_qml.writeArrayBinding(QLatin1String("values"), valueList);
+ m_qml.writeEndObject();
+ }
+}
+
+static QJsonArray members(const QJsonObject *classDef, const QJsonObject *origClassDef, const QString &key)
+{
+ QJsonArray classDefMembers = classDef->value(key).toArray();
+
+ if (classDef != origClassDef) {
+ const QJsonArray origClassDefMembers = origClassDef->value(key).toArray();
+ for (const auto &member : origClassDefMembers)
+ classDefMembers.append(member);
+ }
+
+ return classDefMembers;
+}
+
+void QmlTypesCreator::writeComponents()
+{
+ const QLatin1String nameKey("name");
+ const QLatin1String signalsKey("signals");
+ const QLatin1String enumsKey("enums");
+ const QLatin1String propertiesKey("properties");
+ const QLatin1String slotsKey("slots");
+ const QLatin1String methodsKey("methods");
+ const QLatin1String accessKey("access");
+ const QLatin1String typeKey("type");
+ const QLatin1String argumentsKey("arguments");
+
+ const QLatin1String destroyedName("destroyed");
+ const QLatin1String deleteLaterName("deleteLater");
+ const QLatin1String toStringName("toString");
+ const QLatin1String destroyName("destroy");
+ const QLatin1String delayName("delay");
+
+ const QLatin1String signalElement("Signal");
+ const QLatin1String componentElement("Component");
+ const QLatin1String methodElement("Method");
+
+ const QLatin1String publicAccess("public");
+ const QLatin1String intType("int");
+
+ for (const QJsonObject &component : m_ownTypes) {
+ m_qml.writeStartObject(componentElement);
+
+ QmlTypesClassDescription collector;
+ collector.collect(&component, m_ownTypes, m_foreignTypes,
+ QmlTypesClassDescription::TopLevel);
+
+ writeClassProperties(collector);
+
+ const QJsonObject *classDef = collector.resolvedClass;
+ writeEnums(members(classDef, &component, enumsKey));
+
+ QSet<QString> notifySignals;
+ writeProperties(members(classDef, &component, propertiesKey), notifySignals);
+
+ if (collector.isRootClass) {
+
+ // Hide destroyed() signals
+ QJsonArray componentSignals = members(classDef, &component, signalsKey);
+ for (auto it = componentSignals.begin(); it != componentSignals.end();) {
+ if (it->toObject().value(nameKey).toString() == destroyedName)
+ it = componentSignals.erase(it);
+ else
+ ++it;
+ }
+ writeMethods(componentSignals, signalElement, notifySignals);
+
+ // Hide deleteLater() methods
+ QJsonArray componentMethods = members(classDef, &component, methodsKey);
+ const QJsonArray componentSlots = members(classDef, &component, slotsKey);
+ for (const QJsonValue &componentSlot : componentSlots)
+ componentMethods.append(componentSlot);
+ for (auto it = componentMethods.begin(); it != componentMethods.end();) {
+ if (it->toObject().value(nameKey).toString() == deleteLaterName)
+ it = componentMethods.erase(it);
+ else
+ ++it;
+ }
+
+ // Add toString()
+ QJsonObject toStringMethod;
+ toStringMethod.insert(nameKey, toStringName);
+ toStringMethod.insert(accessKey, publicAccess);
+ componentMethods.append(toStringMethod);
+
+ // Add destroy()
+ QJsonObject destroyMethod;
+ destroyMethod.insert(nameKey, destroyName);
+ destroyMethod.insert(accessKey, publicAccess);
+ componentMethods.append(destroyMethod);
+
+ // Add destroy(int)
+ QJsonObject destroyMethodWithArgument;
+ destroyMethodWithArgument.insert(nameKey, destroyName);
+ destroyMethodWithArgument.insert(accessKey, publicAccess);
+ QJsonObject delayArgument;
+ delayArgument.insert(nameKey, delayName);
+ delayArgument.insert(typeKey, intType);
+ QJsonArray destroyArguments;
+ destroyArguments.append(delayArgument);
+ destroyMethodWithArgument.insert(argumentsKey, destroyArguments);
+ componentMethods.append(destroyMethodWithArgument);
+
+ writeMethods(componentMethods, methodElement);
+ } else {
+ writeMethods(members(classDef, &component, signalsKey), signalElement, notifySignals);
+ writeMethods(members(classDef, &component, slotsKey), methodElement);
+ writeMethods(members(classDef, &component, methodsKey), methodElement);
+ }
+ m_qml.writeEndObject();
+ }
+}
+
+void QmlTypesCreator::generate(const QString &outFileName, const QString &dependenciesFileName)
+{
+ m_qml.writeStartDocument();
+ m_qml.writeLibraryImport(QLatin1String("QtQuick.tooling"), 1, 2);
+ m_qml.write(QString::fromLatin1(
+ "\n// This file describes the plugin-supplied types contained in the library."
+ "\n// It is used for QML tooling purposes only."
+ "\n//"
+ "\n// This file was auto-generated by qmltyperegistrar.\n\n"));
+ m_qml.writeStartObject(QLatin1String("Module"));
+
+ QStringList dependencies;
+ if (!dependenciesFileName.isEmpty()) {
+ QFile file(dependenciesFileName);
+ if (!file.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Failed to open %s\n", qPrintable(dependenciesFileName));
+ } else {
+ QJsonParseError error { -1, QJsonParseError::NoError };
+ QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error);
+ if (error.error != QJsonParseError::NoError) {
+ fprintf(stderr, "Failed to parse %s\n", qPrintable(dependenciesFileName));
+ } else {
+ const QJsonArray array = doc.array();
+ for (const QJsonValue &value : array)
+ dependencies.append(enquote(value.toString()));
+ }
+ }
+ } else {
+ // Default dependency is QtQuick 2.0
+ dependencies.append(enquote(QLatin1String("QtQuick 2.0")));
+ }
+
+ m_qml.writeArrayBinding(QLatin1String("dependencies"), dependencies);
+
+ writeComponents();
+
+ m_qml.writeEndObject();
+
+ QSaveFile file(outFileName);
+ file.open(QIODevice::WriteOnly);
+ file.write(m_output);
+ file.commit();
+}
+
diff --git a/src/qmltyperegistrar/qmltypescreator.h b/src/qmltyperegistrar/qmltypescreator.h
new file mode 100644
index 0000000000..9207a64b7e
--- /dev/null
+++ b/src/qmltyperegistrar/qmltypescreator.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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: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 QMLTYPESCREATOR_H
+#define QMLTYPESCREATOR_H
+
+#include "qmlstreamwriter.h"
+#include "qmltypesclassdescription.h"
+
+#include <QtCore/qstring.h>
+#include <QtCore/qset.h>
+
+class QmlTypesCreator
+{
+public:
+ QmlTypesCreator() : m_qml(&m_output) {}
+
+ void generate(const QString &outFileName, const QString &dependenciesFileName);
+
+ void setOwnTypes(QVector<QJsonObject> ownTypes) { m_ownTypes = std::move(ownTypes); }
+ void setForeignTypes(QVector<QJsonObject> foreignTypes) { m_foreignTypes = std::move(foreignTypes); }
+ void setModule(QString module) { m_module = std::move(module); }
+ void setMajorVersion(int majorVersion) { m_majorVersion = majorVersion; }
+
+private:
+ void writeClassProperties(const QmlTypesClassDescription &collector);
+ void writeType(const QJsonObject &property, const QString &key, bool isReadonly,
+ bool parsePointer);
+ void writeProperties(const QJsonArray &properties, QSet<QString> &notifySignals);
+ void writeMethods(const QJsonArray &methods, const QString &type,
+ const QSet<QString> &notifySignals = QSet<QString>());
+ void writeEnums(const QJsonArray &enums);
+ void writeComponents();
+
+ QByteArray m_output;
+ QmlStreamWriter m_qml;
+ QVector<QJsonObject> m_ownTypes;
+ QVector<QJsonObject> m_foreignTypes;
+ QString m_module;
+ int m_majorVersion = 0;
+};
+
+#endif // QMLTYPESCREATOR_H
diff --git a/src/imports/workerscript/dependencies.json b/src/qmlworkerscript/dependencies.json
index 0d4f101c7a..0d4f101c7a 100644
--- a/src/imports/workerscript/dependencies.json
+++ b/src/qmlworkerscript/dependencies.json
diff --git a/src/qmlworkerscript/qmlworkerscript.pro b/src/qmlworkerscript/qmlworkerscript.pro
index 9f5e0e809a..84466062e1 100644
--- a/src/qmlworkerscript/qmlworkerscript.pro
+++ b/src/qmlworkerscript/qmlworkerscript.pro
@@ -19,4 +19,10 @@ SOURCES += \
include(../3rdparty/masm/masm-defs.pri)
+QMLTYPES_FILENAME = plugins.qmltypes
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/WorkerScript.2
+QML_IMPORT_NAME = QtQml.WorkerScript
+IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+CONFIG += qmltypes install_qmltypes install_metatypes
+
load(qt_module)
diff --git a/src/qmlworkerscript/qqmlworkerscriptmodule.cpp b/src/qmlworkerscript/qqmlworkerscriptmodule.cpp
index 98e82dbeba..f6ad5b87e8 100644
--- a/src/qmlworkerscript/qqmlworkerscriptmodule.cpp
+++ b/src/qmlworkerscript/qqmlworkerscriptmodule.cpp
@@ -47,16 +47,11 @@ QT_BEGIN_NAMESPACE
void QQmlWorkerScriptModule::registerQuickTypes()
{
// Don't add anything here. These are only for backwards compatibility.
+ // Also, don't convert to qmlRegisterTypesAndRevisions as that will add future revisions.
const char uri[] = "QtQuick";
qmlRegisterType<QQuickWorkerScript>(uri, 2, 0, "WorkerScript");
}
#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-void QQmlWorkerScriptModule::defineModule()
-{
- const char uri[] = "QtQml.WorkerScript";
- qmlRegisterType<QQuickWorkerScript>(uri, 2, 0, "WorkerScript");
-}
-
QT_END_NAMESPACE
diff --git a/src/qmlworkerscript/qqmlworkerscriptmodule_p.h b/src/qmlworkerscript/qqmlworkerscriptmodule_p.h
index a2efb304c1..b7748d12a0 100644
--- a/src/qmlworkerscript/qqmlworkerscriptmodule_p.h
+++ b/src/qmlworkerscript/qqmlworkerscriptmodule_p.h
@@ -61,7 +61,6 @@ public:
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
static void registerQuickTypes();
#endif
- static void defineModule();
};
QT_END_NAMESPACE
diff --git a/src/qmlworkerscript/qquickworkerscript.cpp b/src/qmlworkerscript/qquickworkerscript.cpp
index 635d508daf..20294d7ba7 100644
--- a/src/qmlworkerscript/qquickworkerscript.cpp
+++ b/src/qmlworkerscript/qquickworkerscript.cpp
@@ -548,6 +548,17 @@ void QQuickWorkerScript::setSource(const QUrl &source)
}
/*!
+ \qmlproperty bool WorkerScript::ready
+
+ This holds whether the WorkerScript has been initialized and is ready
+ for receiving messages via \tt WorkerScript.sendMessage().
+*/
+bool QQuickWorkerScript::ready() const
+{
+ return m_engine != nullptr;
+}
+
+/*!
\qmlmethod WorkerScript::sendMessage(jsobject message)
Sends the given \a message to a worker script handler in another
@@ -607,6 +618,8 @@ QQuickWorkerScriptEngine *QQuickWorkerScript::engine()
if (m_source.isValid())
m_engine->executeUrl(m_scriptId, m_source);
+ emit readyChanged();
+
return m_engine;
}
return nullptr;
@@ -623,8 +636,6 @@ void QQuickWorkerScript::componentComplete()
This signal is emitted when a message \a msg is received from a worker
script in another thread through a call to sendMessage().
-
- The corresponding handler is \c onMessage.
*/
bool QQuickWorkerScript::event(QEvent *event)
diff --git a/src/qmlworkerscript/qquickworkerscript_p.h b/src/qmlworkerscript/qquickworkerscript_p.h
index 87cf2e9754..e56ce84b6d 100644
--- a/src/qmlworkerscript/qquickworkerscript_p.h
+++ b/src/qmlworkerscript/qquickworkerscript_p.h
@@ -53,6 +53,7 @@
#include <qqml.h>
+#include <QtQmlWorkerScript/private/qtqmlworkerscriptglobal_p.h>
#include <QtQml/qqmlparserstatus.h>
#include <QtCore/qthread.h>
#include <QtQml/qjsvalue.h>
@@ -87,6 +88,9 @@ class Q_AUTOTEST_EXPORT QQuickWorkerScript : public QObject, public QQmlParserSt
{
Q_OBJECT
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(bool ready READ ready NOTIFY readyChanged REVISION 15)
+
+ QML_NAMED_ELEMENT(WorkerScript);
Q_INTERFACES(QQmlParserStatus)
public:
@@ -96,11 +100,14 @@ public:
QUrl source() const;
void setSource(const QUrl &);
+ bool ready() const;
+
public Q_SLOTS:
void sendMessage(QQmlV4Function*);
Q_SIGNALS:
void sourceChanged();
+ Q_REVISION(15) void readyChanged();
void message(const QJSValue &messageObject);
protected:
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/qmlworkerscript/qv4serialize.cpp b/src/qmlworkerscript/qv4serialize.cpp
index a5e62d3e35..f0a644a8b8 100644
--- a/src/qmlworkerscript/qv4serialize.cpp
+++ b/src/qmlworkerscript/qv4serialize.cpp
@@ -81,6 +81,7 @@ enum Type {
WorkerDate,
WorkerRegexp,
WorkerListModel,
+ WorkerUrl,
#if QT_CONFIG(qml_sequence_object)
WorkerSequence
#endif
@@ -142,10 +143,29 @@ static inline void *popPtr(const char *&data)
return rv;
}
+#define ALIGN(size) (((size) + 3) & ~3)
+static inline void serializeString(QByteArray &data, const QString &str, Type type)
+{
+ int length = str.length();
+ if (length > 0xFFFFFF) {
+ push(data, valueheader(WorkerUndefined));
+ return;
+ }
+ int utf16size = ALIGN(length * sizeof(quint16));
+
+ reserve(data, utf16size + sizeof(quint32));
+ push(data, valueheader(type, length));
+
+ int offset = data.size();
+ data.resize(data.size() + utf16size);
+ char *buffer = data.data() + offset;
+
+ memcpy(buffer, str.constData(), length*sizeof(QChar));
+}
+
// XXX TODO: Check that worker script is exception safe in the case of
// serialization/deserialization failures
-#define ALIGN(size) (((size) + 3) & ~3)
void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine *engine)
{
QV4::Scope scope(engine);
@@ -159,22 +179,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
} else if (v.isBoolean()) {
push(data, valueheader(v.booleanValue() == true ? WorkerTrue : WorkerFalse));
} else if (v.isString()) {
- const QString &qstr = v.toQString();
- int length = qstr.length();
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- int utf16size = ALIGN(length * sizeof(quint16));
-
- reserve(data, utf16size + sizeof(quint32));
- push(data, valueheader(WorkerString, length));
-
- int offset = data.size();
- data.resize(data.size() + utf16size);
- char *buffer = data.data() + offset;
-
- memcpy(buffer, qstr.constData(), length*sizeof(QChar));
+ serializeString(data, v.toQString(), WorkerString);
} else if (v.as<FunctionObject>()) {
// XXX TODO: Implement passing function objects between the main and
// worker scripts
@@ -259,6 +264,11 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
return;
}
#endif
+ const QVariant variant = engine->toVariant(v, QMetaType::QUrl, false);
+ if (variant.userType() == QMetaType::QUrl) {
+ serializeString(data, variant.value<QUrl>().toString(), WorkerUrl);
+ return;
+ }
// regular object
QV4::ScopedValue val(scope, v);
@@ -340,11 +350,14 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine)
case WorkerFalse:
return QV4::Encode(false);
case WorkerString:
+ case WorkerUrl:
{
quint32 size = headersize(header);
QString qstr((const QChar *)data, size);
data += ALIGN(size * sizeof(quint16));
- return QV4::Encode(engine->newString(qstr));
+ return (type == WorkerUrl)
+ ? engine->fromVariant(QVariant::fromValue(QUrl(qstr)))
+ : Encode(engine->newString(qstr));
}
case WorkerFunction:
Q_ASSERT(!"Unreachable");
diff --git a/src/quick/dependencies.json b/src/quick/dependencies.json
new file mode 100644
index 0000000000..fe51488c70
--- /dev/null
+++ b/src/quick/dependencies.json
@@ -0,0 +1 @@
+[]
diff --git a/src/quick/designer/qqmldesignermetaobject.cpp b/src/quick/designer/qqmldesignermetaobject.cpp
index de7da7f9be..0aa5dc2613 100644
--- a/src/quick/designer/qqmldesignermetaobject.cpp
+++ b/src/quick/designer/qqmldesignermetaobject.cpp
@@ -240,7 +240,7 @@ int QQmlDesignerMetaObject::metaCall(QObject *o, QMetaObject::Call call, int id,
if (call == QMetaObject::WriteProperty
&& propertyById.userType() == QMetaType::QVariant
- && reinterpret_cast<QVariant *>(a[0])->type() == QVariant::Double
+ && reinterpret_cast<QVariant *>(a[0])->userType() == QMetaType::Double
&& qt_is_nan(reinterpret_cast<QVariant *>(a[0])->toDouble())) {
return -1;
}
diff --git a/src/quick/designer/qquickdesignercustomobjectdata.cpp b/src/quick/designer/qquickdesignercustomobjectdata.cpp
index 8989de711e..66a86bffd5 100644
--- a/src/quick/designer/qquickdesignercustomobjectdata.cpp
+++ b/src/quick/designer/qquickdesignercustomobjectdata.cpp
@@ -192,7 +192,7 @@ void QQuickDesignerCustomObjectData::doResetProperty(QQmlContext *context, const
QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(property);
if (binding && !(hasValidResetBinding(propertyName) && getResetBinding(propertyName) == binding)) {
- binding->setEnabled(false, nullptr);
+ binding->setEnabled(false, {});
}
@@ -278,7 +278,7 @@ void QQuickDesignerCustomObjectData::setPropertyBinding(QQmlContext *context,
//Refcounting is taking take care of deletion
binding->update();
if (binding->hasError()) {
- if (property.property().userType() == QVariant::String)
+ if (property.property().userType() == QMetaType::QString)
property.write(QVariant(QLatin1Char('#') + expression + QLatin1Char('#')));
}
diff --git a/src/quick/doc/snippets/qml/listview/ReusableDelegate.qml b/src/quick/doc/snippets/qml/listview/ReusableDelegate.qml
new file mode 100644
index 0000000000..050572d5f2
--- /dev/null
+++ b/src/quick/doc/snippets/qml/listview/ReusableDelegate.qml
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+import QtQuick 2.15
+
+//![0]
+Component {
+ id: listViewDelegate
+ Rectangle {
+ width: 100
+ height: 50
+
+ ListView.onPooled: rotationAnimation.pause()
+ ListView.onReused: rotationAnimation.resume()
+
+ Rectangle {
+ id: rect
+ anchors.centerIn: parent
+ width: 40
+ height: 5
+ color: "green"
+
+ RotationAnimation {
+ id: rotationAnimation
+ target: rect
+ duration: (Math.random() * 2000) + 200
+ from: 0
+ to: 359
+ running: true
+ loops: Animation.Infinite
+ }
+ }
+ }
+}
+//![0]
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/snippets/qml/tableview/cpp-tablemodel.cpp b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp
index ea9f76f131..a8a37f80af 100644
--- a/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp
+++ b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp
@@ -48,56 +48,19 @@
**
****************************************************************************/
-//![0]
+#include "cpp-tablemodel.h"
#include <QGuiApplication>
-#include <QQmlApplicationEngine>
-#include <QAbstractTableModel>
-
-class TableModel : public QAbstractTableModel
-{
- Q_OBJECT
-
-public:
-
- int rowCount(const QModelIndex & = QModelIndex()) const override
- {
- return 200;
- }
-
- int columnCount(const QModelIndex & = QModelIndex()) const override
- {
- return 200;
- }
-
- QVariant data(const QModelIndex &index, int role) const override
- {
- switch (role) {
- case Qt::DisplayRole:
- return QString("%1, %2").arg(index.column()).arg(index.row());
- default:
- break;
- }
-
- return QVariant();
- }
-
- QHash<int, QByteArray> roleNames() const override
- {
- return { {Qt::DisplayRole, "display"} };
- }
-};
+#include <QQuickView>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
- qmlRegisterType<TableModel>("TableModel", 0, 1, "TableModel");
-
- QQmlApplicationEngine engine;
- engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ QQuickView view;
+ view.setSource(QStringLiteral("qrc:/cpp-tablemodel.qml"));
+ view.show();
return app.exec();
}
-#include "main.moc"
//![0]
diff --git a/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h
new file mode 100644
index 0000000000..4a3c46b573
--- /dev/null
+++ b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+ **
+ ** 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$
+ **
+ ****************************************************************************/
+
+#ifndef CPPTABLEMODEL_H
+#define CPPTABLEMODEL_H
+
+//![0]
+#include <qqml.h>
+#include <QAbstractTableModel>
+
+class TableModel : public QAbstractTableModel
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_ADDED_IN_MINOR_VERSION(1)
+
+public:
+ int rowCount(const QModelIndex & = QModelIndex()) const override
+ {
+ return 200;
+ }
+
+ int columnCount(const QModelIndex & = QModelIndex()) const override
+ {
+ return 200;
+ }
+
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ switch (role) {
+ case Qt::DisplayRole:
+ return QString("%1, %2").arg(index.column()).arg(index.row());
+ default:
+ break;
+ }
+
+ return QVariant();
+ }
+
+ QHash<int, QByteArray> roleNames() const override
+ {
+ return { {Qt::DisplayRole, "display"} };
+ }
+};
+//![0]
+
+#endif // CPPTABLEMODEL_H
diff --git a/src/quick/doc/snippets/qml/tableview/tableview.pro b/src/quick/doc/snippets/qml/tableview/tableview.pro
new file mode 100644
index 0000000000..0821f1b5d3
--- /dev/null
+++ b/src/quick/doc/snippets/qml/tableview/tableview.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+
+QT += qml quick
+
+CONFIG += qmltypes
+QML_IMPORT_NAME = TableModel
+QML_IMPORT_MAJOR_VERSION = 0
+
+SOURCES += \
+ cpp-tablemodel.cpp
+
+HEADERS += \
+ cpp-tablemodel.h
+
+RESOURCES += \
+ cpp-tablemodel.qml \
+ qml-tablemodel.qml \
+ reusabledelegate.qml \
+ tableviewwithheader.qml \
+ tableviewwithprovider.qml
diff --git a/src/quick/doc/src/advtutorial.qdoc b/src/quick/doc/src/advtutorial.qdoc
index a18d4493ea..63c70067fd 100644
--- a/src/quick/doc/src/advtutorial.qdoc
+++ b/src/quick/doc/src/advtutorial.qdoc
@@ -64,7 +64,6 @@ directory.
/*!
\title QML Advanced Tutorial 1 - Creating the Game Canvas and Blocks
-\contentspage QML Advanced Tutorial
\previouspage QML Advanced Tutorial
\nextpage QML Advanced Tutorial 2 - Populating the Game Canvas
@@ -132,7 +131,6 @@ types to get started. Next, we will populate the game canvas with some blocks.
/*!
\title QML Advanced Tutorial 2 - Populating the Game Canvas
-\contentspage QML Advanced Tutorial
\previouspage QML Advanced Tutorial 1 - Creating the Game Canvas and Blocks
\nextpage QML Advanced Tutorial 3 - Implementing the Game Logic
@@ -206,7 +204,6 @@ Now, we have a screen of blocks, and we can begin to add the game mechanics.
/*!
\title QML Advanced Tutorial 3 - Implementing the Game Logic
-\contentspage QML Advanced Tutorial
\previouspage QML Advanced Tutorial 2 - Populating the Game Canvas
\nextpage QML Advanced Tutorial 4 - Finishing Touches
@@ -293,7 +290,6 @@ until the next chapter - where your application becomes alive!
/*!
\title QML Advanced Tutorial 4 - Finishing Touches
-\contentspage QML Advanced Tutorial
\previouspage QML Advanced Tutorial 3 - Implementing the Game Logic
\example tutorials/samegame/samegame4
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/dynamicview-tutorial.qdoc b/src/quick/doc/src/dynamicview-tutorial.qdoc
index 6f44ba1947..d221e2ae62 100644
--- a/src/quick/doc/src/dynamicview-tutorial.qdoc
+++ b/src/quick/doc/src/dynamicview-tutorial.qdoc
@@ -50,7 +50,6 @@ directory.
/*!
\title QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
-\contentspage QML Dynamic View Ordering Tutorial
\previouspage QML Dynamic View Ordering Tutorial
\nextpage QML Dynamic View Ordering Tutorial 2 - Dragging View Items
@@ -85,7 +84,6 @@ The second part of the application is the ListView itself to which we bind the m
/*!
\title QML Dynamic View Ordering Tutorial 2 - Dragging View Items
-\contentspage QML Dynamic View Ordering Tutorial
\previouspage QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
\nextpage QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
@@ -128,7 +126,6 @@ so that is above other items in the stacking order and isn't obscured as it is d
/*!
\title QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
-\contentspage QML Dynamic View Ordering Tutorial
\previouspage QML Dynamic View Ordering Tutorial 2 - Dragging View Items
\nextpage QML Dynamic View Ordering Tutorial 4 - Sorting Items
@@ -180,7 +177,6 @@ property of the view and bind the \l {DelegateModel::}{model} and
/*!
\title QML Dynamic View Ordering Tutorial 4 - Sorting Items
-\contentspage QML Dynamic View Ordering Tutorial
\previouspage QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
\example tutorials/dynamicview/dynamicview4
diff --git a/src/quick/doc/src/examples.qdoc b/src/quick/doc/src/examples.qdoc
index a913af47c1..9a1308440f 100644
--- a/src/quick/doc/src/examples.qdoc
+++ b/src/quick/doc/src/examples.qdoc
@@ -177,6 +177,7 @@ Creator.
\li \l{Scene Graph - OpenGL Under QML}{OpenGL Under QML}
\li \l{Scene Graph - Direct3D 11 Under QML}{Direct3D 11 Under QML}
\li \l{Scene Graph - Vulkan Under QML}{Vulkan Under QML}
+ \li \l{Scene Graph - Vulkan Texture Import}{Vulkan Texture Import}
\li \l{Scene Graph - Custom Rendering with QSGRenderNode}{Render Node}
\li \l{Scene Graph - Painted Item}{Painted Item}
\li \l{Scene Graph - Graph}{Graph}
diff --git a/src/quick/doc/src/tutorial.qdoc b/src/quick/doc/src/tutorial.qdoc
index 20021f2432..7cb5f655e8 100644
--- a/src/quick/doc/src/tutorial.qdoc
+++ b/src/quick/doc/src/tutorial.qdoc
@@ -54,7 +54,6 @@ Tutorial chapters:
/*!
\page qml-tutorial1.html
\title QML Tutorial 1 - Basic Types
-\contentspage QML Tutorial
\previouspage QML Tutorial
\nextpage QML Tutorial 2 - QML Components
@@ -112,7 +111,6 @@ qmlscene tutorials/helloworld/tutorial1.qml
/*!
\page qml-tutorial2.html
\title QML Tutorial 2 - QML Components
-\contentspage QML Tutorial
\previouspage QML Tutorial 1 - Basic Types
\nextpage QML Tutorial 3 - States and Transitions
@@ -184,7 +182,6 @@ We can react to any signal of our component through a property of the name \e 'o
/*!
\page qml-tutorial3.html
\title QML Tutorial 3 - States and Transitions
-\contentspage QML Tutorial
\previouspage QML Tutorial 2 - QML Components
In this chapter, we make this example a little bit more dynamic by introducing states and transitions.
diff --git a/src/quick/handlers/qquickdragaxis_p.h b/src/quick/handlers/qquickdragaxis_p.h
index a4649d5eb9..ef74902122 100644
--- a/src/quick/handlers/qquickdragaxis_p.h
+++ b/src/quick/handlers/qquickdragaxis_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtQml/qqml.h>
#include <private/qtquickglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -61,6 +62,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDragAxis : public QObject
Q_PROPERTY(qreal minimum READ minimum WRITE setMinimum NOTIFY minimumChanged)
Q_PROPERTY(qreal maximum READ maximum WRITE setMaximum NOTIFY maximumChanged)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+ QML_NAMED_ELEMENT(DragAxis)
+ QML_ADDED_IN_MINOR_VERSION(12)
+ QML_UNCREATABLE("DragAxis is only available as a grouped property of DragHandler.")
public:
QQuickDragAxis();
diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp
index 61b66beff4..492897b68b 100644
--- a/src/quick/handlers/qquickdraghandler.cpp
+++ b/src/quick/handlers/qquickdraghandler.cpp
@@ -39,6 +39,7 @@
#include "qquickdraghandler_p.h"
#include <private/qquickwindow_p.h>
+#include <private/qquickmultipointhandler_p_p.h>
#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -228,7 +229,7 @@ void QQuickDragHandler::handlePointerEventImpl(QQuickPointerEvent *event)
accumulatedDragDelta.setY(0);
}
qreal angle = std::atan2(accumulatedDragDelta.y(), accumulatedDragDelta.x()) * 180 / M_PI;
- bool overThreshold = QQuickWindowPrivate::dragOverThreshold(accumulatedDragDelta);
+ bool overThreshold = d_func()->dragOverThreshold(accumulatedDragDelta);
qCDebug(lcDragHandler) << "movement" << accumulatedDragDelta << "angle" << angle << "of point" << point
<< "pressed @" << point->scenePressPosition() << "over threshold?" << overThreshold;
minAngle = qMin(angle, minAngle);
diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h
index e8f47163ed..22d51c78ec 100644
--- a/src/quick/handlers/qquickdraghandler_p.h
+++ b/src/quick/handlers/qquickdraghandler_p.h
@@ -63,6 +63,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDragHandler : public QQuickMultiPointHandler
Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT)
Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged)
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged REVISION 14)
+ QML_NAMED_ELEMENT(DragHandler)
+ QML_ADDED_IN_MINOR_VERSION(12)
public:
enum SnapMode {
diff --git a/src/quick/handlers/qquickhandlerpoint.cpp b/src/quick/handlers/qquickhandlerpoint.cpp
index f3d92cf200..72efdfd0f4 100644
--- a/src/quick/handlers/qquickhandlerpoint.cpp
+++ b/src/quick/handlers/qquickhandlerpoint.cpp
@@ -119,8 +119,13 @@ void QQuickHandlerPoint::reset(const QQuickEventPoint *point)
m_rotation = tp->rotation();
m_pressure = tp->pressure();
m_ellipseDiameters = tp->ellipseDiameters();
+#if QT_CONFIG(tabletevent)
} 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();
+#endif
} else {
m_uniqueId = event->device()->uniqueId();
m_rotation = 0;
diff --git a/src/quick/handlers/qquickhoverhandler.cpp b/src/quick/handlers/qquickhoverhandler.cpp
index 79cb288af8..b12d85784a 100644
--- a/src/quick/handlers/qquickhoverhandler.cpp
+++ b/src/quick/handlers/qquickhoverhandler.cpp
@@ -64,6 +64,9 @@ Q_LOGGING_CATEGORY(lcHoverHandler, "qt.quick.handler.hover")
properties can be used to narrow the behavior to detect hovering of
specific kinds of devices or while holding a modifier key.
+ The \l cursorShape property allows changing the cursor whenever
+ \l hovered changes to \c true.
+
\sa MouseArea, PointHandler
*/
@@ -90,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;
}
@@ -104,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);
}
@@ -121,8 +137,58 @@ 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();
}
}
+/*!
+ \since 5.15
+ \qmlproperty Qt::CursorShape QtQuick::HoverHandler::cursorShape
+ This property holds the cursor shape that will appear whenever
+ \l hovered is \c true and no other handler is overriding it.
+
+ The available cursor shapes are:
+ \list
+ \li Qt.ArrowCursor
+ \li Qt.UpArrowCursor
+ \li Qt.CrossCursor
+ \li Qt.WaitCursor
+ \li Qt.IBeamCursor
+ \li Qt.SizeVerCursor
+ \li Qt.SizeHorCursor
+ \li Qt.SizeBDiagCursor
+ \li Qt.SizeFDiagCursor
+ \li Qt.SizeAllCursor
+ \li Qt.BlankCursor
+ \li Qt.SplitVCursor
+ \li Qt.SplitHCursor
+ \li Qt.PointingHandCursor
+ \li Qt.ForbiddenCursor
+ \li Qt.WhatsThisCursor
+ \li Qt.BusyCursor
+ \li Qt.OpenHandCursor
+ \li Qt.ClosedHandCursor
+ \li Qt.DragCopyCursor
+ \li Qt.DragMoveCursor
+ \li Qt.DragLinkCursor
+ \endlist
+
+ The default value of this property is not set, which allows any active
+ handler on the same \l parentItem to determine the cursor shape.
+ This property can be reset to the initial condition by setting it to
+ \c undefined.
+
+ If any handler with defined \c cursorShape is
+ \l {PointerHandler::active}{active}, that cursor will appear.
+ Else if the HoverHandler has a defined \c cursorShape, that cursor will appear.
+ Otherwise, the \l {QQuickItem::cursor()}{cursor} of \l parentItem will appear.
+
+ \note When this property has not been set, or has been set to \c undefined,
+ if you read the value it will return \c Qt.ArrowCursor.
+
+ \sa Qt::CursorShape, QQuickItem::cursor()
+*/
+
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickhoverhandler_p.h b/src/quick/handlers/qquickhoverhandler_p.h
index d8e5fc00a1..313b87217c 100644
--- a/src/quick/handlers/qquickhoverhandler_p.h
+++ b/src/quick/handlers/qquickhoverhandler_p.h
@@ -62,6 +62,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickHoverHandler : public QQuickSinglePointHandle
{
Q_OBJECT
Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged)
+ QML_NAMED_ELEMENT(HoverHandler)
+ QML_ADDED_IN_MINOR_VERSION(12)
public:
explicit QQuickHoverHandler(QQuickItem *parent = nullptr);
@@ -82,6 +84,7 @@ private:
private:
bool m_hovered = false;
+ bool m_hoveredTablet = false;
};
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp
index a5a867015c..5b30d08557 100644
--- a/src/quick/handlers/qquickpinchhandler.cpp
+++ b/src/quick/handlers/qquickpinchhandler.cpp
@@ -43,6 +43,7 @@
#include <private/qsgadaptationlayer_p.h>
#include <private/qquickitem_p.h>
#include <private/qguiapplication_p.h>
+#include <private/qquickmultipointhandler_p_p.h>
#include <private/qquickwindow_p.h>
#include <QEvent>
#include <QMouseEvent>
@@ -289,7 +290,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
{
if (Q_UNLIKELY(lcPinchHandler().isDebugEnabled())) {
for (const QQuickHandlerPoint &p : currentPoints())
- qCDebug(lcPinchHandler) << hex << p.id() << p.sceneGrabPosition() << "->" << p.scenePosition();
+ qCDebug(lcPinchHandler) << Qt::hex << p.id() << p.sceneGrabPosition() << "->" << p.scenePosition();
}
QQuickMultiPointHandler::handlePointerEventImpl(event);
@@ -338,8 +339,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
const QVector2D currentCentroid(centroid().scenePosition());
const QVector2D pressCentroid(centroid().scenePressPosition());
- QStyleHints *styleHints = QGuiApplication::styleHints();
- const int dragThreshold = styleHints->startDragDistance();
+ const int dragThreshold = QQuickPointerHandler::dragThreshold();
const int dragThresholdSquared = dragThreshold * dragThreshold;
double accumulatedCentroidDistance = 0; // Used to detect scale
@@ -399,7 +399,8 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
point->setAccepted(false); // don't stop propagation
setPassiveGrab(point);
}
- if (QQuickWindowPrivate::dragOverThreshold(point))
+ Q_D(QQuickMultiPointHandler);
+ if (d->dragOverThreshold(point))
++numberOfPointsDraggedOverThreshold;
}
diff --git a/src/quick/handlers/qquickpinchhandler_p.h b/src/quick/handlers/qquickpinchhandler_p.h
index cea794f0c8..708c836acf 100644
--- a/src/quick/handlers/qquickpinchhandler_p.h
+++ b/src/quick/handlers/qquickpinchhandler_p.h
@@ -78,6 +78,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPinchHandler : public QQuickMultiPointHandler
#endif
Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT)
Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT)
+ QML_NAMED_ELEMENT(PinchHandler)
+ QML_ADDED_IN_MINOR_VERSION(12)
public:
explicit QQuickPinchHandler(QQuickItem *parent = nullptr);
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
index 0f5cf59c67..adb753e000 100644
--- a/src/quick/handlers/qquickpointerhandler.cpp
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -51,7 +51,6 @@ Q_LOGGING_CATEGORY(lcPointerHandlerActive, "qt.quick.handler.active")
\qmltype PointerHandler
\qmlabstract
\since 5.10
- \preliminary
\instantiates QQuickPointerHandler
\inqmlmodule QtQuick
\brief Abstract handler for pointer events.
@@ -113,6 +112,128 @@ void QQuickPointerHandler::setMargin(qreal pointDistanceThreshold)
}
/*!
+ \qmlproperty int PointerHandler::dragThreshold
+ \since 5.15
+
+ The distance in pixels that the user must drag an event point in order to
+ have it treated as a drag gesture.
+
+ The default value depends on the platform and screen resolution.
+ It can be reset back to the default value by setting it to undefined.
+ The behavior when a drag gesture begins varies in different handlers.
+*/
+int QQuickPointerHandler::dragThreshold() const
+{
+ Q_D(const QQuickPointerHandler);
+ if (d->dragThreshold < 0)
+ return qApp->styleHints()->startDragDistance();
+ return d->dragThreshold;
+}
+
+void QQuickPointerHandler::setDragThreshold(int t)
+{
+ Q_D(QQuickPointerHandler);
+ if (d->dragThreshold == t)
+ return;
+
+ if (t > std::numeric_limits<qint16>::max())
+ qWarning() << "drag threshold cannot exceed" << std::numeric_limits<qint16>::max();
+ d->dragThreshold = qint16(t);
+ emit dragThresholdChanged();
+}
+
+void QQuickPointerHandler::resetDragThreshold()
+{
+ Q_D(QQuickPointerHandler);
+ if (d->dragThreshold < 0)
+ return;
+
+ d->dragThreshold = -1;
+ emit dragThresholdChanged();
+}
+
+/*!
+ \since 5.15
+ \qmlproperty Qt::CursorShape PointerHandler::cursorShape
+ This property holds the cursor shape that will appear whenever the mouse is
+ hovering over the \l parentItem while \l active is \c true.
+
+ The available cursor shapes are:
+ \list
+ \li Qt.ArrowCursor
+ \li Qt.UpArrowCursor
+ \li Qt.CrossCursor
+ \li Qt.WaitCursor
+ \li Qt.IBeamCursor
+ \li Qt.SizeVerCursor
+ \li Qt.SizeHorCursor
+ \li Qt.SizeBDiagCursor
+ \li Qt.SizeFDiagCursor
+ \li Qt.SizeAllCursor
+ \li Qt.BlankCursor
+ \li Qt.SplitVCursor
+ \li Qt.SplitHCursor
+ \li Qt.PointingHandCursor
+ \li Qt.ForbiddenCursor
+ \li Qt.WhatsThisCursor
+ \li Qt.BusyCursor
+ \li Qt.OpenHandCursor
+ \li Qt.ClosedHandCursor
+ \li Qt.DragCopyCursor
+ \li Qt.DragMoveCursor
+ \li Qt.DragLinkCursor
+ \endlist
+
+ The default value is not set, which allows the \l {QQuickItem::cursor()}{cursor}
+ of \l parentItem to appear. This property can be reset to the same initial
+ condition by setting it to undefined.
+
+ \note When this property has not been set, or has been set to \c undefined,
+ if you read the value it will return \c Qt.ArrowCursor.
+
+ \sa Qt::CursorShape, QQuickItem::cursor(), HoverHandler::cursorShape
+*/
+#if QT_CONFIG(cursor)
+Qt::CursorShape QQuickPointerHandler::cursorShape() const
+{
+ Q_D(const QQuickPointerHandler);
+ return d->cursorShape;
+}
+
+void QQuickPointerHandler::setCursorShape(Qt::CursorShape shape)
+{
+ Q_D(QQuickPointerHandler);
+ if (d->cursorSet && shape == d->cursorShape)
+ return;
+ d->cursorShape = shape;
+ d->cursorSet = true;
+ QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parentItem());
+ itemPriv->hasCursorHandler = true;
+ itemPriv->setHasCursorInChild(true);
+ emit cursorShapeChanged();
+}
+
+void QQuickPointerHandler::resetCursorShape()
+{
+ Q_D(QQuickPointerHandler);
+ if (!d->cursorSet)
+ return;
+ d->cursorShape = Qt::ArrowCursor;
+ d->cursorSet = false;
+ QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parentItem());
+ itemPriv->hasCursorHandler = false;
+ itemPriv->setHasCursorInChild(itemPriv->hasCursor);
+ emit cursorShapeChanged();
+}
+
+bool QQuickPointerHandler::isCursorShapeExplicitlySet() const
+{
+ Q_D(const QQuickPointerHandler);
+ return d->cursorSet;
+}
+#endif
+
+/*!
Notification that the grab has changed in some way which is relevant to this handler.
The \a grabber (subject) will be the Input Handler whose state is changing,
or null if the state change regards an Item.
@@ -266,7 +387,7 @@ bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObjec
allowed = true;
}
}
- qCDebug(lcPointerHandlerGrab) << "point" << hex << point->pointId() << "permission" <<
+ qCDebug(lcPointerHandlerGrab) << "point" << Qt::hex << point->pointId() << "permission" <<
QMetaEnum::fromType<GrabPermissions>().valueToKeys(grabPermissions()) <<
':' << this << (allowed ? "approved to" : "denied to") << proposedGrabber;
return allowed;
@@ -490,7 +611,7 @@ bool QQuickPointerHandler::wantsPointerEvent(QQuickPointerEvent *event)
bool QQuickPointerHandler::wantsEventPoint(QQuickEventPoint *point)
{
bool ret = point->exclusiveGrabber() == this || point->passiveGrabbers().contains(this) || parentContains(point);
- qCDebug(lcPointerHandlerDispatch) << hex << point->pointId() << "@" << point->scenePosition()
+ qCDebug(lcPointerHandlerDispatch) << Qt::hex << point->pointId() << "@" << point->scenePosition()
<< metaObject()->className() << objectName() << ret;
return ret;
}
@@ -556,12 +677,42 @@ QQuickPointerHandlerPrivate::QQuickPointerHandlerPrivate()
: grabPermissions(QQuickPointerHandler::CanTakeOverFromItems |
QQuickPointerHandler::CanTakeOverFromHandlersOfDifferentType |
QQuickPointerHandler::ApprovesTakeOverByAnything)
+ , cursorShape(Qt::ArrowCursor)
, enabled(true)
, active(false)
, targetExplicitlySet(false)
, hadKeepMouseGrab(false)
, hadKeepTouchGrab(false)
+ , cursorSet(false)
+{
+}
+
+template <typename TEventPoint>
+bool QQuickPointerHandlerPrivate::dragOverThreshold(qreal d, Qt::Axis axis, const TEventPoint *p) const
+{
+ Q_Q(const QQuickPointerHandler);
+ QStyleHints *styleHints = qApp->styleHints();
+ bool overThreshold = qAbs(d) > q->dragThreshold();
+ const bool dragVelocityLimitAvailable = (styleHints->startDragVelocity() > 0);
+ if (!overThreshold && dragVelocityLimitAvailable) {
+ qreal velocity = qreal(axis == Qt::XAxis ? p->velocity().x() : p->velocity().y());
+ overThreshold |= qAbs(velocity) > styleHints->startDragVelocity();
+ }
+ return overThreshold;
+}
+
+bool QQuickPointerHandlerPrivate::dragOverThreshold(QVector2D delta) const
+{
+ Q_Q(const QQuickPointerHandler);
+ const float threshold = q->dragThreshold();
+ return qAbs(delta.x()) > threshold || qAbs(delta.y()) > threshold;
+}
+
+bool QQuickPointerHandlerPrivate::dragOverThreshold(const QQuickEventPoint *point) const
{
+ QPointF delta = point->scenePosition() - point->scenePressPosition();
+ return (dragOverThreshold(delta.x(), Qt::XAxis, point) ||
+ dragOverThreshold(delta.y(), Qt::YAxis, point));
}
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h
index c600e42491..7262f4bcd3 100644
--- a/src/quick/handlers/qquickpointerhandler_p.h
+++ b/src/quick/handlers/qquickpointerhandler_p.h
@@ -71,6 +71,14 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject, public QQmlP
Q_PROPERTY(QQuickItem * parent READ parentItem CONSTANT)
Q_PROPERTY(GrabPermissions grabPermissions READ grabPermissions WRITE setGrabPermissions NOTIFY grabPermissionChanged)
Q_PROPERTY(qreal margin READ margin WRITE setMargin NOTIFY marginChanged)
+ Q_PROPERTY(int dragThreshold READ dragThreshold WRITE setDragThreshold RESET resetDragThreshold NOTIFY dragThresholdChanged REVISION 15)
+#if QT_CONFIG(cursor)
+ Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET resetCursorShape NOTIFY cursorShapeChanged REVISION 15)
+#endif
+
+ QML_NAMED_ELEMENT(PointerHandler)
+ QML_UNCREATABLE("PointerHandler is an abstract base class.")
+ QML_ADDED_IN_MINOR_VERSION(12)
public:
explicit QQuickPointerHandler(QQuickItem *parent = nullptr);
@@ -110,14 +118,29 @@ public:
qreal margin() const;
void setMargin(qreal pointDistanceThreshold);
+ int dragThreshold() const;
+ void setDragThreshold(int t);
+ void resetDragThreshold();
+
+#if QT_CONFIG(cursor)
+ Qt::CursorShape cursorShape() const;
+ void setCursorShape(Qt::CursorShape shape);
+ void resetCursorShape();
+ bool isCursorShapeExplicitlySet() const;
+#endif
+
Q_SIGNALS:
void enabledChanged();
void activeChanged();
void targetChanged();
void marginChanged();
+ Q_REVISION(15) void dragThresholdChanged();
void grabChanged(QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point);
void grabPermissionChanged();
void canceled(QQuickEventPoint *point);
+#if QT_CONFIG(cursor)
+ Q_REVISION(15) void cursorShapeChanged();
+#endif
protected:
QQuickPointerHandler(QQuickPointerHandlerPrivate &dd, QQuickItem *parent);
diff --git a/src/quick/handlers/qquickpointerhandler_p_p.h b/src/quick/handlers/qquickpointerhandler_p_p.h
index 2ea4905643..db053fb6b4 100644
--- a/src/quick/handlers/qquickpointerhandler_p_p.h
+++ b/src/quick/handlers/qquickpointerhandler_p_p.h
@@ -68,15 +68,24 @@ public:
QQuickPointerHandlerPrivate();
+ template<typename TEventPoint>
+ bool dragOverThreshold(qreal d, Qt::Axis axis, const TEventPoint *p) const;
+
+ bool dragOverThreshold(QVector2D delta) const;
+ bool dragOverThreshold(const QQuickEventPoint *point) const;
+
QQuickPointerEvent *currentEvent = nullptr;
QQuickItem *target = nullptr;
qreal m_margin = 0;
+ qint16 dragThreshold = -1; // -1 means use the platform default
uint8_t grabPermissions : 8;
+ Qt::CursorShape cursorShape : 6;
bool enabled : 1;
bool active : 1;
bool targetExplicitlySet : 1;
bool hadKeepMouseGrab : 1; // some handlers override target()->setKeepMouseGrab(); this remembers previous state
bool hadKeepTouchGrab : 1; // some handlers override target()->setKeepTouchGrab(); this remembers previous state
+ bool cursorSet : 1;
};
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpointhandler_p.h b/src/quick/handlers/qquickpointhandler_p.h
index c197cb4f20..42677540a7 100644
--- a/src/quick/handlers/qquickpointhandler_p.h
+++ b/src/quick/handlers/qquickpointhandler_p.h
@@ -59,6 +59,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointHandler : public QQuickSinglePointHandle
{
Q_OBJECT
Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged)
+ QML_NAMED_ELEMENT(PointHandler)
+ QML_ADDED_IN_MINOR_VERSION(12)
public:
explicit QQuickPointHandler(QQuickItem *parent = nullptr);
diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp
index 15fe0cc89e..b51f53b74f 100644
--- a/src/quick/handlers/qquicksinglepointhandler.cpp
+++ b/src/quick/handlers/qquicksinglepointhandler.cpp
@@ -95,7 +95,7 @@ bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event)
}
}
if (missing)
- qCWarning(DBG_TOUCH_TARGET) << this << "pointId" << hex << d->pointInfo.id()
+ qCWarning(DBG_TOUCH_TARGET) << this << "pointId" << Qt::hex << d->pointInfo.id()
<< "is missing from current event, but was neither canceled nor released";
if (point) {
if (candidatePointCount == 1 || (candidatePointCount > 1 && d->ignoreAdditionalPoints)) {
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
index bfb3df7c6c..f3674d6fa9 100644
--- a/src/quick/handlers/qquicktaphandler.cpp
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -97,13 +97,6 @@ QQuickTapHandler::QQuickTapHandler(QQuickItem *parent)
}
}
-static bool dragOverThreshold(const QQuickEventPoint *point)
-{
- QPointF delta = point->scenePosition() - point->scenePressPosition();
- return (QQuickWindowPrivate::dragOverThreshold(delta.x(), Qt::XAxis, point) ||
- QQuickWindowPrivate::dragOverThreshold(delta.y(), Qt::YAxis, point));
-}
-
bool QQuickTapHandler::wantsEventPoint(QQuickEventPoint *point)
{
if (!point->pointerEvent()->asPointerMouseEvent() &&
@@ -115,7 +108,7 @@ bool QQuickTapHandler::wantsEventPoint(QQuickEventPoint *point)
// (e.g. DragHandler) gets a chance to take over.
// Don't forget to emit released in case of a cancel.
bool ret = false;
- bool overThreshold = dragOverThreshold(point);
+ bool overThreshold = d_func()->dragOverThreshold(point);
if (overThreshold) {
m_longPressTimer.stop();
m_holdTimer.invalidate();
diff --git a/src/quick/handlers/qquicktaphandler_p.h b/src/quick/handlers/qquicktaphandler_p.h
index 56e08590b2..07454bccb8 100644
--- a/src/quick/handlers/qquicktaphandler_p.h
+++ b/src/quick/handlers/qquicktaphandler_p.h
@@ -67,6 +67,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTapHandler : public QQuickSinglePointHandler
Q_PROPERTY(qreal longPressThreshold READ longPressThreshold WRITE setLongPressThreshold NOTIFY longPressThresholdChanged)
Q_PROPERTY(GesturePolicy gesturePolicy READ gesturePolicy WRITE setGesturePolicy NOTIFY gesturePolicyChanged)
+ QML_NAMED_ELEMENT(TapHandler)
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
enum GesturePolicy {
DragThreshold,
diff --git a/src/quick/handlers/qquickwheelhandler_p.h b/src/quick/handlers/qquickwheelhandler_p.h
index f8d1c00726..26b052c5b3 100644
--- a/src/quick/handlers/qquickwheelhandler_p.h
+++ b/src/quick/handlers/qquickwheelhandler_p.h
@@ -72,6 +72,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWheelHandler : public QQuickSinglePointHandle
Q_PROPERTY(qreal targetScaleMultiplier READ targetScaleMultiplier WRITE setTargetScaleMultiplier NOTIFY targetScaleMultiplierChanged)
Q_PROPERTY(bool targetTransformAroundCursor READ isTargetTransformAroundCursor WRITE setTargetTransformAroundCursor NOTIFY targetTransformAroundCursorChanged)
+ QML_NAMED_ELEMENT(WheelHandler)
+ QML_ADDED_IN_MINOR_VERSION(14)
+
public:
explicit QQuickWheelHandler(QQuickItem *parent = nullptr);
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index b8e6d58af4..bfee190baf 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -1019,8 +1019,6 @@ QQmlRefPointer<QQuickCanvasPixmap> QQuickCanvasItem::loadedPixmap(const QUrl& ur
This signal is emitted when an image has been loaded.
- The corresponding handler is \c onImageLoaded.
-
\sa loadImage()
*/
@@ -1244,8 +1242,6 @@ QRect QQuickCanvasItem::tiledRect(const QRectF &window, const QSize &tileSize)
This signal can be triggered by markdirty(), requestPaint() or by changing
the current canvas window.
-
- The corresponding handler is \c onPaint.
*/
/*!
@@ -1253,8 +1249,6 @@ QRect QQuickCanvasItem::tiledRect(const QRectF &window, const QSize &tileSize)
This signal is emitted after all context painting commands are executed and
the Canvas has been rendered.
-
- The corresponding handler is \c onPainted.
*/
QT_END_NAMESPACE
diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h
index cd2977429b..6575caf806 100644
--- a/src/quick/items/context2d/qquickcanvasitem_p.h
+++ b/src/quick/items/context2d/qquickcanvasitem_p.h
@@ -99,6 +99,7 @@ class QQuickCanvasItem : public QQuickItem
Q_PROPERTY(QRectF canvasWindow READ canvasWindow WRITE setCanvasWindow NOTIFY canvasWindowChanged)
Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged)
Q_PROPERTY(RenderStrategy renderStrategy READ renderStrategy WRITE setRenderStrategy NOTIFY renderStrategyChanged)
+ QML_NAMED_ELEMENT(Canvas)
public:
enum RenderTarget {
diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp
index 2da01e9151..ae23c4c07e 100644
--- a/src/quick/items/qquickaccessibleattached.cpp
+++ b/src/quick/items/qquickaccessibleattached.cpp
@@ -273,71 +273,51 @@ QT_BEGIN_NAMESPACE
\qmlsignal QtQuick::Accessible::pressAction()
This signal is emitted when a press action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onPressAction.
*/
/*!
\qmlsignal QtQuick::Accessible::toggleAction()
This signal is emitted when a toggle action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onToggleAction.
*/
/*!
\qmlsignal QtQuick::Accessible::increaseAction()
This signal is emitted when a increase action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onIncreaseAction.
*/
/*!
\qmlsignal QtQuick::Accessible::decreaseAction()
This signal is emitted when a decrease action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onDecreaseAction.
*/
/*!
\qmlsignal QtQuick::Accessible::scrollUpAction()
This signal is emitted when a scroll up action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onScrollUpAction.
*/
/*!
\qmlsignal QtQuick::Accessible::scrollDownAction()
This signal is emitted when a scroll down action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onScrollDownAction.
*/
/*!
\qmlsignal QtQuick::Accessible::scrollLeftAction()
This signal is emitted when a scroll left action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onScrollLeftAction.
*/
/*!
\qmlsignal QtQuick::Accessible::scrollRightAction()
This signal is emitted when a scroll right action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onScrollRightAction.
*/
/*!
\qmlsignal QtQuick::Accessible::previousPageAction()
This signal is emitted when a previous page action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onPreviousPageAction.
*/
/*!
\qmlsignal QtQuick::Accessible::nextPageAction()
This signal is emitted when a next page action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onNextPageAction.
*/
QMetaMethod QQuickAccessibleAttached::sigPress;
diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h
index 87fb79ecc9..b7254d6686 100644
--- a/src/quick/items/qquickaccessibleattached_p.h
+++ b/src/quick/items/qquickaccessibleattached_p.h
@@ -90,6 +90,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAccessibleAttached : public QObject
Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged FINAL)
Q_PROPERTY(bool ignored READ ignored WRITE setIgnored NOTIFY ignoredChanged FINAL)
+ QML_NAMED_ELEMENT(Accessible)
+ QML_UNCREATABLE("Accessible is only available via attached properties.")
+ QML_ATTACHED(QQuickAccessibleAttached)
+
public:
Q_ENUMS(QAccessible::Role QAccessible::Event)
STATE_PROPERTY(checkable)
@@ -242,7 +246,6 @@ public:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickAccessibleAttached)
-QML_DECLARE_TYPEINFO(QQuickAccessibleAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // accessibility
diff --git a/src/quick/items/qquickanchors_p.h b/src/quick/items/qquickanchors_p.h
index c7995cb7a8..e0276549e9 100644
--- a/src/quick/items/qquickanchors_p.h
+++ b/src/quick/items/qquickanchors_p.h
@@ -84,6 +84,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnchors : public QObject
Q_PROPERTY(QQuickItem *fill READ fill WRITE setFill RESET resetFill NOTIFY fillChanged)
Q_PROPERTY(QQuickItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged)
Q_PROPERTY(bool alignWhenCentered READ alignWhenCentered WRITE setAlignWhenCentered NOTIFY centerAlignedChanged)
+ QML_ANONYMOUS
public:
QQuickAnchors(QQuickItem *item, QObject *parent=nullptr);
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index 18d492cd68..eb3385c8f8 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -67,7 +67,7 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine
.arg(current));
}
if (!requestedUrl.isEmpty()) {
- if (QQuickPixmap::isCached(requestedUrl, QSize(), 0, QQuickImageProviderOptions()))
+ if (QQuickPixmap::isCached(requestedUrl, QRect(), QSize(), 0, QQuickImageProviderOptions()))
pixmap = new QQuickPixmap(engine, requestedUrl);
else
pixmap = new QQuickPixmap(requestedUrl, movie->currentImage());
@@ -129,10 +129,9 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine
This property holds the URL that refers to the source image.
- AnimatedImage can handle any image format supported by Qt, loaded from any
- URL scheme supported by Qt.
-
- \sa QQuickImageProvider
+ AnimatedImage can handle any image format supported by Qt, loaded
+ from any URL scheme supported by Qt. It is however not compatible
+ with QQuickImageProvider.
*/
QQuickAnimatedImage::QQuickAnimatedImage(QQuickItem *parent)
diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h
index 13eae83350..7f2199fd2a 100644
--- a/src/quick/items/qquickanimatedimage_p.h
+++ b/src/quick/items/qquickanimatedimage_p.h
@@ -74,6 +74,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedImage : public QQuickImage
// read-only for AnimatedImage
Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
+ QML_NAMED_ELEMENT(AnimatedImage)
public:
QQuickAnimatedImage(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp
index d22e77c8ad..b285fe56ed 100644
--- a/src/quick/items/qquickanimatedsprite.cpp
+++ b/src/quick/items/qquickanimatedsprite.cpp
@@ -263,6 +263,19 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \qmlproperty enumeration QtQuick::AnimatedSprite::finishBehavior
+
+ The behavior when the animation finishes on its own.
+
+ \value FinishAtInitialFrame
+ When the animation finishes it returns to the initial frame.
+ This is the default behavior.
+
+ \value FinishAtFinalFrame
+ When the animation finishes it stays on the final frame.
+*/
+
+/*!
\qmlmethod int QtQuick::AnimatedSprite::restart()
Stops, then starts the sprite animation.
@@ -381,6 +394,12 @@ int QQuickAnimatedSprite::currentFrame() const
return d->m_curFrame;
}
+QQuickAnimatedSprite::FinishBehavior QQuickAnimatedSprite::finishBehavior() const
+{
+ Q_D(const QQuickAnimatedSprite);
+ return d->m_finishBehavior;
+}
+
bool QQuickAnimatedSprite::isCurrentFrameChangedConnected()
{
IS_SIGNAL_CONNECTED(this, QQuickAnimatedSprite, currentFrameChanged, (int));
@@ -395,20 +414,34 @@ void QQuickAnimatedSprite::reloadImage()
void QQuickAnimatedSprite::componentComplete()
{
- Q_D(const QQuickAnimatedSprite);
+ Q_D(QQuickAnimatedSprite);
createEngine();
QQuickItem::componentComplete();
- if (d->m_running)
+ if (d->m_running) {
+ d->m_running = false;
start();
+ }
}
+/*!
+ \qmlmethod QtQuick::AnimatedSprite::start()
+ \since 5.15
+
+ Starts the sprite animation. If the animation is already running, calling
+ this method has no effect.
+
+ \sa stop()
+*/
void QQuickAnimatedSprite::start()
{
Q_D(QQuickAnimatedSprite);
+ if (d->m_running)
+ return;
d->m_running = true;
if (!isComponentComplete())
return;
d->m_curLoop = 0;
+ d->m_curFrame = 0;
d->m_timestamp.start();
if (d->m_spriteEngine) {
d->m_spriteEngine->stop(0);
@@ -420,9 +453,20 @@ void QQuickAnimatedSprite::start()
maybeUpdate();
}
+/*!
+ \qmlmethod QtQuick::AnimatedSprite::stop()
+ \since 5.15
+
+ Stops the sprite animation. If the animation is not running, calling this
+ method has no effect.
+
+ \sa start()
+*/
void QQuickAnimatedSprite::stop()
{
Q_D(QQuickAnimatedSprite);
+ if (!d->m_running)
+ return;
d->m_running = false;
if (!isComponentComplete())
return;
@@ -679,6 +723,16 @@ void QQuickAnimatedSprite::setCurrentFrame(int arg) //TODO-C: Probably only work
}
}
+void QQuickAnimatedSprite::setFinishBehavior(FinishBehavior arg)
+{
+ Q_D(QQuickAnimatedSprite);
+
+ if (d->m_finishBehavior != arg) {
+ d->m_finishBehavior = arg;
+ Q_EMIT finishBehaviorChanged(arg);
+ }
+}
+
void QQuickAnimatedSprite::createEngine()
{
Q_D(QQuickAnimatedSprite);
@@ -813,7 +867,11 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node)
progress = 0;
}
if (d->m_loops > 0 && d->m_curLoop >= d->m_loops) {
- frameAt = 0;
+ if (d->m_finishBehavior == FinishAtInitialFrame)
+ frameAt = 0;
+ else
+ frameAt = frameCount() - 1;
+ d->m_curFrame = frameAt;
d->m_running = false;
emit runningChanged(false);
emit finished();
diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h
index d36f908c78..546598a409 100644
--- a/src/quick/items/qquickanimatedsprite_p.h
+++ b/src/quick/items/qquickanimatedsprite_p.h
@@ -92,6 +92,8 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedSprite : public QQuickItem
Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged)
Q_PROPERTY(bool paused READ paused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged)
+ Q_PROPERTY(FinishBehavior finishBehavior READ finishBehavior WRITE setFinishBehavior NOTIFY finishBehaviorChanged REVISION 15)
+ QML_NAMED_ELEMENT(AnimatedSprite)
public:
explicit QQuickAnimatedSprite(QQuickItem *parent = nullptr);
@@ -100,6 +102,12 @@ public:
};
Q_ENUM(LoopParameters)
+ enum FinishBehavior {
+ FinishAtInitialFrame,
+ FinishAtFinalFrame
+ };
+ Q_ENUM(FinishBehavior)
+
bool running() const;
bool interpolate() const;
QUrl source() const;
@@ -115,6 +123,8 @@ public:
int loops() const;
bool paused() const;
int currentFrame() const;
+ FinishBehavior finishBehavior() const;
+ void setFinishBehavior(FinishBehavior arg);
Q_SIGNALS:
@@ -134,6 +144,7 @@ Q_SIGNALS:
void frameDurationChanged(int arg);
void loopsChanged(int arg);
void currentFrameChanged(int arg);
+ Q_REVISION(15) void finishBehaviorChanged(FinishBehavior arg);
Q_REVISION(12) void finished();
@@ -163,7 +174,6 @@ public Q_SLOTS:
void setLoops(int arg);
void setCurrentFrame(int arg);
-
private Q_SLOTS:
void createEngine();
diff --git a/src/quick/items/qquickanimatedsprite_p_p.h b/src/quick/items/qquickanimatedsprite_p_p.h
index 3610e58861..fb8faefbee 100644
--- a/src/quick/items/qquickanimatedsprite_p_p.h
+++ b/src/quick/items/qquickanimatedsprite_p_p.h
@@ -57,11 +57,10 @@ QT_REQUIRE_CONFIG(quick_sprite);
#include "qquickitem_p.h"
#include "qquicksprite_p.h"
+#include "qquickanimatedsprite_p.h"
QT_BEGIN_NAMESPACE
-class QQuickAnimatedSprite;
-
class QQuickAnimatedSpritePrivate : public QQuickItemPrivate
{
Q_DECLARE_PUBLIC(QQuickAnimatedSprite)
@@ -78,6 +77,7 @@ public:
, m_loops(-1)
, m_curLoop(0)
, m_pauseOffset(0)
+ , m_finishBehavior(QQuickAnimatedSprite::FinishAtInitialFrame)
{
}
@@ -93,6 +93,7 @@ public:
int m_loops;
int m_curLoop;
int m_pauseOffset;
+ QQuickAnimatedSprite::FinishBehavior m_finishBehavior;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp
index 462a44634e..3679df37d1 100644
--- a/src/quick/items/qquickborderimage.cpp
+++ b/src/quick/items/qquickborderimage.cpp
@@ -168,6 +168,7 @@ QT_BEGIN_NAMESPACE
QQuickBorderImage::QQuickBorderImage(QQuickItem *parent)
: QQuickImageBase(*(new QQuickBorderImagePrivate), parent)
{
+ connect(this, &QQuickImageBase::sourceSizeChanged, this, &QQuickBorderImage::sourceSizeChanged);
}
QQuickBorderImage::~QQuickBorderImage()
@@ -295,20 +296,7 @@ void QQuickBorderImage::load()
Q_D(QQuickBorderImage);
if (d->url.isEmpty()) {
- d->pix.clear(this);
- d->status = Null;
- setImplicitSize(0, 0);
- emit statusChanged(d->status);
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
- if (sourceSize() != d->oldSourceSize) {
- d->oldSourceSize = sourceSize();
- emit sourceSizeChanged();
- }
- pixmapChange();
- return;
+ loadEmptyUrl();
} else {
if (d->url.path().endsWith(QLatin1String("sci"))) {
QString lf = QQmlFile::urlToLocalFileOrQrc(d->url);
@@ -316,7 +304,6 @@ void QQuickBorderImage::load()
QFile file(lf);
file.open(QIODevice::ReadOnly);
setGridScaledImage(QQuickGridScaledImage(&file));
- return;
} else {
#if QT_CONFIG(qml_network)
if (d->progress != 0.0) {
@@ -328,50 +315,13 @@ void QQuickBorderImage::load()
d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
qmlobject_connect(d->sciReply, QNetworkReply, SIGNAL(finished()),
this, QQuickBorderImage, SLOT(sciRequestFinished()));
+ emit statusChanged(d->status);
#endif
}
} else {
- QQuickPixmap::Options options;
- if (d->async)
- options |= QQuickPixmap::Asynchronous;
- if (d->cache)
- options |= QQuickPixmap::Cache;
- d->pix.clear(this);
-
- const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qGuiApp->devicePixelRatio());
- d->devicePixelRatio = 1.0;
-
- QUrl loadUrl = d->url;
- resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
- d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options, QQuickImageProviderOptions(), d->currentFrame, d->frameCount);
-
- if (d->pix.isLoading()) {
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
- d->status = Loading;
-
- static int thisRequestProgress = -1;
- static int thisRequestFinished = -1;
- if (thisRequestProgress == -1) {
- thisRequestProgress =
- QQuickImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
- thisRequestFinished =
- QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
- }
- d->pix.connectFinished(this, thisRequestFinished);
- d->pix.connectDownloadProgress(this, thisRequestProgress);
-
- update(); //pixmap may have invalidated texture, updatePaintNode needs to be called before the next repaint
- } else {
- requestFinished();
- return;
- }
+ loadPixmap(d->url, LoadPixmapOptions(HandleDPR | UseProviderOptions));
}
}
-
- emit statusChanged(d->status);
}
/*!
@@ -472,39 +422,7 @@ void QQuickBorderImage::setGridScaledImage(const QQuickGridScaledImage& sci)
d->verticalTileMode = sci.verticalTileRule();
d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
-
- QQuickPixmap::Options options;
- if (d->async)
- options |= QQuickPixmap::Asynchronous;
- if (d->cache)
- options |= QQuickPixmap::Cache;
- d->pix.clear(this);
- d->pix.load(qmlEngine(this), d->sciurl, options);
-
- if (d->pix.isLoading()) {
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
- if (d->status != Loading) {
- d->status = Loading;
- emit statusChanged(d->status);
- }
- static int thisRequestProgress = -1;
- static int thisRequestFinished = -1;
- if (thisRequestProgress == -1) {
- thisRequestProgress =
- QQuickBorderImage::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
- thisRequestFinished =
- QQuickBorderImage::staticMetaObject.indexOfSlot("requestFinished()");
- }
-
- d->pix.connectFinished(this, thisRequestFinished);
- d->pix.connectDownloadProgress(this, thisRequestProgress);
-
- } else {
- requestFinished();
- }
+ loadPixmap(d->sciurl);
}
}
diff --git a/src/quick/items/qquickborderimage_p.h b/src/quick/items/qquickborderimage_p.h
index 61bd26ba83..515edb33da 100644
--- a/src/quick/items/qquickborderimage_p.h
+++ b/src/quick/items/qquickborderimage_p.h
@@ -67,6 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickBorderImage : public QQuickImageBase
Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)
// read-only for BorderImage
Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
+ QML_NAMED_ELEMENT(BorderImage)
public:
QQuickBorderImage(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 7c6f1caa54..32695e9245 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE
class QQuickDragAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickDragAttached)
+ QML_ANONYMOUS
+
public:
static QQuickDragAttachedPrivate *get(QQuickDragAttached *attached) {
return static_cast<QQuickDragAttachedPrivate *>(QObjectPrivate::get(attached)); }
@@ -742,8 +744,6 @@ void QQuickDragAttached::cancel()
This signal is emitted when a drag is started with the \l startDrag() method
or when it is started automatically using the \l dragType property.
-
- The corresponding handler is \c onDragStarted.
*/
/*!
@@ -754,8 +754,6 @@ void QQuickDragAttached::cancel()
\a dropAction holds the action accepted by the target item.
- The corresponding handler is \c onDragFinished.
-
\sa drop()
*/
diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h
index 094070aa2c..9dbaac18f9 100644
--- a/src/quick/items/qquickdrag_p.h
+++ b/src/quick/items/qquickdrag_p.h
@@ -172,6 +172,10 @@ class Q_AUTOTEST_EXPORT QQuickDrag : public QObject
Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged RESET resetThreshold)
//### consider drag and drop
+ QML_NAMED_ELEMENT(Drag)
+ QML_UNCREATABLE("Drag is only available via attached properties.")
+ QML_ATTACHED(QQuickDragAttached)
+
public:
QQuickDrag(QObject *parent=nullptr);
~QQuickDrag();
@@ -254,6 +258,9 @@ class QQuickDragAttached : public QObject
Q_PROPERTY(Qt::DropActions supportedActions READ supportedActions WRITE setSupportedActions NOTIFY supportedActionsChanged)
Q_PROPERTY(Qt::DropAction proposedAction READ proposedAction WRITE setProposedAction NOTIFY proposedActionChanged)
Q_PROPERTY(QQuickDrag::DragType dragType READ dragType WRITE setDragType NOTIFY dragTypeChanged)
+
+ QML_ANONYMOUS
+
public:
QQuickDragAttached(QObject *parent);
~QQuickDragAttached();
@@ -316,6 +323,5 @@ Q_SIGNALS:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickDrag)
-QML_DECLARE_TYPEINFO(QQuickDrag, QML_HAS_ATTACHED_PROPERTIES)
#endif
diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp
index 76be8cc261..d90ee209d6 100644
--- a/src/quick/items/qquickdroparea.cpp
+++ b/src/quick/items/qquickdroparea.cpp
@@ -212,8 +212,6 @@ qreal QQuickDropAreaDrag::y() const
\qmlsignal QtQuick::DropArea::positionChanged(DragEvent drag)
This signal is emitted when the position of a \a drag has changed.
-
- The corresponding handler is \c onPositionChanged.
*/
void QQuickDropArea::dragMoveEvent(QDragMoveEvent *event)
@@ -254,8 +252,6 @@ QStringList QQuickDropAreaPrivate::getKeys(const QMimeData *mimeData) const
\qmlsignal QtQuick::DropArea::entered(DragEvent drag)
This signal is emitted when a \a drag enters the bounds of a DropArea.
-
- The corresponding handler is \c onEntered.
*/
void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
@@ -291,8 +287,6 @@ void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
\qmlsignal QtQuick::DropArea::exited()
This signal is emitted when a drag exits the bounds of a DropArea.
-
- The corresponding handler is \c onExited.
*/
void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
@@ -315,8 +309,6 @@ void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
This signal is emitted when a \a drop event occurs within the bounds of
a DropArea.
-
- The corresponding handler is \c onDropped.
*/
void QQuickDropArea::dropEvent(QDropEvent *event)
diff --git a/src/quick/items/qquickdroparea_p.h b/src/quick/items/qquickdroparea_p.h
index 2b2ace2eae..ee2deaa97a 100644
--- a/src/quick/items/qquickdroparea_p.h
+++ b/src/quick/items/qquickdroparea_p.h
@@ -80,6 +80,7 @@ class QQuickDropEvent : public QObject
Q_PROPERTY(QString text READ text)
Q_PROPERTY(QList<QUrl> urls READ urls)
Q_PROPERTY(QStringList formats READ formats)
+ QML_ANONYMOUS
public:
QQuickDropEvent(QQuickDropAreaPrivate *d, QDropEvent *event) : d(d), event(event) {}
@@ -125,6 +126,7 @@ class QQuickDropAreaDrag : public QObject
Q_PROPERTY(qreal x READ x NOTIFY positionChanged)
Q_PROPERTY(qreal y READ y NOTIFY positionChanged)
Q_PROPERTY(QObject *source READ source NOTIFY sourceChanged)
+ QML_ANONYMOUS
public:
QQuickDropAreaDrag(QQuickDropAreaPrivate *d, QObject *parent = 0);
~QQuickDropAreaDrag();
@@ -151,6 +153,7 @@ class Q_AUTOTEST_EXPORT QQuickDropArea : public QQuickItem
Q_PROPERTY(bool containsDrag READ containsDrag NOTIFY containsDragChanged)
Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged)
Q_PROPERTY(QQuickDropAreaDrag *drag READ drag CONSTANT)
+ QML_NAMED_ELEMENT(DropArea)
public:
QQuickDropArea(QQuickItem *parent=0);
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index b5644d55e6..950afaed52 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -597,8 +597,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(ConstructableQQuickPointerDevice, g_genericMouseDevice
QQuickPointerDevice::Position | QQuickPointerDevice::Scroll | QQuickPointerDevice::Hover,
1, 3, QLatin1String("core pointer"), 0))
+#if QT_CONFIG(tabletevent)
typedef QHash<qint64, QQuickPointerDevice *> PointerDeviceForDeviceIdHash;
Q_GLOBAL_STATIC(PointerDeviceForDeviceIdHash, g_tabletDevices)
+#endif
// debugging helpers
static const char *pointStateString(const QQuickEventPoint *point)
@@ -658,15 +660,76 @@ QQuickPointerDevice *QQuickPointerDevice::genericMouseDevice()
return g_genericMouseDevice;
}
-QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id)
+#if QT_CONFIG(tabletevent)
+QQuickPointerDevice *QQuickPointerDevice::tabletDevice(const QTabletEvent *event)
{
- auto it = g_tabletDevices->find(id);
+ // 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->deviceType()) {
+ 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;
}
+#endif
/*!
\qmltype EventPoint
@@ -852,7 +915,7 @@ void QQuickEventPoint::setGrabberItem(QQuickItem *grabber)
if (oldGrabberHandler && !oldGrabberHandler->approveGrabTransition(this, grabber))
return;
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
- qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this) << "@" << m_scenePos
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this) << "@" << m_scenePos
<< ": grab" << m_exclusiveGrabber << "->" << grabber;
}
QQuickItem *oldGrabberItem = grabberItem();
@@ -893,10 +956,10 @@ void QQuickEventPoint::setGrabberPointerHandler(QQuickPointerHandler *grabber, b
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
if (exclusive) {
if (m_exclusiveGrabber != grabber)
- qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
<< ": grab (exclusive)" << m_exclusiveGrabber << "->" << grabber;
} else {
- qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
<< ": grab (passive)" << grabber;
}
}
@@ -959,7 +1022,7 @@ void QQuickEventPoint::cancelExclusiveGrabImpl(QTouchEvent *cancelEvent)
if (m_exclusiveGrabber.isNull())
return;
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
- qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
<< ": grab (exclusive)" << m_exclusiveGrabber << "-> nullptr";
}
if (auto handler = grabberPointerHandler()) {
@@ -982,7 +1045,7 @@ void QQuickEventPoint::cancelPassiveGrab(QQuickPointerHandler *handler)
{
if (removePassiveGrabber(handler)) {
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
- qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
<< ": grab (passive)" << handler << "removed";
}
handler->onGrabChanged(handler, CancelGrabPassive, this);
@@ -1284,6 +1347,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 +1467,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 +1635,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);
@@ -1626,6 +1707,8 @@ bool QQuickSinglePointEvent::allPointsGrabbed() const
QMouseEvent *QQuickPointerMouseEvent::asMouseEvent(const QPointF &localPos) const
{
+ if (!m_event)
+ return nullptr;
auto event = static_cast<QMouseEvent *>(m_event);
event->setLocalPos(localPos);
return event;
@@ -1661,6 +1744,8 @@ bool QQuickSinglePointEvent::hasExclusiveGrabber(const QQuickPointerHandler *han
bool QQuickPointerMouseEvent::isPressEvent() const
{
+ if (!m_event)
+ return false;
auto me = static_cast<QMouseEvent*>(m_event);
return ((me->type() == QEvent::MouseButtonPress || me->type() == QEvent::MouseButtonDblClick) &&
(me->buttons() & me->button()) == me->buttons());
@@ -1668,18 +1753,24 @@ bool QQuickPointerMouseEvent::isPressEvent() const
bool QQuickPointerMouseEvent::isDoubleClickEvent() const
{
+ if (!m_event)
+ return false;
auto me = static_cast<QMouseEvent*>(m_event);
return (me->type() == QEvent::MouseButtonDblClick);
}
bool QQuickPointerMouseEvent::isUpdateEvent() const
{
+ if (!m_event)
+ return false;
auto me = static_cast<QMouseEvent*>(m_event);
return me->type() == QEvent::MouseMove;
}
bool QQuickPointerMouseEvent::isReleaseEvent() const
{
+ if (!m_event)
+ return false;
auto me = static_cast<QMouseEvent*>(m_event);
return me && me->type() == QEvent::MouseButtonRelease;
}
@@ -1830,6 +1921,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
{
@@ -1998,7 +2164,7 @@ QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool i
tpCopy.setPos(item->mapFromScene(tpCopy.scenePos()));
tpCopy.setLastPos(item->mapFromScene(tpCopy.lastScenePos()));
tpCopy.setStartPos(item->mapFromScene(tpCopy.startScenePos()));
- tpCopy.setRect(item->mapRectFromScene(tpCopy.sceneRect()));
+ tpCopy.setEllipseDiameters(tpCopy.ellipseDiameters());
tpCopy.setVelocity(transformMatrix.mapVector(tpCopy.velocity()).toVector2D());
touchPoints << tpCopy;
}
@@ -2102,7 +2268,7 @@ Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickEventPoint *eve
dbg << "QQuickEventPoint(accepted:" << event->isAccepted()
<< " state:";
QtDebugUtils::formatQEnum(dbg, event->state());
- dbg << " scenePos:" << event->scenePosition() << " id:" << hex << event->pointId() << dec
+ dbg << " scenePos:" << event->scenePosition() << " id:" << Qt::hex << event->pointId() << Qt::dec
<< " timeHeld:" << event->timeHeld() << ')';
return dbg;
}
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 1a3737091f..7004b341de 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -58,7 +58,9 @@
#include <QtCore/qpointer.h>
#include <QtGui/qvector2d.h>
#include <QtGui/qevent.h>
-#include <QtGui/qkeysequence.h>
+#if QT_CONFIG(shortcut)
+# include <QtGui/qkeysequence.h>
+#endif
#include <QtQuick/qquickitem.h>
QT_BEGIN_NAMESPACE
@@ -84,10 +86,11 @@ class QQuickKeyEvent : public QObject
Q_PROPERTY(int count READ count CONSTANT)
Q_PROPERTY(quint32 nativeScanCode READ nativeScanCode CONSTANT)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+ QML_ANONYMOUS
public:
QQuickKeyEvent()
- : event(QEvent::None, 0, nullptr)
+ : event(QEvent::None, 0, { })
{}
void reset(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
@@ -135,17 +138,17 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseEvent : public QObject
Q_PROPERTY(bool isClick READ isClick CONSTANT)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
Q_PROPERTY(int flags READ flags CONSTANT REVISION 11)
+ QML_ANONYMOUS
public:
QQuickMouseEvent()
: _buttons(Qt::NoButton), _modifiers(Qt::NoModifier)
, _wasHeld(false), _isClick(false), _accepted(false)
- , _flags(Qt::MouseEventFlags(nullptr))
{}
void reset(qreal x, qreal y, Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers, bool isClick = false, bool wasHeld = false,
- Qt::MouseEventFlags flags = nullptr)
+ Qt::MouseEventFlags flags = { })
{
_x = x;
_y = y;
@@ -201,6 +204,7 @@ class QQuickWheelEvent : public QObject
Q_PROPERTY(int modifiers READ modifiers CONSTANT)
Q_PROPERTY(bool inverted READ inverted CONSTANT)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+ QML_ANONYMOUS
public:
QQuickWheelEvent()
@@ -245,6 +249,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickCloseEvent : public QObject
{
Q_OBJECT
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+ QML_ANONYMOUS
public:
QQuickCloseEvent() {}
@@ -271,6 +276,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventPoint : public QObject
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
Q_PROPERTY(QObject *exclusiveGrabber READ exclusiveGrabber WRITE setExclusiveGrabber)
+ QML_NAMED_ELEMENT(EventPoint)
+ QML_UNCREATABLE("EventPoint is only available as a member of PointerEvent.")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
enum State {
Pressed = Qt::TouchPointPressed,
@@ -362,6 +371,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventTouchPoint : public QQuickEventPoint
Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters)
Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId)
+ QML_NAMED_ELEMENT(EventTouchPoint)
+ QML_UNCREATABLE("EventTouchPoint is only available as a member of PointerEvent.")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
QQuickEventTouchPoint(QQuickPointerTouchEvent *parent);
@@ -391,6 +404,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerEvent : public QObject
Q_PROPERTY(Qt::MouseButtons button READ button CONSTANT)
Q_PROPERTY(Qt::MouseButtons buttons READ buttons CONSTANT)
+ QML_NAMED_ELEMENT(PointerEvent)
+ QML_UNCREATABLE("PointerEvent is only available as a parameter of several signals in PointerHandler")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
QQuickPointerEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
: QObject(parent)
@@ -459,8 +476,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; }
@@ -474,7 +491,7 @@ public:
bool hasExclusiveGrabber(const QQuickPointerHandler *handler) const override;
protected:
- QQuickEventPoint *m_point;
+ QQuickEventPoint *m_point = nullptr;
Q_DISABLE_COPY(QQuickSinglePointEvent)
};
@@ -482,9 +499,13 @@ protected:
class Q_QUICK_PRIVATE_EXPORT QQuickPointerMouseEvent : public QQuickSinglePointEvent
{
Q_OBJECT
+
+ QML_NAMED_ELEMENT(PointerMouseEvent)
+ QML_UNCREATABLE("PointerMouseEvent is only available as a parameter of several signals in PointerHandler")
+ 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;
@@ -502,6 +523,11 @@ public:
class Q_QUICK_PRIVATE_EXPORT QQuickPointerTouchEvent : public QQuickPointerEvent
{
Q_OBJECT
+
+ QML_NAMED_ELEMENT(PointerTouchEvent)
+ QML_UNCREATABLE("PointerTouchEvent is only available as a parameter of several signals in PointerHandler")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
QQuickPointerTouchEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
: QQuickPointerEvent(parent, device)
@@ -541,6 +567,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
{
@@ -549,8 +629,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;
@@ -574,9 +653,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerScrollEvent : public QQuickSinglePoint
Q_PROPERTY(bool hasPixelDelta READ hasPixelDelta CONSTANT)
Q_PROPERTY(bool inverted READ isInverted CONSTANT)
+ QML_NAMED_ELEMENT(PointerScrollEvent)
+ QML_UNCREATABLE("PointerScrollEvent is only available via the WheelHandler::wheel signal.")
+ 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;
@@ -623,6 +705,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerDevice : public QObject
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId CONSTANT)
+ QML_NAMED_ELEMENT(PointerDevice)
+ QML_UNCREATABLE("PointerDevice is only available as a property of PointerEvent.")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
enum DeviceType : qint16 {
UnknownDevice = 0x0000,
@@ -677,7 +763,9 @@ public:
static QQuickPointerDevice *touchDevice(const QTouchDevice *d);
static QList<QQuickPointerDevice *> touchDevices();
static QQuickPointerDevice *genericMouseDevice();
- static QQuickPointerDevice *tabletDevice(qint64);
+#if QT_CONFIG(tabletevent)
+ static QQuickPointerDevice *tabletDevice(const QTabletEvent *event);
+#endif
QVector<QQuickPointerHandler *> &eventDeliveryTargets() { return m_eventDeliveryTargets; }
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 445fa0215b..c91a5ef92b 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -327,7 +327,7 @@ void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometr
{
Q_Q(QQuickFlickable);
if (item == contentItem) {
- Qt::Orientations orient = nullptr;
+ Qt::Orientations orient;
if (change.xChange())
orient |= Qt::Horizontal;
if (change.yChange())
@@ -591,8 +591,6 @@ void QQuickFlickablePrivate::updateBeginningEnd()
This signal is emitted when the view starts to be dragged due to user
interaction.
-
- The corresponding handler is \c onDragStarted.
*/
/*!
@@ -602,8 +600,6 @@ void QQuickFlickablePrivate::updateBeginningEnd()
If the velocity of the drag is sufficient at the time the
touch/mouse button is released then a flick will start.
-
- The corresponding handler is \c onDragEnded.
*/
/*!
@@ -689,8 +685,6 @@ void QQuickFlickablePrivate::updateBeginningEnd()
This signal is emitted when the view begins moving due to user
interaction or a generated flick().
-
- The corresponding handler is \c onMovementStarted.
*/
/*!
@@ -701,8 +695,6 @@ void QQuickFlickablePrivate::updateBeginningEnd()
be emitted once the flick stops. If a flick was not
active, this signal will be emitted when the
user stops dragging - i.e. a mouse or touch release.
-
- The corresponding handler is \c onMovementEnded.
*/
/*!
@@ -711,16 +703,12 @@ void QQuickFlickablePrivate::updateBeginningEnd()
This signal is emitted when the view is flicked. A flick
starts from the point that the mouse or touch is released,
while still in motion.
-
- The corresponding handler is \c onFlickStarted.
*/
/*!
\qmlsignal QtQuick::Flickable::flickEnded()
This signal is emitted when the view stops moving due to a flick.
-
- The corresponding handler is \c onFlickEnded.
*/
/*!
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index c54ed5ce71..2d8d4a5e9a 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -114,6 +114,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem
Q_PROPERTY(QQmlListProperty<QObject> flickableData READ flickableData)
Q_PROPERTY(QQmlListProperty<QQuickItem> flickableChildren READ flickableChildren)
Q_CLASSINFO("DefaultProperty", "flickableData")
+ QML_NAMED_ELEMENT(Flickable)
public:
QQuickFlickable(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 835c54170f..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)
@@ -284,6 +284,7 @@ class QQuickFlickableVisibleArea : public QObject
Q_PROPERTY(qreal yPosition READ yPosition NOTIFY yPositionChanged)
Q_PROPERTY(qreal widthRatio READ widthRatio NOTIFY widthRatioChanged)
Q_PROPERTY(qreal heightRatio READ heightRatio NOTIFY heightRatioChanged)
+ QML_ANONYMOUS
public:
QQuickFlickableVisibleArea(QQuickFlickable *parent=nullptr);
diff --git a/src/quick/items/qquickflipable_p.h b/src/quick/items/qquickflipable_p.h
index d70cd02d35..42c632a33c 100644
--- a/src/quick/items/qquickflipable_p.h
+++ b/src/quick/items/qquickflipable_p.h
@@ -71,6 +71,7 @@ class Q_AUTOTEST_EXPORT QQuickFlipable : public QQuickItem
Q_PROPERTY(QQuickItem *front READ front WRITE setFront NOTIFY frontChanged)
Q_PROPERTY(QQuickItem *back READ back WRITE setBack NOTIFY backChanged)
Q_PROPERTY(Side side READ side NOTIFY sideChanged)
+ QML_NAMED_ELEMENT(Flipable)
//### flipAxis
//### flipRotation
public:
diff --git a/src/quick/items/qquickfocusscope_p.h b/src/quick/items/qquickfocusscope_p.h
index af750fc127..c32fa93cd9 100644
--- a/src/quick/items/qquickfocusscope_p.h
+++ b/src/quick/items/qquickfocusscope_p.h
@@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE
class Q_AUTOTEST_EXPORT QQuickFocusScope : public QQuickItem
{
Q_OBJECT
+ QML_NAMED_ELEMENT(FocusScope)
public:
QQuickFocusScope(QQuickItem *parent=nullptr);
virtual ~QQuickFocusScope();
diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp
index 190bc6853c..d5550e78b6 100644
--- a/src/quick/items/qquickframebufferobject.cpp
+++ b/src/quick/items/qquickframebufferobject.cpp
@@ -83,6 +83,11 @@ public:
* Everything that relates to rendering must be located in the
* QQuickFramebufferObject::Renderer class.
*
+ * \warning This class is only functional when Qt Quick is rendering
+ * via OpenGL, either directly or through the \l{Scene Graph
+ * Adaptations}{RHI-based rendering path}. It is not compatible with
+ * other RHI backends, such as, Vulkan or Metal.
+ *
* To avoid race conditions and read/write issues from two threads
* it is important that the renderer and the item never read or
* write shared variables. Communication between the item and the renderer
@@ -109,10 +114,6 @@ public:
* and can be used directly in \l {ShaderEffect}{ShaderEffects} and other
* classes that consume texture providers.
*
- * \warning This class is only suitable when working directly with OpenGL. It
- * is not compatible with the \l{Scene Graph Adaptations}{RHI-based rendering
- * path}.
- *
* \sa {Scene Graph - Rendering FBOs}, {Scene Graph and Rendering}
*/
@@ -233,6 +234,13 @@ public Q_SLOTS:
{
if (renderPending) {
renderPending = false;
+
+ const bool needsWrap = QSGRendererInterface::isApiRhiBased(window->rendererInterface()->graphicsApi());
+ if (needsWrap) {
+ window->beginExternalCommands();
+ window->resetOpenGLState();
+ }
+
fbo->bind();
QOpenGLContext::currentContext()->functions()->glViewport(0, 0, fbo->width(), fbo->height());
renderer->render();
@@ -241,6 +249,9 @@ public Q_SLOTS:
if (msDisplayFbo)
QOpenGLFramebufferObject::blitFramebuffer(msDisplayFbo, fbo);
+ if (needsWrap)
+ window->endExternalCommands();
+
markDirty(QSGNode::DirtyMaterial);
emit textureChanged();
}
@@ -270,7 +281,8 @@ public:
static inline bool isOpenGL(QSGRenderContext *rc)
{
QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
- return !rif || rif->graphicsApi() == QSGRendererInterface::OpenGL;
+ return rif && (rif->graphicsApi() == QSGRendererInterface::OpenGL
+ || rif->graphicsApi() == QSGRendererInterface::OpenGLRhi);
}
/*!
@@ -335,9 +347,11 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode
displayTexture = n->msDisplayFbo->texture();
}
- n->setTexture(window()->createTextureFromId(displayTexture,
- n->fbo->size(),
- QQuickWindow::TextureHasAlphaChannel));
+ QSGTexture *wrapper = window()->createTextureFromNativeObject(QQuickWindow::NativeObjectTexture,
+ &displayTexture, 0,
+ n->fbo->size(),
+ QQuickWindow::TextureHasAlphaChannel);
+ n->setTexture(wrapper);
}
n->setTextureCoordinatesTransform(d->mirrorVertically ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform);
diff --git a/src/quick/items/qquickframebufferobject.h b/src/quick/items/qquickframebufferobject.h
index db143e48cf..e26c8293a6 100644
--- a/src/quick/items/qquickframebufferobject.h
+++ b/src/quick/items/qquickframebufferobject.h
@@ -48,7 +48,8 @@ class QOpenGLFramebufferObject;
class QQuickFramebufferObjectPrivate;
class QSGFramebufferObjectNode;
-// ### Qt 6: To be removed. To be seen if an alternative will need to be introduced.
+// ### Qt 6: Consider what to do here. QQuickFbo supports both direct OpenGL and
+// OpenGL via QRhi, but it cannot function when running with another rhi backend.
class Q_QUICK_EXPORT QQuickFramebufferObject : public QQuickItem
{
diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp
index df61ee853d..a3d04f5dd3 100644
--- a/src/quick/items/qquickgenericshadereffect.cpp
+++ b/src/quick/items/qquickgenericshadereffect.cpp
@@ -78,7 +78,6 @@ QQuickGenericShaderEffect::QQuickGenericShaderEffect(QQuickShaderEffect *item, Q
, m_mgr(nullptr)
, m_fragNeedsUpdate(true)
, m_vertNeedsUpdate(true)
- , m_dirty(nullptr)
{
qRegisterMetaType<QSGGuiThreadShaderEffectManager::ShaderInfo::Type>("ShaderInfo::Type");
for (int i = 0; i < NShader; ++i)
@@ -311,7 +310,7 @@ QSGNode *QQuickGenericShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQui
m_dirty &= ~QSGShaderEffectNode::DirtyShaderGeometry;
}
- m_dirty = nullptr;
+ m_dirty = {};
for (int i = 0; i < NShader; ++i) {
m_dirtyConstants[i].clear();
m_dirtyTextures[i].clear();
diff --git a/src/quick/items/qquickgraphicsinfo_p.h b/src/quick/items/qquickgraphicsinfo_p.h
index f0a18c29cc..066a419c37 100644
--- a/src/quick/items/qquickgraphicsinfo_p.h
+++ b/src/quick/items/qquickgraphicsinfo_p.h
@@ -75,6 +75,11 @@ class QQuickGraphicsInfo : public QObject
Q_PROPERTY(OpenGLContextProfile profile READ profile NOTIFY profileChanged FINAL)
Q_PROPERTY(RenderableType renderableType READ renderableType NOTIFY renderableTypeChanged FINAL)
+ QML_NAMED_ELEMENT(GraphicsInfo)
+ QML_ADDED_IN_MINOR_VERSION(8)
+ QML_UNCREATABLE("GraphicsInfo is only available via attached properties.")
+ QML_ATTACHED(QQuickGraphicsInfo)
+
public:
enum GraphicsApi {
Unknown = QSGRendererInterface::Unknown,
@@ -168,6 +173,4 @@ private:
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickGraphicsInfo, QML_HAS_ATTACHED_PROPERTIES)
-
#endif // QQUICKGRAPHICSINFO_P_H
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index e69e9cff46..7ca5b0c34c 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -497,7 +497,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
// We've jumped more than a page. Estimate which items are now
// visible and fill from there.
int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
- releaseVisibleItems();
+ releaseVisibleItems(reusableFlag);
modelIndex += count;
if (modelIndex >= model->count())
modelIndex = model->count() - 1;
@@ -576,7 +576,7 @@ void QQuickGridViewPrivate::removeItem(FxViewItem *item)
item->releaseAfterTransition = true;
releasePendingTransition.append(item);
} else {
- releaseItem(item);
+ releaseItem(item, QQmlDelegateModel::NotReusable);
}
}
@@ -1298,8 +1298,6 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
/*!
\qmlattachedsignal QtQuick::GridView::add()
This attached signal is emitted immediately after an item is added to the view.
-
- The corresponding handler is \c onAdd.
*/
/*!
@@ -1308,8 +1306,6 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
If a \l remove transition has been specified, it is applied after
this signal is handled, providing that \l delayRemove is false.
-
- The corresponding handler is \c onRemove.
*/
diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h
index 7daeaf41a1..9072e5f269 100644
--- a/src/quick/items/qquickgridview_p.h
+++ b/src/quick/items/qquickgridview_p.h
@@ -73,6 +73,8 @@ class Q_AUTOTEST_EXPORT QQuickGridView : public QQuickItemView
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
Q_CLASSINFO("DefaultProperty", "data")
+ QML_NAMED_ELEMENT(GridView)
+ QML_ATTACHED(QQuickGridViewAttached)
public:
enum Flow {
@@ -136,6 +138,5 @@ public:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickGridView)
-QML_DECLARE_TYPEINFO(QQuickGridView, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKGRIDVIEW_P_H
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index 840cfe15da..1882ec8997 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -76,14 +76,8 @@ QSGTexture *QQuickImageTextureProvider::texture() const {
}
QQuickImagePrivate::QQuickImagePrivate()
- : fillMode(QQuickImage::Stretch)
- , paintedWidth(0)
- , paintedHeight(0)
- , pixmapChanged(false)
+ : pixmapChanged(false)
, mipmap(false)
- , hAlign(QQuickImage::AlignHCenter)
- , vAlign(QQuickImage::AlignVCenter)
- , provider(nullptr)
{
}
@@ -433,10 +427,10 @@ qreal QQuickImage::paintedHeight() const
/*!
\qmlproperty QSize QtQuick::Image::sourceSize
- This property holds the actual width and height of the loaded image.
+ This property holds the scaled width and height of the full-frame image.
Unlike the \l {Item::}{width} and \l {Item::}{height} properties, which scale
- the painting of the image, this property sets the actual number of pixels
+ the painting of the image, this property sets the maximum number of pixels
stored for the loaded image so that large images do not use more
memory than necessary. For example, this ensures the image in memory is no
larger than 1024x1024 pixels, regardless of the Image's \l {Item::}{width} and
@@ -461,7 +455,7 @@ qreal QQuickImage::paintedHeight() const
other dimension is set in proportion to preserve the source image's aspect ratio.
(The \l fillMode is independent of this.)
- If both the sourceSize.width and sourceSize.height are set the image will be scaled
+ If both the sourceSize.width and sourceSize.height are set, the image will be scaled
down to fit within the specified size (unless PreserveAspectCrop or PreserveAspectFit
are used, then it will be scaled to match the optimal size for cropping/fitting),
maintaining the image's aspect ratio. The actual
@@ -476,6 +470,9 @@ qreal QQuickImage::paintedHeight() const
be no greater than this property specifies. For some formats (currently only JPEG),
the whole image will never actually be loaded into memory.
+ If the \l sourceClipRect property is also set, \c sourceSize determines the scale,
+ but it will be clipped to the size of the clip rectangle.
+
sourceSize can be cleared to the natural size of the image
by setting sourceSize to \c undefined.
@@ -484,6 +481,51 @@ qreal QQuickImage::paintedHeight() const
*/
/*!
+ \qmlproperty rect QtQuick::Image::sourceClipRect
+ \since 5.15
+
+ This property, if set, holds the rectangular region of the source image to
+ be loaded.
+
+ The \c sourceClipRect works together with the \l sourceSize property to
+ conserve system resources when only a portion of an image needs to be
+ loaded.
+
+ \code
+ Rectangle {
+ width: ...
+ height: ...
+
+ Image {
+ anchors.fill: parent
+ source: "reallyBigImage.svg"
+ sourceSize.width: 1024
+ sourceSize.height: 1024
+ sourceClipRect: Qt.rect(100, 100, 512, 512)
+ }
+ }
+ \endcode
+
+ In the above example, we conceptually scale the SVG graphic to 1024x1024
+ first, and then cut out a region of interest that is 512x512 pixels from a
+ location 100 pixels from the top and left edges. Thus \c sourceSize
+ determines the scale, but the actual output image is 512x512 pixels.
+
+ Some image formats are able to conserve CPU time by rendering only the
+ specified region. Others will need to load the entire image first and then
+ clip it to the specified region.
+
+ This property can be cleared to reload the entire image by setting
+ \c sourceClipRect to \c undefined.
+
+ \note \e {Changing this property dynamically causes the image source to be reloaded,
+ potentially even from the network, if it is not in the disk cache.}
+
+ \note Sub-pixel clipping is not supported: the given rectangle will be
+ passed to \l QImageReader::setScaledClipRect().
+*/
+
+/*!
\qmlproperty url QtQuick::Image::source
Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h
index 257cde5313..e22a94c5af 100644
--- a/src/quick/items/qquickimage_p.h
+++ b/src/quick/items/qquickimage_p.h
@@ -68,6 +68,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImage : public QQuickImageBase
Q_PROPERTY(VAlignment verticalAlignment READ verticalAlignment WRITE setVerticalAlignment NOTIFY verticalAlignmentChanged)
Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged REVISION 3)
Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION 5)
+ Q_PROPERTY(QRectF sourceClipRect READ sourceClipRect WRITE setSourceClipRect RESET resetSourceClipRect NOTIFY sourceClipRectChanged REVISION 15)
+ QML_NAMED_ELEMENT(Image)
public:
QQuickImage(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickimage_p_p.h b/src/quick/items/qquickimage_p_p.h
index e2c467c311..1c4ba88655 100644
--- a/src/quick/items/qquickimage_p_p.h
+++ b/src/quick/items/qquickimage_p_p.h
@@ -80,19 +80,18 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImagePrivate : public QQuickImageBasePrivate
public:
QQuickImagePrivate();
-
- QQuickImage::FillMode fillMode;
- qreal paintedWidth;
- qreal paintedHeight;
void setImage(const QImage &img);
void setPixmap(const QQuickPixmap &pixmap);
bool pixmapChanged : 1;
bool mipmap : 1;
- QQuickImage::HAlignment hAlign;
- QQuickImage::VAlignment vAlign;
+ QQuickImage::HAlignment hAlign = QQuickImage::AlignHCenter;
+ QQuickImage::VAlignment vAlign = QQuickImage::AlignVCenter;
+ QQuickImage::FillMode fillMode = QQuickImage::Stretch;
- QQuickImageTextureProvider *provider;
+ qreal paintedWidth = 0;
+ qreal paintedHeight = 0;
+ QQuickImageTextureProvider *provider = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index 8bab14bfd1..8849c2005c 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -167,6 +167,29 @@ void QQuickImageBase::resetSourceSize()
setSourceSize(QSize());
}
+QRectF QQuickImageBase::sourceClipRect() const
+{
+ Q_D(const QQuickImageBase);
+ return d->sourceClipRect;
+}
+
+void QQuickImageBase::setSourceClipRect(const QRectF &r)
+{
+ Q_D(QQuickImageBase);
+ if (d->sourceClipRect == r)
+ return;
+
+ d->sourceClipRect = r;
+ emit sourceClipRectChanged();
+ if (isComponentComplete())
+ load();
+}
+
+void QQuickImageBase::resetSourceClipRect()
+{
+ setSourceClipRect(QRect());
+}
+
bool QQuickImageBase::cache() const
{
Q_D(const QQuickImageBase);
@@ -241,46 +264,47 @@ int QQuickImageBase::frameCount() const
return d->frameCount;
}
-void QQuickImageBase::load()
+void QQuickImageBase::loadEmptyUrl()
{
Q_D(QQuickImageBase);
+ d->pix.clear(this);
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ d->status = Null;
+ setImplicitSize(0, 0); // also called in QQuickImageBase::pixmapChange, but not QQuickImage/QQuickBorderImage overrides
+ pixmapChange(); // This calls update() in QQuickBorderImage and QQuickImage, not in QQuickImageBase...
- if (d->url.isEmpty()) {
- d->pix.clear(this);
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
- pixmapChange();
- d->status = Null;
- emit statusChanged(d->status);
-
- if (sourceSize() != d->oldSourceSize) {
- d->oldSourceSize = sourceSize();
- emit sourceSizeChanged();
- }
- if (autoTransform() != d->oldAutoTransform) {
- d->oldAutoTransform = autoTransform();
- emitAutoTransformBaseChanged();
- }
- update();
-
- } else {
- QQuickPixmap::Options options;
- if (d->async)
- options |= QQuickPixmap::Asynchronous;
- if (d->cache)
- options |= QQuickPixmap::Cache;
- d->pix.clear(this);
+ emit statusChanged(d->status);
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
+ emit sourceSizeChanged();
+ }
+ if (autoTransform() != d->oldAutoTransform) {
+ d->oldAutoTransform = autoTransform();
+ emitAutoTransformBaseChanged();
+ }
+ update(); // .. but double updating should be harmless
+}
+void QQuickImageBase::loadPixmap(const QUrl &url, LoadPixmapOptions loadOptions)
+{
+ Q_D(QQuickImageBase);
+ QQuickPixmap::Options options;
+ if (d->async)
+ options |= QQuickPixmap::Asynchronous;
+ if (d->cache)
+ options |= QQuickPixmap::Cache;
+ d->pix.clear(this);
+ QUrl loadUrl = url;
+ QQmlEngine* engine = qmlEngine(this);
+ if (engine && engine->urlInterceptor())
+ loadUrl = engine->urlInterceptor()->intercept(loadUrl, QQmlAbstractUrlInterceptor::UrlString);
+
+ if (loadOptions & HandleDPR) {
const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio());
d->devicePixelRatio = 1.0;
-
- QUrl loadUrl = d->url;
- QQmlEngine* engine = qmlEngine(this);
- if (engine && engine->urlInterceptor())
- loadUrl = engine->urlInterceptor()->intercept(loadUrl, QQmlAbstractUrlInterceptor::UrlString);
-
bool updatedDevicePixelRatio = false;
if (d->sourcesize.isValid())
updatedDevicePixelRatio = d->updateDevicePixelRatio(targetDevicePixelRatio);
@@ -290,34 +314,52 @@ void QQuickImageBase::load()
// an "@2x" file is found.
resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
}
+ }
- d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options, d->providerOptions, d->currentFrame, d->frameCount);
-
- if (d->pix.isLoading()) {
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
- if (d->status != Loading) {
- d->status = Loading;
- emit statusChanged(d->status);
- }
-
- static int thisRequestProgress = -1;
- static int thisRequestFinished = -1;
- if (thisRequestProgress == -1) {
- thisRequestProgress =
- QQuickImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
- thisRequestFinished =
- QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
- }
-
- d->pix.connectFinished(this, thisRequestFinished);
- d->pix.connectDownloadProgress(this, thisRequestProgress);
- update(); //pixmap may have invalidated texture, updatePaintNode needs to be called before the next repaint
- } else {
- requestFinished();
+ d->pix.load(qmlEngine(this),
+ loadUrl,
+ d->sourceClipRect.toRect(),
+ (loadOptions & HandleDPR) ? d->sourcesize * d->devicePixelRatio : QSize(),
+ options,
+ (loadOptions & UseProviderOptions) ? d->providerOptions : QQuickImageProviderOptions(),
+ d->currentFrame, d->frameCount);
+
+ if (d->pix.isLoading()) {
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ if (d->status != Loading) {
+ d->status = Loading;
+ emit statusChanged(d->status);
+ }
+
+ static int thisRequestProgress = -1;
+ static int thisRequestFinished = -1;
+ if (thisRequestProgress == -1) {
+ thisRequestProgress =
+ QQuickImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
+ thisRequestFinished =
+ QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
}
+
+ d->pix.connectFinished(this, thisRequestFinished);
+ d->pix.connectDownloadProgress(this, thisRequestProgress);
+ update(); //pixmap may have invalidated texture, updatePaintNode needs to be called before the next repaint
+ } else {
+ requestFinished();
+ }
+}
+
+void QQuickImageBase::load()
+{
+ Q_D(QQuickImageBase);
+
+ if (d->url.isEmpty()) {
+ loadEmptyUrl();
+ update();
+ } else {
+ loadPixmap(d->url, LoadPixmapOptions(HandleDPR | UseProviderOptions));
}
}
@@ -354,6 +396,10 @@ void QQuickImageBase::requestFinished()
d->frameCount = d->pix.frameCount();
emit frameCountChanged();
}
+ if (d->colorSpace != d->pix.colorSpace()) {
+ d->colorSpace = d->pix.colorSpace();
+ emit colorSpaceChanged();
+ }
update();
}
@@ -446,6 +492,22 @@ void QQuickImageBase::setAutoTransform(bool transform)
emitAutoTransformBaseChanged();
}
+QColorSpace QQuickImageBase::colorSpace() const
+{
+ Q_D(const QQuickImageBase);
+ return d->colorSpace;
+}
+
+void QQuickImageBase::setColorSpace(const QColorSpace &colorSpace)
+{
+ Q_D(QQuickImageBase);
+ if (d->colorSpace == colorSpace)
+ return;
+ d->colorSpace = colorSpace;
+ d->providerOptions.setTargetColorSpace(colorSpace);
+ emit colorSpaceChanged();
+}
+
QT_END_NAMESPACE
#include "moc_qquickimagebase_p.cpp"
diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h
index 8cd59c8cea..095547a2cf 100644
--- a/src/quick/items/qquickimagebase_p.h
+++ b/src/quick/items/qquickimagebase_p.h
@@ -53,6 +53,7 @@
#include "qquickimplicitsizeitem_p.h"
#include <private/qtquickglobal_p.h>
+#include <QtGui/qcolorspace.h>
QT_BEGIN_NAMESPACE
@@ -70,8 +71,22 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImageBase : public QQuickImplicitSizeItem
Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged)
Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged REVISION 14)
Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged REVISION 14)
+ Q_PROPERTY(QColorSpace colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged REVISION 15)
+
+ QML_NAMED_ELEMENT(ImageBase);
+ QML_ADDED_IN_MINOR_VERSION(14)
+ QML_UNCREATABLE("ImageBase is an abstract base class.")
public:
+ enum LoadPixmapOption {
+ NoOption = 0x0000,
+ HandleDPR = 0x0001,
+ UseProviderOptions = 0x0002
+ };
+
+ Q_DECLARE_FLAGS(LoadPixmapOptions, LoadPixmapOption)
+ Q_FLAG(LoadPixmapOptions)
+
QQuickImageBase(QQuickItem *parent=nullptr);
~QQuickImageBase();
enum Status { Null, Ready, Loading, Error };
@@ -94,6 +109,10 @@ public:
QSize sourceSize() const;
void resetSourceSize();
+ QRectF sourceClipRect() const;
+ void setSourceClipRect(const QRectF &r);
+ void resetSourceClipRect();
+
virtual void setMirror(bool mirror);
bool mirror() const;
@@ -105,6 +124,9 @@ public:
virtual void setAutoTransform(bool transform);
bool autoTransform() const;
+ QColorSpace colorSpace() const;
+ virtual void setColorSpace(const QColorSpace &colorSpace);
+
static void resolve2xLocalFile(const QUrl &url, qreal targetDevicePixelRatio, QUrl *sourceUrl, qreal *sourceDevicePixelRatio);
// Use a virtual rather than a signal->signal to avoid the huge
@@ -121,8 +143,12 @@ Q_SIGNALS:
void mirrorChanged();
Q_REVISION(14) void currentFrameChanged();
Q_REVISION(14) void frameCountChanged();
+ Q_REVISION(15) void sourceClipRectChanged();
+ Q_REVISION(15) void colorSpaceChanged();
protected:
+ void loadEmptyUrl();
+ void loadPixmap(const QUrl &url, LoadPixmapOptions loadOptions = NoOption);
virtual void load();
void componentComplete() override;
virtual void pixmapChange();
diff --git a/src/quick/items/qquickimagebase_p_p.h b/src/quick/items/qquickimagebase_p_p.h
index 88e18ba32e..ebb7568caf 100644
--- a/src/quick/items/qquickimagebase_p_p.h
+++ b/src/quick/items/qquickimagebase_p_p.h
@@ -86,7 +86,9 @@ public:
QSize sourcesize;
QSize oldSourceSize;
qreal devicePixelRatio;
+ QRectF sourceClipRect;
QQuickImageProviderOptions providerOptions;
+ QColorSpace colorSpace;
int currentFrame;
int frameCount;
bool async : 1;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 11c1f12e75..3f655e84fa 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -74,6 +74,7 @@
#include <private/qv4object_p.h>
#include <private/qv4qobjectwrapper_p.h>
#include <private/qdebug_p.h>
+#include <private/qqmlvaluetypewrapper_p.h>
#if QT_CONFIG(cursor)
# include <QtGui/qcursor.h>
@@ -938,8 +939,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when a key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onPressed.
*/
/*!
@@ -947,8 +946,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when a key has been released. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onReleased.
*/
/*!
@@ -986,8 +983,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
As with the other signals, \c shortcutOverride will only be emitted for an
item if that item has \l {Item::}{activeFocus}.
- The corresponding handler is \c onShortcutOverride.
-
\sa Shortcut
*/
@@ -996,8 +991,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '0' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit0Pressed.
*/
/*!
@@ -1005,8 +998,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '1' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit1Pressed.
*/
/*!
@@ -1014,8 +1005,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '2' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit2Pressed.
*/
/*!
@@ -1023,8 +1012,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '3' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit3Pressed.
*/
/*!
@@ -1032,8 +1019,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '4' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit4Pressed.
*/
/*!
@@ -1041,8 +1026,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '5' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit5Pressed.
*/
/*!
@@ -1050,8 +1033,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '6' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit6Pressed.
*/
/*!
@@ -1059,8 +1040,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '7' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit7Pressed.
*/
/*!
@@ -1068,8 +1047,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '8' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit8Pressed.
*/
/*!
@@ -1077,8 +1054,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '9' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit9Pressed.
*/
/*!
@@ -1086,8 +1061,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Left arrow has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onLeftPressed.
*/
/*!
@@ -1095,8 +1068,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Right arrow has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onRightPressed.
*/
/*!
@@ -1104,8 +1075,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Up arrow has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onUpPressed.
*/
/*!
@@ -1113,8 +1082,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Down arrow has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDownPressed.
*/
/*!
@@ -1122,8 +1089,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Tab key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onTabPressed.
*/
/*!
@@ -1131,8 +1096,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Shift+Tab key combination (Backtab) has
been pressed. The \a event parameter provides information about the event.
-
- The corresponding handler is \c onBacktabPressed.
*/
/*!
@@ -1140,8 +1103,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Asterisk '*' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onAsteriskPressed.
*/
/*!
@@ -1149,8 +1110,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Escape key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onEscapePressed.
*/
/*!
@@ -1158,8 +1117,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Return key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onReturnPressed.
*/
/*!
@@ -1167,8 +1124,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Enter key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onEnterPressed.
*/
/*!
@@ -1176,8 +1131,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Delete key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDeletePressed.
*/
/*!
@@ -1185,8 +1138,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Space key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onSpacePressed.
*/
/*!
@@ -1194,8 +1145,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Back key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onBackPressed.
*/
/*!
@@ -1203,8 +1152,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Cancel key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onCancelPressed.
*/
/*!
@@ -1212,8 +1159,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Select key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onSelectPressed.
*/
/*!
@@ -1221,8 +1166,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Yes key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onYesPressed.
*/
/*!
@@ -1230,8 +1173,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the No key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onNoPressed.
*/
/*!
@@ -1239,8 +1180,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Context1 key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onContext1Pressed.
*/
/*!
@@ -1248,8 +1187,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Context2 key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onContext2Pressed.
*/
/*!
@@ -1257,8 +1194,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Context3 key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onContext3Pressed.
*/
/*!
@@ -1266,8 +1201,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Context4 key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onContext4Pressed.
*/
/*!
@@ -1275,8 +1208,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Call key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onCallPressed.
*/
/*!
@@ -1284,8 +1215,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Hangup key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onHangupPressed.
*/
/*!
@@ -1293,8 +1222,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Flip key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onFlipPressed.
*/
/*!
@@ -1302,8 +1229,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Menu key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onMenuPressed.
*/
/*!
@@ -1311,8 +1236,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the VolumeUp key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onVolumeUpPressed.
*/
/*!
@@ -1320,8 +1243,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the VolumeDown key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onVolumeDownPressed.
*/
QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
@@ -1478,7 +1399,7 @@ QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
//### how robust is i == d->imeItem check?
QVariant v = i->inputMethodQuery(query);
- if (v.userType() == QVariant::RectF)
+ if (v.userType() == QMetaType::QRectF)
v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
return v;
}
@@ -3249,6 +3170,7 @@ QQuickItemPrivate::QQuickItemPrivate()
#else
, touchEnabled(false)
#endif
+ , hasCursorHandler(false)
, dirtyAttributes(0)
, nextDirtyItem(nullptr)
, prevDirtyItem(nullptr)
@@ -4055,6 +3977,9 @@ void QQuickItem::focusOutEvent(QFocusEvent * /*event*/)
press events for an item. The event information is provided by the
\a event parameter.
+ In order to receive mouse press events, \l acceptedMouseButtons() must
+ return the relevant mouse button.
+
\input item.qdocinc accepting-events
*/
void QQuickItem::mousePressEvent(QMouseEvent *event)
@@ -4067,6 +3992,10 @@ void QQuickItem::mousePressEvent(QMouseEvent *event)
move events for an item. The event information is provided by the
\a event parameter.
+ In order to receive mouse movement events, the preceding mouse press event
+ must be accepted (by overriding \l mousePressEvent(), for example) and
+ \l acceptedMouseButtons() must return the relevant mouse button.
+
\input item.qdocinc accepting-events
*/
void QQuickItem::mouseMoveEvent(QMouseEvent *event)
@@ -4079,6 +4008,10 @@ void QQuickItem::mouseMoveEvent(QMouseEvent *event)
release events for an item. The event information is provided by the
\a event parameter.
+ In order to receive mouse release events, the preceding mouse press event
+ must be accepted (by overriding \l mousePressEvent(), for example) and
+ \l acceptedMouseButtons() must return the relevant mouse button.
+
\input item.qdocinc accepting-events
*/
void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
@@ -4481,9 +4414,94 @@ void QQuickItem::polish()
}
}
+static bool unwrapMapFromToFromItemArgs(QQmlV4Function *args, const QQuickItem *itemForWarning, const QString &functionNameForWarning,
+ QQuickItem **itemObj, qreal *x, qreal *y, qreal *w, qreal *h, bool *isRect)
+{
+ QV4::ExecutionEngine *v4 = args->v4engine();
+ if (args->length() != 2 && args->length() != 3 && args->length() != 5) {
+ v4->throwTypeError();
+ return false;
+ }
+
+ QV4::Scope scope(v4);
+ QV4::ScopedValue item(scope, (*args)[0]);
+
+ *itemObj = nullptr;
+ if (!item->isNull()) {
+ QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>());
+ if (qobjectWrapper)
+ *itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object());
+ }
+
+ if (!(*itemObj) && !item->isNull()) {
+ qmlWarning(itemForWarning) << functionNameForWarning << " given argument \"" << item->toQStringNoThrow()
+ << "\" which is neither null nor an Item";
+ v4->throwTypeError();
+ return false;
+ }
+
+ *isRect = false;
+
+ if (args->length() == 2) {
+ QV4::ScopedValue sv(scope, (*args)[1]);
+ if (sv->isNull()) {
+ qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
+ << "\" which is neither a point nor a rect";
+ v4->throwTypeError();
+ return false;
+ }
+ const QV4::Scoped<QV4::QQmlValueTypeWrapper> variantWrapper(scope, sv->as<QV4::QQmlValueTypeWrapper>());
+ const QVariant v = variantWrapper ? variantWrapper->toVariant() : QVariant();
+ if (v.canConvert<QPointF>()) {
+ const QPointF p = v.toPointF();
+ *x = p.x();
+ *y = p.y();
+ } else if (v.canConvert<QRectF>()) {
+ const QRectF r = v.toRectF();
+ *x = r.x();
+ *y = r.y();
+ *w = r.width();
+ *h = r.height();
+ *isRect = true;
+ } else {
+ qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
+ << "\" which is neither a point nor a rect";
+ v4->throwTypeError();
+ return false;
+ }
+ } else {
+ QV4::ScopedValue vx(scope, (*args)[1]);
+ QV4::ScopedValue vy(scope, (*args)[2]);
+
+ if (!vx->isNumber() || !vy->isNumber()) {
+ v4->throwTypeError();
+ return false;
+ }
+
+ *x = vx->asDouble();
+ *y = vy->asDouble();
+
+ if (args->length() > 3) {
+ QV4::ScopedValue vw(scope, (*args)[3]);
+ QV4::ScopedValue vh(scope, (*args)[4]);
+ if (!vw->isNumber() || !vh->isNumber()) {
+ v4->throwTypeError();
+ return false;
+ }
+ *w = vw->asDouble();
+ *h = vh->asDouble();
+ *isRect = true;
+ }
+ }
+
+ return true;
+}
+
/*!
\qmlmethod object QtQuick::Item::mapFromItem(Item item, real x, real y)
+ \qmlmethod object QtQuick::Item::mapFromItem(Item item, point p)
\qmlmethod object QtQuick::Item::mapFromItem(Item item, real x, real y, real width, real height)
+ \qmlmethod object QtQuick::Item::mapFromItem(Item item, rect r)
Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
item's coordinate system, to this item's coordinate system, and returns a \l point or \l rect
@@ -4493,6 +4511,8 @@ void QQuickItem::polish()
If \a item is a \c null value, this maps the point or rect from the coordinate system of
the root QML view.
+
+ The versions accepting point and rect are since Qt 5.15.
*/
/*!
\internal
@@ -4500,55 +4520,16 @@ void QQuickItem::polish()
void QQuickItem::mapFromItem(QQmlV4Function *args) const
{
QV4::ExecutionEngine *v4 = args->v4engine();
- if (args->length() != 3 && args->length() != 5) {
- v4->throwTypeError();
- return;
- }
-
QV4::Scope scope(v4);
- QV4::ScopedValue item(scope, (*args)[0]);
-
- QQuickItem *itemObj = nullptr;
- if (!item->isNull()) {
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>());
- if (qobjectWrapper)
- itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object());
- }
- if (!itemObj && !item->isNull()) {
- qmlWarning(this) << "mapFromItem() given argument \"" << item->toQStringNoThrow()
- << "\" which is neither null nor an Item";
- v4->throwTypeError();
+ qreal x, y, w, h;
+ bool isRect;
+ QQuickItem *itemObj;
+ if (!unwrapMapFromToFromItemArgs(args, this, QStringLiteral("mapFromItem()"), &itemObj, &x, &y, &w, &h, &isRect))
return;
- }
-
- QV4::ScopedValue vx(scope, (*args)[1]);
- QV4::ScopedValue vy(scope, (*args)[2]);
- if (!vx->isNumber() || !vy->isNumber()) {
- v4->throwTypeError();
- return;
- }
-
- qreal x = vx->asDouble();
- qreal y = vy->asDouble();
-
- QVariant result;
-
- if (args->length() > 3) {
- QV4::ScopedValue vw(scope, (*args)[3]);
- QV4::ScopedValue vh(scope, (*args)[4]);
- if (!vw->isNumber() || !vh->isNumber()) {
- v4->throwTypeError();
- return;
- }
- qreal w = vw->asDouble();
- qreal h = vh->asDouble();
-
- result = mapRectFromItem(itemObj, QRectF(x, y, w, h));
- } else {
- result = mapFromItem(itemObj, QPointF(x, y));
- }
+ const QVariant result = isRect ? QVariant(mapRectFromItem(itemObj, QRectF(x, y, w, h)))
+ : QVariant(mapFromItem(itemObj, QPointF(x, y)));
QV4::ScopedObject rv(scope, v4->fromVariant(result));
args->setReturnValue(rv.asReturnedValue());
@@ -4573,7 +4554,9 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
/*!
\qmlmethod object QtQuick::Item::mapToItem(Item item, real x, real y)
+ \qmlmethod object QtQuick::Item::mapToItem(Item item, point p)
\qmlmethod object QtQuick::Item::mapToItem(Item item, real x, real y, real width, real height)
+ \qmlmethod object QtQuick::Item::mapToItem(Item item, rect r)
Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
item's coordinate system, to \a item's coordinate system, and returns a \l point or \l rect
@@ -4583,6 +4566,8 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
If \a item is a \c null value, this maps the point or rect to the coordinate system of the
root QML view.
+
+ The versions accepting point and rect are since Qt 5.15.
*/
/*!
\internal
@@ -4590,58 +4575,65 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
void QQuickItem::mapToItem(QQmlV4Function *args) const
{
QV4::ExecutionEngine *v4 = args->v4engine();
- if (args->length() != 3 && args->length() != 5) {
- v4->throwTypeError();
- return;
- }
-
QV4::Scope scope(v4);
- QV4::ScopedValue item(scope, (*args)[0]);
-
- QQuickItem *itemObj = nullptr;
- if (!item->isNull()) {
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>());
- if (qobjectWrapper)
- itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object());
- }
- if (!itemObj && !item->isNull()) {
- qmlWarning(this) << "mapToItem() given argument \"" << item->toQStringNoThrow()
- << "\" which is neither null nor an Item";
- v4->throwTypeError();
+ qreal x, y, w, h;
+ bool isRect;
+ QQuickItem *itemObj;
+ if (!unwrapMapFromToFromItemArgs(args, this, QStringLiteral("mapToItem()"), &itemObj, &x, &y, &w, &h, &isRect))
return;
- }
- QV4::ScopedValue vx(scope, (*args)[1]);
- QV4::ScopedValue vy(scope, (*args)[2]);
+ const QVariant result = isRect ? QVariant(mapRectToItem(itemObj, QRectF(x, y, w, h)))
+ : QVariant(mapToItem(itemObj, QPointF(x, y)));
+
+ QV4::ScopedObject rv(scope, v4->fromVariant(result));
+ args->setReturnValue(rv.asReturnedValue());
+}
- if (!vx->isNumber() || !vy->isNumber()) {
+static bool unwrapMapFromToFromGlobalArgs(QQmlV4Function *args, const QQuickItem *itemForWarning, const QString &functionNameForWarning, qreal *x, qreal *y)
+{
+ QV4::ExecutionEngine *v4 = args->v4engine();
+ if (args->length() != 1 && args->length() != 2) {
v4->throwTypeError();
- return;
+ return false;
}
- qreal x = vx->asDouble();
- qreal y = vy->asDouble();
+ QV4::Scope scope(v4);
- QVariant result;
+ if (args->length() == 1) {
+ QV4::ScopedValue sv(scope, (*args)[0]);
+ if (sv->isNull()) {
+ qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
+ << "\" which is not a point";
+ v4->throwTypeError();
+ return false;
+ }
+ const QV4::Scoped<QV4::QQmlValueTypeWrapper> variantWrapper(scope, sv->as<QV4::QQmlValueTypeWrapper>());
+ const QVariant v = variantWrapper ? variantWrapper->toVariant() : QVariant();
+ if (v.canConvert<QPointF>()) {
+ const QPointF p = v.toPointF();
+ *x = p.x();
+ *y = p.y();
+ } else {
+ qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
+ << "\" which is not a point";
+ v4->throwTypeError();
+ return false;
+ }
+ } else {
+ QV4::ScopedValue vx(scope, (*args)[0]);
+ QV4::ScopedValue vy(scope, (*args)[1]);
- if (args->length() > 3) {
- QV4::ScopedValue vw(scope, (*args)[3]);
- QV4::ScopedValue vh(scope, (*args)[4]);
- if (!vw->isNumber() || !vh->isNumber()) {
+ if (!vx->isNumber() || !vy->isNumber()) {
v4->throwTypeError();
- return;
+ return false;
}
- qreal w = vw->asDouble();
- qreal h = vh->asDouble();
- result = mapRectToItem(itemObj, QRectF(x, y, w, h));
- } else {
- result = mapToItem(itemObj, QPointF(x, y));
+ *x = vx->asDouble();
+ *y = vy->asDouble();
}
- QV4::ScopedObject rv(scope, v4->fromVariant(result));
- args->setReturnValue(rv.asReturnedValue());
+ return true;
}
/*!
@@ -4659,22 +4651,12 @@ void QQuickItem::mapToItem(QQmlV4Function *args) const
void QQuickItem::mapFromGlobal(QQmlV4Function *args) const
{
QV4::ExecutionEngine *v4 = args->v4engine();
- if (args->length() != 2) {
- v4->throwTypeError();
- return;
- }
-
QV4::Scope scope(v4);
- QV4::ScopedValue vx(scope, (*args)[0]);
- QV4::ScopedValue vy(scope, (*args)[1]);
- if (!vx->isNumber() || !vy->isNumber()) {
- v4->throwTypeError();
+ qreal x, y;
+ if (!unwrapMapFromToFromGlobalArgs(args, this, QStringLiteral("mapFromGlobal()"), &x, &y))
return;
- }
- qreal x = vx->asDouble();
- qreal y = vy->asDouble();
QVariant result = mapFromGlobal(QPointF(x, y));
QV4::ScopedObject rv(scope, v4->fromVariant(result));
@@ -4696,22 +4678,12 @@ void QQuickItem::mapFromGlobal(QQmlV4Function *args) const
void QQuickItem::mapToGlobal(QQmlV4Function *args) const
{
QV4::ExecutionEngine *v4 = args->v4engine();
- if (args->length() != 2) {
- v4->throwTypeError();
- return;
- }
-
QV4::Scope scope(v4);
- QV4::ScopedValue vx(scope, (*args)[0]);
- QV4::ScopedValue vy(scope, (*args)[1]);
- if (!vx->isNumber() || !vy->isNumber()) {
- v4->throwTypeError();
+ qreal x, y;
+ if (!unwrapMapFromToFromGlobalArgs(args, this, QStringLiteral("mapFromGlobal()"), &x, &y))
return;
- }
- qreal x = vx->asDouble();
- qreal y = vy->asDouble();
QVariant result = mapToGlobal(QPointF(x, y));
QV4::ScopedObject rv(scope, v4->fromVariant(result));
@@ -7438,14 +7410,14 @@ void QQuickItem::setAcceptTouchEvents(bool enabled)
d->touchEnabled = enabled;
}
-void QQuickItemPrivate::setHasCursorInChild(bool hasCursor)
+void QQuickItemPrivate::setHasCursorInChild(bool hc)
{
#if QT_CONFIG(cursor)
Q_Q(QQuickItem);
// if we're asked to turn it off (because of an unsetcursor call, or a node
// removal) then we should make sure it's really ok to turn it off.
- if (!hasCursor && subtreeCursorEnabled) {
+ if (!hc && subtreeCursorEnabled) {
if (hasCursor)
return; // nope! sorry, I have a cursor myself
for (QQuickItem *otherChild : qAsConst(childItems)) {
@@ -7455,14 +7427,14 @@ void QQuickItemPrivate::setHasCursorInChild(bool hasCursor)
}
}
- subtreeCursorEnabled = hasCursor;
+ subtreeCursorEnabled = hc;
QQuickItem *parent = q->parentItem();
if (parent) {
QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
- parentPrivate->setHasCursorInChild(hasCursor);
+ parentPrivate->setHasCursorInChild(hc);
}
#else
- Q_UNUSED(hasCursor);
+ Q_UNUSED(hc);
#endif
}
@@ -7539,17 +7511,20 @@ void QQuickItem::setCursor(const QCursor &cursor)
}
}
+ QPointF updateCursorPos;
if (!d->hasCursor) {
- d->setHasCursorInChild(true);
d->hasCursor = true;
if (d->window) {
QWindow *renderWindow = QQuickRenderControl::renderWindowFor(d->window);
QWindow *window = renderWindow ? renderWindow : d->window;
QPointF pos = window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint());
if (contains(mapFromScene(pos)))
- QQuickWindowPrivate::get(d->window)->updateCursor(pos);
+ updateCursorPos = pos;
}
}
+ d->setHasCursorInChild(d->hasCursor || d->hasCursorHandler);
+ if (!updateCursorPos.isNull())
+ QQuickWindowPrivate::get(d->window)->updateCursor(updateCursorPos);
}
/*!
@@ -7563,8 +7538,8 @@ void QQuickItem::unsetCursor()
Q_D(QQuickItem);
if (!d->hasCursor)
return;
- d->setHasCursorInChild(false);
d->hasCursor = false;
+ d->setHasCursorInChild(d->hasCursorHandler);
if (d->extra.isAllocated())
d->extra->cursor = QCursor();
@@ -7577,6 +7552,64 @@ void QQuickItem::unsetCursor()
}
}
+/*!
+ \internal
+ Returns the cursor that should actually be shown, allowing the given
+ \handler to override the Item cursor if it is active or hovered.
+
+ \sa cursor(), setCursor(), QtQuick::PointerHandler::cursor
+*/
+QCursor QQuickItemPrivate::effectiveCursor(const QQuickPointerHandler *handler) const
+{
+ Q_Q(const QQuickItem);
+ if (!handler)
+ return q->cursor();
+ bool hoverCursorSet = false;
+ QCursor hoverCursor;
+ bool activeCursorSet = false;
+ QCursor activeCursor;
+ if (const QQuickHoverHandler *hoverHandler = qobject_cast<const QQuickHoverHandler *>(handler)) {
+ hoverCursorSet = hoverHandler->isCursorShapeExplicitlySet();
+ hoverCursor = hoverHandler->cursorShape();
+ } else if (handler->active()) {
+ activeCursorSet = handler->isCursorShapeExplicitlySet();
+ activeCursor = handler->cursorShape();
+ }
+ if (activeCursorSet)
+ return activeCursor;
+ if (hoverCursorSet)
+ return hoverCursor;
+ return q->cursor();
+}
+
+/*!
+ \internal
+ Returns the Pointer Handler that is currently attempting to set the cursor shape,
+ or null if there is no such handler.
+
+ \sa QtQuick::PointerHandler::cursor
+*/
+QQuickPointerHandler *QQuickItemPrivate::effectiveCursorHandler() const
+{
+ if (!hasPointerHandlers())
+ return nullptr;
+ QQuickPointerHandler *retHoverHandler = nullptr;
+ for (QQuickPointerHandler *h : extra->pointerHandlers) {
+ if (!h->isCursorShapeExplicitlySet())
+ continue;
+ QQuickHoverHandler *hoverHandler = qmlobject_cast<QQuickHoverHandler *>(h);
+ // For now, we don't expect multiple hover handlers in one Item, so we choose the first one found;
+ // but a future use case could be to have different cursors for different tablet stylus devices.
+ // In that case, this function needs more information: which device did the event come from.
+ // TODO Qt 6: add QPointerDevice* as argument to this function? (it doesn't exist yet in Qt 5)
+ if (!retHoverHandler && hoverHandler)
+ retHoverHandler = hoverHandler;
+ if (!hoverHandler && h->active())
+ return h;
+ }
+ return retHoverHandler;
+}
+
#endif
/*!
@@ -8158,6 +8191,10 @@ bool QQuickItem::event(QEvent *ev)
ev->ignore();
break;
#endif // gestures
+ case QEvent::LanguageChange:
+ for (QQuickItem *item : d->childItems)
+ QCoreApplication::sendEvent(item, ev);
+ break;
default:
return QObject::event(ev);
}
@@ -8818,7 +8855,7 @@ QQuickItemPrivate::ExtraData::ExtraData()
effectRefCount(0), hideRefCount(0),
recursiveEffectRefCount(0),
opacityNode(nullptr), clipNode(nullptr), rootNode(nullptr),
- acceptedMouseButtons(nullptr), origin(QQuickItem::Center),
+ origin(QQuickItem::Center),
transparentForPositioner(false)
{
}
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 394a5adb8c..8c04ced11b 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -58,6 +58,7 @@ class QQuickTransformPrivate;
class Q_QUICK_EXPORT QQuickTransform : public QObject
{
Q_OBJECT
+ QML_ANONYMOUS
public:
explicit QQuickTransform(QObject *parent = nullptr);
~QQuickTransform() override;
@@ -150,6 +151,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
Q_CLASSINFO("DefaultProperty", "data")
Q_CLASSINFO("qt_QmlJSWrapperFactoryMethod", "_q_createJSWrapper(QV4::ExecutionEngine*)")
+ QML_NAMED_ELEMENT(Item)
public:
enum Flag {
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 2faf694eeb..841d91bb40 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -152,6 +152,7 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener
Q_PROPERTY(QQmlComponent *effect READ effect WRITE setEffect NOTIFY effectChanged)
Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged)
Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged)
+ QML_ANONYMOUS
public:
QQuickItemLayer(QQuickItem *item);
@@ -335,7 +336,7 @@ public:
struct ChangeListener {
using ChangeTypes = QQuickItemPrivate::ChangeTypes;
- ChangeListener(QQuickItemChangeListener *l = nullptr, ChangeTypes t = nullptr)
+ ChangeListener(QQuickItemChangeListener *l = nullptr, ChangeTypes t = { })
: listener(l)
, types(t)
, gTypes(QQuickGeometryChange::All)
@@ -470,6 +471,7 @@ public:
bool isTabFence:1;
bool replayingPressEvent:1;
bool touchEnabled:1;
+ bool hasCursorHandler:1;
enum DirtyType {
TransformOrigin = 0x00000001,
@@ -650,6 +652,10 @@ public:
void setHasCursorInChild(bool hasCursor);
void setHasHoverInChild(bool hasHover);
+#if QT_CONFIG(cursor)
+ QCursor effectiveCursor(const QQuickPointerHandler *handler) const;
+ QQuickPointerHandler *effectiveCursorHandler() const;
+#endif
virtual void updatePolish() { }
};
@@ -715,6 +721,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickKeyNavigationAttached : public QObject, publi
Q_PROPERTY(QQuickItem *backtab READ backtab WRITE setBacktab NOTIFY backtabChanged)
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
+ QML_NAMED_ELEMENT(KeyNavigation)
+ QML_UNCREATABLE("KeyNavigation is only available via attached properties.")
+ QML_ATTACHED(QQuickKeyNavigationAttached)
+
public:
QQuickKeyNavigationAttached(QObject * = nullptr);
@@ -760,6 +770,10 @@ class QQuickLayoutMirroringAttached : public QObject
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled RESET resetEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged)
+ QML_NAMED_ELEMENT(LayoutMirroring)
+ QML_UNCREATABLE("LayoutMirroring is only available via attached properties.")
+ QML_ATTACHED(QQuickLayoutMirroringAttached)
+
public:
explicit QQuickLayoutMirroringAttached(QObject *parent = nullptr);
@@ -784,6 +798,11 @@ class QQuickEnterKeyAttached : public QObject
Q_OBJECT
Q_PROPERTY(Qt::EnterKeyType type READ type WRITE setType NOTIFY typeChanged)
+ QML_NAMED_ELEMENT(EnterKey)
+ QML_UNCREATABLE("EnterKey is only available via attached properties")
+ QML_ADDED_IN_MINOR_VERSION(6)
+ QML_ATTACHED(QQuickEnterKeyAttached)
+
public:
explicit QQuickEnterKeyAttached(QObject *parent = nullptr);
@@ -829,6 +848,10 @@ class QQuickKeysAttached : public QObject, public QQuickItemKeyFilter
Q_PROPERTY(QQmlListProperty<QQuickItem> forwardTo READ forwardTo)
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
+ QML_NAMED_ELEMENT(Keys)
+ QML_UNCREATABLE("Keys is only available via attached properties")
+ QML_ATTACHED(QQuickKeysAttached)
+
public:
QQuickKeysAttached(QObject *parent=nullptr);
~QQuickKeysAttached() override;
@@ -849,7 +872,7 @@ public:
QQmlListProperty<QQuickItem> forwardTo() {
Q_D(QQuickKeysAttached);
- return QQmlListProperty<QQuickItem>(this, d->targets);
+ return QQmlListProperty<QQuickItem>(this, &(d->targets));
}
void componentComplete() override;
@@ -919,7 +942,7 @@ private:
Qt::MouseButtons QQuickItemPrivate::acceptedMouseButtons() const
{
return ((extra.flag() ? Qt::LeftButton : Qt::MouseButton(0)) |
- (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons(nullptr)));
+ (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons{}));
}
QSGContext *QQuickItemPrivate::sceneGraphContext() const
@@ -984,12 +1007,8 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickItemLayer)
#endif
QML_DECLARE_TYPE(QQuickKeysAttached)
-QML_DECLARE_TYPEINFO(QQuickKeysAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickKeyNavigationAttached)
-QML_DECLARE_TYPEINFO(QQuickKeyNavigationAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickLayoutMirroringAttached)
-QML_DECLARE_TYPEINFO(QQuickLayoutMirroringAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickEnterKeyAttached)
-QML_DECLARE_TYPEINFO(QQuickEnterKeyAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKITEM_P_H
diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp
index 8251282736..23694e2de3 100644
--- a/src/quick/items/qquickitemanimation.cpp
+++ b/src/quick/items/qquickitemanimation.cpp
@@ -456,7 +456,7 @@ QQuickAnchorAnimation::~QQuickAnchorAnimation()
QQmlListProperty<QQuickItem> QQuickAnchorAnimation::targets()
{
Q_D(QQuickAnchorAnimation);
- return QQmlListProperty<QQuickItem>(this, d->targets);
+ return QQmlListProperty<QQuickItem>(this, &(d->targets));
}
/*!
diff --git a/src/quick/items/qquickitemanimation_p.h b/src/quick/items/qquickitemanimation_p.h
index b803455f12..28c18c874d 100644
--- a/src/quick/items/qquickitemanimation_p.h
+++ b/src/quick/items/qquickitemanimation_p.h
@@ -66,6 +66,7 @@ class Q_AUTOTEST_EXPORT QQuickParentAnimation : public QQuickAnimationGroup
Q_PROPERTY(QQuickItem *target READ target WRITE setTargetObject NOTIFY targetChanged)
Q_PROPERTY(QQuickItem *newParent READ newParent WRITE setNewParent NOTIFY newParentChanged)
Q_PROPERTY(QQuickItem *via READ via WRITE setVia NOTIFY viaChanged)
+ QML_NAMED_ELEMENT(ParentAnimation)
public:
QQuickParentAnimation(QObject *parent=nullptr);
@@ -100,6 +101,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorAnimation : public QQuickAbstractAnimation
Q_PROPERTY(QQmlListProperty<QQuickItem> targets READ targets)
Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
+ QML_NAMED_ELEMENT(AnchorAnimation)
public:
QQuickAnchorAnimation(QObject *parent=nullptr);
@@ -143,6 +145,7 @@ class Q_AUTOTEST_EXPORT QQuickPathAnimation : public QQuickAbstractAnimation
Q_PROPERTY(int orientationEntryDuration READ orientationEntryDuration WRITE setOrientationEntryDuration NOTIFY orientationEntryDurationChanged)
Q_PROPERTY(int orientationExitDuration READ orientationExitDuration WRITE setOrientationExitDuration NOTIFY orientationExitDurationChanged)
Q_PROPERTY(qreal endRotation READ endRotation WRITE setEndRotation NOTIFY endRotationChanged)
+ QML_NAMED_ELEMENT(PathAnimation)
public:
QQuickPathAnimation(QObject *parent=nullptr);
diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp
index f298803c7f..00e84536e9 100644
--- a/src/quick/items/qquickitemgrabresult.cpp
+++ b/src/quick/items/qquickitemgrabresult.cpp
@@ -195,6 +195,7 @@ bool QQuickItemGrabResult::saveToFile(const QString &fileName) const
}
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
* \overload
* \internal
@@ -203,6 +204,7 @@ bool QQuickItemGrabResult::saveToFile(const QString &fileName)
{
return qAsConst(*this).saveToFile(fileName);
}
+#endif
#endif // < Qt 6
QUrl QQuickItemGrabResult::url() const
diff --git a/src/quick/items/qquickitemgrabresult.h b/src/quick/items/qquickitemgrabresult.h
index 3dc10e2d75..a45ed62ed5 100644
--- a/src/quick/items/qquickitemgrabresult.h
+++ b/src/quick/items/qquickitemgrabresult.h
@@ -45,6 +45,7 @@
#include <QtCore/QUrl>
#include <QtGui/QImage>
#include <QtQml/QJSValue>
+#include <QtQml/qqml.h>
#include <QtQuick/qtquickglobal.h>
QT_BEGIN_NAMESPACE
@@ -60,12 +61,17 @@ class Q_QUICK_EXPORT QQuickItemGrabResult : public QObject
Q_PROPERTY(QImage image READ image CONSTANT)
Q_PROPERTY(QUrl url READ url CONSTANT)
+ QML_ANONYMOUS
+
public:
QImage image() const;
QUrl url() const;
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- Q_INVOKABLE bool saveToFile(const QString &fileName); // ### Qt 6: remove
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("This overload is deprecated. Use the const member function instead")
+ Q_INVOKABLE bool saveToFile(const QString &fileName);
+#endif
#endif
Q_INVOKABLE bool saveToFile(const QString &fileName) const;
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 86253e770f..125518e51b 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -175,332 +175,14 @@ static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject
return QQmlPrivate::IncompatibleObject;
}
-static void qt_quickitems_defineModule(const char *uri, int major, int minor)
+static void qt_quickitems_defineModule()
{
QQmlPrivate::RegisterAutoParent autoparent = { 0, &qquickitem_autoParent };
QQmlPrivate::qmlregister(QQmlPrivate::AutoParentRegistration, &autoparent);
- // Register the latest version, even if there are no new types or new revisions for existing types yet.
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
-
-#if !QT_CONFIG(quick_animatedimage)
- qmlRegisterTypeNotAvailable(uri,major,minor,"AnimatedImage", QCoreApplication::translate("QQuickAnimatedImage","Qt was built without support for QMovie"));
-#else
- qmlRegisterType<QQuickAnimatedImage>(uri,major,minor,"AnimatedImage");
-#endif
- qmlRegisterType<QQuickBorderImage>(uri,major,minor,"BorderImage");
- qmlRegisterType<QQuickFlickable>(uri,major,minor,"Flickable");
-#if QT_CONFIG(quick_flipable)
- qmlRegisterType<QQuickFlipable>(uri,major,minor,"Flipable");
-#endif
-// qmlRegisterType<QQuickFocusPanel>(uri,major,minor,"FocusPanel");
- qmlRegisterType<QQuickFocusScope>(uri,major,minor,"FocusScope");
- qmlRegisterType<QQuickGradient>(uri,major,minor,"Gradient");
- qmlRegisterType<QQuickGradientStop>(uri,major,minor,"GradientStop");
-#if QT_CONFIG(quick_positioners)
- qmlRegisterType<QQuickColumn>(uri,major,minor,"Column");
- qmlRegisterType<QQuickFlow>(uri,major,minor,"Flow");
- qmlRegisterType<QQuickGrid>(uri,major,minor,"Grid");
- qmlRegisterUncreatableType<QQuickBasePositioner>(uri,major,minor,"Positioner",
- QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
- qmlRegisterType<QQuickRow>(uri,major,minor,"Row");
-#endif
-#if QT_CONFIG(quick_gridview)
- qmlRegisterType<QQuickGridView>(uri,major,minor,"GridView");
-#endif
- qmlRegisterType<QQuickImage>(uri,major,minor,"Image");
- qmlRegisterType<QQuickItem>(uri,major,minor,"Item");
-#if QT_CONFIG(quick_listview)
- qmlRegisterType<QQuickListView>(uri,major,minor,"ListView");
- qmlRegisterType<QQuickViewSection>(uri,major,minor,"ViewSection");
-#endif
- qmlRegisterType<QQuickLoader>(uri,major,minor,"Loader");
- qmlRegisterType<QQuickMouseArea>(uri,major,minor,"MouseArea");
-#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPath>(uri,major,minor,"Path");
- qmlRegisterType<QQuickPathAttribute>(uri,major,minor,"PathAttribute");
- qmlRegisterType<QQuickPathCubic>(uri,major,minor,"PathCubic");
- qmlRegisterType<QQuickPathLine>(uri,major,minor,"PathLine");
- qmlRegisterType<QQuickPathPercent>(uri,major,minor,"PathPercent");
- qmlRegisterType<QQuickPathQuad>(uri,major,minor,"PathQuad");
- qmlRegisterType<QQuickPathCatmullRomCurve>("QtQuick",2,0,"PathCurve");
- qmlRegisterType<QQuickPathArc>("QtQuick",2,0,"PathArc");
- qmlRegisterType<QQuickPathSvg>("QtQuick",2,0,"PathSvg");
- qmlRegisterType<QQuickPath, 14>(uri, 2, 14, "Path");
- qmlRegisterType<QQuickPathPolyline>("QtQuick", 2, 14, "PathPolyline");
- qmlRegisterType<QQuickPathMultiline>("QtQuick", 2, 14, "PathMultiline");
-#endif
-#if QT_CONFIG(quick_pathview)
- qmlRegisterType<QQuickPathView>(uri,major,minor,"PathView");
-#endif
- qmlRegisterType<QQuickRectangle>(uri,major,minor,"Rectangle");
-#if QT_CONFIG(quick_repeater)
- qmlRegisterType<QQuickRepeater>(uri,major,minor,"Repeater");
-#endif
- qmlRegisterType<QQuickTranslate>(uri,major,minor,"Translate");
- qmlRegisterType<QQuickRotation>(uri,major,minor,"Rotation");
- qmlRegisterType<QQuickScale>(uri,major,minor,"Scale");
- qmlRegisterType<QQuickMatrix4x4>(uri,2,3,"Matrix4x4");
- qmlRegisterType<QQuickText>(uri,major,minor,"Text");
- qmlRegisterType<QQuickTextEdit>(uri,major,minor,"TextEdit");
- qmlRegisterType<QQuickTextEdit,1>(uri,2,1,"TextEdit");
- qmlRegisterType<QQuickTextInput>(uri,major,minor,"TextInput");
- qmlRegisterType<QQuickTextInput,2>(uri,2,2,"TextInput");
- qmlRegisterType<QQuickTextInput,4>(uri,2,4,"TextInput");
- qmlRegisterAnonymousType<QQuickItemGrabResult>(uri, major);
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterAnonymousType<QQuickItemLayer>(uri, major);
-#endif
- qmlRegisterAnonymousType<QQuickAnchors>(uri, major);
- qmlRegisterAnonymousType<QQuickKeyEvent>(uri, major);
- qmlRegisterAnonymousType<QQuickMouseEvent>(uri, major);
- qmlRegisterAnonymousType<QQuickWheelEvent>(uri, major);
- qmlRegisterAnonymousType<QQuickCloseEvent>(uri, major);
- qmlRegisterAnonymousType<QQuickTransform>(uri, major);
-#if QT_CONFIG(quick_path)
- qmlRegisterAnonymousType<QQuickPathElement>(uri, major);
- qmlRegisterAnonymousType<QQuickCurve>(uri, major);
-#endif
- qmlRegisterAnonymousType<QQuickScaleGrid>(uri, major);
- qmlRegisterAnonymousType<QQuickTextLine>(uri, major);
- qmlRegisterAnonymousType<QQuickPen>(uri, major);
- qmlRegisterAnonymousType<QQuickFlickableVisibleArea>(uri, major);
qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
-
- qmlRegisterAnonymousType<QQuickTextDocument>(uri, major);
-
-
- qmlRegisterUncreatableType<QQuickKeyNavigationAttached>(uri,major,minor,"KeyNavigation",QQuickKeyNavigationAttached::tr("KeyNavigation is only available via attached properties"));
- qmlRegisterUncreatableType<QQuickKeysAttached>(uri,major,minor,"Keys",QQuickKeysAttached::tr("Keys is only available via attached properties"));
- qmlRegisterUncreatableType<QQuickLayoutMirroringAttached>(uri,major,minor,"LayoutMirroring", QQuickLayoutMirroringAttached::tr("LayoutMirroring is only available via attached properties"));
-#if QT_CONFIG(quick_viewtransitions)
- qmlRegisterUncreatableType<QQuickViewTransitionAttached>(uri,major,minor,"ViewTransition",QQuickViewTransitionAttached::tr("ViewTransition is only available via attached properties"));
-#endif
-
- qmlRegisterType<QQuickPinchArea>(uri,major,minor,"PinchArea");
- qmlRegisterType<QQuickPinch>(uri,major,minor,"Pinch");
- qmlRegisterAnonymousType<QQuickPinchEvent>(uri, major);
-
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffectSource>("QtQuick", 2, 0, "ShaderEffectSource");
- qmlRegisterUncreatableType<QQuickShaderEffectMesh>("QtQuick", 2, 0, "ShaderEffectMesh", QQuickShaderEffectMesh::tr("Cannot create instance of abstract class ShaderEffectMesh."));
- qmlRegisterType<QQuickGridMesh>("QtQuick", 2, 0, "GridMesh");
- qmlRegisterType<QQuickShaderEffect>("QtQuick", 2, 0, "ShaderEffect");
-#endif
-
- qmlRegisterUncreatableType<QQuickPaintedItem>("QtQuick", 2, 0, "PaintedItem", QQuickPaintedItem::tr("Cannot create instance of abstract class PaintedItem"));
-
-#if QT_CONFIG(quick_canvas)
- qmlRegisterType<QQuickCanvasItem>("QtQuick", 2, 0, "Canvas");
-#endif
-
-#if QT_CONFIG(quick_sprite)
- qmlRegisterType<QQuickSprite>("QtQuick", 2, 0, "Sprite");
- qmlRegisterType<QQuickAnimatedSprite>("QtQuick", 2, 0, "AnimatedSprite");
- qmlRegisterType<QQuickSpriteSequence>("QtQuick", 2, 0, "SpriteSequence");
-#endif
-
- qmlRegisterType<QQuickParentChange>(uri, major, minor,"ParentChange");
- qmlRegisterType<QQuickAnchorChanges>(uri, major, minor,"AnchorChanges");
- qmlRegisterAnonymousType<QQuickAnchorSet>(uri, major);
- qmlRegisterType<QQuickAnchorAnimation>(uri, major, minor,"AnchorAnimation");
- qmlRegisterType<QQuickParentAnimation>(uri, major, minor,"ParentAnimation");
-#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPathAnimation>("QtQuick",2,0,"PathAnimation");
- qmlRegisterType<QQuickPathInterpolator>("QtQuick",2,0,"PathInterpolator");
-#endif
-
-#if QT_CONFIG(quick_draganddrop)
- qmlRegisterType<QQuickDropArea>("QtQuick", 2, 0, "DropArea");
- qmlRegisterAnonymousType<QQuickDropEvent>(uri, 2);
- qmlRegisterAnonymousType<QQuickDropAreaDrag>(uri, 2);
- qmlRegisterUncreatableType<QQuickDrag>("QtQuick", 2, 0, "Drag", QQuickDragAttached::tr("Drag is only available via attached properties"));
-#endif
-
- qmlRegisterType<QQuickMultiPointTouchArea>("QtQuick", 2, 0, "MultiPointTouchArea");
- qmlRegisterType<QQuickTouchPoint>("QtQuick", 2, 0, "TouchPoint");
- qmlRegisterUncreatableType<QQuickGrabGestureEvent>(uri,major,minor, "GestureEvent",
- QQuickMouseEvent::tr("GestureEvent is only available in the context of handling the gestureStarted signal from MultiPointTouchArea"));
-
-#if QT_CONFIG(accessibility)
- qmlRegisterUncreatableType<QQuickAccessibleAttached>("QtQuick", 2, 0, "Accessible",QQuickAccessibleAttached::tr("Accessible is only available via attached properties"));
-#endif
-
- qmlRegisterType<QQuickItem, 1>(uri, 2, 1,"Item");
-#if QT_CONFIG(quick_positioners)
- qmlRegisterType<QQuickGrid, 1>(uri, 2, 1, "Grid");
-#endif
-#if QT_CONFIG(quick_itemview)
- const char *itemViewName = "ItemView";
- const QString itemViewMessage = QQuickItemView::tr("ItemView is an abstract base class");
- qmlRegisterUncreatableType<QQuickItemView, 1>(uri, 2, 1, itemViewName, itemViewMessage);
- qmlRegisterUncreatableType<QQuickItemView, 3>(uri, 2, 3, itemViewName, itemViewMessage);
-#endif
-#if QT_CONFIG(quick_listview)
- qmlRegisterType<QQuickListView, 1>(uri, 2, 1, "ListView");
-#endif
-#if QT_CONFIG(quick_gridview)
- qmlRegisterType<QQuickGridView, 1>(uri, 2, 1, "GridView");
-#endif
- qmlRegisterType<QQuickTextEdit, 1>(uri, 2, 1, "TextEdit");
-
- qmlRegisterType<QQuickText, 2>(uri, 2, 2, "Text");
- qmlRegisterType<QQuickTextEdit, 2>(uri, 2, 2, "TextEdit");
-
- qmlRegisterType<QQuickText, 3>(uri, 2, 3, "Text");
- qmlRegisterType<QQuickTextEdit, 3>(uri, 2, 3, "TextEdit");
- qmlRegisterType<QQuickImage, 3>(uri, 2, 3,"Image");
-
- qmlRegisterType<QQuickItem, 4>(uri, 2, 4, "Item");
-#if QT_CONFIG(quick_listview)
- qmlRegisterType<QQuickListView, 4>(uri, 2, 4, "ListView");
-#endif
- qmlRegisterType<QQuickMouseArea, 4>(uri, 2, 4, "MouseArea");
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffect, 4>(uri, 2, 4, "ShaderEffect");
-#endif
-
-#if QT_CONFIG(opengl)
- qmlRegisterUncreatableType<QQuickOpenGLInfo>(uri, 2, 4,"OpenGLInfo", QQuickOpenGLInfo::tr("OpenGLInfo is only available via attached properties"));
-#endif
- qmlRegisterType<QQuickPinchArea, 5>(uri, 2, 5,"PinchArea");
- qmlRegisterType<QQuickImage, 5>(uri, 2, 5,"Image");
- qmlRegisterType<QQuickMouseArea, 5>(uri, 2, 5, "MouseArea");
-
- qmlRegisterType<QQuickText, 6>(uri, 2, 6, "Text");
- qmlRegisterType<QQuickTextEdit, 6>(uri, 2, 6, "TextEdit");
- qmlRegisterType<QQuickTextInput, 6>(uri, 2, 6, "TextInput");
-#if QT_CONFIG(quick_positioners)
- qmlRegisterUncreatableType<QQuickBasePositioner, 6>(uri, 2, 6, "Positioner",
- QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
- qmlRegisterType<QQuickColumn, 6>(uri, 2, 6, "Column");
- qmlRegisterType<QQuickRow, 6>(uri, 2, 6, "Row");
- qmlRegisterType<QQuickGrid, 6>(uri, 2, 6, "Grid");
- qmlRegisterType<QQuickFlow, 6>(uri, 2, 6, "Flow");
-#endif
- qmlRegisterUncreatableType<QQuickEnterKeyAttached, 6>(uri, 2, 6, "EnterKey",
- QQuickEnterKeyAttached::tr("EnterKey is only available via attached properties"));
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffectSource, 6>(uri, 2, 6, "ShaderEffectSource");
-#endif
-
- qmlRegisterType<QQuickItem, 7>(uri, 2, 7, "Item");
-#if QT_CONFIG(quick_listview)
- qmlRegisterType<QQuickListView, 7>(uri, 2, 7, "ListView");
-#endif
-#if QT_CONFIG(quick_gridview)
- qmlRegisterType<QQuickGridView, 7>(uri, 2, 7, "GridView");
-#endif
- qmlRegisterType<QQuickTextInput, 7>(uri, 2, 7, "TextInput");
- qmlRegisterType<QQuickTextEdit, 7>(uri, 2, 7, "TextEdit");
-#if QT_CONFIG(quick_pathview)
- qmlRegisterType<QQuickPathView, 7>(uri, 2, 7, "PathView");
-#endif
-#if QT_CONFIG(quick_itemview)
- qmlRegisterUncreatableType<QQuickItemView, 7>(uri, 2, 7, itemViewName, itemViewMessage);
-#endif
-
- qmlRegisterUncreatableType<QQuickMouseEvent, 7>(uri, 2, 7, nullptr, QQuickMouseEvent::tr("MouseEvent is only available within handlers in MouseArea"));
-
- qmlRegisterUncreatableType<QQuickGraphicsInfo>(uri, 2, 8,"GraphicsInfo", QQuickGraphicsInfo::tr("GraphicsInfo is only available via attached properties"));
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickBorderImageMesh>("QtQuick", 2, 8, "BorderImageMesh");
-#endif
-
- qmlRegisterType<QQuickFlickable, 9>(uri, 2, 9, "Flickable");
- qmlRegisterType<QQuickMouseArea, 9>(uri, 2, 9, "MouseArea");
-
-#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPathArc, 9>(uri, 2, 9, "PathArc");
- qmlRegisterType<QQuickPathMove>(uri, 2, 9, "PathMove");
-#endif
-
- qmlRegisterType<QQuickText, 9>(uri, 2, 9, "Text");
- qmlRegisterType<QQuickTextInput, 9>(uri, 2, 9, "TextInput");
- qmlRegisterType<QQuickTouchPoint>(uri, 2, 9, "TouchPoint");
qRegisterMetaType<QPointingDeviceUniqueId>("QPointingDeviceUniqueId");
- qmlRegisterUncreatableType<QPointingDeviceUniqueId>(uri, 2, 9, "PointingDeviceUniqueId", QQuickTouchPoint::tr("PointingDeviceUniqueId is only available via read-only properties"));
-#if QT_CONFIG(quick_positioners)
- qmlRegisterUncreatableType<QQuickBasePositioner, 9>(uri, 2, 9, "Positioner",
- QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
-#endif
-
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffectSource, 9>(uri, 2, 9, "ShaderEffectSource");
-#endif
-
- qmlRegisterType<QQuickFlickable, 10>(uri, 2, 10, "Flickable");
- qmlRegisterType<QQuickTextEdit, 10>(uri, 2, 10, "TextEdit");
- qmlRegisterType<QQuickText, 10>(uri, 2, 10, "Text");
-
-#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPathAngleArc>(uri, 2, 11, "PathAngleArc");
-#endif
-
-#if QT_CONFIG(quick_animatedimage)
- qmlRegisterType<QQuickAnimatedImage, 11>(uri, 2, 11,"AnimatedImage");
-#endif
- qmlRegisterType<QQuickItem, 11>(uri, 2, 11,"Item");
- qmlRegisterType<QQuickFlickable, 12>(uri, 2, 12, "Flickable");
-
- // classes related to Input Handlers which are newly exposed since 5.12
- qmlRegisterUncreatableType<QQuickPointerEvent>(uri, 2, 12, "PointerEvent",
- QQuickPointerHandler::tr("PointerEvent is only available as a parameter of several signals in PointerHandler"));
- qmlRegisterUncreatableType<QQuickPointerMouseEvent>(uri, 2, 12, "PointerMouseEvent",
- QQuickPointerHandler::tr("PointerMouseEvent is only available as a parameter of several signals in PointerHandler"));
- qmlRegisterUncreatableType<QQuickPointerTouchEvent>(uri, 2, 12, "PointerTouchEvent",
- QQuickPointerHandler::tr("PointerTouchEvent is only available as a parameter of several signals in PointerHandler"));
- qmlRegisterUncreatableType<QQuickEventPoint>(uri, 2, 12, "EventPoint",
- QQuickPointerHandler::tr("EventPoint is only available as a member of PointerEvent"));
- qmlRegisterUncreatableType<QQuickEventTouchPoint>(uri, 2, 12, "EventTouchPoint",
- QQuickPointerHandler::tr("EventTouchPoint is only available as a member of PointerEvent"));
- qmlRegisterUncreatableType<QQuickPointerDevice>(uri, 2, 12, "PointerDevice",
- QQuickPointerHandler::tr("PointerDevice is only available as a property of PointerEvent"));
-
- // Input Handlers are part of QtQuick, not a separate module, since 5.12
- qmlRegisterUncreatableType<QQuickPointerHandler>(uri, 2, 12, "PointerHandler",
- QQuickPointerHandler::tr("PointerHandler is an abstract base class"));
- qmlRegisterType<QQuickPointHandler>(uri, 2, 12, "PointHandler");
- qmlRegisterType<QQuickDragHandler>(uri, 2, 12, "DragHandler");
- qmlRegisterUncreatableType<QQuickDragAxis>(uri, 2, 12, "DragAxis",
- QQuickDragHandler::tr("DragAxis is only available as a grouped property of DragHandler"));
- qmlRegisterType<QQuickHoverHandler>(uri, 2, 12, "HoverHandler");
- qmlRegisterType<QQuickPinchHandler>(uri, 2, 12, "PinchHandler");
- qmlRegisterType<QQuickTapHandler>(uri, 2, 12, "TapHandler");
qRegisterMetaType<QQuickHandlerPoint>();
-
- // The rest of the 5.12 revisions
-#if QT_CONFIG(quick_sprite)
- qmlRegisterType<QQuickAnimatedSprite, 12>("QtQuick", 2, 12, "AnimatedSprite");
-#endif
- qmlRegisterType<QQuickGradient, 12>(uri, 2, 12, "Gradient");
- qmlRegisterType<QQuickFlickable, 12>(uri, 2, 12, "Flickable");
- qmlRegisterType<QQuickText, 12>(uri, 2, 12, "Text");
-#if QT_CONFIG(quick_tableview)
- qmlRegisterType<QQuickTableView>(uri, 2, 12, "TableView");
-#endif
-
-#if QT_CONFIG(quick_itemview)
- qmlRegisterUncreatableType<QQuickItemView, 13>(uri, 2, 13, itemViewName, itemViewMessage);
-#endif
-#if QT_CONFIG(quick_pathview)
- qmlRegisterType<QQuickPathView, 13>(uri, 2, 13, "PathView");
-#endif
-#if QT_CONFIG(quick_gridview)
- qmlRegisterType<QQuickGridView, 13>(uri, 2, 13, "GridView");
-#endif
-#if QT_CONFIG(quick_tableview)
- qmlRegisterType<QQuickTableView, 14>(uri, 2, 14, "TableView");
-#endif
-#if QT_CONFIG(wheelevent)
- qmlRegisterType<QQuickWheelHandler>(uri, 2, 14, "WheelHandler");
- qmlRegisterUncreatableType<QQuickPointerScrollEvent>(uri, 2, 14, "PointerScrollEvent",
- QQuickPointerHandler::tr("PointerScrollEvent is only available via the WheelHandler::wheel signal"));
-#endif
- qmlRegisterUncreatableType<QQuickImageBase, 14>(uri, 2, 14, "ImageBase",
- QQuickPointerHandler::tr("ImageBase is an abstract base class"));
- qmlRegisterType<QQuickImage, 14>(uri, 2, 14, "Image");
- qmlRegisterType<QQuickDragHandler, 14>(uri, 2, 14, "DragHandler");
}
static void initResources()
@@ -513,12 +195,7 @@ QT_BEGIN_NAMESPACE
void QQuickItemsModule::defineModule()
{
initResources();
-
- QByteArray name = "QtQuick";
- int majorVersion = 2;
- int minorVersion = 0;
-
- qt_quickitems_defineModule(name, majorVersion, minorVersion);
+ qt_quickitems_defineModule();
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickitemsmodule_p.h b/src/quick/items/qquickitemsmodule_p.h
index cd79efe256..815c5ae644 100644
--- a/src/quick/items/qquickitemsmodule_p.h
+++ b/src/quick/items/qquickitemsmodule_p.h
@@ -51,6 +51,8 @@
// We mean it.
//
+#include <private/qtquickglobal_p.h>
+#include <QtGui/qevent.h>
#include <qqml.h>
QT_BEGIN_NAMESPACE
@@ -61,6 +63,26 @@ public:
static void defineModule();
};
+struct QPointingDeviceUniqueIdForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QPointingDeviceUniqueId)
+ QML_NAMED_ELEMENT(PointingDeviceUniqueId)
+ QML_ADDED_IN_MINOR_VERSION(9)
+ 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_MINOR_VERSION(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 a931abca58..7fb392233e 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -197,6 +197,10 @@ void QQuickItemView::setModel(const QVariant &m)
disconnect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
disconnect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*)));
disconnect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*)));
+ if (QQmlDelegateModel *delegateModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
+ disconnect(delegateModel, SIGNAL(itemPooled(int, QObject *)), this, SLOT(onItemPooled(int, QObject *)));
+ disconnect(delegateModel, SIGNAL(itemReused(int, QObject *)), this, SLOT(onItemReused(int, QObject *)));
+ }
}
QQmlInstanceModel *oldModel = d->model;
@@ -232,6 +236,10 @@ void QQuickItemView::setModel(const QVariant &m)
connect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*)));
connect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
connect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*)));
+ if (QQmlDelegateModel *delegateModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
+ connect(delegateModel, SIGNAL(itemPooled(int, QObject *)), this, SLOT(onItemPooled(int, QObject *)));
+ connect(delegateModel, SIGNAL(itemReused(int, QObject *)), this, SLOT(onItemReused(int, QObject *)));
+ }
if (isComponentComplete()) {
d->updateSectionCriteria();
d->refill();
@@ -694,6 +702,28 @@ void QQuickItemView::setHighlightMoveDuration(int duration)
}
}
+bool QQuickItemView::reuseItems() const
+{
+ return bool(d_func()->reusableFlag == QQmlDelegateModel::Reusable);
+}
+
+void QQuickItemView::setReuseItems(bool reuse)
+{
+ Q_D(QQuickItemView);
+ if (reuseItems() == reuse)
+ return;
+
+ d->reusableFlag = reuse ? QQmlDelegateModel::Reusable : QQmlDelegateModel::NotReusable;
+
+ if (!reuse && d->model) {
+ // When we're told to not reuse items, we
+ // immediately, as documented, drain the pool.
+ d->model->drainReusableItemsPool(0);
+ }
+
+ emit reuseItemsChanged();
+}
+
QQuickTransition *QQuickItemView::populateTransition() const
{
Q_D(const QQuickItemView);
@@ -848,7 +878,7 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
setPosition(qMin(itemPos, maxExtent));
// now release the reference to all the old visible items.
for (FxViewItem *item : oldVisible)
- releaseItem(item);
+ releaseItem(item, reusableFlag);
item = visibleItem(idx);
}
if (item) {
@@ -1091,8 +1121,8 @@ qreal QQuickItemViewPrivate::calculatedMaxExtent() const
void QQuickItemViewPrivate::applyDelegateChange()
{
- releaseVisibleItems();
- releaseItem(currentItem);
+ releaseVisibleItems(QQmlDelegateModel::NotReusable);
+ releaseItem(currentItem, QQmlDelegateModel::NotReusable);
currentItem = nullptr;
updateSectionCriteria();
refill();
@@ -1194,7 +1224,7 @@ void QQuickItemView::destroyRemoved()
} else {
if (hasRemoveTransition)
d->runDelayedRemoveTransition = true;
- d->releaseItem(item);
+ d->releaseItem(item, d->reusableFlag);
it = d->visibleItems.erase(it);
}
} else {
@@ -1638,7 +1668,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
if (currentItem) {
if (currentItem->attached)
currentItem->attached->setIsCurrentItem(false);
- releaseItem(currentItem);
+ releaseItem(currentItem, reusableFlag);
currentItem = nullptr;
currentIndex = modelIndex;
emit q->currentIndexChanged();
@@ -1675,7 +1705,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
if (oldCurrentItem != currentItem
&& (!oldCurrentItem || !currentItem || oldCurrentItem->item != currentItem->item))
emit q->currentItemChanged();
- releaseItem(oldCurrentItem);
+ releaseItem(oldCurrentItem, reusableFlag);
}
void QQuickItemViewPrivate::clear(bool onDestruction)
@@ -1689,17 +1719,17 @@ void QQuickItemViewPrivate::clear(bool onDestruction)
bufferedChanges.reset();
timeline.clear();
- releaseVisibleItems();
+ releaseVisibleItems(QQmlInstanceModel::NotReusable);
visibleIndex = 0;
for (FxViewItem *item : qAsConst(releasePendingTransition)) {
item->releaseAfterTransition = false;
- releaseItem(item);
+ releaseItem(item, QQmlInstanceModel::NotReusable);
}
releasePendingTransition.clear();
auto oldCurrentItem = currentItem;
- releaseItem(currentItem);
+ releaseItem(currentItem, QQmlDelegateModel::NotReusable);
currentItem = nullptr;
if (oldCurrentItem)
emit q->currentItemChanged();
@@ -1758,7 +1788,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) {
currentChanges.reset();
bufferedChanges.reset();
- releaseVisibleItems();
+ releaseVisibleItems(reusableFlag);
}
int prevCount = itemCount;
@@ -1925,7 +1955,7 @@ void QQuickItemViewPrivate::layout()
continue;
if (!success) {
- releaseItem(releasePendingTransition[i]);
+ releaseItem(releasePendingTransition[i], reusableFlag);
releasePendingTransition.remove(i);
--count;
} else {
@@ -2071,9 +2101,9 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
// Whatever removed/moved items remain are no longer visible items.
prepareRemoveTransitions(&currentChanges.removedItems);
- for (QHash<QQmlChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin();
+ for (auto it = currentChanges.removedItems.begin();
it != currentChanges.removedItems.end(); ++it) {
- releaseItem(it.value());
+ releaseItem(it.value(), reusableFlag);
}
currentChanges.removedItems.clear();
@@ -2082,7 +2112,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
if (currentItem->item && currentItem->attached)
currentItem->attached->setIsCurrentItem(false);
auto oldCurrentItem = currentItem;
- releaseItem(currentItem);
+ releaseItem(currentItem, reusableFlag);
currentItem = nullptr;
if (oldCurrentItem)
emit q->currentItemChanged();
@@ -2163,11 +2193,11 @@ void QQuickItemViewPrivate::removeItem(FxViewItem *item, const QQmlChangeSet::Ch
removeResult->sizeChangesAfterVisiblePos += item->size();
}
if (removal.isMove()) {
- currentChanges.removedItems.insert(removal.moveKey(item->index), item);
+ currentChanges.removedItems.replace(removal.moveKey(item->index), item);
item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true);
} else {
// track item so it is released later
- currentChanges.removedItems.insertMulti(QQmlChangeSet::MoveKey(), item);
+ currentChanges.removedItems.insert(QQmlChangeSet::MoveKey(), item);
}
if (!removeResult->changedFirstItem && item == *visibleItems.constBegin())
removeResult->changedFirstItem = true;
@@ -2238,15 +2268,14 @@ void QQuickItemViewPrivate::prepareVisibleItemTransitions()
visibleItems[i]->prepareTransition(transitioner, viewBounds);
}
-void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems)
+void QQuickItemViewPrivate::prepareRemoveTransitions(QMultiHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems)
{
if (!transitioner)
return;
if (transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)
|| transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false)) {
- for (QHash<QQmlChangeSet::MoveKey, FxViewItem *>::Iterator it = removedItems->begin();
- it != removedItems->end(); ) {
+ for (auto it = removedItems->begin(); it != removedItems->end(); ) {
bool isRemove = it.key().moveId < 0;
if (isRemove) {
FxViewItem *item = *it;
@@ -2289,7 +2318,7 @@ void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitiona
{
for (int i=0; i<releasePendingTransition.count(); i++) {
if (releasePendingTransition.at(i)->transitionableItem == item) {
- releaseItem(releasePendingTransition.takeAt(i));
+ releaseItem(releasePendingTransition.takeAt(i), reusableFlag);
return;
}
}
@@ -2395,7 +2424,23 @@ void QQuickItemView::destroyingItem(QObject *object)
}
}
-bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
+void QQuickItemView::onItemPooled(int modelIndex, QObject *object)
+{
+ Q_UNUSED(modelIndex);
+
+ if (auto *attached = d_func()->getAttachedObject(object))
+ emit attached->pooled();
+}
+
+void QQuickItemView::onItemReused(int modelIndex, QObject *object)
+{
+ Q_UNUSED(modelIndex);
+
+ if (auto *attached = d_func()->getAttachedObject(object))
+ emit attached->reused();
+}
+
+bool QQuickItemViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag)
{
Q_Q(QQuickItemView);
if (!item)
@@ -2406,7 +2451,7 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
QQmlInstanceModel::ReleaseFlags flags = {};
if (model && item->item) {
- flags = model->release(item->item);
+ flags = model->release(item->item, reusableFlag);
if (!flags && !isClearing) {
// item was not destroyed, and we no longer reference it.
if (item->item->parentItem() == contentItem) {
@@ -2417,6 +2462,8 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
unrequestedItems.insert(item->item, model->indexOf(item->item, q));
} else if (flags & QQmlInstanceModel::Destroyed) {
item->item->setParentItem(nullptr);
+ } else if (flags & QQmlInstanceModel::Pooled) {
+ item->setVisible(false);
}
}
delete item;
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 66e09f9ed1..3f83383cd5 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -110,6 +110,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged RESET resetPreferredHighlightEnd)
Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged)
+ Q_PROPERTY(bool reuseItems READ reuseItems WRITE setReuseItems NOTIFY reuseItemsChanged REVISION 15)
+
+ QML_NAMED_ELEMENT(ItemView)
+ QML_UNCREATABLE("ItemView is an abstract base class.")
+ QML_ADDED_IN_MINOR_VERSION(1)
+
public:
// this holds all layout enum values so they can be referred to by other enums
// to ensure consistent values - e.g. QML references to GridView.TopToBottom flow
@@ -222,6 +228,9 @@ public:
int highlightMoveDuration() const;
virtual void setHighlightMoveDuration(int);
+ bool reuseItems() const;
+ void setReuseItems(bool reuse);
+
enum PositionMode { Beginning, Center, End, Visible, Contain, SnapPosition };
Q_ENUM(PositionMode)
@@ -277,6 +286,8 @@ Q_SIGNALS:
void preferredHighlightEndChanged();
void highlightMoveDurationChanged();
+ Q_REVISION(15) void reuseItemsChanged();
+
protected:
void updatePolish() override;
void componentComplete() override;
@@ -292,6 +303,8 @@ protected Q_SLOTS:
virtual void initItem(int index, QObject *item);
void modelUpdated(const QQmlChangeSet &changeSet, bool reset);
void destroyingItem(QObject *item);
+ Q_REVISION(15) void onItemPooled(int modelIndex, QObject *object);
+ Q_REVISION(15) void onItemReused(int modelIndex, QObject *object);
void animStopped();
void trackedPositionChanged();
@@ -395,6 +408,9 @@ Q_SIGNALS:
void prevSectionChanged();
void nextSectionChanged();
+ void pooled();
+ void reused();
+
public:
QPointer<QQuickItemView> m_view;
bool m_isCurrent : 1;
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index a448cf9a38..0bc2a6b768 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -92,7 +92,7 @@ public:
int itemCount;
int newCurrentIndex;
QQmlChangeSet pendingChanges;
- QHash<QQmlChangeSet::MoveKey, FxViewItem *> removedItems;
+ QMultiHash<QQmlChangeSet::MoveKey, FxViewItem *> removedItems;
bool active : 1;
bool currentChanged : 1;
@@ -174,7 +174,7 @@ public:
void mirrorChange() override;
FxViewItem *createItem(int modelIndex,QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested);
- virtual bool releaseItem(FxViewItem *item);
+ virtual bool releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag);
QQuickItem *createHighlightItem() const;
QQuickItem *createComponentItem(QQmlComponent *component, qreal zValue, bool createDefault = false) const;
@@ -203,7 +203,7 @@ public:
void createTransitioner();
void prepareVisibleItemTransitions();
- void prepareRemoveTransitions(QHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems);
+ void prepareRemoveTransitions(QMultiHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems);
bool prepareNonVisibleItemTransition(FxViewItem *item, const QRectF &viewBounds);
void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) override;
@@ -238,15 +238,17 @@ public:
q->polish();
}
- void releaseVisibleItems() {
+ void releaseVisibleItems(QQmlInstanceModel::ReusableFlag reusableFlag) {
// make a copy and clear the visibleItems first to avoid destroyed
// items being accessed during the loop (QTBUG-61294)
const QList<FxViewItem *> oldVisible = visibleItems;
visibleItems.clear();
for (FxViewItem *item : oldVisible)
- releaseItem(item);
+ releaseItem(item, reusableFlag);
}
+ virtual QQuickItemViewAttached *getAttachedObject(const QObject *) const { return nullptr; }
+
QPointer<QQmlInstanceModel> model;
QVariant modelVariant;
int itemCount;
@@ -288,6 +290,11 @@ public:
QQmlComponent *footerComponent;
FxViewItem *footer;
+ // Reusing delegate items cannot be on by default for backwards compatibility.
+ // Reusing an item will e.g mean that Component.onCompleted will only be called for an
+ // item when it's created and not when it's reused, which will break legacy applications.
+ QQmlInstanceModel::ReusableFlag reusableFlag = QQmlInstanceModel::NotReusable;
+
struct MovedItem {
FxViewItem *item;
QQmlChangeSet::MoveKey moveKey;
diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp
index 109851608b..b7649c9952 100644
--- a/src/quick/items/qquickitemviewtransition.cpp
+++ b/src/quick/items/qquickitemviewtransition.cpp
@@ -925,7 +925,7 @@ QQuickViewTransitionAttached::QQuickViewTransitionAttached(QObject *parent)
*/
QQmlListProperty<QObject> QQuickViewTransitionAttached::targetItems()
{
- return QQmlListProperty<QObject>(this, m_targetItems);
+ return QQmlListProperty<QObject>(this, &m_targetItems);
}
QQuickViewTransitionAttached *QQuickViewTransitionAttached::qmlAttachedProperties(QObject *obj)
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
index 0c7a9cad75..5f4e74171e 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -194,6 +194,10 @@ class QQuickViewTransitionAttached : public QObject
Q_PROPERTY(QList<int> targetIndexes READ targetIndexes NOTIFY targetIndexesChanged)
Q_PROPERTY(QQmlListProperty<QObject> targetItems READ targetItems NOTIFY targetItemsChanged)
+ QML_NAMED_ELEMENT(ViewTransition)
+ QML_UNCREATABLE("ViewTransition is only available via attached properties.")
+ QML_ATTACHED(QQuickViewTransitionAttached)
+
public:
QQuickViewTransitionAttached(QObject *parent);
@@ -227,6 +231,5 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickViewTransitionAttached)
-QML_DECLARE_TYPEINFO(QQuickViewTransitionAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKITEMVIEWTRANSITION_P_P_H
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index ef601dcaec..0d78070401 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -49,6 +49,7 @@
#include <QtCore/qmath.h>
#include <private/qquicksmoothedanimation_p_p.h>
+#include <private/qqmlcomponent_p.h>
#include "qplatformdefs.h"
QT_BEGIN_NAMESPACE
@@ -91,7 +92,7 @@ public:
FxViewItem *newViewItem(int index, QQuickItem *item) override;
void initializeViewItem(FxViewItem *item) override;
- bool releaseItem(FxViewItem *item) override;
+ bool releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag) override;
void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer) override;
void repositionPackageItemAt(QQuickItem *item, int index) override;
void resetFirstItemPosition(qreal pos = 0.0) override;
@@ -138,6 +139,8 @@ public:
bool flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
QQuickTimeLineCallback::Callback fixupCallback, qreal velocity) override;
+ QQuickItemViewAttached *getAttachedObject(const QObject *object) const override;
+
void fixupHeader();
void fixupHeaderCompleted();
QQuickListView::Orientation orient;
@@ -200,6 +203,8 @@ public:
}
friend class QQuickViewSection;
+
+ static void setSectionHelper(QQmlContext *context, QQuickItem *sectionItem, const QString &section);
};
//----------------------------------------------------------------------------
@@ -641,15 +646,15 @@ void QQuickListViewPrivate::initializeViewItem(FxViewItem *item)
}
}
-bool QQuickListViewPrivate::releaseItem(FxViewItem *item)
+bool QQuickListViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag)
{
if (!item || !model)
- return QQuickItemViewPrivate::releaseItem(item);
+ return QQuickItemViewPrivate::releaseItem(item, reusableFlag);
QPointer<QQuickItem> it = item->item;
QQuickListViewAttached *att = static_cast<QQuickListViewAttached*>(item->attached);
- bool released = QQuickItemViewPrivate::releaseItem(item);
+ bool released = QQuickItemViewPrivate::releaseItem(item, reusableFlag);
if (released && it && att && att->m_sectionItem) {
// We hold no more references to this item
int i = 0;
@@ -689,7 +694,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
int newModelIdx = qBound(0, modelIndex + count, model->count());
count = newModelIdx - modelIndex;
if (count) {
- releaseVisibleItems();
+ releaseVisibleItems(reusableFlag);
modelIndex = newModelIdx;
visibleIndex = modelIndex;
visiblePos = itemEnd + count * (averageSize + spacing);
@@ -744,7 +749,7 @@ void QQuickListViewPrivate::removeItem(FxViewItem *item)
releasePendingTransition.append(item);
} else {
qCDebug(lcItemViewDelegateLifecycle) << "\treleasing stationary item" << item->index << (QObject *)(item->item);
- releaseItem(item);
+ releaseItem(item, reusableFlag);
}
}
@@ -1003,14 +1008,20 @@ QQuickItem * QQuickListViewPrivate::getSectionItem(const QString &section)
sectionCache[i] = nullptr;
sectionItem->setVisible(true);
QQmlContext *context = QQmlEngine::contextForObject(sectionItem)->parentContext();
- context->setContextProperty(QLatin1String("section"), section);
+ setSectionHelper(context, sectionItem, section);
} else {
QQmlContext *creationContext = sectionCriteria->delegate()->creationContext();
QQmlContext *context = new QQmlContext(
creationContext ? creationContext : qmlContext(q));
- context->setContextProperty(QLatin1String("section"), section);
- QObject *nobj = sectionCriteria->delegate()->beginCreate(context);
+ QQmlComponent* delegate = sectionCriteria->delegate();
+ QQmlComponentPrivate* delegatePriv = QQmlComponentPrivate::get(delegate);
+ QObject *nobj = delegate->beginCreate(context);
if (nobj) {
+ if (delegatePriv->hadRequiredProperties()) {
+ delegate->setInitialProperties(nobj, {{"section", section}});
+ } else {
+ context->setContextProperty(QLatin1String("section"), section);
+ }
QQml_setParent_noEvent(context, nobj);
sectionItem = qobject_cast<QQuickItem *>(nobj);
if (!sectionItem) {
@@ -1080,7 +1091,7 @@ void QQuickListViewPrivate::updateInlineSection(FxListItemSG *listItem)
listItem->setPosition(pos);
} else {
QQmlContext *context = QQmlEngine::contextForObject(listItem->section())->parentContext();
- context->setContextProperty(QLatin1String("section"), listItem->attached->m_section);
+ setSectionHelper(context, listItem->section(), listItem->attached->m_section);
}
} else if (listItem->section()) {
qreal pos = listItem->position();
@@ -1136,7 +1147,7 @@ void QQuickListViewPrivate::updateStickySections()
currentSectionItem = getSectionItem(currentSection);
} else if (QString::compare(currentStickySection, currentSection, Qt::CaseInsensitive)) {
QQmlContext *context = QQmlEngine::contextForObject(currentSectionItem)->parentContext();
- context->setContextProperty(QLatin1String("section"), currentSection);
+ setSectionHelper(context, currentSectionItem, currentSection);
}
currentStickySection = currentSection;
if (!currentSectionItem)
@@ -1170,7 +1181,7 @@ void QQuickListViewPrivate::updateStickySections()
nextSectionItem = getSectionItem(nextSection);
} else if (QString::compare(nextStickySection, nextSection, Qt::CaseInsensitive)) {
QQmlContext *context = QQmlEngine::contextForObject(nextSectionItem)->parentContext();
- context->setContextProperty(QLatin1String("section"), nextSection);
+ setSectionHelper(context, nextSectionItem, nextSection);
}
nextStickySection = nextSection;
if (!nextSectionItem)
@@ -1893,6 +1904,20 @@ bool QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
}
}
+void QQuickListViewPrivate::setSectionHelper(QQmlContext *context, QQuickItem *sectionItem, const QString &section)
+{
+ if (context->contextProperty(QLatin1String("section")).isValid())
+ context->setContextProperty(QLatin1String("section"), section);
+ else
+ sectionItem->setProperty("section", section);
+}
+
+QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject *object) const
+{
+ QObject *attachedObject = qmlAttachedPropertiesObject<QQuickListView>(object);
+ return static_cast<QQuickItemViewAttached *>(attachedObject);
+}
+
//----------------------------------------------------------------------------
/*!
@@ -2041,6 +2066,39 @@ bool QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
of type \l [QML] {real}, so it is possible to set fractional
values like \c 0.1.
+ \section1 Reusing items
+
+ Since 5.15, ListView can be configured to recycle items instead of instantiating
+ from the \l delegate whenever new rows are flicked into view. This approach improves
+ performance, depending on the complexity of the delegate. Reusing
+ items is off by default (for backwards compatibility reasons), but can be switched
+ on by setting the \l reuseItems property to \c true.
+
+ When an item is flicked out, it moves to the \e{reuse pool}, which is an
+ internal cache of unused items. When this happens, the \l ListView::pooled
+ signal is emitted to inform the item about it. Likewise, when the item is
+ moved back from the pool, the \l ListView::reused signal is emitted.
+
+ Any item properties that come from the model are updated when the
+ item is reused. This includes \c index and \c row, but also
+ any model roles.
+
+ \note Avoid storing any state inside a delegate. If you do, reset it
+ manually on receiving the \l ListView::reused signal.
+
+ If an item has timers or animations, consider pausing them on receiving
+ the \l ListView::pooled signal. That way you avoid using the CPU resources
+ for items that are not visible. Likewise, if an item has resources that
+ cannot be reused, they could be freed up.
+
+ \note While an item is in the pool, it might still be alive and respond
+ to connected signals and bindings.
+
+ The following example shows a delegate that animates a spinning rectangle. When
+ it is pooled, the animation is temporarily paused:
+
+ \snippet qml/listview/reusabledelegate.qml 0
+
\sa {QML Data Models}, GridView, PathView, {Qt Quick Examples - Views}
*/
QQuickListView::QQuickListView(QQuickItem *parent)
@@ -2120,8 +2178,6 @@ QQuickListView::~QQuickListView()
If an \l add transition is specified, it is applied immediately after
this signal is handled.
-
- The corresponding handler is \c onAdd.
*/
/*!
@@ -2130,8 +2186,6 @@ QQuickListView::~QQuickListView()
If a \l remove transition has been specified, it is applied after
this signal is handled, providing that \l delayRemove is false.
-
- The corresponding handler is \c onRemove.
*/
/*!
@@ -2207,6 +2261,20 @@ QQuickListView::~QQuickListView()
*/
/*!
+ \qmlproperty bool QtQuick::ListView::reuseItems
+
+ This property enables you to reuse items that are instantiated
+ from the \l delegate. If set to \c false, any currently
+ pooled items are destroyed.
+
+ This property is \c false by default.
+
+ \since 5.15
+
+ \sa {Reusing items}, ListView::pooled, ListView::reused
+*/
+
+/*!
\qmlproperty Component QtQuick::ListView::highlight
This property holds the component to use as the highlight.
@@ -2776,21 +2844,25 @@ void QQuickListView::setSnapMode(SnapMode mode)
This property determines the positioning of the \l{headerItem}{header item}.
- The possible values are:
- \list
- \li ListView.InlineHeader (default) - the header is positioned in the beginning
+ \value ListView.InlineHeader (default) The header is positioned at the beginning
of the content and moves together with the content like an ordinary item.
- \li ListView.OverlayHeader - the header is positioned in the beginning of the view.
- \li ListView.PullBackHeader - the header is positioned in the beginning of the view.
+
+ \value ListView.OverlayHeader The header is positioned at the beginning of the view.
+
+ \value ListView.PullBackHeader The header is positioned at the beginning of the view.
The header can be pushed away by moving the content forwards, and pulled back by
moving the content backwards.
- \endlist
\note This property has no effect on the \l {QQuickItem::z}{stacking order}
of the header. For example, if the header should be shown above the
\l delegate items when using \c ListView.OverlayHeader, its Z value
should be set to a value higher than that of the delegates. For more
information, see \l {Stacking Order in ListView}.
+
+ \note If \c headerPositioning is not set to \c ListView.InlineHeader, the
+ user cannot press and flick the list from the header. In any case, the
+ \l{headerItem}{header item} may contain items or event handlers that
+ provide custom handling of mouse or touch input.
*/
QQuickListView::HeaderPositioning QQuickListView::headerPositioning() const
{
@@ -2819,21 +2891,25 @@ void QQuickListView::setHeaderPositioning(QQuickListView::HeaderPositioning posi
This property determines the positioning of the \l{footerItem}{footer item}.
- The possible values are:
- \list
- \li ListView.InlineFooter (default) - the footer is positioned in the end
+ \value ListView.InlineFooter (default) The footer is positioned at the end
of the content and moves together with the content like an ordinary item.
- \li ListView.OverlayFooter - the footer is positioned in the end of the view.
- \li ListView.PullBackFooter - the footer is positioned in the end of the view.
+
+ \value ListView.OverlayFooter The footer is positioned at the end of the view.
+
+ \value ListView.PullBackFooter The footer is positioned at the end of the view.
The footer can be pushed away by moving the content backwards, and pulled back by
moving the content forwards.
- \endlist
\note This property has no effect on the \l {QQuickItem::z}{stacking order}
of the footer. For example, if the footer should be shown above the
\l delegate items when using \c ListView.OverlayFooter, its Z value
should be set to a value higher than that of the delegates. For more
information, see \l {Stacking Order in ListView}.
+
+ \note If \c footerPositioning is not set to \c ListView.InlineFooter, the
+ user cannot press and flick the list from the footer. In any case, the
+ \l{footerItem}{footer item} may contain items or event handlers that
+ provide custom handling of mouse or touch input.
*/
QQuickListView::FooterPositioning QQuickListView::footerPositioning() const
{
@@ -3307,6 +3383,13 @@ void QQuickListView::keyPressEvent(QKeyEvent *event)
void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickListView);
+
+ if (d->model) {
+ // When the view changes size, we force the pool to
+ // shrink by releasing all pooled items.
+ d->model->drainReusableItemsPool(0);
+ }
+
if (d->isRightToLeft()) {
// maintain position relative to the right edge
qreal dx = newGeometry.width() - oldGeometry.width();
@@ -3714,6 +3797,23 @@ QQuickListViewAttached *QQuickListView::qmlAttachedProperties(QObject *obj)
return new QQuickListViewAttached(obj);
}
+bool QQuickListView::contains(const QPointF &point) const
+{
+ bool ret = QQuickItemView::contains(point);
+ // QTBUG-74046: if a mouse press "falls through" a floating header or footer, don't allow dragging the list from there
+ if (ret) {
+ if (auto header = headerItem()) {
+ if (headerPositioning() != QQuickListView::InlineHeader && header->contains(mapToItem(header, point)))
+ ret = false;
+ }
+ if (auto footer = footerItem()) {
+ if (footerPositioning() != QQuickListView::InlineFooter && footer->contains(mapToItem(footer, point)))
+ ret = false;
+ }
+ }
+ return ret;
+}
+
QT_END_NAMESPACE
#include "moc_qquicklistview_p.cpp"
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index f2bab9e018..be21b93155 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -70,6 +70,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickViewSection : public QObject
Q_PROPERTY(SectionCriteria criteria READ criteria WRITE setCriteria NOTIFY criteriaChanged)
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(int labelPositioning READ labelPositioning WRITE setLabelPositioning NOTIFY labelPositioningChanged)
+ QML_NAMED_ELEMENT(ViewSection)
public:
QQuickViewSection(QQuickListView *parent=nullptr);
@@ -130,6 +131,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickListView : public QQuickItemView
Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION 4)
Q_CLASSINFO("DefaultProperty", "data")
+ QML_NAMED_ELEMENT(ListView)
+ QML_ATTACHED(QQuickListViewAttached)
public:
QQuickListView(QQuickItem *parent=nullptr);
@@ -176,6 +179,8 @@ public:
static QQuickListViewAttached *qmlAttachedProperties(QObject *);
+ bool contains(const QPointF &point) const override;
+
public Q_SLOTS:
void incrementCurrentIndex();
void decrementCurrentIndex();
@@ -216,7 +221,6 @@ public:
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickListView, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickListView)
QML_DECLARE_TYPE(QQuickViewSection)
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 8c15b60712..e1d533f092 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -45,6 +45,7 @@
#include <private/qqmlglobal_p.h>
#include <private/qqmlcomponent_p.h>
+#include <private/qqmlincubator_p.h>
QT_BEGIN_NAMESPACE
@@ -665,7 +666,8 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj)
QV4::Scope scope(v4);
QV4::ScopedValue ipv(scope, initialPropertyValues.value());
QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value());
- d->initializeObjectWithInitialProperties(qmlContext, ipv, obj);
+ auto incubatorPriv = QQmlIncubatorPrivate::get(incubator);
+ d->initializeObjectWithInitialProperties(qmlContext, ipv, obj, incubatorPriv->requiredProperties());
}
void QQuickLoaderIncubator::statusChanged(Status status)
@@ -821,8 +823,6 @@ void QQuickLoader::itemChange(QQuickItem::ItemChange change, const QQuickItem::I
This signal is emitted when the \l status becomes \c Loader.Ready, or on successful
initial load.
-
- The corresponding handler is \c onLoaded.
*/
diff --git a/src/quick/items/qquickloader_p.h b/src/quick/items/qquickloader_p.h
index de1dfa9da5..2d560fb856 100644
--- a/src/quick/items/qquickloader_p.h
+++ b/src/quick/items/qquickloader_p.h
@@ -67,6 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickLoader : public QQuickImplicitSizeItem
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
+ QML_NAMED_ELEMENT(Loader)
public:
QQuickLoader(QQuickItem *parent = nullptr);
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index dc60712a9c..f54858e4eb 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -62,7 +62,7 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_HOVER_TRACE)
QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
: enabled(true), scrollGestureEnabled(true), hovered(false), longPress(false),
moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
- propagateComposedEvents(false), overThreshold(false), pressed(nullptr),
+ propagateComposedEvents(false), overThreshold(false),
pressAndHoldInterval(-1)
#if QT_CONFIG(quick_draganddrop)
, drag(nullptr)
@@ -275,8 +275,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
even when no mouse button is pressed.
\sa hoverEnabled
-
- The corresponding handler is \c onEntered.
*/
/*!
@@ -315,8 +313,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
both be considered to be simultaneously hovered.
\sa hoverEnabled
-
- The corresponding handler is \c onExited.
*/
/*!
@@ -333,8 +329,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
parameter has no effect.
-
- The corresponding handler is \c onPositionChanged.
*/
/*!
@@ -349,8 +343,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
parameter has no effect, unless the \l propagateComposedEvents property is \c true.
-
- The corresponding handler is \c onClicked.
*/
/*!
@@ -365,8 +357,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
release. The default is to accept the event and not allow other MouseAreas beneath this one to
handle the event. If \e accepted is set to false, no further events will be sent to this MouseArea
until the button is next pressed.
-
- The corresponding handler is \c onPressed.
*/
/*!
@@ -379,8 +369,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
parameter has no effect.
- The corresponding handler is \c onReleased.
-
\sa canceled
*/
@@ -393,8 +381,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
parameter has no effect, unless the \l propagateComposedEvents property is \c true.
-
- The corresponding handler is \c onPressAndHold.
*/
/*!
@@ -407,8 +393,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
When handling this signal, if the \l {MouseEvent::}{accepted} property of the \a mouse
parameter is set to false, the pressed/released/clicked signals will be emitted for the second
click; otherwise they are suppressed. The \c accepted property defaults to true.
-
- The corresponding handler is \c onDoubleClicked.
*/
/*!
@@ -422,8 +406,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
\l Flickable will steal the mouse handling from the MouseArea. In these cases, to reset
the logic when the MouseArea has lost the mouse handling to the \l Flickable,
\c canceled should be handled in addition to \l released.
-
- The corresponding handler is \c onCanceled.
*/
/*!
@@ -434,8 +416,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
The \a wheel parameter provides information about the event, including the x and y
position, any buttons currently pressed, and information about the wheel movement, including
angleDelta and pixelDelta.
-
- The corresponding handler is \c onWheel.
*/
QQuickMouseArea::QQuickMouseArea(QQuickItem *parent)
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index 139289c06b..806cc41369 100644
--- a/src/quick/items/qquickmousearea_p.h
+++ b/src/quick/items/qquickmousearea_p.h
@@ -85,6 +85,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem
#endif
Q_PROPERTY(bool containsPress READ containsPress NOTIFY containsPressChanged REVISION 4)
Q_PROPERTY(int pressAndHoldInterval READ pressAndHoldInterval WRITE setPressAndHoldInterval NOTIFY pressAndHoldIntervalChanged RESET resetPressAndHoldInterval REVISION 9)
+ QML_NAMED_ELEMENT(MouseArea)
public:
QQuickMouseArea(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 9a371207ce..383718c979 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();
}
/*!
@@ -365,24 +363,18 @@ void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id)
If minimumTouchPoints is set to a value greater than one, this signal will not be emitted until the minimum number
of required touch points has been reached.
-
- The corresponding handler is \c onPressed.
*/
/*!
\qmlsignal QtQuick::MultiPointTouchArea::updated(list<TouchPoint> touchPoints)
This signal is emitted when existing touch points are updated. \a touchPoints is a list of these updated points.
-
- The corresponding handler is \c onUpdated.
*/
/*!
\qmlsignal QtQuick::MultiPointTouchArea::released(list<TouchPoint> touchPoints)
This signal is emitted when existing touch points are removed. \a touchPoints is a list of these removed points.
-
- The corresponding handler is \c onReleased.
*/
/*!
@@ -398,8 +390,6 @@ void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id)
\c canceled should be handled in addition to \l released.
\a touchPoints is the list of canceled points.
-
- The corresponding handler is \c onCanceled.
*/
/*!
@@ -413,8 +403,6 @@ void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id)
gesture is not grabbed, the nesting Flickable, for example, would also have an opportunity to grab.
The \a gesture object also includes information on the current set of \c touchPoints and the \c dragThreshold.
-
- The corresponding handler is \c onGestureStarted.
*/
/*!
@@ -423,8 +411,6 @@ void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id)
This signal is emitted when the touch points handled by the MultiPointTouchArea change. This includes adding new touch points,
removing or canceling previous touch points, as well as updating current touch point data. \a touchPoints is the list of all current touch
points.
-
- The corresponding handler is \c onTouchUpdated.
*/
/*!
@@ -798,13 +784,14 @@ 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());
dtp->setVelocity(p->velocity());
- dtp->setArea(p->rect());
+ QRectF area(QPointF(), p->ellipseDiameters());
+ area.moveCenter(p->pos());
+ dtp->setArea(area);
dtp->setStartX(p->startPos().x());
dtp->setStartY(p->startPos().y());
dtp->setPreviousX(p->lastPos().x());
@@ -817,8 +804,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 23f4ebff75..e34a3faad6 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -83,6 +83,7 @@ class Q_AUTOTEST_EXPORT QQuickTouchPoint : public QObject
Q_PROPERTY(qreal previousY READ previousY NOTIFY previousYChanged)
Q_PROPERTY(qreal sceneX READ sceneX NOTIFY sceneXChanged)
Q_PROPERTY(qreal sceneY READ sceneY NOTIFY sceneYChanged)
+ QML_NAMED_ELEMENT(TouchPoint)
public:
QQuickTouchPoint(bool qmlDefined = true)
@@ -96,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);
@@ -187,6 +186,9 @@ class QQuickGrabGestureEvent : public QObject
Q_OBJECT
Q_PROPERTY(QQmlListProperty<QObject> touchPoints READ touchPoints CONSTANT)
Q_PROPERTY(qreal dragThreshold READ dragThreshold CONSTANT)
+ QML_NAMED_ELEMENT(GestureEvent)
+ QML_UNCREATABLE("GestureEvent is only available in the context of handling the gestureStarted signal from MultiPointTouchArea.")
+
public:
QQuickGrabGestureEvent() : _dragThreshold(QGuiApplication::styleHints()->startDragDistance()) {}
@@ -194,7 +196,7 @@ public:
bool wantsGrab() const { return _grab; }
QQmlListProperty<QObject> touchPoints() {
- return QQmlListProperty<QObject>(this, _touchPoints);
+ return QQmlListProperty<QObject>(this, &_touchPoints);
}
qreal dragThreshold() const { return _dragThreshold; }
@@ -213,6 +215,7 @@ class Q_AUTOTEST_EXPORT QQuickMultiPointTouchArea : public QQuickItem
Q_PROPERTY(int minimumTouchPoints READ minimumTouchPoints WRITE setMinimumTouchPoints NOTIFY minimumTouchPointsChanged)
Q_PROPERTY(int maximumTouchPoints READ maximumTouchPoints WRITE setMaximumTouchPoints NOTIFY maximumTouchPointsChanged)
Q_PROPERTY(bool mouseEnabled READ mouseEnabled WRITE setMouseEnabled NOTIFY mouseEnabledChanged)
+ QML_NAMED_ELEMENT(MultiPointTouchArea)
public:
QQuickMultiPointTouchArea(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickopenglinfo_p.h b/src/quick/items/qquickopenglinfo_p.h
index 86683d5348..b733d205e3 100644
--- a/src/quick/items/qquickopenglinfo_p.h
+++ b/src/quick/items/qquickopenglinfo_p.h
@@ -70,6 +70,11 @@ class QQuickOpenGLInfo : public QObject
Q_PROPERTY(ContextProfile profile READ profile NOTIFY profileChanged FINAL)
Q_PROPERTY(RenderableType renderableType READ renderableType NOTIFY renderableTypeChanged FINAL)
+ QML_NAMED_ELEMENT(OpenGLInfo)
+ QML_UNCREATABLE("OpenGLInfo is only available via attached properties.")
+ QML_ADDED_IN_MINOR_VERSION(4)
+ QML_ATTACHED(QQuickOpenGLInfo)
+
public:
QQuickOpenGLInfo(QQuickItem *item = 0);
@@ -116,6 +121,4 @@ private:
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickOpenGLInfo, QML_HAS_ATTACHED_PROPERTIES)
-
#endif // QQUICKOPENGLINFO_P_H
diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp
index 26ef59c20e..5721f116e8 100644
--- a/src/quick/items/qquickopenglshadereffectnode.cpp
+++ b/src/quick/items/qquickopenglshadereffectnode.cpp
@@ -178,7 +178,7 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri
if (state.isMatrixDirty())
program()->setUniformValue(loc, state.combinedMatrix());
} else if (d.specialType == UniformData::None) {
- switch (int(d.value.type())) {
+ switch (int(d.value.userType())) {
case QMetaType::QColor:
program()->setUniformValue(loc, qt_premultiply_color(qvariant_cast<QColor>(d.value)));
break;
diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp
index 57848919f3..386c8d8862 100644
--- a/src/quick/items/qquickpainteditem.cpp
+++ b/src/quick/items/qquickpainteditem.cpp
@@ -133,7 +133,6 @@ QQuickPaintedItemPrivate::QQuickPaintedItemPrivate()
, contentsScale(1.0)
, fillColor(Qt::transparent)
, renderTarget(QQuickPaintedItem::Image)
- , performanceHints(nullptr)
, opaquePainting(false)
, antialiasing(false)
, mipmap(false)
diff --git a/src/quick/items/qquickpainteditem.h b/src/quick/items/qquickpainteditem.h
index ddc1fd99d9..4821a409be 100644
--- a/src/quick/items/qquickpainteditem.h
+++ b/src/quick/items/qquickpainteditem.h
@@ -56,6 +56,9 @@ class Q_QUICK_EXPORT QQuickPaintedItem : public QQuickItem
Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged)
Q_PROPERTY(QSize textureSize READ textureSize WRITE setTextureSize NOTIFY textureSizeChanged)
+ QML_NAMED_ELEMENT(PaintedItem)
+ QML_UNCREATABLE("Cannot create instance of abstract class PaintedItem.")
+
public:
explicit QQuickPaintedItem(QQuickItem *parent = nullptr);
~QQuickPaintedItem() override;
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 7ebe174a9e..4a8089f49c 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -1164,8 +1164,6 @@ bool QQuickPathView::isDragging() const
This signal is emitted when the view begins moving due to user
interaction.
-
- The corresponding handler is \c onMovementStarted.
*/
/*!
@@ -1176,8 +1174,6 @@ bool QQuickPathView::isDragging() const
be emitted once the flick stops. If a flick was not
generated, this signal will be emitted when the
user stops dragging - i.e. a mouse or touch release.
-
- The corresponding handler is \c onMovementEnded.
*/
/*!
@@ -1186,16 +1182,12 @@ bool QQuickPathView::isDragging() const
This signal is emitted when the view is flicked. A flick
starts from the point that the mouse or touch is released,
while still in motion.
-
- The corresponding handler is \c onFlickStarted.
*/
/*!
\qmlsignal QtQuick::PathView::flickEnded()
This signal is emitted when the view stops moving due to a flick.
-
- The corresponding handler is \c onFlickEnded.
*/
/*!
@@ -1203,8 +1195,6 @@ bool QQuickPathView::isDragging() const
This signal is emitted when the view starts to be dragged due to user
interaction.
-
- The corresponding handler is \c onDragStarted.
*/
/*!
@@ -1214,8 +1204,6 @@ bool QQuickPathView::isDragging() const
If the velocity of the drag is suffient at the time the
touch/mouse button is released then a flick will start.
-
- The corresponding handler is \c onDragEnded.
*/
/*!
diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h
index 66be7fa6ff..c12358e4f6 100644
--- a/src/quick/items/qquickpathview_p.h
+++ b/src/quick/items/qquickpathview_p.h
@@ -100,6 +100,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathView : public QQuickItem
Q_PROPERTY(MovementDirection movementDirection READ movementDirection WRITE setMovementDirection NOTIFY movementDirectionChanged REVISION 7)
Q_PROPERTY(int cacheItemCount READ cacheItemCount WRITE setCacheItemCount NOTIFY cacheItemCountChanged)
+ QML_NAMED_ELEMENT(PathView)
+ QML_ATTACHED(QQuickPathViewAttached)
public:
QQuickPathView(QQuickItem *parent = nullptr);
@@ -299,6 +301,5 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickPathView)
-QML_DECLARE_TYPEINFO(QQuickPathView, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKPATHVIEW_P_H
diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp
index 2301a5c26e..0692a1da42 100644
--- a/src/quick/items/qquickpincharea.cpp
+++ b/src/quick/items/qquickpincharea.cpp
@@ -210,8 +210,6 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
To ignore this gesture set the \c pinch.accepted property to false. The gesture
will be canceled and no further events will be sent.
-
- The corresponding handler is \c onPinchStarted.
*/
/*!
@@ -224,8 +222,6 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
reflect changes only since the beginning of the current gesture, and
therefore are not limited by the minimum and maximum limits in the
\l {PinchArea}{pinch} property.
-
- The corresponding handler is \c onPinchUpdated.
*/
/*!
@@ -236,8 +232,6 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
The \l {PinchEvent}{pinch} parameter (not the same as the \l {PinchArea}{pinch}
property) provides information about the pinch gesture, including the
scale, center and angle of the pinch.
-
- The corresponding handler is \c onPinchFinished.
*/
/*!
@@ -252,8 +246,6 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
will be greater than zero when the gesture indicates that the user wishes to
enter smart zoom, and zero when exiting (even though typically the same gesture
is used to toggle between the two states).
-
- The corresponding handler is \c onSmartZoom.
*/
diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h
index cf21555823..d7f814cc8a 100644
--- a/src/quick/items/qquickpincharea_p.h
+++ b/src/quick/items/qquickpincharea_p.h
@@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickPinch : public QObject
Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged)
Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged)
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
+ QML_NAMED_ELEMENT(Pinch)
public:
QQuickPinch();
@@ -210,6 +211,7 @@ class Q_AUTOTEST_EXPORT QQuickPinchEvent : public QObject
Q_PROPERTY(QPointF startPoint2 READ startPoint2)
Q_PROPERTY(int pointCount READ pointCount)
Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
+ QML_ANONYMOUS
public:
QQuickPinchEvent(QPointF c, qreal s, qreal a, qreal r)
@@ -268,6 +270,7 @@ class Q_AUTOTEST_EXPORT QQuickPinchArea : public QQuickItem
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(QQuickPinch *pinch READ pinch CONSTANT)
+ QML_NAMED_ELEMENT(PinchArea)
public:
QQuickPinchArea(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp
index 65c48c583a..a8d050527b 100644
--- a/src/quick/items/qquickpositioners.cpp
+++ b/src/quick/items/qquickpositioners.cpp
@@ -928,8 +928,6 @@ void QQuickPositionerAttached::setIsLastItem(bool isLastItem)
\since 5.9
This signal is emitted when positioning has been completed.
-
- The corresponding handler is \c onPositioningComplete.
*/
QQuickColumn::QQuickColumn(QQuickItem *parent)
@@ -1113,8 +1111,6 @@ void QQuickColumn::reportConflictingAnchors()
\since 5.9
This signal is emitted when positioning has been completed.
-
- The corresponding handler is \c onPositioningComplete.
*/
class QQuickRowPrivate : public QQuickBasePositionerPrivate
@@ -1408,8 +1404,6 @@ void QQuickRow::reportConflictingAnchors()
\since 5.9
This signal is emitted when positioning has been completed.
-
- The corresponding handler is \c onPositioningComplete.
*/
class QQuickGridPrivate : public QQuickBasePositionerPrivate
@@ -1992,8 +1986,6 @@ void QQuickGrid::reportConflictingAnchors()
\since 5.9
This signal is emitted when positioning has been completed.
-
- The corresponding handler is \c onPositioningComplete.
*/
class QQuickFlowPrivate : public QQuickBasePositionerPrivate
diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h
index 94a737e1f1..b924cb9c12 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -112,6 +112,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBasePositioner : public QQuickImplicitSizeIte
Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+
+ QML_NAMED_ELEMENT(Positioner)
+ QML_UNCREATABLE("Positioner is an abstract type that is only available as an attached property.")
+ QML_ATTACHED(QQuickPositionerAttached)
+
public:
enum PositionerType { None = 0x0, Horizontal = 0x1, Vertical = 0x2, Both = 0x3 };
@@ -230,6 +235,7 @@ private:
class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner
{
Q_OBJECT
+ QML_NAMED_ELEMENT(Column)
public:
QQuickColumn(QQuickItem *parent=nullptr);
@@ -246,6 +252,8 @@ class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner
Q_OBJECT
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
+ QML_NAMED_ELEMENT(Row)
+
public:
QQuickRow(QQuickItem *parent=nullptr);
@@ -279,6 +287,7 @@ class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner
Q_PROPERTY(HAlignment horizontalItemAlignment READ hItemAlign WRITE setHItemAlign NOTIFY horizontalAlignmentChanged REVISION 1)
Q_PROPERTY(HAlignment effectiveHorizontalItemAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged REVISION 1)
Q_PROPERTY(VAlignment verticalItemAlignment READ vItemAlign WRITE setVItemAlign NOTIFY verticalAlignmentChanged REVISION 1)
+ QML_NAMED_ELEMENT(Grid)
public:
QQuickGrid(QQuickItem *parent=nullptr);
@@ -359,6 +368,7 @@ class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
+ QML_NAMED_ELEMENT(Flow)
public:
QQuickFlow(QQuickItem *parent=nullptr);
@@ -395,6 +405,5 @@ QML_DECLARE_TYPE(QQuickGrid)
QML_DECLARE_TYPE(QQuickFlow)
QML_DECLARE_TYPE(QQuickBasePositioner)
-QML_DECLARE_TYPEINFO(QQuickBasePositioner, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKPOSITIONERS_P_H
diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp
index f3cefc7463..c1f2b77f5b 100644
--- a/src/quick/items/qquickrectangle.cpp
+++ b/src/quick/items/qquickrectangle.cpp
@@ -257,7 +257,7 @@ QQuickGradient::~QQuickGradient()
QQmlListProperty<QQuickGradientStop> QQuickGradient::stops()
{
- return QQmlListProperty<QQuickGradientStop>(this, m_stops);
+ return QQmlListProperty<QQuickGradientStop>(this, &m_stops);
}
/*!
diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h
index d56a03d22d..934300b63b 100644
--- a/src/quick/items/qquickrectangle_p.h
+++ b/src/quick/items/qquickrectangle_p.h
@@ -66,6 +66,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPen : public QObject
Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY penChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged)
Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY penChanged)
+ QML_ANONYMOUS
public:
QQuickPen(QObject *parent=nullptr);
@@ -96,6 +97,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradientStop : public QObject
Q_PROPERTY(qreal position READ position WRITE setPosition)
Q_PROPERTY(QColor color READ color WRITE setColor)
+ QML_NAMED_ELEMENT(GradientStop)
public:
QQuickGradientStop(QObject *parent=nullptr);
@@ -121,6 +123,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradient : public QObject
Q_PROPERTY(QQmlListProperty<QQuickGradientStop> stops READ stops)
Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged REVISION 12)
Q_CLASSINFO("DefaultProperty", "stops")
+ QML_NAMED_ELEMENT(Gradient)
Q_ENUMS(QGradient::Preset)
public:
@@ -161,6 +164,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRectangle : public QQuickItem
Q_PROPERTY(QJSValue gradient READ gradient WRITE setGradient RESET resetGradient)
Q_PROPERTY(QQuickPen * border READ border CONSTANT)
Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
+ QML_NAMED_ELEMENT(Rectangle)
public:
QQuickRectangle(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index c8c5281089..6dc735d20b 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -139,8 +139,6 @@ QQuickRepeaterPrivate::~QQuickRepeaterPrivate()
This signal is emitted when an item is added to the repeater. The \a index
parameter holds the index at which the item has been inserted within the
repeater, and the \a item parameter holds the \l Item that has been added.
-
- The corresponding handler is \c onItemAdded.
*/
/*!
@@ -152,8 +150,6 @@ QQuickRepeaterPrivate::~QQuickRepeaterPrivate()
Do not keep a reference to \a item if it was created by this repeater, as
in these cases it will be deleted shortly after the signal is handled.
-
- The corresponding handler is \c onItemRemoved.
*/
QQuickRepeater::QQuickRepeater(QQuickItem *parent)
: QQuickItem(*(new QQuickRepeaterPrivate), parent)
@@ -421,6 +417,12 @@ void QQuickRepeater::createdItem(int index, QObject *)
void QQuickRepeater::initItem(int index, QObject *object)
{
Q_D(QQuickRepeater);
+ if (index >= d->deletables.size()) {
+ // this can happen when Package is used
+ // calling regenerate does too much work, all we need is to call resize
+ // so that d->deletables[index] = item below works
+ d->deletables.resize(d->model->count() + 1);
+ }
QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
if (!d->deletables.at(index)) {
diff --git a/src/quick/items/qquickrepeater_p.h b/src/quick/items/qquickrepeater_p.h
index dbe3cd0c55..20984fa23e 100644
--- a/src/quick/items/qquickrepeater_p.h
+++ b/src/quick/items/qquickrepeater_p.h
@@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickRepeater : public QQuickItem
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_CLASSINFO("DefaultProperty", "delegate")
+ QML_NAMED_ELEMENT(Repeater)
public:
QQuickRepeater(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickscalegrid_p_p.h b/src/quick/items/qquickscalegrid_p_p.h
index f5187a8eea..56b0ee86ab 100644
--- a/src/quick/items/qquickscalegrid_p_p.h
+++ b/src/quick/items/qquickscalegrid_p_p.h
@@ -69,6 +69,7 @@ class Q_AUTOTEST_EXPORT QQuickScaleGrid : public QObject
Q_PROPERTY(int top READ top WRITE setTop NOTIFY topBorderChanged)
Q_PROPERTY(int right READ right WRITE setRight NOTIFY rightBorderChanged)
Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY bottomBorderChanged)
+ QML_ANONYMOUS
public:
QQuickScaleGrid(QObject *parent=nullptr);
diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp
index b17e505f4f..ed2d7eda3e 100644
--- a/src/quick/items/qquickscreen.cpp
+++ b/src/quick/items/qquickscreen.cpp
@@ -424,9 +424,6 @@ QScreen *QQuickScreenInfo::wrappedScreen() const
QQuickScreenAttached::QQuickScreenAttached(QObject* attachee)
: QQuickScreenInfo(attachee)
- , m_window(nullptr)
- , m_updateMask(nullptr)
- , m_updateMaskSet(false)
{
m_attachee = qobject_cast<QQuickItem*>(attachee);
diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h
index 10e524e4a0..9a2a9eaecf 100644
--- a/src/quick/items/qquickscreen_p.h
+++ b/src/quick/items/qquickscreen_p.h
@@ -54,7 +54,7 @@
#include <qqml.h>
#include <QRect>
#include <QSize>
-#include <private/qqmlglobal_p.h>
+#include <private/qtquickglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -64,7 +64,7 @@ class QQuickWindow;
class QScreen;
-class Q_AUTOTEST_EXPORT QQuickScreenInfo : public QObject
+class Q_QUICK_PRIVATE_EXPORT QQuickScreenInfo : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
@@ -78,9 +78,7 @@ class Q_AUTOTEST_EXPORT QQuickScreenInfo : public QObject
Q_PROPERTY(qreal logicalPixelDensity READ logicalPixelDensity NOTIFY logicalPixelDensityChanged)
Q_PROPERTY(qreal pixelDensity READ pixelDensity NOTIFY pixelDensityChanged)
Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged)
- // TODO Qt 6 Rename primaryOrientation to orientation
Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY primaryOrientationChanged)
- // TODO Qt 6 Remove this orientation -> incomplete device orientation -> better use OrientationSensor
Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged)
Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION 3)
@@ -128,7 +126,7 @@ protected:
QPointer<QScreen> m_screen;
};
-class Q_AUTOTEST_EXPORT QQuickScreenAttached : public QQuickScreenInfo
+class Q_QUICK_PRIVATE_EXPORT QQuickScreenAttached : public QQuickScreenInfo
{
Q_OBJECT
Q_PROPERTY(Qt::ScreenOrientations orientationUpdateMask READ orientationUpdateMask
@@ -152,22 +150,23 @@ protected Q_SLOTS:
void screenChanged(QScreen*);
private:
- QQuickWindow* m_window;
+ QQuickWindow* m_window = nullptr;
QQuickItem* m_attachee;
Qt::ScreenOrientations m_updateMask;
- bool m_updateMaskSet;
+ bool m_updateMaskSet = false;
};
-class Q_AUTOTEST_EXPORT QQuickScreen : public QObject
+class Q_QUICK_PRIVATE_EXPORT QQuickScreen : public QObject
{
Q_OBJECT
+ QML_ATTACHED(QQuickScreenAttached)
+
public:
static QQuickScreenAttached *qmlAttachedProperties(QObject *object){ return new QQuickScreenAttached(object); }
};
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickScreen, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickScreenInfo)
#endif
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index 6e2f35882b..c14907092c 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -75,6 +75,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffect : public QQuickItem
Q_PROPERTY(QString log READ log NOTIFY logChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION 4)
+ QML_NAMED_ELEMENT(ShaderEffect)
public:
enum CullMode {
diff --git a/src/quick/items/qquickshadereffectmesh_p.h b/src/quick/items/qquickshadereffectmesh_p.h
index 79e05a5f9f..710d37c275 100644
--- a/src/quick/items/qquickshadereffectmesh_p.h
+++ b/src/quick/items/qquickshadereffectmesh_p.h
@@ -49,6 +49,7 @@ QT_REQUIRE_CONFIG(quick_shadereffect);
#include <QtCore/qsize.h>
#include <QtCore/qvector.h>
#include <QtCore/qbytearray.h>
+#include <QtQml/qqml.h>
#ifndef QQUICKSHADEREFFECTMESH_P_H
#define QQUICKSHADEREFFECTMESH_P_H
@@ -75,6 +76,10 @@ class QRectF;
class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectMesh : public QObject
{
Q_OBJECT
+
+ QML_NAMED_ELEMENT(ShaderEffectMesh)
+ QML_UNCREATABLE("Cannot create instance of abstract class ShaderEffectMesh.")
+
public:
QQuickShaderEffectMesh(QObject *parent = nullptr);
virtual bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) = 0;
@@ -96,6 +101,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGridMesh : public QQuickShaderEffectMesh
{
Q_OBJECT
Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
+ QML_NAMED_ELEMENT(GridMesh)
public:
QQuickGridMesh(QObject *parent = nullptr);
bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) override;
@@ -123,6 +129,10 @@ class QQuickBorderImageMesh : public QQuickShaderEffectMesh
Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged)
Q_PROPERTY(TileMode horizontalTileMode READ horizontalTileMode WRITE setHorizontalTileMode NOTIFY horizontalTileModeChanged)
Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)
+
+ QML_NAMED_ELEMENT(BorderImageMesh)
+ QML_ADDED_IN_MINOR_VERSION(8)
+
public:
QQuickBorderImageMesh(QObject *parent = nullptr);
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index d612d1179f..c0a1ccab78 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -89,6 +89,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 6)
Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 9)
+ QML_NAMED_ELEMENT(ShaderEffectSource)
public:
enum WrapMode {
diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h
index fab9e75190..98e5b82db8 100644
--- a/src/quick/items/qquicksprite_p.h
+++ b/src/quick/items/qquicksprite_p.h
@@ -86,6 +86,7 @@ class Q_QUICK_EXPORT QQuickSprite : public QQuickStochasticState
Q_PROPERTY(qreal frameRateVariation READ frameRateVariation WRITE setFrameRateVariation NOTIFY frameRateVariationChanged)
Q_PROPERTY(int frameDuration READ frameDuration WRITE setFrameDuration NOTIFY frameDurationChanged RESET resetFrameDuration)
Q_PROPERTY(int frameDurationVariation READ frameDurationVariation WRITE setFrameDurationVariation NOTIFY frameDurationVariationChanged)
+ QML_NAMED_ELEMENT(Sprite)
public:
explicit QQuickSprite(QObject *parent = nullptr);
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index da505be911..5ad33389de 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -196,7 +196,7 @@ public:
QQmlListProperty<QQuickStochasticState> states()
{
- return QQmlListProperty<QQuickStochasticState>(this, m_states);
+ return QQmlListProperty<QQuickStochasticState>(this, &m_states);
}
QString globalGoal() const
@@ -272,7 +272,7 @@ public:
~QQuickSpriteEngine() override;
QQmlListProperty<QQuickSprite> sprites()
{
- return QQmlListProperty<QQuickSprite>(this, m_sprites);
+ return QQmlListProperty<QQuickSprite>(this, &m_sprites);
}
QQuickSprite* sprite(int sprite = 0) const;
@@ -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/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h
index 12c80d6a27..8361f7832a 100644
--- a/src/quick/items/qquickspritesequence_p.h
+++ b/src/quick/items/qquickspritesequence_p.h
@@ -74,6 +74,7 @@ class Q_AUTOTEST_EXPORT QQuickSpriteSequence : public QQuickItem
//###try to share similar spriteEngines for less overhead?
Q_PROPERTY(QQmlListProperty<QQuickSprite> sprites READ sprites)
Q_CLASSINFO("DefaultProperty", "sprites")
+ QML_NAMED_ELEMENT(SpriteSequence)
public:
explicit QQuickSpriteSequence(QQuickItem *parent = nullptr);
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index 31d1c91649..ddaa1979b6 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -44,6 +44,7 @@
#include <QtQml/qqmlinfo.h>
#include <QtCore/qmath.h>
+#include <memory>
QT_BEGIN_NAMESPACE
@@ -51,15 +52,17 @@ class QQuickParentChangePrivate : public QQuickStateOperationPrivate
{
Q_DECLARE_PUBLIC(QQuickParentChange)
public:
- QQuickParentChangePrivate() : target(nullptr), parent(nullptr), origParent(nullptr), origStackBefore(nullptr),
- rewindParent(nullptr), rewindStackBefore(nullptr) {}
-
- QQuickItem *target;
+ QQuickItem *target = nullptr;
QPointer<QQuickItem> parent;
- QPointer<QQuickItem> origParent;
- QPointer<QQuickItem> origStackBefore;
- QQuickItem *rewindParent;
- QQuickItem *rewindStackBefore;
+
+ struct StateSnapshot {
+ QPointer<QQuickItem> parent;
+ QPointer<QQuickItem> stackBefore;
+ qreal x = 0, y = 0, width = 0, height = 0, scale = 0, rotation = 0;
+ };
+
+ std::unique_ptr<StateSnapshot> orig;
+ std::unique_ptr<StateSnapshot> rewind;
QQmlNullableValue<QQmlScriptString> xString;
QQmlNullableValue<QQmlScriptString> yString;
@@ -68,10 +71,11 @@ public:
QQmlNullableValue<QQmlScriptString> scaleString;
QQmlNullableValue<QQmlScriptString> rotationString;
- void doChange(QQuickItem *targetParent, QQuickItem *stackBefore = nullptr);
+ void doChange(QQuickItem *targetParent);
+ void reverseRewindHelper(const std::unique_ptr<StateSnapshot> &snapshot);
};
-void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *stackBefore)
+void QQuickParentChangePrivate::doChange(QQuickItem *targetParent)
{
if (targetParent && target && target->parentItem()) {
Q_Q(QQuickParentChange);
@@ -137,11 +141,6 @@ void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *s
} else if (target) {
target->setParentItem(targetParent);
}
-
- //restore the original stack position.
- //### if stackBefore has also been reparented this won't work
- if (target && stackBefore)
- target->stackBefore(stackBefore);
}
/*!
@@ -305,7 +304,7 @@ bool QQuickParentChange::rotationIsSet() const
QQuickItem *QQuickParentChange::originalParent() const
{
Q_D(const QQuickParentChange);
- return d->origParent;
+ return d->orig ? d->orig->parent : nullptr;
}
/*!
@@ -473,21 +472,11 @@ void QQuickParentChange::saveOriginals()
{
Q_D(QQuickParentChange);
saveCurrentValues();
- d->origParent = d->rewindParent;
- d->origStackBefore = d->rewindStackBefore;
+ if (!d->orig)
+ d->orig.reset(new QQuickParentChangePrivate::StateSnapshot);
+ *d->orig = *d->rewind;
}
-/*void QQuickParentChange::copyOriginals(QQuickStateActionEvent *other)
-{
- Q_D(QQuickParentChange);
- QQuickParentChange *pc = static_cast<QQuickParentChange*>(other);
-
- d->origParent = pc->d_func()->rewindParent;
- d->origStackBefore = pc->d_func()->rewindStackBefore;
-
- saveCurrentValues();
-}*/
-
void QQuickParentChange::execute()
{
Q_D(QQuickParentChange);
@@ -499,10 +488,26 @@ bool QQuickParentChange::isReversable()
return true;
}
+void QQuickParentChangePrivate::reverseRewindHelper(const std::unique_ptr<QQuickParentChangePrivate::StateSnapshot> &snapshot)
+{
+ if (!target || !snapshot)
+ return;
+ target->setX(snapshot->x);
+ target->setY(snapshot->y);
+ target->setScale(snapshot->scale);
+ target->setWidth(snapshot->width);
+ target->setHeight(snapshot->height);
+ target->setRotation(snapshot->rotation);
+ target->setParentItem(snapshot->parent);
+ if (snapshot->stackBefore)
+ target->stackBefore(snapshot->stackBefore);
+}
+
+
void QQuickParentChange::reverse()
{
Q_D(QQuickParentChange);
- d->doChange(d->origParent, d->origStackBefore);
+ d->reverseRewindHelper(d->orig);
}
QQuickStateActionEvent::EventType QQuickParentChange::type() const
@@ -524,21 +529,28 @@ void QQuickParentChange::saveCurrentValues()
{
Q_D(QQuickParentChange);
if (!d->target) {
- d->rewindParent = nullptr;
- d->rewindStackBefore = nullptr;
+ d->rewind = nullptr;
return;
}
- d->rewindParent = d->target->parentItem();
- d->rewindStackBefore = nullptr;
+ d->rewind.reset(new QQuickParentChangePrivate::StateSnapshot);
+ d->rewind->x = d->target->x();
+ d->rewind->y = d->target->y();
+ d->rewind->scale = d->target->scale();
+ d->rewind->width = d->target->width();
+ d->rewind->height = d->target->height();
+ d->rewind->rotation = d->target->rotation();
+
+ d->rewind->parent = d->target->parentItem();
+ d->rewind->stackBefore = nullptr;
- if (!d->rewindParent)
+ if (!d->rewind->parent)
return;
- QList<QQuickItem *> children = d->rewindParent->childItems();
+ QList<QQuickItem *> children = d->rewind->parent->childItems();
for (int ii = 0; ii < children.count() - 1; ++ii) {
if (children.at(ii) == d->target) {
- d->rewindStackBefore = children.at(ii + 1);
+ d->rewind->stackBefore = children.at(ii + 1);
break;
}
}
@@ -547,7 +559,8 @@ void QQuickParentChange::saveCurrentValues()
void QQuickParentChange::rewind()
{
Q_D(QQuickParentChange);
- d->doChange(d->rewindParent, d->rewindStackBefore);
+ d->reverseRewindHelper(d->rewind);
+ d->rewind.reset();
}
/*!
@@ -587,11 +600,6 @@ class QQuickAnchorSetPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QQuickAnchorSet)
public:
- QQuickAnchorSetPrivate()
- : usedAnchors(nullptr), resetAnchors(nullptr)
- {
- }
-
QQuickAnchors::Anchors usedAnchors;
QQuickAnchors::Anchors resetAnchors;
diff --git a/src/quick/items/qquickstateoperations_p.h b/src/quick/items/qquickstateoperations_p.h
index 357366bc60..d451dc6f77 100644
--- a/src/quick/items/qquickstateoperations_p.h
+++ b/src/quick/items/qquickstateoperations_p.h
@@ -74,6 +74,7 @@ class Q_AUTOTEST_EXPORT QQuickParentChange : public QQuickStateOperation, public
Q_PROPERTY(QQmlScriptString height READ height WRITE setHeight)
Q_PROPERTY(QQmlScriptString scale READ scale WRITE setScale)
Q_PROPERTY(QQmlScriptString rotation READ rotation WRITE setRotation)
+ QML_NAMED_ELEMENT(ParentChange)
public:
QQuickParentChange(QObject *parent=nullptr);
~QQuickParentChange();
@@ -136,6 +137,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorSet : public QObject
Q_PROPERTY(QQmlScriptString bottom READ bottom WRITE setBottom RESET resetBottom)
Q_PROPERTY(QQmlScriptString verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter)
Q_PROPERTY(QQmlScriptString baseline READ baseline WRITE setBaseline RESET resetBaseline)
+ QML_ANONYMOUS
public:
QQuickAnchorSet(QObject *parent=nullptr);
@@ -185,6 +187,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorChanges : public QQuickStateOperation, publi
Q_PROPERTY(QQuickItem *target READ object WRITE setObject)
Q_PROPERTY(QQuickAnchorSet *anchors READ anchors CONSTANT)
+ QML_NAMED_ELEMENT(AnchorChanges)
public:
QQuickAnchorChanges(QObject *parent=nullptr);
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 4105996b31..c7882fb2b1 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -1,4 +1,4 @@
-/****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
@@ -82,7 +82,7 @@
The following example shows how to create a model from C++ with multiple
columns:
- \snippet qml/tableview/cpp-tablemodel.cpp 0
+ \snippet qml/tableview/cpp-tablemodel.h 0
And then how to use it from QML:
@@ -193,8 +193,10 @@
\qmlproperty int QtQuick::TableView::rows
\readonly
- This property holds the number of rows in the table. This is
- equal to the number of rows in the model.
+ This property holds the number of rows in the table.
+
+ \note \a rows is usually equal to the number of rows in the model, but can
+ temporarily differ until all pending model changes have been processed.
This property is read only.
*/
@@ -203,9 +205,12 @@
\qmlproperty int QtQuick::TableView::columns
\readonly
- This property holds the number of columns in the table. This is
- equal to the number of columns in the model. If the model is
- a list, columns will be \c 1.
+ This property holds the number of rows in the table.
+
+ \note \a columns is usually equal to the number of columns in the model, but
+ can temporarily differ until all pending model changes have been processed.
+
+ If the model is a list, columns will be \c 1.
This property is read only.
*/
@@ -457,6 +462,8 @@ QQuickTableViewPrivate::~QQuickTableViewPrivate()
QString QQuickTableViewPrivate::tableLayoutToString() const
{
+ if (loadedItems.isEmpty())
+ return QLatin1String("table is empty!");
return QString(QLatin1String("table cells: (%1,%2) -> (%3,%4), item count: %5, table rect: %6,%7 x %8,%9"))
.arg(leftColumn()).arg(topRow())
.arg(rightColumn()).arg(bottomRow())
@@ -493,20 +500,34 @@ QQuickTableViewAttached *QQuickTableViewPrivate::getAttachedObject(const QObject
int QQuickTableViewPrivate::modelIndexAtCell(const QPoint &cell) const
{
- int availableRows = tableSize.height();
- int modelIndex = cell.y() + (cell.x() * availableRows);
- Q_TABLEVIEW_ASSERT(modelIndex < model->count(),
- "modelIndex:" << modelIndex << "cell:" << cell << "count:" << model->count());
- return modelIndex;
+ // QQmlTableInstanceModel expects index to be in column-major
+ // order. This means that if the view is transposed (with a flipped
+ // width and height), we need to calculate it in row-major instead.
+ if (isTransposed) {
+ int availableColumns = tableSize.width();
+ return (cell.y() * availableColumns) + cell.x();
+ } else {
+ int availableRows = tableSize.height();
+ return (cell.x() * availableRows) + cell.y();
+ }
}
QPoint QQuickTableViewPrivate::cellAtModelIndex(int modelIndex) const
{
- int availableRows = tableSize.height();
- Q_TABLEVIEW_ASSERT(availableRows > 0, availableRows);
- int column = int(modelIndex / availableRows);
- int row = modelIndex % availableRows;
- return QPoint(column, row);
+ // QQmlTableInstanceModel expects index to be in column-major
+ // order. This means that if the view is transposed (with a flipped
+ // width and height), we need to calculate it in row-major instead.
+ if (isTransposed) {
+ int availableColumns = tableSize.width();
+ int row = int(modelIndex / availableColumns);
+ int column = modelIndex % availableColumns;
+ return QPoint(column, row);
+ } else {
+ int availableRows = tableSize.height();
+ int column = int(modelIndex / availableRows);
+ int row = modelIndex % availableRows;
+ return QPoint(column, row);
+ }
}
int QQuickTableViewPrivate::edgeToArrayIndex(Qt::Edge edge)
@@ -1083,15 +1104,8 @@ void QQuickTableViewPrivate::releaseItem(FxTableItem *fxTableItem, QQmlTableInst
Q_TABLEVIEW_ASSERT(item, fxTableItem->index);
delete item;
} else if (item) {
- // Only QQmlTableInstanceModel supports reusing items
- auto releaseFlag = tableModel ?
- tableModel->release(item, reusableFlag) :
- model->release(item);
-
- if (releaseFlag != QQmlInstanceModel::Destroyed) {
- // When items are not destroyed, it typically means that the
- // item is reused, or that the model is an ObjectModel. If
- // so, we just hide the item instead.
+ auto releaseFlag = model->release(item, reusableFlag);
+ if (releaseFlag == QQmlInstanceModel::Pooled) {
fxTableItem->setVisible(false);
// If the item (or a descendant) has focus, remove it, so
@@ -1241,12 +1255,13 @@ void QQuickTableViewPrivate::updateTableSize()
QSize QQuickTableViewPrivate::calculateTableSize()
{
+ QSize size(0, 0);
if (tableModel)
- return QSize(tableModel->columns(), tableModel->rows());
+ size = QSize(tableModel->columns(), tableModel->rows());
else if (model)
- return QSize(1, model->count());
+ size = QSize(1, model->count());
- return QSize(0, 0);
+ return isTransposed ? size.transposed() : size;
}
qreal QQuickTableViewPrivate::getColumnLayoutWidth(int column)
@@ -2257,6 +2272,21 @@ void QQuickTableViewPrivate::syncDelegate()
tableModel->setDelegate(assignedDelegate);
}
+QVariant QQuickTableViewPrivate::modelImpl() const
+{
+ return assignedModel;
+}
+
+void QQuickTableViewPrivate::setModelImpl(const QVariant &newModel)
+{
+ if (newModel == assignedModel)
+ return;
+
+ assignedModel = newModel;
+ scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::All);
+ emit q_func()->modelChanged();
+}
+
void QQuickTableViewPrivate::syncModel()
{
if (modelVariant == assignedModel)
@@ -2350,14 +2380,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
@@ -2385,13 +2412,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);
@@ -2678,18 +2702,12 @@ void QQuickTableView::setColumnWidthProvider(const QJSValue &provider)
QVariant QQuickTableView::model() const
{
- return d_func()->assignedModel;
+ return d_func()->modelImpl();
}
void QQuickTableView::setModel(const QVariant &newModel)
{
- Q_D(QQuickTableView);
- if (newModel == d->assignedModel)
- return;
-
- d->assignedModel = newModel;
- d->scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::All);
- emit modelChanged();
+ return d_func()->setModelImpl(newModel);
}
QQmlComponent *QQuickTableView::delegate() const
diff --git a/src/quick/items/qquicktableview_p.h b/src/quick/items/qquicktableview_p.h
index a5f727d7a4..d549aaddf7 100644
--- a/src/quick/items/qquicktableview_p.h
+++ b/src/quick/items/qquicktableview_p.h
@@ -82,6 +82,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableView : public QQuickFlickable
Q_PROPERTY(QQuickTableView *syncView READ syncView WRITE setSyncView NOTIFY syncViewChanged REVISION 14)
Q_PROPERTY(Qt::Orientations syncDirection READ syncDirection WRITE setSyncDirection NOTIFY syncDirectionChanged REVISION 14)
+ QML_NAMED_ELEMENT(TableView)
+ QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ATTACHED(QQuickTableViewAttached)
+
public:
QQuickTableView(QQuickItem *parent = nullptr);
~QQuickTableView() override;
@@ -100,8 +104,8 @@ public:
QJSValue columnWidthProvider() const;
void setColumnWidthProvider(const QJSValue &provider);
- virtual QVariant model() const;
- virtual void setModel(const QVariant &newModel);
+ QVariant model() const;
+ void setModel(const QVariant &newModel);
QQmlComponent *delegate() const;
void setDelegate(QQmlComponent *);
@@ -186,6 +190,5 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickTableView)
-QML_DECLARE_TYPEINFO(QQuickTableView, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKTABLEVIEW_P_H
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index ec043f5e7e..fe4cf82b46 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -90,7 +90,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)
@@ -277,6 +277,10 @@ public:
bool inSyncViewportPosRecursive = false;
bool inUpdateContentSize = false;
+ // isTransposed is currently only used by HeaderView.
+ // Consider making it public.
+ bool isTransposed = false;
+
QJSValue rowHeightProvider;
QJSValue columnWidthProvider;
QQuickTableSectionSizeProvider rowHeights;
@@ -403,11 +407,13 @@ public:
void itemReusedCallback(int modelIndex, QObject *object);
void modelUpdated(const QQmlChangeSet &changeSet, bool reset);
- inline void syncWithPendingChanges();
- inline void syncDelegate();
- inline void syncModel();
+ virtual void syncWithPendingChanges();
+ virtual void syncDelegate();
+ virtual QVariant modelImpl() const;
+ virtual void setModelImpl(const QVariant &newModel);
+ virtual void syncModel();
inline void syncRebuildOptions();
- inline void syncSyncView();
+ virtual void syncSyncView();
void connectToModel();
void disconnectFromModel();
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index b95a2559ff..90469ee82b 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>
@@ -517,6 +520,11 @@ void QQuickTextLine::setLineOffset(int offset)
m_lineOffset = offset;
}
+void QQuickTextLine::setFullLayoutTextLength(int length)
+{
+ m_fullLayoutTextLength = length;
+}
+
int QQuickTextLine::number() const
{
if (m_line)
@@ -524,6 +532,24 @@ int QQuickTextLine::number() const
return 0;
}
+qreal QQuickTextLine::implicitWidth() const
+{
+ if (m_line)
+ return m_line->naturalTextWidth();
+ return 0;
+}
+
+bool QQuickTextLine::isLast() const
+{
+ if (m_line && (m_line->textStart() + m_line->textLength()) == m_fullLayoutTextLength) {
+ // Ensure that isLast will change if the user reduced the width of the line
+ // so that the text no longer fits.
+ return m_line->width() >= m_line->naturalTextWidth();
+ }
+
+ return false;
+}
+
qreal QQuickTextLine::width() const
{
if (m_line)
@@ -585,12 +611,13 @@ bool QQuickTextPrivate::isLineLaidOutConnected()
IS_SIGNAL_CONNECTED(q, QQuickText, lineLaidOut, (QQuickTextLine *));
}
-void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset)
+void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, int fullLayoutTextLength, int lineOffset)
{
Q_Q(QQuickText);
if (!textLine)
textLine = new QQuickTextLine;
+ textLine->setFullLayoutTextLength(fullLayoutTextLength);
textLine->setLine(&line);
textLine->setY(height);
textLine->setHeight(0);
@@ -790,7 +817,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
if (noBreakLastLine && visibleCount == maxLineCount)
layout.engine()->option.setWrapMode(QTextOption::WrapAnywhere);
if (customLayout) {
- setupCustomLineGeometry(line, naturalHeight);
+ setupCustomLineGeometry(line, naturalHeight, layoutText.length());
} else {
setLineGeometry(line, lineWidth, naturalHeight);
}
@@ -1122,13 +1149,17 @@ 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();
QTextLine elidedLine = elideLayout->createLine();
elidedLine.setPosition(QPointF(0, height));
if (customLayout) {
- setupCustomLineGeometry(elidedLine, height, visibleCount - 1);
+ setupCustomLineGeometry(elidedLine, height, elideText.length(), visibleCount - 1);
} else {
setLineGeometry(elidedLine, lineWidth, height);
}
@@ -1188,7 +1219,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
if (!image->pix) {
QUrl url = q->baseUrl().resolved(image->url);
- image->pix = new QQuickPixmap(qmlEngine(q), url, image->size);
+ image->pix = new QQuickPixmap(qmlEngine(q), url, QRect(), image->size);
if (image->pix->isLoading()) {
image->pix->connectFinished(q, SLOT(imageDownloadFinished()));
if (!extra.isAllocated() || !extra->nbActiveDownloads)
@@ -1335,20 +1366,43 @@ QQuickText::~QQuickText()
\qmlsignal QtQuick::Text::lineLaidOut(object line)
This signal is emitted for each line of text that is laid out during the layout
- process. The specified \a line object provides more details about the line that
+ process in plain text or styled text mode. It is not emitted in rich text mode.
+ The specified \a line object provides more details about the line that
is currently being laid out.
This gives the opportunity to position and resize a line as it is being laid out.
It can for example be used to create columns or lay out text around objects.
The properties of the specified \a line object are:
- \list
- \li number (read-only)
- \li x
- \li y
- \li width
- \li height
- \endlist
+
+ \table
+ \header
+ \li Property name
+ \li Description
+ \row
+ \li number (read-only)
+ \li Line number, starts with zero.
+ \row
+ \li x
+ \li Specifies the line's x position inside the \c Text element.
+ \row
+ \li y
+ \li Specifies the line's y position inside the \c Text element.
+ \row
+ \li width
+ \li Specifies the width of the line.
+ \row
+ \li height
+ \li Specifies the height of the line.
+ \row
+ \li implicitWidth (read-only)
+ \li The width that the line would naturally occupy based on its contents,
+ not taking into account any modifications made to \a width.
+ \row
+ \li isLast (read-only)
+ \li Whether the line is the last. This property can change if you
+ set the \a width property to a different value.
+ \endtable
For example, this will move the first 5 lines of a Text item by 100 pixels to the right:
\code
@@ -1360,7 +1414,15 @@ QQuickText::~QQuickText()
}
\endcode
- The corresponding handler is \c onLineLaidOut.
+ The following example will allow you to position an item at the end of the last line:
+ \code
+ onLineLaidOut: {
+ if (line.isLast) {
+ lastLineMarker.x = line.x + line.implicitWidth
+ lastLineMarker.y = line.y + (line.height - lastLineMarker.height) / 2
+ }
+ }
+ \endcode
*/
/*!
@@ -1377,8 +1439,6 @@ QQuickText::~QQuickText()
Clicking on the highlighted link will output
\tt{http://qt-project.org link activated} to the console.
-
- The corresponding handler is \c onLinkActivated.
*/
/*!
@@ -2586,6 +2646,12 @@ void QQuickText::setLineHeightMode(LineHeightMode mode)
If the text does not fit within the item bounds with the minimum font size
the text will be elided as per the \l elide property.
+
+ If the \l textFormat property is set to \l Text.RichText, this will have no effect at all as the
+ property will be ignored completely. If \l textFormat is set to \l Text.StyledText, then the
+ property will be respected provided there is no font size tags inside the text. If there are
+ font size tags, the property will still respect those. This can cause it to not fully comply with
+ the fontSizeMode setting.
*/
QQuickText::FontSizeMode QQuickText::fontSizeMode() const
@@ -2800,8 +2866,6 @@ bool QQuickTextPrivate::isLinkHoveredConnected()
text. The link must be in rich text or HTML format and the \a link
string provides access to the particular link.
- The corresponding handler is \c onLinkHovered.
-
\sa hoveredLink, linkAt()
*/
@@ -2905,6 +2969,8 @@ void QQuickText::setRenderType(QQuickText::RenderType renderType)
d->updateLayout();
}
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\qmlmethod QtQuick::Text::doLayout()
\deprecated
@@ -2916,6 +2982,8 @@ void QQuickText::doLayout()
forceLayout();
}
+#endif
+#endif
/*!
\qmlmethod QtQuick::Text::forceLayout()
\since 5.9
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 45f387cb12..0fffc1fb9a 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -100,6 +100,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
Q_PROPERTY(QJSValue fontInfo READ fontInfo NOTIFY fontInfoChanged REVISION 9)
Q_PROPERTY(QSizeF advance READ advance NOTIFY contentSizeChanged REVISION 10)
+ QML_NAMED_ELEMENT(Text)
public:
QQuickText(QQuickItem *parent=nullptr);
@@ -222,7 +223,12 @@ public:
QRectF boundingRect() const override;
QRectF clipRect() const override;
- Q_INVOKABLE void doLayout(); // ### Qt 6: remove
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use forceLayout() instead")
+ Q_INVOKABLE void doLayout();
+#endif
+#endif
Q_REVISION(9) Q_INVOKABLE void forceLayout();
RenderType renderType() const;
@@ -329,13 +335,19 @@ class QQuickTextLine : public QObject
Q_PROPERTY(qreal height READ height WRITE setHeight)
Q_PROPERTY(qreal x READ x WRITE setX)
Q_PROPERTY(qreal y READ y WRITE setY)
+ Q_PROPERTY(qreal implicitWidth READ implicitWidth REVISION 15)
+ Q_PROPERTY(bool isLast READ isLast REVISION 15)
+ QML_ANONYMOUS
public:
QQuickTextLine();
void setLine(QTextLine* line);
void setLineOffset(int offset);
+ void setFullLayoutTextLength(int length);
int number() const;
+ qreal implicitWidth() const;
+ bool isLast() const;
qreal width() const;
void setWidth(qreal width);
@@ -353,6 +365,7 @@ private:
QTextLine *m_line;
qreal m_height;
int m_lineOffset;
+ int m_fullLayoutTextLength;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index c01998b100..1fbf942130 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -195,7 +195,7 @@ public:
void ensureDoc();
QRectF setupTextLayout(qreal * const baseline);
- void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0);
+ void setupCustomLineGeometry(QTextLine &line, qreal &height, int fullLayoutTextLength, int lineOffset = 0);
bool isLinkActivatedConnected();
bool isLinkHoveredConnected();
static QString anchorAt(const QTextLayout *layout, const QPointF &mousePos);
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 3c392be751..4c741f67e3 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -60,6 +60,7 @@
#include <QtCore/qloggingcategory.h>
#include <qtextformat.h>
+#include <qtransform.h>
#include <qdatetime.h>
#include <qbuffer.h>
#include <qguiapplication.h>
@@ -718,12 +719,12 @@ void QQuickTextControl::selectAll()
void QQuickTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset)
{
- QMatrix m;
- m.translate(coordinateOffset.x(), coordinateOffset.y());
- processEvent(e, m);
+ QTransform t;
+ t.translate(coordinateOffset.x(), coordinateOffset.y());
+ processEvent(e, t);
}
-void QQuickTextControl::processEvent(QEvent *e, const QMatrix &matrix)
+void QQuickTextControl::processEvent(QEvent *e, const QTransform &transform)
{
Q_D(QQuickTextControl);
if (d->interactionFlags == Qt::NoTextInteraction) {
@@ -740,25 +741,25 @@ void QQuickTextControl::processEvent(QEvent *e, const QMatrix &matrix)
break;
case QEvent::MouseButtonPress: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
- d->mousePressEvent(ev, matrix.map(ev->localPos()));
+ d->mousePressEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::MouseMove: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
- d->mouseMoveEvent(ev, matrix.map(ev->localPos()));
+ d->mouseMoveEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::MouseButtonRelease: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
- d->mouseReleaseEvent(ev, matrix.map(ev->localPos()));
+ d->mouseReleaseEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::MouseButtonDblClick: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
- d->mouseDoubleClickEvent(ev, matrix.map(ev->localPos()));
+ d->mouseDoubleClickEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::HoverEnter:
case QEvent::HoverMove:
case QEvent::HoverLeave: {
QHoverEvent *ev = static_cast<QHoverEvent *>(e);
- d->hoverEvent(ev, matrix.map(ev->posF()));
+ d->hoverEvent(ev, transform.map(ev->posF()));
break; }
#if QT_CONFIG(im)
case QEvent::InputMethod:
diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h
index 41b8ed7821..eb5cd27994 100644
--- a/src/quick/items/qquicktextcontrol_p.h
+++ b/src/quick/items/qquicktextcontrol_p.h
@@ -71,6 +71,7 @@ class QQuickTextControlPrivate;
class QAbstractScrollArea;
class QEvent;
class QTimerEvent;
+class QTransform;
class Q_AUTOTEST_EXPORT QQuickTextControl : public QInputControl
{
@@ -169,7 +170,7 @@ Q_SIGNALS:
void markerHovered(bool marker);
public:
- virtual void processEvent(QEvent *e, const QMatrix &matrix);
+ virtual void processEvent(QEvent *e, const QTransform &transform);
void processEvent(QEvent *e, const QPointF &coordinateOffset = QPointF());
#if QT_CONFIG(im)
diff --git a/src/quick/items/qquicktextdocument.h b/src/quick/items/qquicktextdocument.h
index affa0ab4d6..bf9162755c 100644
--- a/src/quick/items/qquicktextdocument.h
+++ b/src/quick/items/qquicktextdocument.h
@@ -49,6 +49,7 @@ class QQuickTextDocumentPrivate;
class Q_QUICK_EXPORT QQuickTextDocument : public QObject
{
Q_OBJECT
+ QML_ANONYMOUS
public:
QQuickTextDocument(QQuickItem *parent);
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 650b1961a4..247d8abc3c 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -118,8 +118,6 @@ TextEdit {
This signal is emitted when the user clicks on a link embedded in the text.
The link must be in rich text or HTML format and the
\a link string provides access to the particular link.
-
- The corresponding handler is \c onLinkActivated.
*/
// This is a pretty arbitrary figure. The idea is that we don't want to break down the document
@@ -2903,8 +2901,6 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
The link must be in rich text or HTML format and the
\a link string provides access to the particular link.
- The corresponding handler is \c onLinkHovered.
-
\sa hoveredLink, linkAt()
*/
@@ -2913,8 +2909,6 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
\since 5.6
This signal is emitted when the text edit loses focus.
-
- The corresponding handler is \c onEditingFinished.
*/
/*!
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 2d1b6c7f9c..227d8cbf51 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -112,6 +112,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7)
Q_PROPERTY(qreal tabStopDistance READ tabStopDistance WRITE setTabStopDistance NOTIFY tabStopDistanceChanged REVISION 10)
+ QML_NAMED_ELEMENT(TextEdit)
public:
QQuickTextEdit(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index ee51711d34..06a9f134ac 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1171,8 +1171,6 @@ bool QQuickTextInput::hasAcceptableInput() const
Note that if there is a \l validator or \l inputMask set on the text
input, the signal will only be emitted if the input is in an acceptable
state.
-
- The corresponding handler is \c onAccepted.
*/
/*!
@@ -1184,8 +1182,6 @@ bool QQuickTextInput::hasAcceptableInput() const
inputMask set on the text input and enter/return is pressed, this
signal will only be emitted if the input follows
the inputMask and the validator returns an acceptable state.
-
- The corresponding handler is \c onEditingFinished.
*/
/*!
@@ -1195,8 +1191,6 @@ bool QQuickTextInput::hasAcceptableInput() const
This signal is emitted whenever the text is edited. Unlike \c textChanged(),
this signal is not emitted when the text is changed programmatically, for example,
by changing the value of the \c text property or by calling \c clear().
-
- The corresponding handler is \c onTextEdited.
*/
#if QT_CONFIG(im)
@@ -3956,7 +3950,7 @@ bool QQuickTextInputPrivate::isValidInput(QChar key, QChar mask) const
return true;
break;
case 'X':
- if (key.isPrint())
+ if (key.isPrint() && key != m_blank)
return true;
break;
case 'x':
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index c10b06d02a..9f7b82b168 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -113,6 +113,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+ QML_NAMED_ELEMENT(TextInput)
public:
QQuickTextInput(QQuickItem * parent=nullptr);
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index a0ae4e5f97..2356ab36ef 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -532,7 +532,7 @@ void QQuickTextNodeEngine::addGlyphsForRanges(const QVarLengthArray<QTextLayout:
int remainingLength = end - start;
for (int j=0; j<ranges.size(); ++j) {
const QTextLayout::FormatRange &range = ranges.at(j);
- if (range.start + range.length >= currentPosition
+ if (range.start + range.length > currentPosition
&& range.start < currentPosition + remainingLength) {
if (range.start > currentPosition) {
diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h
index b6ea43342c..aeda6ca589 100644
--- a/src/quick/items/qquicktranslate_p.h
+++ b/src/quick/items/qquicktranslate_p.h
@@ -64,6 +64,7 @@ class Q_AUTOTEST_EXPORT QQuickTranslate : public QQuickTransform
Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
+ QML_NAMED_ELEMENT(Translate)
public:
QQuickTranslate(QObject *parent = nullptr);
@@ -95,6 +96,7 @@ class Q_AUTOTEST_EXPORT QQuickScale : public QQuickTransform
Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY xScaleChanged)
Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged)
Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged)
+ QML_NAMED_ELEMENT(Scale)
public:
QQuickScale(QObject *parent = nullptr);
~QQuickScale();
@@ -132,6 +134,7 @@ class Q_AUTOTEST_EXPORT QQuickRotation : public QQuickTransform
Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged)
Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged)
+ QML_NAMED_ELEMENT(Rotation)
public:
QQuickRotation(QObject *parent = nullptr);
~QQuickRotation();
@@ -163,6 +166,8 @@ class Q_AUTOTEST_EXPORT QQuickMatrix4x4 : public QQuickTransform
Q_OBJECT
Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY matrixChanged)
+ QML_NAMED_ELEMENT(Matrix4x4)
+ QML_ADDED_IN_MINOR_VERSION(3)
public:
QQuickMatrix4x4(QObject *parent = nullptr);
~QQuickMatrix4x4();
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 2110d4caba..5b3b954460 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -486,7 +486,9 @@ void QQuickView::continueExecute()
return;
}
- QObject *obj = d->initialProperties.empty() ? d->component->create() : d->component->createWithInitialProperties(d->initialProperties);
+ QScopedPointer<QObject> obj(d->initialProperties.empty()
+ ? d->component->create()
+ : d->component->createWithInitialProperties(d->initialProperties));
if (d->component->isError()) {
const QList<QQmlError> errorList = d->component->errors();
@@ -498,7 +500,7 @@ void QQuickView::continueExecute()
return;
}
- d->setRootObject(obj);
+ d->setRootObject(obj.take());
emit statusChanged(status());
}
@@ -516,14 +518,14 @@ void QQuickViewPrivate::setRootObject(QObject *obj)
sgItem->setParentItem(q->QQuickWindow::contentItem());
QQml_setParent_noEvent(sgItem, q->QQuickWindow::contentItem());
} else if (qobject_cast<QWindow *>(obj)) {
- qWarning() << "QQuickView does not support using windows as a root item." << endl
- << endl
- << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << endl;
+ qWarning() << "QQuickView does not support using windows as a root item." << Qt::endl
+ << Qt::endl
+ << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << Qt::endl;
} else {
- qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << endl
- << endl
- << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << endl
- << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << endl;
+ qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << Qt::endl
+ << Qt::endl
+ << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << Qt::endl
+ << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << Qt::endl;
delete obj;
root = nullptr;
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index f07136fcd3..48ba0ecc28 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -39,7 +39,6 @@
#include "qquickwindow.h"
#include "qquickwindow_p.h"
-#include "qquickwindowattached_p.h"
#include "qquickitem.h"
#include "qquickitem_p.h"
@@ -94,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")
@@ -430,7 +430,7 @@ void QQuickWindowPrivate::syncSceneGraph()
if (renderTargetId && !QQuickRenderControl::renderWindowFor(q))
devicePixelRatio = 1;
- context->prepareSync(devicePixelRatio);
+ context->prepareSync(devicePixelRatio, rhi ? swapchain->currentFrameCommandBuffer() : nullptr);
animationController->beforeNodeSync();
@@ -528,7 +528,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
renderer->setDeviceRect(rect);
renderer->setViewportRect(rect);
const bool flipY = rhi ? !rhi->isYUpInNDC() : false;
- QSGAbstractRenderer::MatrixTransformFlags matrixFlags = 0;
+ QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
if (flipY)
matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
renderer->setProjectionMatrixToRect(QRectF(QPoint(0, 0), logicalSize), matrixFlags);
@@ -561,6 +561,7 @@ QQuickWindowPrivate::QQuickWindowPrivate()
, activeFocusItem(nullptr)
#if QT_CONFIG(cursor)
, cursorItem(nullptr)
+ , cursorHandler(nullptr)
#endif
#if QT_CONFIG(quick_draganddrop)
, dragGrabber(nullptr)
@@ -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)
@@ -771,7 +775,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
if (!item->contains(pos))
break;
- qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << p.id() << "->" << item;
+ qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << Qt::hex << p.id() << "->" << item;
QScopedPointer<QMouseEvent> mousePress(touchToMouseEvent(QEvent::MouseButtonPress, p, event.data(), item, false));
// Send a single press and see if that's accepted
@@ -813,7 +817,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
QCoreApplication::sendEvent(item, me.data());
event->setAccepted(me->isAccepted());
if (me->isAccepted()) {
- qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << p.id() << "->" << mouseGrabberItem;
+ qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << Qt::hex << p.id() << "->" << mouseGrabberItem;
}
return event->isAccepted();
} else {
@@ -969,8 +973,7 @@ void QQuickWindowPrivate::translateTouchEvent(QTouchEvent *touchEvent)
QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
for (int i = 0; i < touchPoints.count(); ++i) {
QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
-
- touchPoint.setSceneRect(touchPoint.rect());
+ touchPoint.setScenePos(touchPoint.pos());
touchPoint.setStartScenePos(touchPoint.startPos());
touchPoint.setLastScenePos(touchPoint.lastPos());
}
@@ -1763,12 +1766,18 @@ bool QQuickWindow::event(QEvent *e)
if (d->activeFocusItem)
QCoreApplication::sendEvent(d->activeFocusItem, e);
return true;
+ case QEvent::LanguageChange:
+ if (d->contentItem)
+ QCoreApplication::sendEvent(d->contentItem, e);
+ break;
default:
break;
}
if (e->type() == QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))
update();
+ else if (e->type() == QEvent::Type(QQuickWindowPrivate::TriggerContextCreationFailure))
+ d->windowManager->handleContextCreationFailure(this);
return QWindow::event(e);
}
@@ -2117,6 +2126,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;
@@ -2395,8 +2415,14 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevic
#endif
ev = new QQuickPointerTouchEvent(q, device);
break;
+#if QT_CONFIG(tabletevent)
+ case QQuickPointerDevice::Stylus:
+ case QQuickPointerDevice::Airbrush:
+ case QQuickPointerDevice::Puck:
+ ev = new QQuickPointerTabletEvent(q, device);
+ break;
+#endif
default:
- // TODO tablet event types
break;
}
pointerEventInstances << ev;
@@ -2427,7 +2453,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());
@@ -2462,6 +2496,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);
@@ -2551,7 +2590,7 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event)
QQuickEventPoint *point = event->point(i);
if (point->state() == QQuickEventPoint::Released) {
int id = point->pointId();
- qCDebug(DBG_TOUCH_TARGET) << "TP" << hex << id << "released";
+ qCDebug(DBG_TOUCH_TARGET) << "TP" << Qt::hex << id << "released";
point->setGrabberItem(nullptr);
if (id == touchMouseId)
cancelTouchMouseSynthesis();
@@ -2648,7 +2687,7 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event,
if (point->grabberPointerHandler())
cancelTouchMouseSynthesis();
} else {
- qCWarning(DBG_TOUCH_TARGET) << "during delivery of touch press, synth-mouse ID" << hex << touchMouseId << "is missing from" << event;
+ qCWarning(DBG_TOUCH_TARGET) << "during delivery of touch press, synth-mouse ID" << Qt::hex << touchMouseId << "is missing from" << event;
}
}
for (int i = 0; i < pointCount; ++i) {
@@ -2790,7 +2829,7 @@ void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo
if (point.state() == Qt::TouchPointPressed) {
if (auto *tp = ptEvent->pointById(point.id())) {
if (tp->exclusiveGrabber() == item) {
- qCDebug(DBG_TOUCH_TARGET) << "TP" << hex << point.id() << "disassociated";
+ qCDebug(DBG_TOUCH_TARGET) << "TP" << Qt::hex << point.id() << "disassociated";
tp->setGrabberItem(nullptr);
}
}
@@ -2966,26 +3005,27 @@ void QQuickWindowPrivate::updateCursor(const QPointF &scenePos)
{
Q_Q(QQuickWindow);
- QQuickItem *oldCursorItem = cursorItem;
- cursorItem = findCursorItem(contentItem, scenePos);
+ auto cursorItemAndHandler = findCursorItemAndHandler(contentItem, scenePos);
- if (cursorItem != oldCursorItem) {
+ if (cursorItem != cursorItemAndHandler.first || cursorHandler != cursorItemAndHandler.second) {
QWindow *renderWindow = QQuickRenderControl::renderWindowFor(q);
QWindow *window = renderWindow ? renderWindow : q;
+ cursorItem = cursorItemAndHandler.first;
+ cursorHandler = cursorItemAndHandler.second;
if (cursorItem)
- window->setCursor(cursorItem->cursor());
+ window->setCursor(QQuickItemPrivate::get(cursorItem)->effectiveCursor(cursorHandler));
else
window->unsetCursor();
}
}
-QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF &scenePos)
+QPair<QQuickItem*, QQuickPointerHandler*> QQuickWindowPrivate::findCursorItemAndHandler(QQuickItem *item, const QPointF &scenePos) const
{
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
QPointF p = item->mapFromScene(scenePos);
if (!item->contains(p))
- return nullptr;
+ return {nullptr, nullptr};
}
if (itemPrivate->subtreeCursorEnabled) {
@@ -2994,17 +3034,24 @@ QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF
QQuickItem *child = children.at(ii);
if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
continue;
- if (QQuickItem *cursorItem = findCursorItem(child, scenePos))
- return cursorItem;
+ auto ret = findCursorItemAndHandler(child, scenePos);
+ if (ret.first)
+ return ret;
+ }
+ if (itemPrivate->hasCursor || itemPrivate->hasCursorHandler) {
+ QPointF p = item->mapFromScene(scenePos);
+ if (!item->contains(p))
+ return {nullptr, nullptr};
+ if (itemPrivate->hasCursorHandler) {
+ if (auto handler = itemPrivate->effectiveCursorHandler())
+ return {item, handler};
+ }
+ if (itemPrivate->hasCursor)
+ return {item, nullptr};
}
}
- if (itemPrivate->hasCursor) {
- QPointF p = item->mapFromScene(scenePos);
- if (item->contains(p))
- return item;
- }
- return nullptr;
+ return {nullptr, nullptr};
}
#endif
@@ -3106,7 +3153,7 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
qCDebug(DBG_TOUCH) << "touch event intercepted as synth mouse event by childMouseEventFilter of " << filteringParent;
skipDelivery.append(filteringParent);
if (t != QEvent::MouseButtonRelease) {
- qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << tp.id() << "->" << filteringParent;
+ qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << Qt::hex << tp.id() << "->" << filteringParent;
pointerEventInstance(dev)->pointById(tp.id())->setGrabberItem(filteringParent);
touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set
if (mouseEvent->isAccepted())
@@ -3169,6 +3216,18 @@ bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent
return overThreshold;
}
+bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, const QTouchEvent::TouchPoint *tp, int startDragThreshold)
+{
+ QStyleHints *styleHints = qApp->styleHints();
+ bool overThreshold = qAbs(d) > (startDragThreshold >= 0 ? startDragThreshold : styleHints->startDragDistance());
+ const bool dragVelocityLimitAvailable = (styleHints->startDragVelocity() > 0);
+ if (!overThreshold && dragVelocityLimitAvailable) {
+ qreal velocity = axis == Qt::XAxis ? tp->velocity().x() : tp->velocity().y();
+ overThreshold |= qAbs(velocity) > styleHints->startDragVelocity();
+ }
+ return overThreshold;
+}
+
bool QQuickWindowPrivate::dragOverThreshold(QVector2D delta)
{
int threshold = qApp->styleHints()->startDragDistance();
@@ -3235,6 +3294,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);
@@ -3243,10 +3316,9 @@ bool QQuickWindowPrivate::isRenderable() const
void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &format,
QString *translatedMessage,
- QString *untranslatedMessage,
- bool isEs)
+ QString *untranslatedMessage)
{
- const QString contextType = QLatin1String(isEs ? "EGL" : "OpenGL");
+ const QString contextType = QLatin1String("OpenGL");
QString formatStr;
QDebug(&formatStr) << format;
#if defined(Q_OS_WIN32)
@@ -3271,6 +3343,16 @@ void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &fo
#endif // !Q_OS_WIN32
}
+void QQuickWindowPrivate::rhiCreationFailureMessage(const QString &backendName,
+ QString *translatedMessage,
+ QString *untranslatedMessage)
+{
+ const char msg[] = QT_TRANSLATE_NOOP("QQuickWindow",
+ "Failed to initialize graphics backend for %1.");
+ *translatedMessage = QQuickWindow::tr(msg).arg(backendName);
+ *untranslatedMessage = QString::fromLatin1(msg).arg(backendName);
+}
+
#if QT_DEPRECATED_SINCE(5, 8)
// ### Qt6: remove
@@ -3786,6 +3868,13 @@ bool QQuickWindow::isSceneGraphInitialized() const
This signal will be emitted from the scene graph rendering thread.
*/
+/*!
+ \qmlsignal QtQuick.Window::Window::frameSwapped()
+
+ This signal is emitted when a frame has been queued for presenting. With
+ vertical synchronization enabled the signal is emitted at most once per
+ vsync interval in a continuously animating scene.
+ */
/*!
\fn void QQuickWindow::sceneGraphInitialized()
@@ -3793,9 +3882,12 @@ bool QQuickWindow::isSceneGraphInitialized() const
This signal is emitted when the scene graph has been initialized.
This signal will be emitted from the scene graph rendering thread.
-
*/
+/*!
+ \qmlsignal QtQuick.Window::Window::sceneGraphInitialized()
+ \internal
+ */
/*!
\fn void QQuickWindow::sceneGraphInvalidated()
@@ -3815,6 +3907,11 @@ bool QQuickWindow::isSceneGraphInitialized() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::sceneGraphInvalidated()
+ \internal
+ */
+
+/*!
\fn void QQuickWindow::sceneGraphError(SceneGraphError error, const QString &message)
This signal is emitted when an \a error occurred during scene graph initialization.
@@ -3830,6 +3927,19 @@ bool QQuickWindow::isSceneGraphInitialized() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::sceneGraphError(SceneGraphError error, QString message)
+
+ This signal is emitted when an \a error occurred during scene graph initialization.
+
+ You can implement onSceneGraphError(error, message) to handle errors,
+ such as graphics context creation failures, in a custom way.
+ If no handler is connected to this signal, Quick will print the \a message,
+ or show a message box, and terminate the application.
+
+ \since 5.3
+ */
+
+/*!
\class QQuickCloseEvent
\internal
\since 5.1
@@ -3884,8 +3994,6 @@ bool QQuickWindow::isSceneGraphInitialized() const
property is true by default so that the window is allowed to close; but you
can implement an \c onClosing handler and set \c {close.accepted = false} if
you need to do something else before the window can be closed.
-
- The corresponding handler is \c onClosing.
*/
#if QT_CONFIG(opengl)
@@ -4176,6 +4284,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::beforeSynchronizing()
+ \internal
+*/
+
+/*!
\fn void QQuickWindow::afterSynchronizing()
This signal is emitted after the scene graph is synchronized with the QML state.
@@ -4199,6 +4312,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::afterSynchronizing()
+ \internal
+ \since 5.3
+ */
+
+/*!
\fn void QQuickWindow::beforeRendering()
This signal is emitted before the scene starts rendering.
@@ -4234,6 +4353,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::beforeRendering()
+ \internal
+*/
+
+/*!
\fn void QQuickWindow::afterRendering()
This signal is emitted after the scene has completed rendering, before swapbuffers is called.
@@ -4267,6 +4391,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::afterRendering()
+ \internal
+ */
+
+/*!
\fn void QQuickWindow::beforeRenderPassRecording()
This signal is emitted before the scenegraph starts recording commands for
@@ -4299,6 +4428,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::beforeRenderPassRecording()
+ \internal
+ \since 5.14
+*/
+
+/*!
\fn void QQuickWindow::afterRenderPassRecording()
This signal is emitted after the scenegraph has recorded the commands for
@@ -4330,6 +4465,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::afterRenderPassRecording()
+ \internal
+ \since 5.14
+*/
+
+/*!
\fn void QQuickWindow::afterAnimating()
This signal is emitted on the gui thread before requesting the render thread to
@@ -4344,6 +4485,17 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::afterAnimating()
+
+ This signal is emitted on the gui thread before requesting the render thread to
+ perform the synchronization of the scene graph.
+
+ You can implement onAfterAnimating to do additional processing after each animation step.
+
+ \since 5.3
+ */
+
+/*!
\fn void QQuickWindow::openglContextCreated(QOpenGLContext *context)
This signal is emitted on the gui thread when the OpenGL \a context
@@ -4355,7 +4507,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const
OpenGL context is actually created.
QQuickWindow::openglContext() will still return 0 for this window
- until after the QQuickWindow::sceneGraphInitialize() has been
+ until after the QQuickWindow::sceneGraphInitialized() has been
emitted.
\note
@@ -4366,6 +4518,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::openglContextCreated()
+ \internal
+ \since 5.3
+ */
+
+/*!
\fn void QQuickWindow::sceneGraphAboutToStop()
This signal is emitted on the render thread when the scene graph is
@@ -4388,6 +4546,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const
\since 5.3
*/
+/*!
+ \qmlsignal QtQuick.Window::Window::sceneGraphAboutToStop()
+ \internal
+ \since 5.3
+ */
/*!
Sets whether the scene graph rendering of QML should clear the color buffer
@@ -4433,7 +4596,7 @@ bool QQuickWindow::clearBeforeRendering() const
QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const
{
- return createTextureFromImage(image, nullptr);
+ return createTextureFromImage(image, {});
}
@@ -4491,7 +4654,7 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText
}
-
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
Creates a new QSGTexture object from an existing OpenGL texture \a id and \a size.
@@ -4513,6 +4676,8 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText
\note This function has no effect when running on the RHI graphics
abstraction. Use createTextureFromNativeObject() instead.
+ \obsolete
+
\sa sceneGraphInitialized(), QSGTexture
*/
QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, CreateTextureOptions options) const
@@ -4539,6 +4704,7 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create
#endif
return nullptr;
}
+#endif
/*!
\enum QQuickWindow::NativeObjectType
@@ -4592,7 +4758,7 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create
\a nativeLayout is only used for APIs like Vulkan. When applicable, it must
specify the current image layout, such as, a VkImageLayout value.
- \sa sceneGraphInitialized(), QSGTexture
+ \sa sceneGraphInitialized(), QSGTexture, QSGTexture::nativeTexture()
\since 5.14
*/
@@ -4723,9 +4889,13 @@ void QQuickWindow::setDefaultAlphaBuffer(bool useAlpha)
\note This function only has an effect when using the default OpenGL scene graph
adaptation.
+ \note This function will only reset the OpenGL context in relation to what has been changed
+ internally as part of the OpenGL scene graph. It does not reset anything that has been changed
+ externally such as direct OpenGL calls done inside the application code if those same calls are
+ not used internally.
+
\note This function has no effect when running on the RHI graphics
- abstraction. With the RHI, the functions to call when enqueuing native
- graphics commands are beginExternalCommands() and endExternalCommands().
+ abstraction and the underlying RHI backend is not OpenGL.
\sa QQuickWindow::beforeRendering(), beginExternalCommands(), endExternalCommands()
*/
@@ -4733,7 +4903,7 @@ void QQuickWindow::resetOpenGLState()
{
Q_D(QQuickWindow);
- if (d->rhi || !openglContext())
+ if (!openglContext())
return;
QOpenGLContext *ctx = openglContext();
@@ -4848,7 +5018,13 @@ const QQuickWindow::GraphicsStateInfo &QQuickWindow::graphicsStateInfo()
directly and the RHI graphics abstraction layer is not in use. Refer to
resetOpenGLState() in that case.
- \sa endExternalCommands()
+ \note When the scenegraph is using the RHI graphics abstraction layer with
+ the OpenGL backend underneath, pay attention to the fact that the OpenGL
+ state in the context can have arbitrary settings, and this function does not
+ perform any resetting of the state back to defaults. Call
+ resetOpenGLState() if that is seen necessary.
+
+ \sa endExternalCommands(), resetOpenGLState()
\since 5.14
*/
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index 56d50cec2a..097627374c 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -157,7 +157,12 @@ public:
// Scene graph specific functions
QSGTexture *createTextureFromImage(const QImage &image) const;
QSGTexture *createTextureFromImage(const QImage &image, CreateTextureOptions options) const;
+
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use createTextureFromNativeObject() instead")
QSGTexture *createTextureFromId(uint id, const QSize &size, CreateTextureOptions options = CreateTextureOption()) const;
+#endif
+
QSGTexture *createTextureFromNativeObject(NativeObjectType type,
const void *nativeObjectPtr,
int nativeLayout,
@@ -247,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 165859b5f3..e1ee7daf1c 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -88,7 +88,7 @@ class QRhiRenderBuffer;
class QRhiRenderPassDescriptor;
//Make it easy to identify and customize the root item if needed
-class QQuickRootItem : public QQuickItem
+class Q_QUICK_PRIVATE_EXPORT QQuickRootItem : public QQuickItem
{
Q_OBJECT
public:
@@ -112,7 +112,8 @@ public:
Q_DECLARE_PUBLIC(QQuickWindow)
enum CustomEvents {
- FullUpdateRequest = QEvent::User + 1
+ FullUpdateRequest = QEvent::User + 1,
+ TriggerContextCreationFailure = QEvent::User + 2
};
static inline QQuickWindowPrivate *get(QQuickWindow *c) { return c->d_func(); }
@@ -133,6 +134,7 @@ public:
// Keeps track of the item currently receiving mouse events
#if QT_CONFIG(cursor)
QQuickItem *cursorItem;
+ QQuickPointerHandler *cursorHandler;
#endif
#if QT_CONFIG(quick_draganddrop)
QQuickDragGrabber *dragGrabber;
@@ -196,7 +198,7 @@ public:
#endif
#if QT_CONFIG(cursor)
void updateCursor(const QPointF &scenePos);
- QQuickItem *findCursorItem(QQuickItem *item, const QPointF &scenePos);
+ QPair<QQuickItem*, QQuickPointerHandler*> findCursorItemAndHandler(QQuickItem *item, const QPointF &scenePos) const;
#endif
QList<QQuickItem*> hoverItems;
@@ -206,8 +208,8 @@ public:
};
Q_DECLARE_FLAGS(FocusOptions, FocusOption)
- void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = nullptr);
- void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = nullptr);
+ void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = { });
+ void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = { });
static void notifyFocusChangesRecur(QQuickItem **item, int remaining);
void clearFocusObject() override;
@@ -288,25 +290,7 @@ public:
static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold = -1);
- template <typename TEventPoint>
- static bool dragOverThreshold(qreal d, Qt::Axis axis, const TEventPoint *p, int startDragThreshold = -1)
- {
- QStyleHints *styleHints = qApp->styleHints();
- bool overThreshold = qAbs(d) > (startDragThreshold >= 0 ? startDragThreshold : styleHints->startDragDistance());
- const bool dragVelocityLimitAvailable = (styleHints->startDragVelocity() > 0);
- if (!overThreshold && dragVelocityLimitAvailable) {
- qreal velocity = axis == Qt::XAxis ? p->velocity().x() : p->velocity().y();
- overThreshold |= qAbs(velocity) > styleHints->startDragVelocity();
- }
- return overThreshold;
- }
-
- static bool dragOverThreshold(const QQuickEventPoint *point)
- {
- QPointF delta = point->scenePosition() - point->scenePressPosition();
- return (QQuickWindowPrivate::dragOverThreshold(delta.x(), Qt::XAxis, point) ||
- QQuickWindowPrivate::dragOverThreshold(delta.y(), Qt::YAxis, point));
- }
+ static bool dragOverThreshold(qreal d, Qt::Axis axis, const QTouchEvent::TouchPoint *tp, int startDragThreshold = -1);
static bool dragOverThreshold(QVector2D delta);
@@ -315,11 +299,15 @@ 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,
- QString *untranslatedMessage,
- bool isEs);
+ QString *untranslatedMessage);
+ static void rhiCreationFailureMessage(const QString &backendName,
+ QString *translatedMessage,
+ QString *untranslatedMessage);
static void emitBeforeRenderPassRecording(void *ud);
static void emitAfterRenderPassRecording(void *ud);
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index 4b2b8f498d..ee90af4341 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -48,6 +48,7 @@
#include <private/qguiapplication_p.h>
#include <private/qqmlengine_p.h>
#include <private/qv4qobjectwrapper_p.h>
+#include <private/qqmlglobal_p.h>
#include <qpa/qplatformintegration.h>
QT_BEGIN_NAMESPACE
@@ -195,28 +196,6 @@ void QQuickWindowQmlImpl::setScreen(QObject *screen)
QWindow::setScreen(screenWrapper ? screenWrapper->wrappedScreen() : nullptr);
}
-void QQuickWindowModule::defineModule()
-{
- const char uri[] = "QtQuick.Window";
-
- qmlRegisterType<QQuickWindow>(uri, 2, 0, "Window");
- qmlRegisterRevision<QWindow,1>(uri, 2, 1);
- qmlRegisterRevision<QWindow,2>(uri, 2, 2);
- qmlRegisterRevision<QQuickWindow,1>(uri, 2, 1);//Type moved to a subclass, but also has new members
- qmlRegisterRevision<QQuickWindow,2>(uri, 2, 2);
- qmlRegisterType<QQuickWindowQmlImpl>(uri, 2, 1, "Window");
- qmlRegisterType<QQuickWindowQmlImpl,2>(uri, 2, 2, "Window");
- qmlRegisterType<QQuickWindowQmlImpl,3>(uri, 2, 3, "Window");
- qmlRegisterUncreatableType<QQuickScreen>(uri, 2, 0, "Screen", QStringLiteral("Screen can only be used via the attached property."));
- qmlRegisterUncreatableType<QQuickScreen,3>(uri, 2, 3, "Screen", QStringLiteral("Screen can only be used via the attached property."));
- qmlRegisterUncreatableType<QQuickScreenInfo,3>(uri, 2, 3, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
- qmlRegisterUncreatableType<QQuickScreenInfo,10>(uri, 2, 10, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
- qmlRegisterRevision<QWindow,13>(uri, 2, 13);
- qmlRegisterRevision<QQuickWindow,13>(uri, 2, 13);
- qmlRegisterType<QQuickWindowQmlImpl,13>(uri, 2, 13, "Window");
- qmlRegisterRevision<QQuickWindow,14>(uri, 2, 14);
-}
-
QT_END_NAMESPACE
#include "moc_qquickwindowmodule_p.cpp"
diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h
index 1dcf1a1021..d0bf5c29b3 100644
--- a/src/quick/items/qquickwindowmodule_p.h
+++ b/src/quick/items/qquickwindowmodule_p.h
@@ -68,6 +68,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public Q
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged)
Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION 3)
+ QML_ATTACHED(QQuickWindowAttached)
public:
QQuickWindowQmlImpl(QWindow *parent = nullptr);
@@ -97,15 +98,8 @@ private:
Q_DECLARE_PRIVATE(QQuickWindowQmlImpl)
};
-class Q_QUICK_PRIVATE_EXPORT QQuickWindowModule
-{
-public:
- static void defineModule();
-};
-
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickWindowQmlImpl)
-QML_DECLARE_TYPEINFO(QQuickWindowQmlImpl, QML_HAS_ATTACHED_PROPERTIES)
#endif
diff --git a/src/quick/qtquick.tracepoints b/src/quick/qtquick.tracepoints
new file mode 100644
index 0000000000..f6518444d2
--- /dev/null
+++ b/src/quick/qtquick.tracepoints
@@ -0,0 +1,48 @@
+QSG_renderWindow_entry()
+QSG_renderWindow_exit()
+QSG_renderScene_entry()
+QSG_renderScene_exit()
+QSG_syncAndRender_entry()
+QSG_syncAndRender_exit()
+QSG_polishAndSync_entry()
+QSG_polishAndSync_exit()
+QSG_preprocess_entry()
+QSG_preprocess_exit()
+QSG_update_entry()
+QSG_update_exit()
+
+QSG_polishItems_entry()
+QSG_polishItems_exit()
+QSG_sync_entry()
+QSG_sync_exit()
+QSG_wait_entry()
+QSG_wait_exit()
+QSG_render_entry()
+QSG_render_exit()
+QSG_swap_entry()
+QSG_swap_exit()
+QSG_animations_entry()
+QSG_animations_exit()
+
+QSG_texture_prepare_entry()
+QSG_texture_prepare_exit()
+QSG_texture_bind_entry()
+QSG_texture_bind_exit()
+QSG_texture_delete_entry()
+QSG_texture_delete_exit()
+QSG_texture_upload_entry()
+QSG_texture_upload_exit()
+QSG_texture_mipmap_entry()
+QSG_texture_mipmap_exit()
+
+QSG_binding_entry()
+QSG_binding_exit()
+QSG_prepareMaterial_entry()
+QSG_prepareMaterial_exit()
+
+QSGDistanceFieldGlyphCache_update_entry(int count)
+QSGDistanceFieldGlyphCache_update_exit()
+QSGDistanceFieldGlyphCache_glyphRender_entry()
+QSGDistanceFieldGlyphCache_glyphRender_exit()
+QSGDistanceFieldGlyphCache_glyphStore_entry()
+QSGDistanceFieldGlyphCache_glyphStore_exit()
diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp
index 7a04c2146c..4ba7e896db 100644
--- a/src/quick/qtquick2.cpp
+++ b/src/quick/qtquick2.cpp
@@ -39,7 +39,6 @@
#include "qtquick2_p.h"
#include <private/qqmlengine_p.h>
-#include <private/qquickutilmodule_p.h>
#include <private/qquickvaluetypes_p.h>
#include <private/qquickitemsmodule_p.h>
#include <private/qquickaccessiblefactory_p.h>
@@ -55,6 +54,10 @@
#include <qqmlproperty.h>
#include <QtCore/QPointer>
+#if QT_CONFIG(shortcut)
+Q_DECLARE_METATYPE(QKeySequence::StandardKey)
+#endif
+
QT_BEGIN_NAMESPACE
#if !QT_CONFIG(qml_debug)
@@ -182,12 +185,12 @@ void QQmlQtQuick2Module::defineModule()
{
QQuick_initializeProviders();
- QQuickUtilModule::defineModule();
- QQuickItemsModule::defineModule();
-
- qmlRegisterUncreatableType<QQuickApplication>("QtQuick",2,0,"Application", QQuickApplication::tr("Application is an abstract class"));
+#if QT_CONFIG(shortcut)
+ qRegisterMetaType<QKeySequence::StandardKey>();
+#endif
QQuickValueTypes::registerValueTypes();
+ QQuickItemsModule::defineModule();
#if QT_CONFIG(accessibility)
QAccessible::installFactory(&qQuickAccessibleFactory);
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 cd8ee35135..f2d49cf939 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -4,6 +4,9 @@ QT = core-private gui-private qml-private qmlmodels-private
qtConfig(qml-network): \
QT_PRIVATE += network
+TRACEPOINT_PROVIDER = $$PWD/qtquick.tracepoints
+CONFIG += qt_tracepoints
+
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES
msvc:DEFINES *= _CRT_SECURE_NO_WARNINGS
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
@@ -44,3 +47,9 @@ SOURCES += qtquick2.cpp
INCLUDEPATH += $$PWD
load(qt_module)
+
+QMLTYPES_FILENAME = plugins.qmltypes
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick.2
+QML_IMPORT_NAME = QtQuick
+IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+CONFIG += qmltypes install_qmltypes install_metatypes
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index 7b5ee66df6..f1d0e28fc8 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -206,12 +206,12 @@ QSGRendererInterface::ShaderType QSGSoftwareContext::shaderType() const
QSGRendererInterface::ShaderCompilationTypes QSGSoftwareContext::shaderCompilationType() const
{
- return nullptr;
+ return {};
}
QSGRendererInterface::ShaderSourceTypes QSGSoftwareContext::shaderSourceType() const
{
- return nullptr;
+ return {};
}
void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp
index dd789b78c7..04e9b361ca 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qsgsoftwareglyphnode_p.h"
+#include <QtGui/private/qrawfont_p.h>
QT_BEGIN_NAMESPACE
@@ -52,28 +53,38 @@ QSGSoftwareGlyphNode::QSGSoftwareGlyphNode()
namespace {
QRectF calculateBoundingRect(const QPointF &position, const QGlyphRun &glyphs)
{
- qreal minX = 0;
- qreal minY = 0;
- qreal maxX = 0;
- qreal maxY = 0;
+ QFixed minX;
+ QFixed minY;
+ QFixed maxX;
+ QFixed maxY;
- for (int i = 0, n = qMin(glyphs.glyphIndexes().size(), glyphs.positions().size()); i < n; ++i) {
- QRectF glyphRect = glyphs.rawFont().boundingRect(glyphs.glyphIndexes()[i]);
- glyphRect.translate(glyphs.positions()[i]);
+ QRawFontPrivate *rawFontD = QRawFontPrivate::get(glyphs.rawFont());
+ QFontEngine *fontEngine = rawFontD->fontEngine;
+
+ QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None ? fontEngine->glyphFormat : QFontEngine::Format_A32;
+
+ const QVector<uint> glyphIndexes = glyphs.glyphIndexes();
+ const QVector<QPointF> glyphPositions = glyphs.positions();
+ for (int i = 0, n = qMin(glyphIndexes.size(), glyphPositions.size()); i < n; ++i) {
+ glyph_metrics_t gm = fontEngine->alphaMapBoundingBox(glyphIndexes.at(i), QFixed(), QTransform(), glyphFormat);
+
+ gm.x += QFixed::fromReal(glyphPositions.at(i).x());
+ gm.y += QFixed::fromReal(glyphPositions.at(i).y());
if (i == 0) {
- minX = glyphRect.left();
- minY = glyphRect.top();
- maxX = glyphRect.right();
- maxY = glyphRect.bottom();
+ minX = gm.x;
+ minY = gm.y;
+ maxX = gm.x + gm.width;
+ maxY = gm.y + gm.height;
} else {
- minX = qMin(glyphRect.left(), minX);
- minY = qMin(glyphRect.top(), minY);
- maxX = qMax(glyphRect.right(),maxX);
- maxY = qMax(glyphRect.bottom(), maxY);
+ minX = qMin(gm.x, minX);
+ minY = qMin(gm.y, minY);
+ maxX = qMax(gm.x + gm.width, maxX);
+ maxY = qMax(gm.y + gm.height, maxY);
}
}
- QRectF boundingRect(QPointF(minX, minY), QPointF(maxX, maxY));
+
+ QRectF boundingRect(QPointF(minX.toReal(), minY.toReal()), QPointF(maxX.toReal(), maxY.toReal()));
return boundingRect.translated(position - QPointF(0.0, glyphs.rawFont().ascent()));
}
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
index da5d39db20..214f7d790b 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
@@ -465,7 +465,7 @@ void QSGSoftwareInternalImageNode::paint(QPainter *painter)
m_targetRect.right() - m_innerTargetRect.right(), m_targetRect.bottom() - m_innerTargetRect.bottom());
QSGSoftwareHelpers::QTileRules tilerules(getTileRule(m_subSourceRect.width()), getTileRule(m_subSourceRect.height()));
QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_targetRect.toRect(), margins, pm, QRect(0, 0, pm.width(), pm.height()),
- margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr));
+ margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{});
return;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
index 141d8f3c6d..a10a94125c 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
@@ -205,7 +205,7 @@ void QSGSoftwareNinePatchNode::paint(QPainter *painter)
painter->drawPixmap(m_bounds, m_pixmap, QRectF(0, 0, m_pixmap.width(), m_pixmap.height()));
else
QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_bounds.toRect(), m_margins, m_pixmap, QRect(0, 0, m_pixmap.width(), m_pixmap.height()),
- m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr));
+ m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{});
}
QRectF QSGSoftwareNinePatchNode::bounds() const
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
index c97dcb9326..c010e0cae5 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
@@ -52,6 +52,8 @@
#include <QtGui/QBackingStore>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
QSGSoftwareRenderLoop::QSGSoftwareRenderLoop()
@@ -133,20 +135,25 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
if (!m_windows.contains(window))
return;
}
+
+ Q_TRACE_SCOPE(QSG_renderWindow)
QElapsedTimer renderTimer;
qint64 renderTime = 0, syncTime = 0, polishTime = 0;
bool profileFrames = QSG_RASTER_LOG_TIME_RENDERLOOP().isDebugEnabled();
if (profileFrames)
renderTimer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
+ Q_TRACE(QSG_polishItems_entry);
cd->polishItems();
if (profileFrames)
polishTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -155,8 +162,10 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
//Tell the renderer about the windows backing store
auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(cd->renderer);
@@ -167,8 +176,10 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (data.grabOnly) {
grabContent = m_backingStores[window]->handle()->toImage();
@@ -187,6 +198,7 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
qint64 swapTime = 0;
if (profileFrames)
swapTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index c6b463bb02..f07cc28827 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -60,6 +60,8 @@
#include <QtGui/QBackingStore>
#include <QtQuick/QQuickWindow>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
// Passed from the RL to the RT when a window is removed obscured and should be
@@ -457,6 +459,8 @@ void QSGSoftwareRenderThread::sync(bool inExpose)
void QSGSoftwareRenderThread::syncAndRender()
{
+ Q_TRACE_SCOPE(QSG_syncAndRender);
+ Q_TRACE(QSG_sync_entry);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
QElapsedTimer waitTimer;
@@ -475,6 +479,7 @@ void QSGSoftwareRenderThread::syncAndRender()
if (syncRequested)
sync(exposeRequested);
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
@@ -487,6 +492,7 @@ void QSGSoftwareRenderThread::syncAndRender()
}
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - rendering started");
+ Q_TRACE(QSG_render_entry);
if (rtAnim->isRunning()) {
wd->animationController->lock();
@@ -502,8 +508,10 @@ void QSGSoftwareRenderThread::syncAndRender()
softwareRenderer->setBackingStore(backingStore);
wd->renderSceneGraph(exposedWindow->size());
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (softwareRenderer && (!wd->customRenderStage || !wd->customRenderStage->swap()))
backingStore->flush(softwareRenderer->flushRegion());
@@ -519,8 +527,10 @@ void QSGSoftwareRenderThread::syncAndRender()
wd->fireFrameSwapped();
} else {
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync, 1);
+ Q_TRACE(QSG_swap_entry);
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - window not ready, skipping render");
}
@@ -532,6 +542,7 @@ void QSGSoftwareRenderThread::syncAndRender()
mutex.unlock();
}
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
}
@@ -947,13 +958,18 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop:
return;
}
+ Q_TRACE_SCOPE(QSG_polishAndSync);
+
+ Q_TRACE(QSG_polishItems_entry);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
wd->polishItems();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncPolish);
+ Q_TRACE(QSG_sync_entry);
w->updateDuringSync = false;
@@ -967,15 +983,19 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop:
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - wait for sync");
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncWait);
+ Q_TRACE(QSG_wait_entry);
w->thread->waitCondition.wait(&w->thread->mutex);
lockedForSync = false;
w->thread->mutex.unlock();
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - unlock after sync");
+ Q_TRACE(QSG_wait_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncSync);
+ Q_TRACE(QSG_animations_entry);
if (!animationTimer && m_anim->isRunning()) {
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - advancing animations");
@@ -987,6 +1007,7 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop:
w->window->requestUpdate();
}
+ Q_TRACE(QSG_animations_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncAnimations);
}
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
index 1a8bddaa6e..65abb2a1af 100644
--- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
@@ -296,7 +296,7 @@ void QSGCompressedTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdate
return;
}
- QRhiTexture::Flags texFlags = 0;
+ QRhiTexture::Flags texFlags;
if (fmt.second)
texFlags |= QRhiTexture::sRGB;
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
index 1594352dab..258a5fed14 100644
--- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
+++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
@@ -72,6 +72,10 @@ public:
~QSGAbstractRenderer() override;
+ // just have a warning about becoming private, ifdefing the whole class is not feasible
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("QSGAbstractRenderer is no longer going to be public in Qt 6.0. QSGEngine-based workflows are expected to migrate to QQuickRenderControl instead.")
+#endif
void setRootNode(QSGRootNode *node);
QSGRootNode *rootNode() const;
void setDeviceRect(const QRect &rect);
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 34027cbac7..ce3c4aac4f 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -62,6 +62,8 @@
#include "qsgopenglvisualizer_p.h"
#include "qsgrhivisualizer_p.h"
+#include <qtquick_tracepoints_p.h>
+
#include <algorithm>
#ifndef GL_DOUBLE
@@ -270,6 +272,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material, boo
return nullptr;
}
+ Q_TRACE_SCOPE(QSG_prepareMaterial);
if (QSG_LOG_TIME_COMPILATION().isDebugEnabled())
qsg_renderer_timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
@@ -332,6 +335,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
return nullptr;
}
+ Q_TRACE_SCOPE(QSG_prepareMaterial);
if (QSG_LOG_TIME_COMPILATION().isDebugEnabled())
qsg_renderer_timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
@@ -379,6 +383,9 @@ void ShaderManager::invalidated()
qDeleteAll(srbCache);
srbCache.clear();
+
+ qDeleteAll(pipelineCache);
+ pipelineCache.clear();
}
void ShaderManager::clearCachedRendererData()
@@ -447,13 +454,13 @@ void qsg_dumpShadowRoots(Node *n)
QByteArray ind(indent, ' ');
if (n->type() == QSGNode::ClipNodeType || n->isBatchRoot) {
- qDebug() << ind.constData() << "[X]" << n->sgNode << hex << uint(n->sgNode->flags());
+ qDebug() << ind.constData() << "[X]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
qsg_dumpShadowRoots(n->rootInfo(), indent);
} else {
QDebug d = qDebug();
- d << ind.constData() << "[ ]" << n->sgNode << hex << uint(n->sgNode->flags());
+ d << ind.constData() << "[ ]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
if (n->type() == QSGNode::GeometryNodeType)
- d << "order" << dec << n->element()->order;
+ d << "order" << Qt::dec << n->element()->order;
}
SHADOWNODE_TRAVERSE(n)
@@ -546,7 +553,7 @@ void Updater::visitNode(Node *n)
m_added = count;
m_force_update = force;
- n->dirtyState = nullptr;
+ n->dirtyState = {};
}
void Updater::visitClipNode(Node *n)
@@ -1024,6 +1031,7 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx)
? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream")));
}
+ static const bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
if (!m_rhi) {
// If rendering with an OpenGL Core profile context, we need to create a VAO
// to hold our vertex specification state.
@@ -1031,9 +1039,9 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx)
m_vao = new QOpenGLVertexArrayObject(this);
m_vao->create();
}
-
- bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
m_useDepthBuffer = useDepth && ctx->openglContext()->format().depthBufferSize() > 0;
+ } else {
+ m_useDepthBuffer = useDepth;
}
}
@@ -1103,13 +1111,9 @@ void Renderer::destroyGraphicsResources()
// are going to destroy.
m_shaderManager->clearCachedRendererData();
- qDeleteAll(m_pipelines);
qDeleteAll(m_samplers);
-
m_stencilClipCommon.reset();
-
delete m_dummyTexture;
-
m_visualizer->releaseResources();
}
@@ -1119,7 +1123,6 @@ void Renderer::releaseCachedResources()
destroyGraphicsResources();
- m_pipelines.clear();
m_samplers.clear();
m_dummyTexture = nullptr;
@@ -1399,12 +1402,11 @@ void Renderer::nodeWasRemoved(Node *node)
m_elementsToDelete.add(e);
if (m_renderNodeElements.isEmpty()) {
- if (m_rhi) {
- m_useDepthBuffer = true;
- } else {
- static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
+ static const bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
+ if (m_rhi)
+ m_useDepthBuffer = useDepth;
+ else
m_useDepthBuffer = useDepth && m_context->openglContext()->format().depthBufferSize() > 0;
- }
}
}
}
@@ -2339,7 +2341,7 @@ void Renderer::uploadBatch(Batch *b)
iDump << " -- Index Data, count:" << b->indexCount;
for (int i=0; i<b->indexCount; ++i) {
if ((i % 24) == 0)
- iDump << endl << " --- ";
+ iDump << Qt::endl << " --- ";
iDump << id[i];
}
}
@@ -2352,7 +2354,7 @@ void Renderer::uploadBatch(Batch *b)
iDump << " -- Index Data, count:" << b->indexCount;
for (int i=0; i<b->indexCount; ++i) {
if ((i % 24) == 0)
- iDump << endl << " --- ";
+ iDump << Qt::endl << " --- ";
iDump << id[i];
}
}
@@ -2627,7 +2629,7 @@ QRhiGraphicsPipeline *Renderer::buildStencilPipeline(const Batch *batch, bool fi
QRhiGraphicsPipeline *ps = m_rhi->newGraphicsPipeline();
ps->setFlags(QRhiGraphicsPipeline::UsesStencilRef);
QRhiGraphicsPipeline::TargetBlend blend;
- blend.colorWrite = 0;
+ blend.colorWrite = {};
ps->setTargetBlends({ blend });
ps->setSampleCount(renderTarget()->sampleCount());
ps->setStencilTest(true);
@@ -3237,15 +3239,17 @@ static inline bool needsBlendConstant(QRhiGraphicsPipeline::BlendFactor f)
bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms) // RHI only, [prepare step]
{
- // In unmerged batches the srbs in the elements are all compatible layout-wise.
+ // In unmerged batches the srbs in the elements are all compatible
+ // layout-wise. Note the key's == and qHash implementations: the rp desc and
+ // srb are tested for (layout) compatibility, not pointer equality.
const GraphicsPipelineStateKey k { m_gstate, sms, renderPassDescriptor(), e->srb };
// Note: dynamic state (viewport rect, scissor rect, stencil ref, blend
// constant) is never a part of GraphicsState/QRhiGraphicsPipeline.
// See if there is an existing, matching pipeline state object.
- auto it = m_pipelines.constFind(k);
- if (it != m_pipelines.constEnd()) {
+ auto it = m_shaderManager->pipelineCache.constFind(k);
+ if (it != m_shaderManager->pipelineCache.constEnd()) {
e->ps = *it;
return true;
}
@@ -3257,7 +3261,7 @@ bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms)
ps->setShaderResourceBindings(e->srb);
ps->setRenderPassDescriptor(renderPassDescriptor());
- QRhiGraphicsPipeline::Flags flags = 0;
+ QRhiGraphicsPipeline::Flags flags;
if (needsBlendConstant(m_gstate.srcColor) || needsBlendConstant(m_gstate.dstColor))
flags |= QRhiGraphicsPipeline::UsesBlendConstants;
if (m_gstate.usesScissor)
@@ -3302,7 +3306,7 @@ bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms)
return false;
}
- m_pipelines.insert(k, ps);
+ m_shaderManager->pipelineCache.insert(k, ps);
e->ps = ps;
return true;
}
@@ -3713,7 +3717,7 @@ void Renderer::renderMergedBatch(PreparedRenderBatch *renderBatch) // split prep
{ batch->vbo.buf, quint32(draw.vertices) },
{ batch->vbo.buf, quint32(draw.zorders) }
};
- cb->setVertexInput(VERTEX_BUFFER_BINDING, 2, vbufBindings,
+ cb->setVertexInput(VERTEX_BUFFER_BINDING, m_useDepthBuffer ? 2 : 1, vbufBindings,
batch->ibo.buf, draw.indices,
m_uint32IndexForRhi ? QRhiCommandBuffer::IndexUInt32 : QRhiCommandBuffer::IndexUInt16);
cb->drawIndexed(draw.indexCount);
@@ -3957,8 +3961,8 @@ void Renderer::setGraphicsPipeline(QRhiCommandBuffer *cb, const Batch *batch, El
void Renderer::renderBatches()
{
if (Q_UNLIKELY(debug_render())) {
- qDebug().nospace() << "Rendering:" << endl
- << " -> Opaque: " << qsg_countNodesInBatches(m_opaqueBatches) << " nodes in " << m_opaqueBatches.size() << " batches..." << endl
+ qDebug().nospace() << "Rendering:" << Qt::endl
+ << " -> Opaque: " << qsg_countNodesInBatches(m_opaqueBatches) << " nodes in " << m_opaqueBatches.size() << " batches..." << Qt::endl
<< " -> Alpha: " << qsg_countNodesInBatches(m_alphaBatches) << " nodes in " << m_alphaBatches.size() << " batches...";
}
@@ -4049,8 +4053,8 @@ void Renderer::renderBatches()
m_pstate.viewportSet = false;
m_pstate.scissorSet = false;
- m_gstate.depthTest = true;
- m_gstate.depthWrite = true;
+ m_gstate.depthTest = m_useDepthBuffer;
+ m_gstate.depthWrite = m_useDepthBuffer;
m_gstate.depthFunc = QRhiGraphicsPipeline::Less;
m_gstate.blending = false;
@@ -4082,8 +4086,8 @@ void Renderer::renderBatches()
m_gstate.blending = true;
// factors never change, always set for premultiplied alpha based blending
- // depth test stays enabled but no need to write out depth from the
- // transparent (back-to-front) pass
+ // depth test stays enabled (if m_useDepthBuffer, that is) but no need
+ // to write out depth from the transparent (back-to-front) pass
m_gstate.depthWrite = false;
QVarLengthArray<PreparedRenderBatch, 64> alphaRenderBatches;
@@ -4504,6 +4508,35 @@ bool Renderer::prepareRhiRenderNode(Batch *batch, PreparedRenderBatch *renderBat
updateClipState(rd->m_clip_list, batch);
+ QSGNode *xform = e->renderNode->parent();
+ QMatrix4x4 matrix;
+ QSGNode *root = rootNode();
+ if (e->root) {
+ matrix = qsg_matrixForRoot(e->root);
+ root = e->root->sgNode;
+ }
+ while (xform != root) {
+ if (xform->type() == QSGNode::TransformNodeType) {
+ matrix = matrix * static_cast<QSGTransformNode *>(xform)->combinedMatrix();
+ break;
+ }
+ xform = xform->parent();
+ }
+ rd->m_matrix = &matrix;
+
+ QSGNode *opacity = e->renderNode->parent();
+ rd->m_opacity = 1.0;
+ while (opacity != rootNode()) {
+ if (opacity->type() == QSGNode::OpacityNodeType) {
+ rd->m_opacity = static_cast<QSGOpacityNode *>(opacity)->combinedOpacity();
+ break;
+ }
+ opacity = opacity->parent();
+ }
+
+ if (rd->m_prepareCallback)
+ rd->m_prepareCallback();
+
renderBatch->batch = batch;
renderBatch->sms = nullptr;
@@ -4532,38 +4565,15 @@ void Renderer::renderRhiRenderNode(const Batch *batch) // split prepare-render (
state.m_scissorEnabled = batch->clipState.type & ClipState::ScissorClip;
state.m_stencilEnabled = batch->clipState.type & ClipState::StencilClip;
- QSGNode *xform = e->renderNode->parent();
- QMatrix4x4 matrix;
- QSGNode *root = rootNode();
- if (e->root) {
- matrix = qsg_matrixForRoot(e->root);
- root = e->root->sgNode;
- }
- while (xform != root) {
- if (xform->type() == QSGNode::TransformNodeType) {
- matrix = matrix * static_cast<QSGTransformNode *>(xform)->combinedMatrix();
- break;
- }
- xform = xform->parent();
- }
- rd->m_matrix = &matrix;
-
- QSGNode *opacity = e->renderNode->parent();
- rd->m_opacity = 1.0;
- while (opacity != rootNode()) {
- if (opacity->type() == QSGNode::OpacityNodeType) {
- rd->m_opacity = static_cast<QSGOpacityNode *>(opacity)->combinedOpacity();
- break;
- }
- opacity = opacity->parent();
- }
-
const QSGRenderNode::StateFlags changes = e->renderNode->changedStates();
QRhiCommandBuffer *cb = commandBuffer();
- cb->beginExternal();
+ const bool needsExternal = rd->m_needsExternalRendering;
+ if (needsExternal)
+ cb->beginExternal();
e->renderNode->render(&state);
- cb->endExternal();
+ if (needsExternal)
+ cb->endExternal();
rd->m_matrix = nullptr;
rd->m_clip_list = nullptr;
@@ -4643,7 +4653,7 @@ bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe
{
return a.state == b.state
&& a.sms->programRhi.program == b.sms->programRhi.program
- && a.rpDesc == b.rpDesc
+ && a.compatibleRenderPassDescriptor->isCompatible(b.compatibleRenderPassDescriptor)
&& a.layoutCompatibleSrb->isLayoutCompatible(b.layoutCompatibleSrb);
}
@@ -4654,7 +4664,8 @@ bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe
uint qHash(const GraphicsPipelineStateKey &k, uint seed) Q_DECL_NOTHROW
{
- return qHash(k.state, seed) + qHash(k.sms->programRhi.program, seed) + qHash(k.rpDesc, seed);
+ // no srb and rp included due to their special comparison semantics and lack of hash keys
+ return qHash(k.state, seed) + qHash(k.sms->programRhi.program, seed);
}
Visualizer::Visualizer(Renderer *renderer)
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 297df2232a..878b63fc8c 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -626,27 +626,65 @@ private:
QMatrix4x4 m_identityMatrix;
};
+struct GraphicsState
+{
+ bool depthTest = false;
+ bool depthWrite = false;
+ QRhiGraphicsPipeline::CompareOp depthFunc = QRhiGraphicsPipeline::Less;
+ bool blending = false;
+ QRhiGraphicsPipeline::BlendFactor srcColor = QRhiGraphicsPipeline::One;
+ QRhiGraphicsPipeline::BlendFactor dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
+ QRhiGraphicsPipeline::ColorMask colorWrite = QRhiGraphicsPipeline::ColorMask(0xF);
+ QRhiGraphicsPipeline::CullMode cullMode = QRhiGraphicsPipeline::None;
+ bool usesScissor = false;
+ bool stencilTest = false;
+ int sampleCount = 1;
+ QSGGeometry::DrawingMode drawMode = QSGGeometry::DrawTriangles;
+ float lineWidth = 1.0f;
+};
+
+bool operator==(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
+bool operator!=(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
+uint qHash(const GraphicsState &s, uint seed = 0) Q_DECL_NOTHROW;
+
+struct ShaderManagerShader;
+
+struct GraphicsPipelineStateKey
+{
+ GraphicsState state;
+ const ShaderManagerShader *sms;
+ const QRhiRenderPassDescriptor *compatibleRenderPassDescriptor;
+ const QRhiShaderResourceBindings *layoutCompatibleSrb;
+};
+
+bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
+bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
+uint qHash(const GraphicsPipelineStateKey &k, uint seed = 0) Q_DECL_NOTHROW;
+
+struct ShaderManagerShader
+{
+ ~ShaderManagerShader() {
+ delete programRhi.program;
+ delete programGL.program;
+ }
+ struct {
+ QSGMaterialShader *program = nullptr;
+ int pos_order;
+ } programGL;
+ struct {
+ QSGMaterialRhiShader *program = nullptr;
+ QRhiVertexInputLayout inputLayout;
+ QVarLengthArray<QRhiGraphicsShaderStage, 2> shaderStages;
+ } programRhi;
+
+ float lastOpacity;
+};
+
class ShaderManager : public QObject
{
Q_OBJECT
public:
- struct Shader {
- ~Shader() {
- delete programRhi.program;
- delete programGL.program;
- }
- struct {
- QSGMaterialShader *program = nullptr;
- int pos_order;
- } programGL;
- struct {
- QSGMaterialRhiShader *program = nullptr;
- QRhiVertexInputLayout inputLayout;
- QVarLengthArray<QRhiGraphicsShaderStage, 2> shaderStages;
- } programRhi;
-
- float lastOpacity;
- };
+ using Shader = ShaderManagerShader;
ShaderManager(QSGDefaultRenderContext *ctx) : blitProgram(nullptr), context(ctx) { }
~ShaderManager() {
@@ -657,9 +695,10 @@ public:
void clearCachedRendererData();
using ShaderResourceBindingList = QVarLengthArray<QRhiShaderResourceBinding, 8>;
-
QRhiShaderResourceBindings *srb(const ShaderResourceBindingList &bindings);
+ QHash<GraphicsPipelineStateKey, QRhiGraphicsPipeline *> pipelineCache;
+
public Q_SLOTS:
void invalidated();
@@ -677,39 +716,6 @@ private:
QHash<ShaderResourceBindingList, QRhiShaderResourceBindings *> srbCache;
};
-struct GraphicsState
-{
- bool depthTest = false;
- bool depthWrite = false;
- QRhiGraphicsPipeline::CompareOp depthFunc = QRhiGraphicsPipeline::Less;
- bool blending = false;
- QRhiGraphicsPipeline::BlendFactor srcColor = QRhiGraphicsPipeline::One;
- QRhiGraphicsPipeline::BlendFactor dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
- QRhiGraphicsPipeline::ColorMask colorWrite = QRhiGraphicsPipeline::ColorMask(0xF);
- QRhiGraphicsPipeline::CullMode cullMode = QRhiGraphicsPipeline::None;
- bool usesScissor = false;
- bool stencilTest = false;
- int sampleCount = 1;
- QSGGeometry::DrawingMode drawMode = QSGGeometry::DrawTriangles;
- float lineWidth = 1.0f;
-};
-
-bool operator==(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
-bool operator!=(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
-uint qHash(const GraphicsState &s, uint seed = 0) Q_DECL_NOTHROW;
-
-struct GraphicsPipelineStateKey
-{
- GraphicsState state;
- const ShaderManager::Shader *sms;
- const QRhiRenderPassDescriptor *rpDesc;
- const QRhiShaderResourceBindings *layoutCompatibleSrb;
-};
-
-bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
-bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
-uint qHash(const GraphicsPipelineStateKey &k, uint seed = 0) Q_DECL_NOTHROW;
-
struct RenderPassState
{
QRhiViewport viewport;
@@ -903,7 +909,6 @@ private:
GraphicsState m_gstate;
RenderPassState m_pstate;
QStack<GraphicsState> m_gstateStack;
- QHash<GraphicsPipelineStateKey, QRhiGraphicsPipeline *> m_pipelines;
QHash<QSGSamplerDescription, QRhiSampler *> m_samplers;
QRhiTexture *m_dummyTexture = nullptr;
diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
index c8ae26311b..087c3c4cbf 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
@@ -153,7 +153,6 @@ static void qt_print_material_count()
*/
QSGMaterial::QSGMaterial()
- : m_flags(nullptr)
{
Q_UNUSED(m_reserved);
#ifndef QT_NO_DEBUG
diff --git a/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp b/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp
index 77593591bd..c5cbd0c979 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp
@@ -97,14 +97,14 @@ static inline QRhiShaderResourceBinding::StageFlags toSrbStage(QShader::Stage st
Q_UNREACHABLE();
break;
}
- return 0;
+ return { };
}
void QSGMaterialRhiShaderPrivate::prepare(QShader::Variant vertexShaderVariant)
{
ubufBinding = -1;
ubufSize = 0;
- ubufStages = 0;
+ ubufStages = { };
memset(combinedImageSamplerBindings, 0, sizeof(combinedImageSamplerBindings));
vertexShader = fragmentShader = nullptr;
masterUniformData.clear();
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index 1976538aec..a35629d874 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -245,7 +245,6 @@ static void qt_print_node_count()
*/
QSGNode::QSGNode()
: m_nodeFlags(OwnedByParent)
- , m_dirtyState(nullptr)
{
init();
}
@@ -264,7 +263,6 @@ QSGNode::QSGNode(NodeType type)
, m_previousSibling(nullptr)
, m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0)
, m_nodeFlags(OwnedByParent)
- , m_dirtyState(nullptr)
{
init();
}
@@ -283,7 +281,6 @@ QSGNode::QSGNode(QSGNodePrivate &dd, NodeType type)
, m_previousSibling(nullptr)
, m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0)
, m_nodeFlags(OwnedByParent)
- , m_dirtyState(nullptr)
, d_ptr(&dd)
{
init();
@@ -1466,7 +1463,7 @@ QDebug operator<<(QDebug d, const QSGGeometryNode *n)
d << "Geometry(null)";
return d;
}
- d << "GeometryNode(" << hex << (const void *) n << dec;
+ d << "GeometryNode(" << Qt::hex << (const void *) n << Qt::dec;
const QSGGeometry *g = n->geometry();
@@ -1517,7 +1514,7 @@ QDebug operator<<(QDebug d, const QSGClipNode *n)
d << "ClipNode(null)";
return d;
}
- d << "ClipNode(" << hex << (const void *) n << dec;
+ d << "ClipNode(" << Qt::hex << (const void *) n << Qt::dec;
if (n->childCount())
d << "children=" << n->childCount();
@@ -1540,7 +1537,7 @@ QDebug operator<<(QDebug d, const QSGTransformNode *n)
}
const QMatrix4x4 m = n->matrix();
d << "TransformNode(";
- d << hex << (const void *) n << dec;
+ d << Qt::hex << (const void *) n << Qt::dec;
if (m.isIdentity())
d << "identity";
else if (m.determinant() == 1 && m(0, 0) == 1 && m(1, 1) == 1 && m(2, 2) == 1)
@@ -1562,7 +1559,7 @@ QDebug operator<<(QDebug d, const QSGOpacityNode *n)
return d;
}
d << "OpacityNode(";
- d << hex << (const void *) n << dec;
+ d << Qt::hex << (const void *) n << Qt::dec;
d << "opacity=" << n->opacity()
<< "combined=" << n->combinedOpacity()
<< (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
@@ -1581,7 +1578,7 @@ QDebug operator<<(QDebug d, const QSGRootNode *n)
return d;
}
QDebugStateSaver saver(d);
- d << "RootNode" << hex << (const void *) n << (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
+ d << "RootNode" << Qt::hex << (const void *) n << (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
#ifdef QSG_RUNTIME_DESCRIPTION
d << QSGNodePrivate::description(n);
#endif
@@ -1614,8 +1611,8 @@ QDebug operator<<(QDebug d, const QSGNode *n)
d << static_cast<const QSGOpacityNode *>(n);
break;
case QSGNode::RenderNodeType:
- d << "RenderNode(" << hex << (const void *) n << dec
- << "flags=" << (int) n->flags() << dec
+ d << "RenderNode(" << Qt::hex << (const void *) n << Qt::dec
+ << "flags=" << (int) n->flags() << Qt::dec
<< (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
#ifdef QSG_RUNTIME_DESCRIPTION
d << QSGNodePrivate::description(n);
@@ -1623,8 +1620,8 @@ QDebug operator<<(QDebug d, const QSGNode *n)
d << ')';
break;
default:
- d << "Node(" << hex << (const void *) n << dec
- << "flags=" << (int) n->flags() << dec
+ d << "Node(" << Qt::hex << (const void *) n << Qt::dec
+ << "flags=" << (int) n->flags() << Qt::dec
<< (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
#ifdef QSG_RUNTIME_DESCRIPTION
d << QSGNodePrivate::description(n);
diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h
index cb677de030..5a7faed5e0 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.h
+++ b/src/quick/scenegraph/coreapi/qsgnode.h
@@ -146,7 +146,7 @@ public:
QT_DEPRECATED void clearDirty() { }
void markDirty(DirtyState bits);
- QT_DEPRECATED DirtyState dirtyState() const { return nullptr; }
+ QT_DEPRECATED DirtyState dirtyState() const { return { }; }
virtual bool isSubtreeBlocked() const;
diff --git a/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp b/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp
index 6c2ff0b176..9282b6c308 100644
--- a/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp
@@ -202,7 +202,7 @@ void OpenGLVisualizer::visualizeChanges(Node *n)
// This is because many changes don't propegate their dirty state to the
// parent so the node updater will not unset these states. They are
// not used for anything so, unsetting it should have no side effects.
- n->dirtyState = nullptr;
+ n->dirtyState = {};
}
SHADOWNODE_TRAVERSE(n) {
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
index 7af932eeb5..90090e1cc0 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
@@ -45,6 +45,7 @@
# include <QtGui/QOpenGLFunctions>
#endif
#include <private/qquickprofiler_p.h>
+#include <qtquick_tracepoints_p.h>
#include <QtCore/QElapsedTimer>
@@ -221,6 +222,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
if (!rootNode())
return;
+ Q_TRACE_SCOPE(QSG_renderScene);
m_is_rendering = true;
@@ -235,11 +237,14 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
m_bindable = &bindable;
preprocess();
+ Q_TRACE(QSG_binding_entry);
bindable.bind();
if (profileFrames)
bindTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_binding_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererBinding);
+ Q_TRACE(QSG_render_entry);
#if QT_CONFIG(opengl)
// Sanity check that attribute registers are disabled
@@ -259,6 +264,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
render();
if (profileFrames)
renderTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererRender);
@@ -305,6 +311,8 @@ void QSGRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
void QSGRenderer::preprocess()
{
+ Q_TRACE(QSG_preprocess_entry);
+
m_is_preprocessing = true;
QSGRootNode *root = rootNode();
@@ -331,13 +339,16 @@ void QSGRenderer::preprocess()
bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled();
if (profileFrames)
preprocessTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_preprocess_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererPreprocess);
+ Q_TRACE(QSG_update_entry);
nodeUpdater()->updateStates(root);
if (profileFrames)
updatePassTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_update_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererUpdate);
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index 2892f2f966..45ad49475f 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -77,6 +77,8 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
: m_matrix(nullptr)
, m_clip_list(nullptr)
, m_opacity(1)
+ , m_needsExternalRendering(true)
+ , m_prepareCallback(nullptr)
{
}
@@ -131,7 +133,7 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
*/
QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
{
- return nullptr;
+ return {};
}
/*!
@@ -311,7 +313,7 @@ void QSGRenderNode::releaseResources()
*/
QSGRenderNode::RenderingFlags QSGRenderNode::flags() const
{
- return nullptr;
+ return {};
}
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode_p.h b/src/quick/scenegraph/coreapi/qsgrendernode_p.h
index 5c42e55689..534d630f15 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrendernode_p.h
@@ -51,12 +51,14 @@
// We mean it.
//
+#include <QtQuick/private/qtquickglobal_p.h>
#include <QtQuick/qsgnode.h>
#include <QtQuick/qsgrendernode.h>
+#include <functional>
QT_BEGIN_NAMESPACE
-class QSGRenderNodePrivate
+class Q_QUICK_PRIVATE_EXPORT QSGRenderNodePrivate
{
public:
QSGRenderNodePrivate();
@@ -66,6 +68,11 @@ public:
const QMatrix4x4 *m_matrix;
const QSGClipNode *m_clip_list;
qreal m_opacity;
+
+ // ### Qt 6: change this into a value for flags()
+ bool m_needsExternalRendering;
+ // ### Qt 6: change this into a virtual prepare() function
+ std::function<void()> m_prepareCallback;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
index 38d4c4440f..a0131a3f67 100644
--- a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
@@ -400,7 +400,7 @@ void RhiVisualizer::ChangeVis::gather(Node *n)
// This is because many changes don't propegate their dirty state to the
// parent so the node updater will not unset these states. They are
// not used for anything so, unsetting it should have no side effects.
- n->dirtyState = nullptr;
+ n->dirtyState = { };
}
SHADOWNODE_TRAVERSE(n) {
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp
index 58b42e4094..418aaca605 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.cpp
+++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp
@@ -317,6 +317,34 @@ static void qt_debug_remove_texture(QSGTexture* texture)
\since 5.9
*/
+/*!
+ \class QSGTexture::NativeTexture
+ \brief Contains information about the underlying native resources of a texture.
+ \since 5.15
+ */
+
+/*!
+ \variable QSGTexture::NativeTexture::object
+ \brief a pointer to the native object handle.
+
+ With OpenGL, the native handle is a GLuint value, so \c object is then a
+ pointer to a GLuint. With Vulkan, the native handle is a VkImage, so \c
+ object is a pointer to a VkImage. With Direct3D 11 and Metal \c
+ object is a pointer to a ID3D11Texture2D or MTLTexture pointer, respectively.
+
+ \note Pay attention to the fact that \a object is always a pointer
+ to the native texture handle type, even if the native type itself is a
+ pointer.
+ */
+
+/*!
+ \variable QSGTexture::NativeTexture::layout
+ \brief Specifies the current image layout for APIs like Vulkan.
+
+ For Vulkan, \c layout contains a \c VkImageLayout value.
+ */
+
+
#ifndef QT_NO_DEBUG
Q_QUICK_PRIVATE_EXPORT void qsg_set_material_failure();
#endif
@@ -721,6 +749,28 @@ void QSGTexture::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUp
}
/*!
+ \return the platform-specific texture data for this texture.
+
+ \note This is only available when running the graphics API independent
+ rendering path of the scene graph. Use textureId() otherwise.
+
+ Returns an empty result (\c object is null) if there is no available
+ underlying native texture.
+
+ \since 5.15
+ \sa QQuickWindow::createTextureFromNativeObject()
+ */
+QSGTexture::NativeTexture QSGTexture::nativeTexture() const
+{
+ Q_D(const QSGTexture);
+ if (auto *tex = d->rhiTexture()) {
+ auto nativeTexture = tex->nativeTexture();
+ return {nativeTexture.object, nativeTexture.layout};
+ }
+ return {};
+}
+
+/*!
\internal
*/
void QSGTexture::setWorkResourceUpdateBatch(QRhiResourceUpdateBatch *resourceUpdates)
@@ -792,11 +842,15 @@ void QSGTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *res
/*!
\fn bool QSGDynamicTexture::updateTexture()
- Call this function to explicitly update the dynamic texture. Calling bind() will bind
- the content that was previously updated.
+ Call this function to explicitly update the dynamic texture.
The function returns true if the texture was changed as a resul of the update; otherwise
returns false.
+
+ \note This function is typically called from QQuickItem::updatePaintNode()
+ or QSGNode::preprocess(), meaning during the \c{synchronization} or the
+ \c{node preprocessing} phases of the scenegraph. Calling it at other times
+ is discouraged and can lead to unexpected behavior.
*/
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.h b/src/quick/scenegraph/coreapi/qsgtexture.h
index 2efdd8b7c3..207ef52f4e 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.h
+++ b/src/quick/scenegraph/coreapi/qsgtexture.h
@@ -80,7 +80,13 @@ public:
Anisotropy16x
};
+ struct NativeTexture {
+ const void *object;
+ int layout;
+ };
+
virtual int textureId() const = 0; // ### Qt 6: remove
+ NativeTexture nativeTexture() const;
virtual QSize textureSize() const = 0;
virtual bool hasAlphaChannel() const = 0;
virtual bool hasMipmaps() const = 0;
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index f7b07d724a..eab0369be7 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -50,6 +50,8 @@
#include <private/qquickprofiler_p.h>
#include <QElapsedTimer>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
static QElapsedTimer qsg_render_timer;
@@ -169,10 +171,13 @@ void QSGDistanceFieldGlyphCache::update()
if (m_pendingGlyphs.isEmpty())
return;
+ Q_TRACE_SCOPE(QSGDistanceFieldGlyphCache_update, m_pendingGlyphs.size());
+
bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled();
if (profileFrames)
qsg_render_timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphAdaptationLayerFrame);
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphRender_entry);
QList<QDistanceField> distanceFields;
const int pendingGlyphsSize = m_pendingGlyphs.size();
@@ -189,8 +194,11 @@ void QSGDistanceFieldGlyphCache::update()
int count = m_pendingGlyphs.size();
if (profileFrames)
renderTime = qsg_render_timer.nsecsElapsed();
+
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphRender_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
QQuickProfiler::SceneGraphAdaptationLayerGlyphRender);
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphStore_entry);
m_pendingGlyphs.reset();
@@ -210,6 +218,7 @@ void QSGDistanceFieldGlyphCache::update()
int(renderTime / 1000000),
int((now - (renderTime / 1000000))));
}
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphStore_exit);
Q_QUICK_SG_PROFILE_END_WITH_PAYLOAD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
QQuickProfiler::SceneGraphAdaptationLayerGlyphStore,
(qint64)count);
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 6baee33b53..1db49feb5d 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -57,8 +57,10 @@
#include <QtCore/qrect.h>
#include <QtGui/qbrush.h>
#include <QtGui/qcolor.h>
+#include <QtGui/qpainterpath.h>
#include <QtCore/qsharedpointer.h>
#include <QtGui/qglyphrun.h>
+#include <QtGui/qpainterpath.h>
#include <QtCore/qurl.h>
#include <private/qfontengine_p.h>
#include <QtGui/private/qdatabuffer_p.h>
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 17eb1e312c..e3c951e5ed 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -341,9 +341,10 @@ void QSGRenderContext::invalidate()
{
}
-void QSGRenderContext::prepareSync(qreal devicePixelRatio)
+void QSGRenderContext::prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb)
{
Q_UNUSED(devicePixelRatio);
+ Q_UNUSED(cb);
}
void QSGRenderContext::beginNextFrame(QSGRenderer *renderer,
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 244bcfabd1..d389420907 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -174,7 +174,7 @@ public:
using RenderPassCallback = void (*)(void *);
- virtual void prepareSync(qreal devicePixelRatio);
+ virtual void prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb);
virtual void beginNextFrame(QSGRenderer *renderer,
RenderPassCallback mainPassRecordingStart,
RenderPassCallback mainPassRecordingEnd,
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index 66add51c55..7dfb8488ae 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -87,7 +87,6 @@ struct QSGAdaptationBackendData
};
QSGAdaptationBackendData::QSGAdaptationBackendData()
- : flags(nullptr)
{
// Fill in the table with the built-in adaptations.
builtIns.append(new QSGSoftwareAdaptation);
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 2bf4a83a8e..1d18caa0b4 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -200,9 +200,14 @@ void QSGDefaultRenderContext::invalidate()
emit invalidated();
}
-void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio)
+void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb)
{
m_currentDevicePixelRatio = devicePixelRatio;
+
+ // we store the command buffer already here, in case there is something in
+ // an updatePaintNode() implementation that leads to needing it (for
+ // example, an updateTexture() call on a QSGRhiLayer)
+ m_currentFrameCommandBuffer = cb;
}
static QBasicMutex qsg_framerender_mutex;
@@ -237,14 +242,12 @@ void QSGDefaultRenderContext::beginNextRhiFrame(QSGRenderer *renderer, QRhiRende
RenderPassCallback mainPassRecordingEnd,
void *callbackUserData)
{
- Q_ASSERT(!m_currentFrameCommandBuffer);
-
renderer->setRenderTarget(rt);
renderer->setRenderPassDescriptor(rp);
renderer->setCommandBuffer(cb);
renderer->setRenderPassRecordingCallbacks(mainPassRecordingStart, mainPassRecordingEnd, callbackUserData);
- m_currentFrameCommandBuffer = cb;
+ m_currentFrameCommandBuffer = cb; // usually the same as what was passed to prepareSync() but cannot count on that having been called
m_currentFrameRenderPass = rp;
}
@@ -364,7 +367,7 @@ void QSGDefaultRenderContext::compileShader(QSGMaterialShader *shader, QSGMateri
p->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader());
p->link();
if (!p->isLinked())
- qWarning() << "shader compilation failed:" << endl << p->log();
+ qWarning() << "shader compilation failed:" << Qt::endl << p->log();
} else {
shader->compile();
}
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index 2fdb3a48dd..97ed681f9a 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -104,7 +104,7 @@ public:
void initialize(const QSGRenderContext::InitParams *params) override;
void invalidate() override;
- void prepareSync(qreal devicePixelRatio) override;
+ void prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb) override;
void beginNextFrame(QSGRenderer *renderer,
RenderPassCallback mainPassRecordingStart,
RenderPassCallback mainPassRecordingEnd,
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index f609055677..94f15b55d4 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -60,6 +60,7 @@
#include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/private/qsgrenderer_p.h>
#include <private/qquickprofiler_p.h>
+#include <qtquick_tracepoints_p.h>
#include <private/qsgrhishadereffectnode_p.h>
@@ -195,8 +196,16 @@ public:
bool eventFilter(QObject *watched, QEvent *event) override;
struct WindowData {
+ WindowData()
+ : updatePending(false),
+ grabOnly(false),
+ rhiDeviceLost(false),
+ rhiDoomed(false)
+ { }
bool updatePending : 1;
bool grabOnly : 1;
+ bool rhiDeviceLost : 1;
+ bool rhiDoomed : 1;
};
QHash<QQuickWindow *, WindowData> m_windows;
@@ -316,15 +325,19 @@ void QSGRenderLoop::setInstance(QSGRenderLoop *instance)
s_instance = instance;
}
-void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window,
- bool isEs)
+void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window)
{
QString translatedMessage;
QString untranslatedMessage;
- QQuickWindowPrivate::contextCreationFailureMessage(window->requestedFormat(),
+ if (QSGRhiSupport::instance()->isRhiEnabled()) {
+ QQuickWindowPrivate::rhiCreationFailureMessage(QSGRhiSupport::instance()->rhiBackendName(),
&translatedMessage,
- &untranslatedMessage,
- isEs);
+ &untranslatedMessage);
+ } else {
+ QQuickWindowPrivate::contextCreationFailureMessage(window->requestedFormat(),
+ &translatedMessage,
+ &untranslatedMessage);
+ }
// If there is a slot connected to the error signal, emit it and leave it to
// the application to do something with the message. If nothing is connected,
// show a message on our own and terminate.
@@ -362,10 +375,7 @@ QSGGuiThreadRenderLoop::~QSGGuiThreadRenderLoop()
void QSGGuiThreadRenderLoop::show(QQuickWindow *window)
{
- WindowData data;
- data.updatePending = false;
- data.grabOnly = false;
- m_windows[window] = data;
+ m_windows[window] = WindowData();
maybeUpdate(window);
}
@@ -451,8 +461,10 @@ void QSGGuiThreadRenderLoop::handleDeviceLoss()
rc->invalidate();
- for (auto it = m_windows.constBegin(), itEnd = m_windows.constEnd(); it != itEnd; ++it)
+ for (auto it = m_windows.begin(), itEnd = m_windows.end(); it != itEnd; ++it) {
releaseSwapchain(it.key());
+ it->rhiDeviceLost = true;
+ }
delete rhi;
rhi = nullptr;
@@ -508,6 +520,13 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
const bool enableRhi = rhiSupport->isRhiEnabled();
if (enableRhi && !rhi) {
+ // This block below handles both the initial QRhi initialization and
+ // also the subsequent reinitialization attempts after a device lost
+ // (reset) situation.
+
+ if (data.rhiDoomed) // no repeated attempts if the initial attempt failed
+ return;
+
if (!offscreenSurface)
offscreenSurface = rhiSupport->maybeCreateOffscreenSurface(window);
@@ -517,6 +536,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (rhiSupport->isProfilingRequested())
QSGRhiProfileConnection::instance()->initialize(rhi);
+ data.rhiDeviceLost = false;
+
current = true;
rhi->makeThreadLocalNativeContextCurrent();
@@ -533,7 +554,11 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
rcParams.maybeSurface = window;
cd->context->initialize(&rcParams);
} else {
- handleContextCreationFailure(window, false);
+ if (!data.rhiDeviceLost) {
+ data.rhiDoomed = true;
+ handleContextCreationFailure(window);
+ }
+ // otherwise no error, will retry on a subsequent rendering attempt
}
} else if (!enableRhi && !gl) {
gl = new QOpenGLContext();
@@ -542,10 +567,9 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (qt_gl_global_share_context())
gl->setShareContext(qt_gl_global_share_context());
if (!gl->create()) {
- const bool isEs = gl->isOpenGLES();
delete gl;
gl = nullptr;
- handleContextCreationFailure(window, isEs);
+ handleContextCreationFailure(window);
} else {
if (!offscreenSurface) {
offscreenSurface = new QOffscreenSurface;
@@ -619,7 +643,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
i++;
}
- // Check for context loss.
+ // Check for context loss. (legacy GL only)
if (!current && !rhi && !gl->isValid()) {
for (auto it = m_windows.constBegin() ; it != m_windows.constEnd(); it++) {
QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(it.key());
@@ -657,20 +681,25 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
return;
}
+ Q_TRACE_SCOPE(QSG_renderWindow);
QElapsedTimer renderTimer;
qint64 renderTime = 0, syncTime = 0, polishTime = 0;
bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled();
if (profileFrames)
renderTimer.start();
+ Q_TRACE(QSG_polishItems_entry);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
cd->polishItems();
if (profileFrames)
polishTime = renderTimer.nsecsElapsed();
+
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -725,15 +754,20 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
+
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
cd->renderSceneGraph(window->size(), effectiveOutputSize);
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (data.grabOnly) {
const bool alpha = window->format().alphaBufferSize() > 0 && window->color().alpha() != 255;
@@ -747,7 +781,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
const bool needsPresent = alsoSwap && window->isVisible();
if (cd->swapchain) {
- QRhi::EndFrameFlags flags = 0;
+ QRhi::EndFrameFlags flags;
if (!needsPresent)
flags |= QRhi::SkipPresent;
QRhi::FrameOpResult frameResult = rhi->endFrame(cd->swapchain, flags);
@@ -767,6 +801,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
qint64 swapTime = 0;
if (profileFrames)
swapTime = renderTimer.nsecsElapsed();
+
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index 02d0b84de1..9fd0ab02f5 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -112,12 +112,11 @@ public:
static void cleanup();
+ void handleContextCreationFailure(QQuickWindow *window);
+
Q_SIGNALS:
void timeToIncubate();
-protected:
- void handleContextCreationFailure(QQuickWindow *window, bool isEs);
-
private:
static QSGRenderLoop *s_instance;
diff --git a/src/quick/scenegraph/qsgrhilayer.cpp b/src/quick/scenegraph/qsgrhilayer.cpp
index 757410eded..952279a3ff 100644
--- a/src/quick/scenegraph/qsgrhilayer.cpp
+++ b/src/quick/scenegraph/qsgrhilayer.cpp
@@ -388,7 +388,7 @@ void QSGRhiLayer::grab()
m_mirrorHorizontal ? -m_rect.width() : m_rect.width(),
m_mirrorVertical ? m_rect.height() : -m_rect.height());
}
- QSGAbstractRenderer::MatrixTransformFlags matrixFlags = 0;
+ QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
if (!m_rhi->isYUpInNDC())
matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
m_renderer->setProjectionMatrixToRect(mirrored, matrixFlags);
diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
index 6f6544548c..e86dae7c09 100644
--- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp
+++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
@@ -136,7 +136,7 @@ void QSGRhiShaderLinker::linkTextureSubRects()
// texture binding point.
for (Constant &c : m_constants) {
if (c.specialType == QSGShaderEffectNode::VariableData::SubRect) {
- if (c.value.type() == QVariant::ByteArray) {
+ if (c.value.userType() == QMetaType::QByteArray) {
const QByteArray name = c.value.toByteArray();
if (!m_samplerNameMap.contains(name))
qWarning("ShaderEffect: qt_SubRect_%s refers to unknown source texture", name.constData());
@@ -270,7 +270,7 @@ bool QSGRhiShaderEffectMaterialShader::updateUniformData(RenderState &state, QSG
memcpy(dst, f, sizeof(f));
} else if (c.specialType == QSGShaderEffectNode::VariableData::None) {
changed = true;
- switch (int(c.value.type())) {
+ switch (int(c.value.userType())) {
case QMetaType::QColor: {
const QColor v = qsg_premultiply_color(qvariant_cast<QColor>(c.value));
const float f[4] = { float(v.redF()), float(v.greenF()), float(v.blueF()), float(v.alphaF()) };
diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp
index e2945879b1..f25bbe2d26 100644
--- a/src/quick/scenegraph/qsgrhisupport.cpp
+++ b/src/quick/scenegraph/qsgrhisupport.cpp
@@ -38,7 +38,10 @@
****************************************************************************/
#include "qsgrhisupport_p.h"
-#include "qsgdefaultrendercontext_p.h"
+#include "qsgcontext_p.h"
+#if QT_CONFIG(opengl)
+# include "qsgdefaultrendercontext_p.h"
+#endif
#include <QtGui/qwindow.h>
#if QT_CONFIG(vulkan)
@@ -157,9 +160,11 @@ void QSGRhiSupport::applySettings()
} else if (rhiBackend == QByteArrayLiteral("null")) {
m_rhiBackend = QRhi::Null;
} else {
+ if (!rhiBackend.isEmpty())
+ qWarning("Unknown key \"%s\" for QSG_RHI_BACKEND, falling back to default backend.", qPrintable(rhiBackend));
#if defined(Q_OS_WIN)
m_rhiBackend = QRhi::D3D11;
-#elif defined(Q_OS_DARWIN)
+#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS)
m_rhiBackend = QRhi::Metal;
#else
m_rhiBackend = QRhi::OpenGLES2;
@@ -185,29 +190,10 @@ void QSGRhiSupport::applySettings()
if (m_killDeviceFrameCount > 0 && m_rhiBackend == QRhi::D3D11)
qDebug("Graphics device will be reset every %d frames", m_killDeviceFrameCount);
- const char *backendName = "unknown";
- switch (m_rhiBackend) {
- case QRhi::Null:
- backendName = "Null";
- break;
- case QRhi::Vulkan:
- backendName = "Vulkan";
- break;
- case QRhi::OpenGLES2:
- backendName = "OpenGL";
- break;
- case QRhi::D3D11:
- backendName = "D3D11";
- break;
- case QRhi::Metal:
- backendName = "Metal";
- break;
- default:
- break;
- }
+ const QString backendName = rhiBackendName();
qCDebug(QSG_LOG_INFO,
"Using QRhi with backend %s\n graphics API debug/validation layers: %d\n QRhi profiling and debug markers: %d",
- backendName, m_debugLayer, m_profile);
+ qPrintable(backendName), m_debugLayer, m_profile);
if (m_preferSoftwareRenderer)
qCDebug(QSG_LOG_INFO, "Prioritizing software renderers");
}
@@ -247,6 +233,27 @@ QSGRhiSupport *QSGRhiSupport::instance()
return inst;
}
+QString QSGRhiSupport::rhiBackendName() const
+{
+ if (m_enableRhi) {
+ switch (m_rhiBackend) {
+ case QRhi::Null:
+ return QLatin1String("Null");
+ case QRhi::Vulkan:
+ return QLatin1String("Vulkan");
+ case QRhi::OpenGLES2:
+ return QLatin1String("OpenGL");
+ case QRhi::D3D11:
+ return QLatin1String("D3D11");
+ case QRhi::Metal:
+ return QLatin1String("Metal");
+ default:
+ return QLatin1String("Unknown");
+ }
+ }
+ return QLatin1String("Unknown (RHI not enabled)");
+}
+
QSGRendererInterface::GraphicsApi QSGRhiSupport::graphicsApi() const
{
if (!m_enableRhi)
@@ -350,7 +357,7 @@ static const void *qsgrhi_d3d11_rifResource(QSGRendererInterface::Resource res,
}
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
static const void *qsgrhi_mtl_rifResource(QSGRendererInterface::Resource res, const QRhiNativeHandles *nat,
const QRhiNativeHandles *cbNat)
{
@@ -379,8 +386,15 @@ static const void *qsgrhi_mtl_rifResource(QSGRendererInterface::Resource res, co
}
#endif
-const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, const QSGDefaultRenderContext *rc)
+const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res,
+ const QSGDefaultRenderContext *rc)
{
+// ### This condition is a temporary workaround to allow compilation
+// with -no-opengl, but Vulkan or Metal enabled, to succeed. Full
+// support for RHI-capable -no-opengl builds will be available in
+// Qt 6 once the direct OpenGL code path gets removed.
+#if QT_CONFIG(opengl)
+
QRhi *rhi = rc->rhi();
if (res == QSGRendererInterface::RhiResource || !rhi)
return rhi;
@@ -408,7 +422,7 @@ const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, const
case QRhi::D3D11:
return qsgrhi_d3d11_rifResource(res, nat);
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
case QRhi::Metal:
{
QRhiCommandBuffer *cb = rc->currentFrameCommandBuffer();
@@ -418,6 +432,12 @@ const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, const
default:
return nullptr;
}
+
+#else
+ Q_UNUSED(res);
+ Q_UNUSED(rc);
+ return nullptr;
+#endif
}
int QSGRhiSupport::chooseSampleCountForWindowWithRhi(QWindow *window, QRhi *rhi)
@@ -469,7 +489,7 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf
QRhi *rhi = nullptr;
- QRhi::Flags flags = 0;
+ QRhi::Flags flags;
if (isProfilingRequested())
flags |= QRhi::EnableProfiling | QRhi::EnableDebugMarkers;
if (isSoftwareRendererRequested())
@@ -513,7 +533,7 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf
rhi = QRhi::create(backend, &rhiParams, flags);
}
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
if (backend == QRhi::Metal) {
QRhiMetalInitParams rhiParams;
rhi = QRhi::create(backend, &rhiParams, flags);
@@ -576,7 +596,7 @@ void QSGRhiProfileConnection::initialize(QRhi *rhi)
profPort = 30667;
qCDebug(QSG_LOG_INFO, "Sending RHI profiling output to %s:%d", qPrintable(profHost), profPort);
m_profConn.reset(new QTcpSocket);
- QObject::connect(m_profConn.data(), QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), m_profConn.data(),
+ QObject::connect(m_profConn.data(), &QAbstractSocket::errorOccurred, m_profConn.data(),
[this](QAbstractSocket::SocketError socketError) { qWarning(" RHI profiler error: %d (%s)",
socketError, qPrintable(m_profConn->errorString())); });
m_profConn->connectToHost(profHost, profPort);
diff --git a/src/quick/scenegraph/qsgrhisupport_p.h b/src/quick/scenegraph/qsgrhisupport_p.h
index d008ecd0af..0a95a09ad2 100644
--- a/src/quick/scenegraph/qsgrhisupport_p.h
+++ b/src/quick/scenegraph/qsgrhisupport_p.h
@@ -70,7 +70,7 @@
#include <QtGui/private/qrhid3d11_p.h>
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
#include <QtGui/private/qrhimetal_p.h>
#endif
@@ -109,6 +109,7 @@ public:
bool isRhiEnabled() const { return m_enableRhi; }
QRhi::Implementation rhiBackend() const { return m_rhiBackend; }
+ QString rhiBackendName() const;
QSGRendererInterface::GraphicsApi graphicsApi() const;
bool isDebugLayerRequested() const { return m_debugLayer; }
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index dc1f97de54..9b288029b4 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -70,6 +70,8 @@
#include <private/qsgrhishadereffectnode_p.h>
#include <private/qsgdefaultrendercontext_p.h>
+#include <qtquick_tracepoints_p.h>
+
/*
Overall design:
@@ -368,6 +370,9 @@ public:
QSize windowSize;
float dpr = 1;
int rhiSampleCount = 1;
+ bool rhiDeviceLost = false;
+ bool rhiDoomed = false;
+ bool guiNotifiedAboutRhiFailure = false;
// Local event queue stuff...
bool stopEventProcessing;
@@ -622,13 +627,15 @@ void QSGRenderThread::sync(bool inExpose, bool inGrab)
sgrc->initialize(&rcParams);
}
}
- } else {
+ } else if (rhi) {
// With the rhi making the (OpenGL) context current serves only one
// purpose: to enable external OpenGL rendering connected to one of
// the QQuickWindow signals (beforeSynchronizing, beforeRendering,
// etc.) to function like it did on the direct OpenGL path. For our
// own rendering this call would not be necessary.
rhi->makeThreadLocalNativeContextCurrent();
+ } else {
+ current = false;
}
if (current) {
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
@@ -653,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();
@@ -669,6 +681,7 @@ void QSGRenderThread::handleDeviceLoss()
QQuickWindowPrivate::get(window)->cleanupNodesOnShutdown();
sgrc->invalidate();
wm->releaseSwapchain(window);
+ rhiDeviceLost = true;
delete rhi;
rhi = nullptr;
}
@@ -680,7 +693,9 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
sinceLastTime = threadTimer.nsecsElapsed();
threadTimer.start();
}
+ Q_TRACE_SCOPE(QSG_syncAndRender);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
+ Q_TRACE(QSG_sync_entry);
QElapsedTimer waitTimer;
waitTimer.start();
@@ -693,8 +708,9 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
const bool repaintRequested = (pendingUpdate & RepaintRequest) || d->customRenderStage || grabImage;
const bool syncRequested = (pendingUpdate & SyncRequest) || grabImage;
const bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest;
- pendingUpdate = 0;
const bool grabRequested = grabImage != nullptr;
+ if (!grabRequested)
+ pendingUpdate = 0;
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
// Begin the frame before syncing -> sync is where we may invoke
@@ -745,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();
}
@@ -767,33 +781,46 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
if (profileFrames)
syncTime = threadTimer.nsecsElapsed();
#endif
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
- if (!syncResultedInChanges && !repaintRequested && sgrc->isValid() && !grabImage) {
- if (gl || !rhi->isRecordingFrame()) {
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
- int waitTime = vsyncDelta - (int) waitTimer.elapsed();
- if (waitTime > 0)
- msleep(waitTime);
- return;
- }
+ if (!syncResultedInChanges
+ && !repaintRequested
+ && !(pendingUpdate & RepaintRequest) // may have been set in sync()
+ && sgrc->isValid()
+ && !grabRequested
+ && (gl || (rhi && !rhi->isRecordingFrame())))
+ {
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
+ int waitTime = vsyncDelta - (int) waitTimer.elapsed();
+ if (waitTime > 0)
+ msleep(waitTime);
+ return;
}
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering started");
+ Q_TRACE(QSG_render_entry);
- if (animatorDriver->isRunning() && !grabImage) {
+ // RepaintRequest may have been set in pendingUpdate in an
+ // updatePaintNode() invoked from sync(). We are about to do a repaint
+ // right now, so reset the flag. (bits other than RepaintRequest cannot
+ // be set in pendingUpdate at this point)
+ if (!grabRequested)
+ pendingUpdate = 0;
+
+ if (animatorDriver->isRunning() && !grabRequested) {
d->animationController->lock();
animatorDriver->advance();
d->animationController->unlock();
}
bool current = true;
- if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0) {
+ if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0 && (gl || rhi)) {
if (gl)
current = gl->makeCurrent(window);
- else if (rhi)
+ else
rhi->makeThreadLocalNativeContextCurrent();
} else {
current = false;
@@ -811,21 +838,23 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
if (profileFrames)
renderTime = threadTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
// With the rhi grabs can only be done by adding a readback and then
// blocking in a real frame. The legacy GL path never gets here with
// grabs as it rather invokes sync/render directly without going
// through syncAndRender().
- if (grabImage) {
+ if (grabRequested) {
Q_ASSERT(rhi && !gl && cd->swapchain);
*grabImage = QSGRhiSupport::instance()->grabAndBlockInCurrentFrame(rhi, cd->swapchain);
}
if (cd->swapchain) {
- QRhi::EndFrameFlags flags = 0;
- if (grabImage)
+ QRhi::EndFrameFlags flags;
+ if (grabRequested)
flags |= QRhi::SkipPresent;
QRhi::FrameOpResult frameResult = rhi->endFrame(cd->swapchain, flags);
if (frameResult != QRhi::FrameOpSuccess) {
@@ -841,12 +870,13 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
gl->swapBuffers(window);
}
- if (!grabImage)
+ if (!grabRequested)
d->fireFrameSwapped();
-
} else {
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync, 1);
+ Q_TRACE(QSG_swap_entry);
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window not ready, skipping render");
}
@@ -858,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();
}
@@ -870,7 +901,7 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
int((renderTime - syncTime) / 1000000),
int(threadTimer.elapsed() - renderTime / 1000000));
-
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
@@ -912,14 +943,21 @@ void QSGRenderThread::processEventsAndWaitForMore()
void QSGRenderThread::ensureRhi()
{
if (!rhi) {
+ if (rhiDoomed) // no repeated attempts if the initial attempt failed
+ return;
QSGRhiSupport *rhiSupport = QSGRhiSupport::instance();
rhi = rhiSupport->createRhi(window, offscreenSurface);
if (rhi) {
+ rhiDeviceLost = false;
rhiSampleCount = rhiSupport->chooseSampleCountForWindowWithRhi(window, rhi);
if (rhiSupport->isProfilingRequested())
QSGRhiProfileConnection::instance()->initialize(rhi); // ### this breaks down with multiple windows
} else {
- qWarning("Failed to create QRhi on the render thread; scenegraph is not functional");
+ if (!rhiDeviceLost) {
+ rhiDoomed = true;
+ qWarning("Failed to create QRhi on the render thread; scenegraph is not functional");
+ }
+ // otherwise no error, will retry on a subsequent rendering attempt
return;
}
}
@@ -975,9 +1013,24 @@ void QSGRenderThread::run()
if (window) {
if (enableRhi) {
+
ensureRhi();
- if (rhi)
- syncAndRender();
+
+ // We absolutely have to syncAndRender() here, even when QRhi
+ // failed to initialize otherwise the gui thread will be left
+ // in a blocked state. It is up to syncAndRender() to
+ // gracefully skip all graphics stuff when rhi is null.
+
+ syncAndRender();
+
+ // Now we can do something about rhi init failures. (reinit
+ // failure after device reset does not count)
+ if (rhiDoomed && !guiNotifiedAboutRhiFailure) {
+ guiNotifiedAboutRhiFailure = true;
+ QEvent *e = new QEvent(QEvent::Type(QQuickWindowPrivate::TriggerContextCreationFailure));
+ QCoreApplication::postEvent(window, e);
+ }
+
} else {
if (!sgrc->openglContext() && windowSize.width() > 0 && windowSize.height() > 0 && gl->makeCurrent(window)) {
QSGDefaultRenderContext::InitParams rcParams;
@@ -1282,10 +1335,9 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
w->thread->gl->setFormat(w->window->requestedFormat());
w->thread->gl->setScreen(w->window->screen());
if (!w->thread->gl->create()) {
- const bool isEs = w->thread->gl->isOpenGLES();
delete w->thread->gl;
w->thread->gl = nullptr;
- handleContextCreationFailure(w->window, isEs);
+ handleContextCreationFailure(w->window);
return;
}
@@ -1508,7 +1560,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
return;
}
-
+ Q_TRACE_SCOPE(QSG_polishAndSync);
QElapsedTimer timer;
qint64 polishTime = 0;
qint64 waitTime = 0;
@@ -1517,14 +1569,17 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
if (profileFrames)
timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
+ Q_TRACE(QSG_polishItems_entry);
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
d->polishItems();
if (profileFrames)
polishTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncPolish);
+ Q_TRACE(QSG_wait_entry);
w->updateDuringSync = false;
@@ -1539,8 +1594,11 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
qCDebug(QSG_LOG_RENDERLOOP, "- wait for sync");
if (profileFrames)
waitTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_wait_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncWait);
+ Q_TRACE(QSG_sync_entry);
+
w->thread->waitCondition.wait(&w->thread->mutex);
m_lockedForSync = false;
w->thread->mutex.unlock();
@@ -1548,8 +1606,10 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
if (profileFrames)
syncTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncSync);
+ Q_TRACE(QSG_animations_entry);
if (m_animation_timer == 0 && m_animation_driver->isRunning()) {
qCDebug(QSG_LOG_RENDERLOOP, "- advancing animations");
@@ -1570,6 +1630,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
<< ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000
<< " - (on Gui thread) " << window;
+ Q_TRACE(QSG_animations_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncAnimations);
}
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index 5b48b86568..20d7c4557f 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -60,6 +60,8 @@
#include <private/qquickopenglshadereffectnode_p.h>
#endif
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
// Single-threaded render loop with a custom animation driver. Like a
@@ -180,10 +182,9 @@ void QSGWindowsRenderLoop::show(QQuickWindow *window)
m_gl->setShareContext(qt_gl_global_share_context());
bool created = m_gl->create();
if (!created) {
- const bool isEs = m_gl->isOpenGLES();
delete m_gl;
m_gl = nullptr;
- handleContextCreationFailure(window, isEs);
+ handleContextCreationFailure(window);
return;
}
@@ -393,6 +394,7 @@ bool QSGWindowsRenderLoop::event(QEvent *event)
void QSGWindowsRenderLoop::render()
{
RLDEBUG("render");
+ Q_TRACE(QSG_render_entry);
bool rendered = false;
for (const WindowData &wd : qAsConst(m_windows)) {
if (wd.pendingUpdate) {
@@ -407,10 +409,13 @@ void QSGWindowsRenderLoop::render()
QThread::msleep(m_vsyncDelta);
}
+ Q_TRACE(QSG_render_exit);
+
if (m_animationDriver->isRunning()) {
RLDEBUG("advancing animations");
QSG_LOG_TIME_SAMPLE(time_start);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphWindowsAnimations);
+ Q_TRACE(QSG_animations_entry);
m_animationDriver->advance();
RLDEBUG("animations advanced");
@@ -418,6 +423,7 @@ void QSGWindowsRenderLoop::render()
"animations ticked in %dms",
int((qsg_render_timer.nsecsElapsed() - time_start)/1000000));
+ Q_TRACE(QSG_animations_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphWindowsAnimations, 1);
// It is not given that animations triggered another maybeUpdate()
@@ -476,15 +482,20 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
if (!windowData(window))
return;
+ Q_TRACE_SCOPE(QSG_renderWindow);
+
QSG_LOG_TIME_SAMPLE(time_start);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
+ Q_TRACE(QSG_polishItems_entry);
RLDEBUG(" - polishing");
d->polishItems();
QSG_LOG_TIME_SAMPLE(time_polished);
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -492,17 +503,22 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
d->syncSceneGraph();
if (lastDirtyWindow)
m_rc->endSync();
+ Q_TRACE(QSG_sync_exit);
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_synced,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
RLDEBUG(" - rendering");
d->renderSceneGraph(window->size());
+ Q_TRACE(QSG_render_exit);
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_rendered,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
RLDEBUG(" - swapping");
if (!d->customRenderStage || !d->customRenderStage->swap())
m_gl->swapBuffers(window);
+ Q_TRACE(QSG_swap_exit);
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_swapped,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index 56d97226fb..b12f57d8ef 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -53,7 +53,6 @@ HEADERS += \
$$PWD/util/qsgengine.h \
$$PWD/util/qsgengine_p.h \
$$PWD/util/qsgplaintexture_p.h \
- $$PWD/util/qsgrhinativetextureimporter_p.h \
$$PWD/util/qsgsimplerectnode.h \
$$PWD/util/qsgsimpletexturenode.h \
$$PWD/util/qsgtextureprovider.h \
@@ -70,7 +69,6 @@ SOURCES += \
$$PWD/util/qsgareaallocator.cpp \
$$PWD/util/qsgengine.cpp \
$$PWD/util/qsgplaintexture.cpp \
- $$PWD/util/qsgrhinativetextureimporter.cpp \
$$PWD/util/qsgsimplerectnode.cpp \
$$PWD/util/qsgsimpletexturenode.cpp \
$$PWD/util/qsgtextureprovider.cpp \
diff --git a/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb b/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb
index b16da4d76a..c493996375 100644
--- a/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb
index 1a12a35b49..3f8489bfe6 100644
--- a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb b/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb
index 2d0d23d813..f721207325 100644
--- a/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb
index 65d9af4736..93ac0124be 100644
--- a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
index 5753794649..33de256615 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb
index 6026960d68..018f5aa07e 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
index 451ccbac5b..f64d7ac315 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb
index 41ebc12abf..31f870df23 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb
index 0c37ccb6ed..df7ef28add 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb
index b92235eec3..a90beea1b3 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb
index 28ba15e3de..a219eb5800 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb
index 2877ab92db..0cfdfed5a9 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb
index 2e6085aa39..a3998ad695 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb
index a528c667fd..62ffe0385e 100644
--- a/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb
index e83de529e6..3f23fa0da1 100644
--- a/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb
index 81c51321bb..82e302baa2 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb
index 6bf01658a1..39281bbda5 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb
index 4a9ac900a6..8ca627e6c1 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb
index 76c2459edf..b05b62e968 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb
index 7bfa7ccd4a..92dc0bd710 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb
index 8f8304fb49..3303ddec7f 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb b/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb
index 0b4554568b..785527811a 100644
--- a/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb b/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb
index 2872af0200..eec3bf66b0 100644
--- a/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
index 5ab92fecca..c1e81f4163 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb
index 96746e6b0d..b8d38bdff4 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
index 6e6b1ab6c2..7e26f3775e 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb b/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb
index 4b08ee2ce4..16046468c2 100644
--- a/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb b/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb
index 4a8c646a21..9365ce95c4 100644
--- a/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb
index f99cdf1176..8a30f3eae6 100644
--- a/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb
index 59c4104a2c..1f187b05ac 100644
--- a/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb b/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb
index ffaecbb56c..780486ca29 100644
--- a/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb b/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb
index b7715d4dd5..76d03d4ff7 100644
--- a/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/sprite.frag.qsb b/src/quick/scenegraph/shaders_ng/sprite.frag.qsb
index 45d5bc14ee..2a33d577c7 100644
--- a/src/quick/scenegraph/shaders_ng/sprite.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/sprite.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/sprite.vert.qsb b/src/quick/scenegraph/shaders_ng/sprite.vert.qsb
index b55f881734..c77612a31a 100644
--- a/src/quick/scenegraph/shaders_ng/sprite.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/sprite.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb b/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb
index 6ae7a51f7a..b0b13a1d5a 100644
--- a/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb b/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb
index ce2ed3c5b3..3c091ad73e 100644
--- a/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb b/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb
index 66ebc5f827..b0461a686c 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb b/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb
index d57d92bbe6..18e4685d21 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb
index 9dd4137072..3d9b5a0bdd 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/textmask.frag.qsb b/src/quick/scenegraph/shaders_ng/textmask.frag.qsb
index b16da4d76a..cfae9575da 100644
--- a/src/quick/scenegraph/shaders_ng/textmask.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/textmask.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/textmask.vert.qsb b/src/quick/scenegraph/shaders_ng/textmask.vert.qsb
index 99082297bf..2ea425e1c0 100644
--- a/src/quick/scenegraph/shaders_ng/textmask.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/textmask.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/texture.frag.qsb b/src/quick/scenegraph/shaders_ng/texture.frag.qsb
index 3f4aa3713c..47c75b1e78 100644
--- a/src/quick/scenegraph/shaders_ng/texture.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/texture.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/texture.vert.qsb b/src/quick/scenegraph/shaders_ng/texture.vert.qsb
index bf0bc7d9fa..0301a7bfa0 100644
--- a/src/quick/scenegraph/shaders_ng/texture.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/texture.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb
index 93965a55dd..8a30f3eae6 100644
--- a/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb
index 98abe4ef6f..95787f647b 100644
--- a/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/visualization.frag.qsb b/src/quick/scenegraph/shaders_ng/visualization.frag.qsb
index eadad927dc..f45b7b4488 100644
--- a/src/quick/scenegraph/shaders_ng/visualization.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/visualization.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/visualization.vert.qsb b/src/quick/scenegraph/shaders_ng/visualization.vert.qsb
index 7ba27cb4b5..acb29bb0fd 100644
--- a/src/quick/scenegraph/shaders_ng/visualization.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/visualization.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp
index 4880d98871..aec981871b 100644
--- a/src/quick/scenegraph/util/qsgengine.cpp
+++ b/src/quick/scenegraph/util/qsgengine.cpp
@@ -51,6 +51,7 @@
QT_BEGIN_NAMESPACE
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\class QSGEngine
@@ -58,6 +59,8 @@ QT_BEGIN_NAMESPACE
\inmodule QtQuick
\since 5.4
+ \deprecated
+
A QSGEngine can be used to render a tree of QSGNode directly on a QWindow
or QOpenGLFramebufferObject without any integration with QML, QQuickWindow
or QQuickItem and the convenience that they provide.
@@ -285,6 +288,8 @@ QSGNinePatchNode *QSGEngine::createNinePatchNode() const
return d->sgRenderContext->isValid() ? d->sgRenderContext->sceneGraphContext()->createNinePatchNode() : nullptr;
}
+#endif
+
QT_END_NAMESPACE
#include "moc_qsgengine.cpp"
diff --git a/src/quick/scenegraph/util/qsgengine.h b/src/quick/scenegraph/util/qsgengine.h
index c5a59b47e7..f00b7a0b6f 100644
--- a/src/quick/scenegraph/util/qsgengine.h
+++ b/src/quick/scenegraph/util/qsgengine.h
@@ -54,8 +54,7 @@ class QSGRectangleNode;
class QSGImageNode;
class QSGNinePatchNode;
-// ### Qt 6: Remove or redesign.
-
+#if QT_DEPRECATED_SINCE(5, 15)
class Q_QUICK_EXPORT QSGEngine : public QObject
{
Q_OBJECT
@@ -73,6 +72,7 @@ public:
explicit QSGEngine(QObject *parent = nullptr);
~QSGEngine() override;
+ QT_DEPRECATED_X("QSGEngine is going to be removed in Qt 6.0. Use QQuickRenderControl instead.")
void initialize(QOpenGLContext *context);
void invalidate();
@@ -84,6 +84,7 @@ public:
QSGImageNode *createImageNode() const;
QSGNinePatchNode *createNinePatchNode() const;
};
+#endif
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgengine_p.h b/src/quick/scenegraph/util/qsgengine_p.h
index c5b5c695bd..662c32d3d9 100644
--- a/src/quick/scenegraph/util/qsgengine_p.h
+++ b/src/quick/scenegraph/util/qsgengine_p.h
@@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE
class QSGContext;
class QSGRenderContext;
+#if QT_DEPRECATED_SINCE(5, 15)
class QSGEnginePrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QSGEngine)
@@ -69,6 +70,7 @@ public:
QScopedPointer<QSGContext> sgContext;
QScopedPointer<QSGRenderContext> sgRenderContext;
};
+#endif
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
index 75a874424a..18c72286d1 100644
--- a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
@@ -59,6 +59,8 @@
#include <private/qquickprofiler_p.h>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
#ifndef GL_BGRA
@@ -250,14 +252,17 @@ void AtlasBase::bind(QSGTexture::Filtering filtering)
if (profileFrames)
qsg_renderer_timer.start();
+ Q_TRACE_SCOPE(QSG_texture_prepare);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
// Skip bind, convert, swizzle; they're irrelevant
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareStart, 3);
+ Q_TRACE(QSG_texture_upload_entry);
uploadPendingTexture(i);
+ Q_TRACE(QSG_texture_upload_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareUpload);
diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp
index fdebe03494..f00918bb4e 100644
--- a/src/quick/scenegraph/util/qsgplaintexture.cpp
+++ b/src/quick/scenegraph/util/qsgplaintexture.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qsgplaintexture_p.h"
-#include "qsgrhinativetextureimporter_p.h"
#include <QtQuick/private/qsgcontext_p.h>
#include <qmath.h>
#include <private/qquickprofiler_p.h>
@@ -53,6 +52,8 @@
#endif
#include <QtGui/private/qrhi_p.h>
+#include <qtquick_tracepoints_p.h>
+
#if QT_CONFIG(opengl)
static QElapsedTimer qsg_renderer_timer;
#endif
@@ -150,9 +151,11 @@ void QSGPlainTexture::setTextureId(int id) // legacy (GL-only)
void QSGPlainTexture::bind() // legacy (GL-only)
{
#if QT_CONFIG(opengl)
+ Q_TRACE_SCOPE(QSG_texture_prepare);
QOpenGLContext *context = QOpenGLContext::currentContext();
QOpenGLFunctions *funcs = context->functions();
if (!m_dirty_texture) {
+ Q_TRACE_SCOPE(QSG_texture_bind);
funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
if (mipmapFiltering() != QSGTexture::None && !m_mipmaps_generated) {
funcs->glGenerateMipmap(GL_TEXTURE_2D);
@@ -174,6 +177,7 @@ void QSGPlainTexture::bind() // legacy (GL-only)
if (m_image.isNull()) {
if (m_texture_id && m_owns_texture) {
+ Q_TRACE_SCOPE(QSG_texture_delete);
funcs->glDeleteTextures(1, &m_texture_id);
qCDebug(QSG_LOG_TIME_TEXTURE, "plain texture deleted in %dms - %dx%d",
(int) qsg_renderer_timer.elapsed(),
@@ -189,6 +193,8 @@ void QSGPlainTexture::bind() // legacy (GL-only)
return;
}
+ Q_TRACE(QSG_texture_bind_entry);
+
if (m_texture_id == 0)
funcs->glGenTextures(1, &m_texture_id);
funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
@@ -196,8 +202,10 @@ void QSGPlainTexture::bind() // legacy (GL-only)
qint64 bindTime = 0;
if (profileFrames)
bindTime = qsg_renderer_timer.nsecsElapsed();
+ Q_TRACE(QSG_texture_bind_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareBind);
+ Q_TRACE(QSG_texture_upload_entry);
// ### TODO: check for out-of-memory situations...
@@ -232,8 +240,10 @@ void QSGPlainTexture::bind() // legacy (GL-only)
qint64 uploadTime = 0;
if (profileFrames)
uploadTime = qsg_renderer_timer.nsecsElapsed();
+ Q_TRACE(QSG_texture_upload_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareUpload);
+ Q_TRACE(QSG_texture_mipmap_entry);
if (mipmapFiltering() != QSGTexture::None) {
funcs->glGenerateMipmap(GL_TEXTURE_2D);
@@ -252,6 +262,7 @@ void QSGPlainTexture::bind() // legacy (GL-only)
int((mipmapTime - uploadTime)/1000000),
m_texture_size != m_image.size() ? " (scaled to GL_MAX_TEXTURE_SIZE)" : "");
}
+ Q_TRACE(QSG_texture_mipmap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareMipmap);
@@ -281,14 +292,14 @@ void QSGPlainTexture::setTextureFromNativeObject(QRhi *rhi, QQuickWindow::Native
{
Q_UNUSED(type);
- QRhiTexture::Flags flags = 0;
+ QRhiTexture::Flags flags;
if (mipmap)
flags |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips;
QRhiTexture *t = rhi->newTexture(QRhiTexture::RGBA8, size, 1, flags);
// ownership of the native object is never taken
- QSGRhiNativeTextureImporter::buildWrapper(rhi, t, nativeObjectPtr, nativeLayout);
+ t->buildFrom({nativeObjectPtr, nativeLayout});
setTexture(t);
}
@@ -421,7 +432,7 @@ void QSGPlainTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch
}
if (!q->m_texture) {
- QRhiTexture::Flags f = 0;
+ QRhiTexture::Flags f;
if (hasMipMaps)
f |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips;
diff --git a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
index 3dc1f5f526..6b5f1aec4f 100644
--- a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
@@ -49,6 +49,9 @@
#include <private/qquickprofiler_p.h>
#include <private/qsgdefaultrendercontext_p.h>
#include <private/qsgtexture_p.h>
+
+#include <qtquick_tracepoints_p.h>
+
#if 0
#include <private/qsgcompressedtexture_p.h>
#include <private/qsgcompressedatlastexture_p.h>
@@ -197,14 +200,17 @@ void AtlasBase::updateRhiTexture(QRhiResourceUpdateBatch *resourceUpdates)
if (profileFrames)
qsg_renderer_timer.start();
+ Q_TRACE_SCOPE(QSG_texture_prepare);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
// Skip bind, convert, swizzle; they're irrelevant
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareStart, 3);
+ Q_TRACE(QSG_texture_upload_entry);
enqueueTextureUpload(t, resourceUpdates);
+ Q_TRACE(QSG_texture_upload_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareUpload);
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp
index 1064caccc7..4bbc2b17ba 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.cpp
+++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp
@@ -46,6 +46,8 @@
\inmodule QtQuick
\ingroup qtquick-scenegraph-materials
+ \deprecated
+
\warning This utility class is only functional when running with the legacy
OpenGL renderer of the Qt Quick scenegraph. Its usage is not recommended in
new application code.
@@ -234,6 +236,8 @@
/*!
\class QSGSimpleMaterial
+ \deprecated
+
\inmodule QtQuick
\ingroup qtquick-scenegraph-materials
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.h b/src/quick/scenegraph/util/qsgsimplematerial.h
index 79180ca8e2..78cd05f2d8 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.h
+++ b/src/quick/scenegraph/util/qsgsimplematerial.h
@@ -44,6 +44,8 @@
QT_BEGIN_NAMESPACE
+#if QT_DEPRECATED_SINCE(5, 15)
+
template <typename State>
class QSGSimpleMaterialShader : public QSGMaterialShader
{
@@ -77,6 +79,7 @@ public:
void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
+ QT_DEPRECATED_X("QSGSimpleMaterialShader is going to be removed in Qt 6.0. Use QSGMaterialShader instead.")
virtual void updateState(const State *newState, const State *oldState) = 0;
virtual void resolveUniforms() {}
@@ -139,12 +142,14 @@ class QSGSimpleMaterial : public QSGMaterial
{
public:
#ifndef Q_CLANG_QDOC
+ QT_DEPRECATED_X("QSGSimpleMaterial is going to be removed in Qt 6.0. Use QSGMaterial instead.")
QSGSimpleMaterial(const State &aState, PtrShaderCreateFunc func)
: m_state(aState)
, m_func(func)
{
}
+ QT_DEPRECATED_X("QSGSimpleMaterial is going to be removed in Qt 6.0. Use QSGMaterial instead.")
QSGSimpleMaterial(PtrShaderCreateFunc func)
: m_func(func)
{
@@ -213,6 +218,8 @@ Q_INLINE_TEMPLATE void QSGSimpleMaterialShader<State>::updateState(const RenderS
updateState(ns, old);
}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index fe5b372da8..e5e25d141b 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -176,11 +176,8 @@ void QQuickAbstractAnimationPrivate::commence()
animationInstance = new QQuickAnimatorProxyJob(animationInstance, q);
animationInstance->addAnimationChangeListener(this, QAbstractAnimationJob::Completion);
}
+ emit q->started();
animationInstance->start();
- if (animationInstance->isStopped()) {
- running = false;
- emit q->stopped();
- }
}
}
@@ -213,8 +210,6 @@ QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const
It is only triggered for top-level, standalone animations. It will not be
triggered for animations in a Behavior or Transition, or animations
that are part of an animation group.
-
- The corresponding handler is \c onStarted.
*/
/*!
@@ -230,8 +225,6 @@ QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const
If \l alwaysRunToEnd is true, this signal will not be emitted until the animation
has completed its current iteration.
-
- The corresponding handler is \c onStopped.
*/
/*!
@@ -250,8 +243,6 @@ QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const
If \l alwaysRunToEnd is true, this signal will not be emitted until the
animation has completed its current iteration.
- The corresponding handler is \c onFinished.
-
\sa stopped(), started(), running
*/
@@ -293,10 +284,8 @@ void QQuickAbstractAnimation::setRunning(bool r)
d->animationInstance->setLoopCount(d->animationInstance->currentLoop() + d->loopCount);
supressStart = true; //we want the animation to continue, rather than restart
}
- if (!supressStart) {
+ if (!supressStart)
d->commence();
- emit started();
- }
} else {
if (d->paused) {
d->paused = false; //reset paused state to false when stopped
@@ -314,7 +303,16 @@ void QQuickAbstractAnimation::setRunning(bool r)
}
}
- emit runningChanged(d->running);
+
+ if (r == d->running) {
+ // This might happen if we start an animation with 0 duration: This will result in that
+ // commence() will emit started(), and then when it starts it will call setCurrentTime(0),
+ // (which is both start and end time of the animation), so it will also end up calling
+ // setRunning(false) (recursively) and stop the animation.
+ // Therefore, the state of d->running will in that case be different than r if we are back in
+ // the root stack frame of the recursive calls to setRunning()
+ emit runningChanged(d->running);
+ }
}
/*!
@@ -490,7 +488,7 @@ QQuickAnimationGroup *QQuickAbstractAnimation::group() const
return d->group;
}
-void QQuickAbstractAnimation::setGroup(QQuickAnimationGroup *g)
+void QQuickAbstractAnimation::setGroup(QQuickAnimationGroup *g, int index)
{
Q_D(QQuickAbstractAnimation);
if (d->group == g)
@@ -500,8 +498,12 @@ void QQuickAbstractAnimation::setGroup(QQuickAnimationGroup *g)
d->group = g;
- if (d->group && !d->group->d_func()->animations.contains(this))
- d->group->d_func()->animations.append(this);
+ if (d->group && !d->group->d_func()->animations.contains(this)) {
+ if (index >= 0)
+ d->group->d_func()->animations.insert(index, this);
+ else
+ d->group->d_func()->animations.append(this);
+ }
}
/*!
@@ -903,7 +905,7 @@ void QActionAnimation::updateState(State newState, State oldState)
void QActionAnimation::debugAnimation(QDebug d) const
{
- d << "ActionAnimation(" << hex << (const void *) this << dec << ")";
+ d << "ActionAnimation(" << Qt::hex << (const void *) this << Qt::dec << ")";
if (animAction) {
int indentLevel = 1;
@@ -1170,7 +1172,7 @@ void QQuickPropertyAction::setProperties(const QString &p)
QQmlListProperty<QObject> QQuickPropertyAction::targets()
{
Q_D(QQuickPropertyAction);
- return QQmlListProperty<QObject>(this, d->targets);
+ return QQmlListProperty<QObject>(this, &(d->targets));
}
/*!
@@ -1182,7 +1184,7 @@ QQmlListProperty<QObject> QQuickPropertyAction::targets()
QQmlListProperty<QObject> QQuickPropertyAction::exclude()
{
Q_D(QQuickPropertyAction);
- return QQmlListProperty<QObject>(this, d->exclude);
+ return QQmlListProperty<QObject>(this, &(d->exclude));
}
/*!
@@ -1722,6 +1724,20 @@ void QQuickAnimationGroupPrivate::append_animation(QQmlListProperty<QQuickAbstra
a->setGroup(q);
}
+QQuickAbstractAnimation *QQuickAnimationGroupPrivate::at_animation(QQmlListProperty<QQuickAbstractAnimation> *list, int index)
+{
+ if (auto q = qmlobject_cast<QQuickAnimationGroup *>(list->object))
+ return q->d_func()->animations.at(index);
+ return nullptr;
+}
+
+int QQuickAnimationGroupPrivate::count_animation(QQmlListProperty<QQuickAbstractAnimation> *list)
+{
+ if (auto q = qmlobject_cast<QQuickAnimationGroup *>(list->object))
+ return q->d_func()->animations.count();
+ return 0;
+}
+
void QQuickAnimationGroupPrivate::clear_animation(QQmlListProperty<QQuickAbstractAnimation> *list)
{
QQuickAnimationGroup *q = qobject_cast<QQuickAnimationGroup *>(list->object);
@@ -1733,6 +1749,23 @@ void QQuickAnimationGroupPrivate::clear_animation(QQmlListProperty<QQuickAbstrac
}
}
+void QQuickAnimationGroupPrivate::replace_animation(QQmlListProperty<QQuickAbstractAnimation> *list,
+ int i, QQuickAbstractAnimation *a)
+{
+ if (auto *q = qmlobject_cast<QQuickAnimationGroup *>(list->object)) {
+ if (QQuickAbstractAnimation *anim = q->d_func()->animations.at(i))
+ anim->setGroup(nullptr);
+ if (a)
+ a->setGroup(q, i);
+ }
+}
+
+void QQuickAnimationGroupPrivate::removeLast_animation(QQmlListProperty<QQuickAbstractAnimation> *list)
+{
+ if (auto *q = qobject_cast<QQuickAnimationGroup *>(list->object))
+ q->d_func()->animations.last()->setGroup(nullptr);
+}
+
QQuickAnimationGroup::~QQuickAnimationGroup()
{
Q_D(QQuickAnimationGroup);
@@ -1744,10 +1777,14 @@ QQuickAnimationGroup::~QQuickAnimationGroup()
QQmlListProperty<QQuickAbstractAnimation> QQuickAnimationGroup::animations()
{
Q_D(QQuickAnimationGroup);
- QQmlListProperty<QQuickAbstractAnimation> list(this, d->animations);
- list.append = &QQuickAnimationGroupPrivate::append_animation;
- list.clear = &QQuickAnimationGroupPrivate::clear_animation;
- return list;
+ return QQmlListProperty<QQuickAbstractAnimation>(
+ this, &(d->animations),
+ &QQuickAnimationGroupPrivate::append_animation,
+ &QQuickAnimationGroupPrivate::count_animation,
+ &QQuickAnimationGroupPrivate::at_animation,
+ &QQuickAnimationGroupPrivate::clear_animation,
+ &QQuickAnimationGroupPrivate::replace_animation,
+ &QQuickAnimationGroupPrivate::removeLast_animation);
}
/*!
@@ -1927,20 +1964,20 @@ QAbstractAnimationJob* QQuickParallelAnimation::transition(QQuickStateActions &a
//convert a variant from string type to another animatable type
void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, int type)
{
- if (variant.userType() != QVariant::String) {
+ if (variant.userType() != QMetaType::QString) {
variant.convert(type);
return;
}
switch (type) {
- case QVariant::Rect:
- case QVariant::RectF:
- case QVariant::Point:
- case QVariant::PointF:
- case QVariant::Size:
- case QVariant::SizeF:
- case QVariant::Color:
- case QVariant::Vector3D:
+ case QMetaType::QRect:
+ case QMetaType::QRectF:
+ case QMetaType::QPoint:
+ case QMetaType::QPointF:
+ case QMetaType::QSize:
+ case QMetaType::QSizeF:
+ case QMetaType::QColor:
+ case QMetaType::QVector3D:
{
bool ok = false;
variant = QQmlStringConverters::variantFromString(variant.toString(), type, &ok);
@@ -1996,7 +2033,7 @@ void QQuickBulkValueAnimator::topLevelAnimationLoopChanged()
void QQuickBulkValueAnimator::debugAnimation(QDebug d) const
{
- d << "BulkValueAnimation(" << hex << (const void *) this << dec << ")" << "duration:" << duration();
+ d << "BulkValueAnimation(" << Qt::hex << (const void *) this << Qt::dec << ")" << "duration:" << duration();
if (animValue) {
int indentLevel = 1;
@@ -2533,7 +2570,7 @@ void QQuickPropertyAnimation::setProperties(const QString &prop)
QQmlListProperty<QObject> QQuickPropertyAnimation::targets()
{
Q_D(QQuickPropertyAnimation);
- return QQmlListProperty<QObject>(this, d->targets);
+ return QQmlListProperty<QObject>(this, &(d->targets));
}
/*!
@@ -2544,7 +2581,7 @@ QQmlListProperty<QObject> QQuickPropertyAnimation::targets()
QQmlListProperty<QObject> QQuickPropertyAnimation::exclude()
{
Q_D(QQuickPropertyAnimation);
- return QQmlListProperty<QObject>(this, d->exclude);
+ return QQmlListProperty<QObject>(this, &(d->exclude));
}
void QQuickAnimationPropertyUpdater::setValue(qreal v)
diff --git a/src/quick/util/qquickanimation_p.h b/src/quick/util/qquickanimation_p.h
index 746cb938bd..7bad9d50c4 100644
--- a/src/quick/util/qquickanimation_p.h
+++ b/src/quick/util/qquickanimation_p.h
@@ -80,6 +80,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAbstractAnimation : public QObject, public QQ
Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopCountChanged)
Q_CLASSINFO("DefaultMethod", "start()")
+ QML_NAMED_ELEMENT(Animation)
+ QML_UNCREATABLE("Animation is an abstract class")
+
public:
enum ThreadingModel {
GuiThread,
@@ -108,7 +111,7 @@ public:
void setCurrentTime(int);
QQuickAnimationGroup *group() const;
- void setGroup(QQuickAnimationGroup *);
+ void setGroup(QQuickAnimationGroup *, int index = -1);
void setDefaultTarget(const QQmlProperty &);
void setDisableUserControl();
@@ -165,6 +168,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPauseAnimation : public QQuickAbstractAnimati
Q_DECLARE_PRIVATE(QQuickPauseAnimation)
Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
+ QML_NAMED_ELEMENT(PauseAnimation)
public:
QQuickPauseAnimation(QObject *parent=nullptr);
@@ -191,6 +195,7 @@ class QQuickScriptAction : public QQuickAbstractAnimation
Q_PROPERTY(QQmlScriptString script READ script WRITE setScript)
Q_PROPERTY(QString scriptName READ stateChangeScriptName WRITE setStateChangeScriptName)
+ QML_NAMED_ELEMENT(ScriptAction)
public:
QQuickScriptAction(QObject *parent=nullptr);
@@ -221,6 +226,7 @@ class QQuickPropertyAction : public QQuickAbstractAnimation
Q_PROPERTY(QQmlListProperty<QObject> targets READ targets)
Q_PROPERTY(QQmlListProperty<QObject> exclude READ exclude)
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
+ QML_NAMED_ELEMENT(PropertyAction)
public:
QQuickPropertyAction(QObject *parent=nullptr);
@@ -269,6 +275,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPropertyAnimation : public QQuickAbstractAnim
Q_PROPERTY(QString properties READ properties WRITE setProperties NOTIFY propertiesChanged)
Q_PROPERTY(QQmlListProperty<QObject> targets READ targets)
Q_PROPERTY(QQmlListProperty<QObject> exclude READ exclude)
+ QML_NAMED_ELEMENT(PropertyAnimation)
public:
QQuickPropertyAnimation(QObject *parent=nullptr);
@@ -324,6 +331,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickColorAnimation : public QQuickPropertyAnimati
Q_DECLARE_PRIVATE(QQuickPropertyAnimation)
Q_PROPERTY(QColor from READ from WRITE setFrom)
Q_PROPERTY(QColor to READ to WRITE setTo)
+ QML_NAMED_ELEMENT(ColorAnimation)
public:
QQuickColorAnimation(QObject *parent=nullptr);
@@ -343,6 +351,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickNumberAnimation : public QQuickPropertyAnimat
Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
+ QML_NAMED_ELEMENT(NumberAnimation)
public:
QQuickNumberAnimation(QObject *parent=nullptr);
@@ -368,6 +377,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickVector3dAnimation : public QQuickPropertyAnim
Q_PROPERTY(QVector3D from READ from WRITE setFrom NOTIFY fromChanged)
Q_PROPERTY(QVector3D to READ to WRITE setTo NOTIFY toChanged)
+ QML_NAMED_ELEMENT(Vector3dAnimation)
public:
QQuickVector3dAnimation(QObject *parent=nullptr);
@@ -389,6 +399,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimation : public QQuickPropertyAnim
Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
+ QML_NAMED_ELEMENT(RotationAnimation)
public:
QQuickRotationAnimation(QObject *parent=nullptr);
@@ -433,6 +444,7 @@ class QQuickSequentialAnimation : public QQuickAnimationGroup
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickAnimationGroup)
+ QML_NAMED_ELEMENT(SequentialAnimation)
public:
QQuickSequentialAnimation(QObject *parent=nullptr);
@@ -450,6 +462,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickParallelAnimation : public QQuickAnimationGro
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickAnimationGroup)
+ QML_NAMED_ELEMENT(ParallelAnimation)
public:
QQuickParallelAnimation(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h
index c20ec65c24..8d23242b68 100644
--- a/src/quick/util/qquickanimation_p_p.h
+++ b/src/quick/util/qquickanimation_p_p.h
@@ -256,7 +256,12 @@ public:
: QQuickAbstractAnimationPrivate() {}
static void append_animation(QQmlListProperty<QQuickAbstractAnimation> *list, QQuickAbstractAnimation *role);
+ static QQuickAbstractAnimation *at_animation(QQmlListProperty<QQuickAbstractAnimation> *list, int index);
+ static int count_animation(QQmlListProperty<QQuickAbstractAnimation> *list);
static void clear_animation(QQmlListProperty<QQuickAbstractAnimation> *list);
+ static void replace_animation(QQmlListProperty<QQuickAbstractAnimation> *list, int index,
+ QQuickAbstractAnimation *role);
+ static void removeLast_animation(QQmlListProperty<QQuickAbstractAnimation> *list);
QList<QQuickAbstractAnimation *> animations;
};
diff --git a/src/quick/util/qquickanimationcontroller_p.h b/src/quick/util/qquickanimationcontroller_p.h
index d9ce377060..da6df6038a 100644
--- a/src/quick/util/qquickanimationcontroller_p.h
+++ b/src/quick/util/qquickanimationcontroller_p.h
@@ -64,6 +64,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimationController : public QObject, public QQmlP
Q_DECLARE_PRIVATE(QQuickAnimationController)
Q_CLASSINFO("DefaultProperty", "animation")
+ QML_NAMED_ELEMENT(AnimationController)
Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged)
Q_PROPERTY(QQuickAbstractAnimation *animation READ animation WRITE setAnimation NOTIFY animationChanged)
diff --git a/src/quick/util/qquickanimator_p.h b/src/quick/util/qquickanimator_p.h
index 511cecda7f..9f7aaafcb0 100644
--- a/src/quick/util/qquickanimator_p.h
+++ b/src/quick/util/qquickanimator_p.h
@@ -69,6 +69,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnimator : public QQuickAbstractAnimation
Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
+ QML_NAMED_ELEMENT(Animator)
+ QML_ADDED_IN_MINOR_VERSION(2)
+ QML_UNCREATABLE("Animator is an abstract class")
+
public:
QQuickItem *targetItem() const;
void setTargetItem(QQuickItem *target);
@@ -109,6 +113,8 @@ class QQuickScaleAnimatorPrivate;
class Q_QUICK_PRIVATE_EXPORT QQuickScaleAnimator : public QQuickAnimator
{
Q_OBJECT
+ QML_NAMED_ELEMENT(ScaleAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
QQuickScaleAnimator(QObject *parent = nullptr);
protected:
@@ -119,6 +125,8 @@ protected:
class Q_QUICK_PRIVATE_EXPORT QQuickXAnimator : public QQuickAnimator
{
Q_OBJECT
+ QML_NAMED_ELEMENT(XAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
QQuickXAnimator(QObject *parent = nullptr);
protected:
@@ -129,6 +137,8 @@ protected:
class Q_QUICK_PRIVATE_EXPORT QQuickYAnimator : public QQuickAnimator
{
Q_OBJECT
+ QML_NAMED_ELEMENT(YAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
QQuickYAnimator(QObject *parent = nullptr);
protected:
@@ -139,6 +149,8 @@ protected:
class Q_QUICK_PRIVATE_EXPORT QQuickOpacityAnimator : public QQuickAnimator
{
Q_OBJECT
+ QML_NAMED_ELEMENT(OpacityAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
QQuickOpacityAnimator(QObject *parent = nullptr);
protected:
@@ -152,6 +164,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimator : public QQuickAnimator
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickRotationAnimator)
Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
+ QML_NAMED_ELEMENT(RotationAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
enum RotationDirection { Numerical, Shortest, Clockwise, Counterclockwise };
@@ -177,6 +191,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimator : public QQuickAnimator
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickUniformAnimator)
Q_PROPERTY(QString uniform READ uniform WRITE setUniform NOTIFY uniformChanged)
+ QML_NAMED_ELEMENT(UniformAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
QQuickUniformAnimator(QObject *parent = nullptr);
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index 84480ddd18..767be96403 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -184,7 +184,7 @@ void QQuickAnimatorProxyJob::updateState(QAbstractAnimationJob::State newState,
void QQuickAnimatorProxyJob::debugAnimation(QDebug d) const
{
- d << "QuickAnimatorProxyJob("<< hex << (const void *) this << dec
+ d << "QuickAnimatorProxyJob("<< Qt::hex << (const void *) this << Qt::dec
<< "state:" << state() << "duration:" << duration()
<< "proxying: (" << job() << ')';
}
@@ -266,7 +266,7 @@ QQuickAnimatorJob::QQuickAnimatorJob()
void QQuickAnimatorJob::debugAnimation(QDebug d) const
{
- d << "QuickAnimatorJob(" << hex << (const void *) this << dec
+ d << "QuickAnimatorJob(" << Qt::hex << (const void *) this << Qt::dec
<< ") state:" << state() << "duration:" << duration()
<< "target:" << m_target << "value:" << m_value;
}
diff --git a/src/quick/util/qquickapplication_p.h b/src/quick/util/qquickapplication_p.h
index 66a33489e4..b0eb6fa604 100644
--- a/src/quick/util/qquickapplication_p.h
+++ b/src/quick/util/qquickapplication_p.h
@@ -71,6 +71,9 @@ class Q_AUTOTEST_EXPORT QQuickApplication : public QQmlApplication
Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName NOTIFY displayNameChanged)
Q_PROPERTY(QQmlListProperty<QQuickScreenInfo> screens READ screens NOTIFY screensChanged)
+ QML_NAMED_ELEMENT(Application)
+ QML_UNCREATABLE("Application is an abstract class.")
+
public:
explicit QQuickApplication(QObject *parent = nullptr);
virtual ~QQuickApplication();
diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp
index eee8562a2a..ceda5589b2 100644
--- a/src/quick/util/qquickbehavior.cpp
+++ b/src/quick/util/qquickbehavior.cpp
@@ -185,6 +185,80 @@ QVariant QQuickBehavior::targetValue() const
return d->targetValue;
}
+/*!
+ \readonly
+ \qmlpropertygroup QtQuick::Behavior::targetProperty
+ \qmlproperty string QtQuick::Behavior::targetProperty.name
+ \qmlproperty Object QtQuick::Behavior::targetProperty.object
+
+ \table
+ \header
+ \li Property
+ \li Description
+ \row
+ \li name
+ \li This property holds the name of the property being controlled by this Behavior.
+ \row
+ \li object
+ \li This property holds the object of the property being controlled by this Behavior.
+ \endtable
+
+ This property can be used to define custom behaviors based on the name or the object of
+ the property being controlled.
+
+ The following example defines a Behavior fading out and fading in its target object
+ when the property it controls changes:
+ \qml
+ // FadeBehavior.qml
+ import QtQuick 2.15
+
+ Behavior {
+ id: root
+ property Item fadeTarget: targetProperty.object
+ SequentialAnimation {
+ NumberAnimation {
+ target: root.fadeTarget
+ property: "opacity"
+ to: 0
+ easing.type: Easing.InQuad
+ }
+ PropertyAction { } // actually change the controlled property between the 2 other animations
+ NumberAnimation {
+ target: root.fadeTarget
+ property: "opacity"
+ to: 1
+ easing.type: Easing.OutQuad
+ }
+ }
+ }
+ \endqml
+
+ This can be used to animate a text when it changes:
+ \qml
+ import QtQuick 2.15
+
+ Text {
+ id: root
+ property int counter
+ text: counter
+ FadeBehavior on text {}
+ Timer {
+ running: true
+ repeat: true
+ interval: 1000
+ onTriggered: ++root.counter
+ }
+ }
+ \endqml
+
+ \since QtQuick 2.15
+*/
+QQmlProperty QQuickBehavior::targetProperty() const
+{
+ Q_D(const QQuickBehavior);
+ return d->property;
+}
+
void QQuickBehavior::write(const QVariant &value)
{
Q_D(QQuickBehavior);
@@ -265,6 +339,8 @@ void QQuickBehavior::setTarget(const QQmlProperty &property)
if (finalizedIdx < 0)
finalizedIdx = metaObject()->indexOfSlot("componentFinalized()");
engPriv->registerFinalizeCallback(this, finalizedIdx);
+
+ Q_EMIT targetPropertyChanged();
}
void QQuickBehavior::componentFinalized()
diff --git a/src/quick/util/qquickbehavior_p.h b/src/quick/util/qquickbehavior_p.h
index 80a51d77af..a57a26d822 100644
--- a/src/quick/util/qquickbehavior_p.h
+++ b/src/quick/util/qquickbehavior_p.h
@@ -70,7 +70,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBehavior : public QObject, public QQmlPropert
Q_PROPERTY(QQuickAbstractAnimation *animation READ animation WRITE setAnimation)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(QVariant targetValue READ targetValue NOTIFY targetValueChanged REVISION 13)
+ Q_PROPERTY(QQmlProperty targetProperty READ targetProperty NOTIFY targetPropertyChanged REVISION 15)
Q_CLASSINFO("DeferredPropertyNames", "animation")
+ QML_NAMED_ELEMENT(Behavior)
public:
QQuickBehavior(QObject *parent=nullptr);
@@ -87,9 +89,12 @@ public:
QVariant targetValue() const;
+ QQmlProperty targetProperty() const;
+
Q_SIGNALS:
void enabledChanged();
void targetValueChanged();
+ void targetPropertyChanged();
private Q_SLOTS:
void componentFinalized();
diff --git a/src/quick/util/qquickfontloader_p.h b/src/quick/util/qquickfontloader_p.h
index 8d277f7cf7..e849c52a35 100644
--- a/src/quick/util/qquickfontloader_p.h
+++ b/src/quick/util/qquickfontloader_p.h
@@ -67,6 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickFontLoader : public QObject
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ QML_NAMED_ELEMENT(FontLoader)
public:
enum Status { Null = 0, Ready, Loading, Error };
diff --git a/src/quick/util/qquickfontmetrics_p.h b/src/quick/util/qquickfontmetrics_p.h
index db2b7b6796..ee6d679649 100644
--- a/src/quick/util/qquickfontmetrics_p.h
+++ b/src/quick/util/qquickfontmetrics_p.h
@@ -79,6 +79,8 @@ class Q_AUTOTEST_EXPORT QQuickFontMetrics : public QObject
Q_PROPERTY(qreal overlinePosition READ overlinePosition NOTIFY fontChanged)
Q_PROPERTY(qreal strikeOutPosition READ strikeOutPosition NOTIFY fontChanged)
Q_PROPERTY(qreal lineWidth READ lineWidth NOTIFY fontChanged)
+ QML_NAMED_ELEMENT(FontMetrics)
+ QML_ADDED_IN_MINOR_VERSION(4)
public:
explicit QQuickFontMetrics(QObject *parent = nullptr);
~QQuickFontMetrics();
diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp b/src/quick/util/qquickforeignutils_p.h
index 7a7c19f587..7e51bc4f82 100644
--- a/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp
+++ b/src/quick/util/qquickforeignutils_p.h
@@ -37,68 +37,84 @@
**
****************************************************************************/
-#include "qsgrhinativetextureimporter_p.h"
-#include <private/qsgrhisupport_p.h> // to get all the relevant qrhi headers
+#ifndef QTQUICKFOREIGN_P_H
+#define QTQUICKFOREIGN_P_H
-QT_BEGIN_NAMESPACE
-
-void QSGRhiNativeTextureImporter::buildWrapper(QRhi *rhi, QRhiTexture *t,
- const void *nativeObjectPtr, int nativeLayout)
-{
-#if !QT_CONFIG(vulkan)
- Q_UNUSED(nativeLayout);
-#endif
-#if !QT_CONFIG(opengl) && !QT_CONFIG(vulkan) && !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN)
- Q_UNUSED(nativeObjectPtr);
-#endif
+#include <qtquickglobal_p.h>
- switch (rhi->backend()) {
- case QRhi::OpenGLES2:
- {
-#if QT_CONFIG(opengl)
- QRhiGles2TextureNativeHandles h;
- h.texture = *reinterpret_cast<const uint *>(nativeObjectPtr);
- t->buildFrom(&h);
-#endif
- }
- break;
- case QRhi::Vulkan:
- {
-#if QT_CONFIG(vulkan)
- QRhiVulkanTextureNativeHandles h;
- h.image = *reinterpret_cast<const VkImage *>(nativeObjectPtr);
- h.layout = VkImageLayout(nativeLayout);
- t->buildFrom(&h);
+#if QT_CONFIG(im)
+#include <QtGui/qinputmethod.h>
#endif
- }
- break;
- case QRhi::D3D11:
- {
-#ifdef Q_OS_WIN
- QRhiD3D11TextureNativeHandles h;
- h.texture = *reinterpret_cast<void * const *>(nativeObjectPtr);
- t->buildFrom(&h);
+#if QT_CONFIG(validator)
+#include <QtGui/qvalidator.h>
#endif
- }
- break;
- case QRhi::Metal:
- {
-#ifdef Q_OS_DARWIN
- QRhiMetalTextureNativeHandles h;
- h.texture = *reinterpret_cast<void * const *>(nativeObjectPtr);
- t->buildFrom(&h);
+#if QT_CONFIG(shortcut)
+#include <QtGui/qkeysequence.h>
#endif
- }
- break;
- case QRhi::Null:
- t->build();
- break;
- default:
- qWarning("QSGRhiNativeTextureImporter: encountered an unsupported QRhi backend (%d)",
- int(rhi->backend()));
- t->build();
- break;
- }
-}
+
+#include <QtQml/qqml.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
+
+#if QT_CONFIG(validator)
+struct QValidatorForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QValidator)
+ QML_ANONYMOUS
+};
+
+struct QRegExpValidatorForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QRegExpValidator)
+ QML_NAMED_ELEMENT(RegExpValidator)
+};
+
+#if QT_CONFIG(regularexpression)
+struct QRegularExpressionValidatorForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QRegularExpressionValidator)
+ QML_NAMED_ELEMENT(RegularExpressionValidator)
+ QML_ADDED_IN_MINOR_VERSION(14)
+};
+#endif // QT_CONFIG(regularexpression)
+
+#endif // QT_CONFIG(validator)
+
+#if QT_CONFIG(im)
+struct QInputMethodForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QInputMethod)
+ QML_NAMED_ELEMENT(InputMethod)
+ QML_UNCREATABLE("InputMethod is an abstract class.")
+};
+#endif // QT_CONFIG(im)
+
+#if QT_CONFIG(shortcut)
+struct QKeySequenceForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QKeySequence)
+ QML_NAMED_ELEMENT(StandardKey)
+ QML_ADDED_IN_MINOR_VERSION(2)
+ QML_UNCREATABLE("Cannot create an instance of StandardKey.")
+};
+#endif // QT_CONFIG(shortcut)
QT_END_NAMESPACE
+
+#endif // QTQUICKFOREIGN_P_H
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 527274e6be..70256e202e 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -273,6 +273,52 @@ public:
return QMatrix4x4();
}
+ static QColorSpace colorSpaceFromObject(const QV4::Value &object, QV4::ExecutionEngine *v4, bool *ok)
+ {
+ if (ok)
+ *ok = false;
+ QColorSpace retn;
+ QV4::Scope scope(v4);
+ QV4::ScopedObject obj(scope, object);
+ if (!obj) {
+ if (ok)
+ *ok = false;
+ return retn;
+ }
+
+ QV4::ScopedString s(scope);
+
+ QV4::ScopedValue vName(scope, obj->get((s = v4->newString(QStringLiteral("namedColorSpace")))));
+ if (vName->isInt32()) {
+ if (ok)
+ *ok = true;
+ return QColorSpace((QColorSpace::NamedColorSpace)vName->toInt32());
+ }
+
+ QV4::ScopedValue vPri(scope, obj->get((s = v4->newString(QStringLiteral("primaries")))));
+ QV4::ScopedValue vTra(scope, obj->get((s = v4->newString(QStringLiteral("transferFunction")))));
+ if (!vPri->isInt32() || !vTra->isInt32()) {
+ if (ok)
+ *ok = false;
+ return retn;
+ }
+
+ QColorSpace::Primaries pri = static_cast<QColorSpace::Primaries>(vPri->integerValue());
+ QColorSpace::TransferFunction tra = static_cast<QColorSpace::TransferFunction>(vTra->integerValue());
+ float gamma = 0.0f;
+ if (tra == QColorSpace::TransferFunction::Gamma) {
+ QV4::ScopedValue vGam(scope, obj->get((s = v4->newString(QStringLiteral("gamma")))));
+ if (!vGam->isNumber()) {
+ if (ok)
+ *ok = false;
+ return retn;
+ }
+ gamma = vGam->toNumber();
+ }
+ if (ok) *ok = true;
+ return QColorSpace(pri, tra, gamma);
+ }
+
static QFont fontFromObject(const QV4::Value &object, QV4::ExecutionEngine *v4, bool *ok)
{
if (ok)
@@ -402,6 +448,8 @@ public:
switch (type) {
case QMetaType::QColor:
return &QQuickColorValueType::staticMetaObject;
+ case QMetaType::QColorSpace:
+ return &QQuickColorSpaceValueType::staticMetaObject;
case QMetaType::QFont:
return &QQuickFontValueType::staticMetaObject;
case QMetaType::QVector2D:
@@ -427,6 +475,9 @@ public:
case QMetaType::QColor:
dst.setValue<QColor>(QColor());
return true;
+ case QMetaType::QColorSpace:
+ dst.setValue<QColorSpace>(QColorSpace());
+ return true;
case QMetaType::QFont:
dst.setValue<QFont>(QFont());
return true;
@@ -647,6 +698,9 @@ public:
#endif
bool ok = false;
switch (type) {
+ case QMetaType::QColorSpace:
+ *v = QVariant::fromValue(colorSpaceFromObject(object, v4, &ok));
+ break;
case QMetaType::QFont:
*v = QVariant::fromValue(fontFromObject(object, v4, &ok));
break;
@@ -669,6 +723,8 @@ public:
switch (type) {
case QMetaType::QColor:
return typedEqual<QColor>(lhs, rhs);
+ case QMetaType::QColorSpace:
+ return typedEqual<QColorSpace>(lhs, rhs);
case QMetaType::QFont:
return typedEqual<QFont>(lhs, rhs);
case QMetaType::QVector2D:
@@ -719,7 +775,7 @@ public:
bool typedRead(const QVariant& src, int dstType, void *dst)
{
T *dstT = reinterpret_cast<T *>(dst);
- if (src.type() == static_cast<uint>(dstType)) {
+ if (src.userType() == dstType) {
*dstT = src.value<T>();
} else {
*dstT = T();
@@ -732,6 +788,8 @@ public:
switch (dstType) {
case QMetaType::QColor:
return typedRead<QColor>(src, dstType, dst);
+ case QMetaType::QColorSpace:
+ return typedRead<QColorSpace>(src, dstType, dst);
case QMetaType::QFont:
return typedRead<QFont>(src, dstType, dst);
case QMetaType::QVector2D:
@@ -766,6 +824,8 @@ public:
switch (type) {
case QMetaType::QColor:
return typedWrite<QColor>(src, dst);
+ case QMetaType::QColorSpace:
+ return typedWrite<QColorSpace>(src, dst);
case QMetaType::QFont:
return typedWrite<QFont>(src, dst);
case QMetaType::QVector2D:
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index ebcca77f17..b885f0406a 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -43,6 +43,7 @@
#include "qquickpixmapcache_p.h"
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qqmlglobal_p.h>
+#include <QtGui/qcolorspace.h>
QT_BEGIN_NAMESPACE
@@ -291,7 +292,7 @@ void QQuickImageResponse::cancel()
\image imageprovider.png
See the \l {imageprovider}{Image Provider Example} for the complete implementation.
- Note that the example registers the provider via a \l{QQmlExtensionPlugin}{plugin}
+ Note that the example registers the provider via a \l{QQmlEngineExtensionPlugin}{plugin}
instead of registering it in the application \c main() function as shown above.
@@ -300,7 +301,7 @@ void QQuickImageResponse::cancel()
Image providers that support QImage or Texture loading automatically include support
for asychronous loading of images. To enable asynchronous loading for an
image source, set the \c asynchronous property to \c true for the relevant
- \l Image, \l BorderImage or \l AnimatedImage object. When this is enabled,
+ \l Image or \l BorderImage object. When this is enabled,
the image request to the provider is run in a low priority thread,
allowing image loading to be executed in the background, and reducing the
performance impact on the user interface.
@@ -329,10 +330,10 @@ void QQuickImageResponse::cancel()
Images returned by a QQuickImageProvider are automatically cached,
similar to any image loaded by the QML engine. When an image with a
"image://" prefix is loaded from cache, requestImage() and requestPixmap()
- will not be called for the relevant image provider. If an image should always
- be fetched from the image provider, and should not be cached at all, set the
- \c cache property to \c false for the relevant \l Image, \l BorderImage or
- \l AnimatedImage object.
+ will not be called for the relevant image provider. If an image should
+ always be fetched from the image provider, and should not be cached at
+ all, set the \c cache property to \c false for the relevant \l Image
+ or \l BorderImage object.
\sa QQmlEngine::addImageProvider()
*/
@@ -510,6 +511,7 @@ public:
{
}
+ QColorSpace targetColorSpace;
QQuickImageProviderOptions::AutoTransform autoTransform = QQuickImageProviderOptions::UsePluginDefaultTransform;
bool preserveAspectRatioCrop = false;
bool preserveAspectRatioFit = false;
@@ -558,7 +560,8 @@ bool QQuickImageProviderOptions::operator==(const QQuickImageProviderOptions &ot
{
return d->autoTransform == other.d->autoTransform &&
d->preserveAspectRatioCrop == other.d->preserveAspectRatioCrop &&
- d->preserveAspectRatioFit == other.d->preserveAspectRatioFit;
+ d->preserveAspectRatioFit == other.d->preserveAspectRatioFit &&
+ d->targetColorSpace == other.d->targetColorSpace;
}
/*!
@@ -602,6 +605,19 @@ void QQuickImageProviderOptions::setPreserveAspectRatioFit(bool preserveAspectRa
d->preserveAspectRatioFit = preserveAspectRatioFit;
}
+/*!
+ Returns the color space the image provider should return the image in.
+*/
+QColorSpace QQuickImageProviderOptions::targetColorSpace() const
+{
+ return d->targetColorSpace;
+}
+
+void QQuickImageProviderOptions::setTargetColorSpace(const QColorSpace &colorSpace)
+{
+ d->targetColorSpace = colorSpace;
+}
+
QQuickImageProviderWithOptions::QQuickImageProviderWithOptions(ImageType type, Flags flags)
: QQuickAsyncImageProvider()
{
@@ -672,17 +688,17 @@ QSize QQuickImageProviderWithOptions::loadSize(const QSize &originalSize, const
return res;
const bool preserveAspectCropOrFit = options.preserveAspectRatioCrop() || options.preserveAspectRatioFit();
- const bool formatIsSvg = (format == "svg" || format == "svgz");
+ const bool formatIsScalable = (format == "svg" || format == "svgz" || format == "pdf");
- if (!preserveAspectCropOrFit && formatIsSvg && !requestedSize.isEmpty())
+ if (!preserveAspectCropOrFit && formatIsScalable && !requestedSize.isEmpty())
return requestedSize;
qreal ratio = 0.0;
- if (requestedSize.width() && (preserveAspectCropOrFit || formatIsSvg ||
+ if (requestedSize.width() && (preserveAspectCropOrFit || formatIsScalable ||
requestedSize.width() < originalSize.width())) {
ratio = qreal(requestedSize.width()) / originalSize.width();
}
- if (requestedSize.height() && (preserveAspectCropOrFit || formatIsSvg ||
+ if (requestedSize.height() && (preserveAspectCropOrFit || formatIsScalable ||
requestedSize.height() < originalSize.height())) {
qreal hr = qreal(requestedSize.height()) / originalSize.height();
if (ratio == 0.0)
diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp
index 24b22f00c1..74ee52b1d3 100644
--- a/src/quick/util/qquickpath.cpp
+++ b/src/quick/util/qquickpath.cpp
@@ -301,6 +301,8 @@ void QQuickPath::pathElements_append(QQmlListProperty<QQuickPathElement> *proper
QQuickCurve *curve = qobject_cast<QQuickCurve *>(pathElement);
if (curve)
d->_pathCurves.append(curve);
+ else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement))
+ d->_pathTexts.append(text);
else {
QQuickPathAttribute *attribute = qobject_cast<QQuickPathAttribute *>(pathElement);
if (attribute && !d->_attributes.contains(attribute->name()))
@@ -329,6 +331,7 @@ void QQuickPath::pathElements_clear(QQmlListProperty<QQuickPathElement> *propert
d->_pathElements.clear();
d->_pathCurves.clear();
d->_pointCache.clear();
+ d->_pathTexts.clear();
}
void QQuickPath::interpolate(int idx, const QString &name, qreal value)
@@ -478,6 +481,8 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en
point.values[percentString] = percent->value();
interpolate(attributePoints, attributePoints.count() - 1, percentString, percent->value());
usesPercent = true;
+ } else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement)) {
+ text->addToPath(path);
}
}
@@ -547,6 +552,9 @@ QPainterPath QQuickPath::createShapePath(const QPointF &startPoint, const QPoint
++index;
}
+ for (QQuickPathText *text : qAsConst(d->_pathTexts))
+ text->addToPath(path);
+
if (closed) {
QPointF end = path.currentPosition();
*closed = startX == end.x() && startY == end.y();
@@ -593,6 +601,8 @@ void QQuickPath::gatherAttributes()
for (QQuickPathElement *pathElement : qAsConst(d->_pathElements)) {
if (QQuickCurve *curve = qobject_cast<QQuickCurve *>(pathElement))
d->_pathCurves.append(curve);
+ else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement))
+ d->_pathTexts.append(text);
else if (QQuickPathAttribute *attribute = qobject_cast<QQuickPathAttribute *>(pathElement))
attributes.insert(attribute->name());
}
@@ -2415,7 +2425,7 @@ QVariant QQuickPathPolyline::path() const
void QQuickPathPolyline::setPath(const QVariant &path)
{
- if (path.type() == QVariant::PolygonF) {
+ if (path.userType() == QMetaType::QPolygonF) {
setPath(path.value<QPolygonF>());
} else if (path.canConvert<QVector<QPointF>>()) {
setPath(path.value<QVector<QPointF>>());
@@ -2431,7 +2441,7 @@ void QQuickPathPolyline::setPath(const QVariant &path)
pathList.append(v.toPointF());
setPath(pathList);
} else {
- qWarning() << "PathPolyline: path of type" << path.type() << "not supported";
+ qWarning() << "PathPolyline: path of type" << path.userType() << "not supported";
}
}
@@ -2583,7 +2593,7 @@ void QQuickPathMultiline::setPaths(const QVariant &paths)
}
setPaths(pathsList);
} else {
- qWarning() << "PathMultiline: paths of type" << paths.type() << "not supported";
+ qWarning() << "PathMultiline: paths of type" << paths.userType() << "not supported";
setPaths(QVector<QVector<QPointF>>());
}
}
@@ -2619,6 +2629,219 @@ void QQuickPathMultiline::addToPath(QPainterPath &path, const QQuickPathData &)
}
}
+/*!
+ \qmltype PathText
+ \instantiates QQuickPathText
+ \inqmlmodule QtQuick
+ \ingroup qtquick-animation-paths
+ \brief Defines a string in a specified font.
+ \since QtQuick 2.15
+
+ This element defines the shape of a specified string in a specified font. The text's
+ baseline will be translated to the x and y coordinates, and the outlines from the font
+ will be added to the path accordingly.
+
+ \qml
+ PathText {
+ x: 0
+ y: font.pixelSize
+ font.family: "Arial"
+ font.pixelSize: 100
+ text: "Foobar"
+ }
+ \endqml
+
+ \sa Path, QPainterPath::setFillRule, PathPolyline, PathQuad, PathCubic, PathArc, PathAngleArc, PathCurve, PathSvg, PathMove
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathText::x
+
+ The horizontal position of the PathText's baseline.
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathText::y
+
+ The vertical position of the PathText's baseline.
+
+ \note This property refers to the position of the baseline of the text, not the top of its bounding box. This may
+ cause some confusion, e.g. when using the PathText with Qt Quick Shapes. See \l FontMetrics for information on how to
+ get the ascent of a font, which can be used to translate the text into the expected position.
+*/
+
+/*!
+ \qmlproperty string QtQuick::PathText::text
+
+ The text for which this PathText should contain the outlines.
+*/
+
+/*!
+ \qmlproperty string QtQuick::PathText::font.family
+
+ Sets the family name of the font.
+
+ The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
+ If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
+ If the family isn't available a family will be set using the font matching algorithm.
+*/
+
+/*!
+ \qmlproperty string QtQuick::PathText::font.styleName
+
+ Sets the style name of the font.
+
+ The style name is case insensitive. If set, the font will be matched against style name instead
+ of the font properties \l font.weight, \l font.bold and \l font.italic.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.bold
+
+ Sets whether the font weight is bold.
+*/
+
+/*!
+ \qmlproperty enumeration QtQuick::PathText::font.weight
+
+ Sets the font's weight.
+
+ The weight can be one of:
+ \list
+ \li Font.Thin
+ \li Font.Light
+ \li Font.ExtraLight
+ \li Font.Normal - the default
+ \li Font.Medium
+ \li Font.DemiBold
+ \li Font.Bold
+ \li Font.ExtraBold
+ \li Font.Black
+ \endlist
+
+ \qml
+ PathText { text: "Hello"; font.weight: Font.DemiBold }
+ \endqml
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.italic
+
+ Sets whether the font has an italic style.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.underline
+
+ Sets whether the text is underlined.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.strikeout
+
+ Sets whether the font has a strikeout style.
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathText::font.pointSize
+
+ Sets the font size in points. The point size must be greater than zero.
+*/
+
+/*!
+ \qmlproperty int QtQuick::PathText::font.pixelSize
+
+ Sets the font size in pixels.
+
+ Using this function makes the font device dependent.
+ Use \c pointSize to set the size of the font in a device independent manner.
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathText::font.letterSpacing
+
+ Sets the letter spacing for the font.
+
+ Letter spacing changes the default spacing between individual letters in the font.
+ A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathText::font.wordSpacing
+
+ Sets the word spacing for the font.
+
+ Word spacing changes the default spacing between individual words.
+ A positive value increases the word spacing by a corresponding amount of pixels,
+ while a negative value decreases the inter-word spacing accordingly.
+*/
+
+/*!
+ \qmlproperty enumeration QtQuick::PathText::font.capitalization
+
+ Sets the capitalization for the text.
+
+ \list
+ \li Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
+ \li Font.AllUppercase - This alters the text to be rendered in all uppercase type.
+ \li Font.AllLowercase - This alters the text to be rendered in all lowercase type.
+ \li Font.SmallCaps - This alters the text to be rendered in small-caps type.
+ \li Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
+ \endlist
+
+ \qml
+ PathText { text: "Hello"; font.capitalization: Font.AllLowercase }
+ \endqml
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.kerning
+
+ Enables or disables the kerning OpenType feature when shaping the text. Disabling this may
+ improve performance when creating or changing the text, at the expense of some cosmetic
+ features. The default value is true.
+
+ \qml
+ PathText { text: "OATS FLAVOUR WAY"; font.kerning: false }
+ \endqml
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.preferShaping
+
+ Sometimes, a font will apply complex rules to a set of characters in order to
+ display them correctly. In some writing systems, such as Brahmic scripts, this is
+ required in order for the text to be legible, but in e.g. Latin script, it is merely
+ a cosmetic feature. Setting the \c preferShaping property to false will disable all
+ such features when they are not required, which will improve performance in most cases.
+
+ The default value is true.
+
+ \qml
+ PathText { text: "Some text"; font.preferShaping: false }
+ \endqml
+*/
+
+void QQuickPathText::updatePath() const
+{
+ if (!_path.isEmpty())
+ return;
+
+ _path.addText(0.0, 0.0, _font, _text);
+
+ // Account for distance from baseline to top, since addText() takes baseline position
+ QRectF brect = _path.boundingRect();
+ _path.translate(_x, _y - brect.y());
+}
+
+void QQuickPathText::addToPath(QPainterPath &path)
+{
+ if (_text.isEmpty())
+ return;
+ updatePath();
+ path.addPath(_path);
+}
+
QT_END_NAMESPACE
#include "moc_qquickpath_p.cpp"
diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h
index 5987ae8f35..159c46d13c 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -63,6 +63,7 @@ QT_REQUIRE_CONFIG(quick_path);
#include <QtCore/QObject>
#include <QtGui/QPainterPath>
+#include <QtGui/QFont>
QT_BEGIN_NAMESPACE
@@ -77,6 +78,7 @@ struct QQuickPathData
class Q_QUICK_PRIVATE_EXPORT QQuickPathElement : public QObject
{
Q_OBJECT
+ QML_ANONYMOUS
public:
QQuickPathElement(QObject *parent=nullptr) : QObject(parent) {}
Q_SIGNALS:
@@ -89,6 +91,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathAttribute : public QQuickPathElement
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
+ QML_NAMED_ELEMENT(PathAttribute)
public:
QQuickPathAttribute(QObject *parent=nullptr) : QQuickPathElement(parent) {}
@@ -116,6 +119,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickCurve : public QQuickPathElement
Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
Q_PROPERTY(qreal relativeX READ relativeX WRITE setRelativeX NOTIFY relativeXChanged)
Q_PROPERTY(qreal relativeY READ relativeY WRITE setRelativeY NOTIFY relativeYChanged)
+ QML_ANONYMOUS
public:
QQuickCurve(QObject *parent=nullptr) : QQuickPathElement(parent) {}
@@ -153,6 +157,7 @@ private:
class Q_QUICK_PRIVATE_EXPORT QQuickPathLine : public QQuickCurve
{
Q_OBJECT
+ QML_NAMED_ELEMENT(PathLine)
public:
QQuickPathLine(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -162,6 +167,8 @@ public:
class Q_QUICK_PRIVATE_EXPORT QQuickPathMove : public QQuickCurve
{
Q_OBJECT
+ QML_NAMED_ELEMENT(PathMove)
+ QML_ADDED_IN_MINOR_VERSION(9)
public:
QQuickPathMove(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -176,6 +183,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathQuad : public QQuickCurve
Q_PROPERTY(qreal controlY READ controlY WRITE setControlY NOTIFY controlYChanged)
Q_PROPERTY(qreal relativeControlX READ relativeControlX WRITE setRelativeControlX NOTIFY relativeControlXChanged)
Q_PROPERTY(qreal relativeControlY READ relativeControlY WRITE setRelativeControlY NOTIFY relativeControlYChanged)
+
+ QML_NAMED_ELEMENT(PathQuad)
public:
QQuickPathQuad(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -220,6 +229,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathCubic : public QQuickCurve
Q_PROPERTY(qreal relativeControl1Y READ relativeControl1Y WRITE setRelativeControl1Y NOTIFY relativeControl1YChanged)
Q_PROPERTY(qreal relativeControl2X READ relativeControl2X WRITE setRelativeControl2X NOTIFY relativeControl2XChanged)
Q_PROPERTY(qreal relativeControl2Y READ relativeControl2Y WRITE setRelativeControl2Y NOTIFY relativeControl2YChanged)
+ QML_NAMED_ELEMENT(PathCubic)
public:
QQuickPathCubic(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -277,6 +287,7 @@ private:
class Q_QUICK_PRIVATE_EXPORT QQuickPathCatmullRomCurve : public QQuickCurve
{
Q_OBJECT
+ QML_NAMED_ELEMENT(PathCurve)
public:
QQuickPathCatmullRomCurve(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -291,6 +302,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathArc : public QQuickCurve
Q_PROPERTY(bool useLargeArc READ useLargeArc WRITE setUseLargeArc NOTIFY useLargeArcChanged)
Q_PROPERTY(ArcDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION 9)
+ QML_NAMED_ELEMENT(PathArc)
public:
QQuickPathArc(QObject *parent=nullptr)
@@ -342,6 +354,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathAngleArc : public QQuickCurve
Q_PROPERTY(qreal sweepAngle READ sweepAngle WRITE setSweepAngle NOTIFY sweepAngleChanged)
Q_PROPERTY(bool moveToStart READ moveToStart WRITE setMoveToStart NOTIFY moveToStartChanged)
+ QML_NAMED_ELEMENT(PathAngleArc)
+ QML_ADDED_IN_MINOR_VERSION(11)
+
public:
QQuickPathAngleArc(QObject *parent=nullptr)
: QQuickCurve(parent) {}
@@ -392,6 +407,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathSvg : public QQuickCurve
{
Q_OBJECT
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
+ QML_NAMED_ELEMENT(PathSvg)
public:
QQuickPathSvg(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -411,6 +427,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPercent : public QQuickPathElement
{
Q_OBJECT
Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
+ QML_NAMED_ELEMENT(PathPercent)
public:
QQuickPathPercent(QObject *parent=nullptr) : QQuickPathElement(parent) {}
@@ -429,6 +446,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPolyline : public QQuickCurve
Q_OBJECT
Q_PROPERTY(QPointF start READ start NOTIFY startChanged)
Q_PROPERTY(QVariant path READ path WRITE setPath NOTIFY pathChanged)
+ QML_NAMED_ELEMENT(PathPolyline)
+ QML_ADDED_IN_MINOR_VERSION(14)
public:
QQuickPathPolyline(QObject *parent=nullptr);
@@ -451,6 +470,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathMultiline : public QQuickCurve
Q_OBJECT
Q_PROPERTY(QPointF start READ start NOTIFY startChanged)
Q_PROPERTY(QVariant paths READ paths WRITE setPaths NOTIFY pathsChanged)
+ QML_NAMED_ELEMENT(PathMultiline)
+ QML_ADDED_IN_MINOR_VERSION(14)
public:
QQuickPathMultiline(QObject *parent=nullptr);
@@ -493,6 +514,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPath : public QObject, public QQmlParserStatu
Q_PROPERTY(bool closed READ isClosed NOTIFY changed)
Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION 14)
Q_CLASSINFO("DefaultProperty", "pathElements")
+ QML_NAMED_ELEMENT(Path)
Q_INTERFACES(QQmlParserStatus)
public:
QQuickPath(QObject *parent=nullptr);
@@ -577,6 +599,106 @@ public:
static QPointF sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr);
};
+class Q_QUICK_PRIVATE_EXPORT QQuickPathText : public QQuickPathElement
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
+ Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
+ Q_PROPERTY(qreal width READ width NOTIFY changed)
+ Q_PROPERTY(qreal height READ height NOTIFY changed)
+ Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+ Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
+ QML_NAMED_ELEMENT(PathText)
+ QML_ADDED_IN_MINOR_VERSION(15)
+public:
+ QQuickPathText(QObject *parent=nullptr) : QQuickPathElement(parent)
+ {
+ connect(this, &QQuickPathText::xChanged, this, &QQuickPathElement::changed);
+ connect(this, &QQuickPathText::yChanged, this, &QQuickPathElement::changed);
+ connect(this, &QQuickPathText::textChanged, this, &QQuickPathElement::changed);
+ connect(this, &QQuickPathText::fontChanged, this, &QQuickPathElement::changed);
+
+ connect(this, &QQuickPathElement::changed, this, &QQuickPathText::invalidate);
+ }
+
+ void addToPath(QPainterPath &path);
+
+ qreal x() const { return _x; }
+ qreal y() const { return _y; }
+ QString text() const { return _text; }
+ QFont font() const { return _font; }
+
+ void setX(qreal x)
+ {
+ if (qFuzzyCompare(_x, x))
+ return;
+
+ _x = x;
+ Q_EMIT xChanged();
+ }
+
+ void setY(qreal y)
+ {
+ if (qFuzzyCompare(_y, y))
+ return;
+
+ _y = y;
+ Q_EMIT yChanged();
+ }
+
+ void setText(const QString &text)
+ {
+ if (text == _text)
+ return;
+
+ _text = text;
+ Q_EMIT textChanged();
+ }
+
+ void setFont(const QFont &font)
+ {
+ if (font == _font)
+ return;
+
+ _font = font;
+ Q_EMIT fontChanged();
+ }
+
+ qreal width() const
+ {
+ updatePath();
+ return _path.boundingRect().width();
+ }
+
+ qreal height() const
+ {
+ updatePath();
+ return _path.boundingRect().height();
+ }
+
+Q_SIGNALS:
+ void xChanged();
+ void yChanged();
+ void textChanged();
+ void fontChanged();
+
+private Q_SLOTS:
+ void invalidate()
+ {
+ _path.clear();
+ }
+
+private:
+ void updatePath() const;
+
+ QString _text;
+ qreal _x = qreal(0.0);
+ qreal _y = qreal(0.0);
+ QFont _font;
+
+ mutable QPainterPath _path;
+};
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickPathElement)
@@ -593,5 +715,6 @@ QML_DECLARE_TYPE(QQuickPathSvg)
QML_DECLARE_TYPE(QQuickPathPercent)
QML_DECLARE_TYPE(QQuickPathPolyline)
QML_DECLARE_TYPE(QQuickPath)
+QML_DECLARE_TYPE(QQuickPathText)
#endif // QQUICKPATH_H
diff --git a/src/quick/util/qquickpath_p_p.h b/src/quick/util/qquickpath_p_p.h
index e26001ec77..5505b876c1 100644
--- a/src/quick/util/qquickpath_p_p.h
+++ b/src/quick/util/qquickpath_p_p.h
@@ -80,6 +80,7 @@ public:
QList<QQuickPath::AttributePoint> _attributePoints;
QStringList _attributes;
QList<QQuickCurve*> _pathCurves;
+ QList<QQuickPathText*> _pathTexts;
mutable QQuickCachedBezier prevBez;
QQmlNullableValue<qreal> startX;
QQmlNullableValue<qreal> startY;
diff --git a/src/quick/util/qquickpathinterpolator_p.h b/src/quick/util/qquickpathinterpolator_p.h
index 60a9ff2e22..440ea06841 100644
--- a/src/quick/util/qquickpathinterpolator_p.h
+++ b/src/quick/util/qquickpathinterpolator_p.h
@@ -69,6 +69,7 @@ class Q_AUTOTEST_EXPORT QQuickPathInterpolator : public QObject
Q_PROPERTY(qreal x READ x NOTIFY xChanged)
Q_PROPERTY(qreal y READ y NOTIFY yChanged)
Q_PROPERTY(qreal angle READ angle NOTIFY angleChanged)
+ QML_NAMED_ELEMENT(PathInterpolator)
public:
explicit QQuickPathInterpolator(QObject *parent = nullptr);
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index e1b30f2b2c..d96ebe70b2 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -86,6 +86,8 @@ QT_BEGIN_NAMESPACE
const QLatin1String QQuickPixmap::itemGrabberScheme = QLatin1String("itemgrabber");
+Q_LOGGING_CATEGORY(lcImg, "qt.quick.image")
+
#ifndef QT_NO_DEBUG
static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK");
#endif
@@ -137,6 +139,7 @@ public:
QQuickPixmapData *data;
QQmlEngine *engineForReader; // always access reader inside readerMutex
+ QRect requestRegion;
QSize requestSize;
QUrl url;
@@ -240,9 +243,10 @@ public:
class QQuickPixmapData
{
public:
- QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &s, const QQuickImageProviderOptions &po, const QString &e)
+ QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QRect &r, const QSize &rs,
+ const QQuickImageProviderOptions &po, const QString &e)
: refCount(1), frameCount(1), frame(0), inCache(false), pixmapStatus(QQuickPixmap::Error),
- url(u), errorString(e), requestSize(s),
+ url(u), errorString(e), requestRegion(r), requestSize(rs),
providerOptions(po), appliedTransform(QQuickImageProviderOptions::UsePluginDefaultTransform),
textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr),
prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr)
@@ -250,9 +254,10 @@ public:
declarativePixmaps.insert(pixmap);
}
- QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
+ QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QRect &r, const QSize &s, const QQuickImageProviderOptions &po,
+ QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
: refCount(1), frameCount(frameCount), frame(frame), inCache(false), pixmapStatus(QQuickPixmap::Loading),
- url(u), requestSize(r),
+ url(u), requestRegion(r), requestSize(s),
providerOptions(po), appliedTransform(aTransform),
textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr), prevUnreferencedPtr(nullptr),
nextUnreferenced(nullptr)
@@ -261,9 +266,10 @@ public:
}
QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *texture,
- const QSize &s, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
+ const QSize &s, const QRect &r, const QSize &rs, const QQuickImageProviderOptions &po,
+ QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
: refCount(1), frameCount(frameCount), frame(frame), inCache(false), pixmapStatus(QQuickPixmap::Ready),
- url(u), implicitSize(s), requestSize(r),
+ url(u), implicitSize(s), requestRegion(r), requestSize(rs),
providerOptions(po), appliedTransform(aTransform),
textureFactory(texture), reply(nullptr), prevUnreferenced(nullptr),
prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr)
@@ -308,9 +314,11 @@ public:
QUrl url;
QString errorString;
QSize implicitSize;
+ QRect requestRegion;
QSize requestSize;
QQuickImageProviderOptions providerOptions;
QQuickImageProviderOptions::AutoTransform appliedTransform;
+ QColorSpace targetColorSpace;
QQuickTextureFactory *textureFactory;
@@ -399,7 +407,7 @@ static void maybeRemoveAlpha(QImage *image)
}
static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize, int *frameCount,
- const QSize &requestSize, const QQuickImageProviderOptions &providerOptions,
+ const QRect &requestRegion, const QSize &requestSize, const QQuickImageProviderOptions &providerOptions,
QQuickImageProviderOptions::AutoTransform *appliedTransform = nullptr, int frame = 0)
{
QImageReader imgio(dev);
@@ -417,14 +425,25 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e
QSize scSize = QQuickImageProviderWithOptions::loadSize(imgio.size(), requestSize, imgio.format(), providerOptions);
if (scSize.isValid())
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" << originalSize << "-> scSize" << scSize;
if (impsize)
- *impsize = imgio.size();
+ *impsize = originalSize;
if (imgio.read(image)) {
maybeRemoveAlpha(image);
if (impsize && impsize->width() < 0)
*impsize = image->size();
+ if (providerOptions.targetColorSpace().isValid()) {
+ if (image->colorSpace().isValid())
+ image->convertToColorSpace(providerOptions.targetColorSpace());
+ else
+ image->setColorSpace(providerOptions.targetColorSpace());
+ }
return true;
} else {
if (errorString)
@@ -568,7 +587,8 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
buff.open(QIODevice::ReadOnly);
int frameCount;
int const frame = job->data ? job->data->frame : 0;
- if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, &frameCount, job->requestSize, job->providerOptions, nullptr, frame))
+ if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, &frameCount,
+ job->requestRegion, job->requestSize, job->providerOptions, nullptr, frame))
error = QQuickPixmapReply::Decoding;
else if (job->data)
job->data->frameCount = frameCount;
@@ -884,7 +904,8 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
} else {
int frameCount;
int const frame = runningJob->data ? runningJob->data->frame : 0;
- if ( !readImage(url, &f, &image, &errorStr, &readSize, &frameCount, runningJob->requestSize, runningJob->providerOptions, nullptr, frame)) {
+ if (!readImage(url, &f, &image, &errorStr, &readSize, &frameCount, runningJob->requestRegion, runningJob->requestSize,
+ runningJob->providerOptions, nullptr, frame)) {
errorCode = QQuickPixmapReply::Loading;
if (f.fileName() != localFile)
errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
@@ -997,6 +1018,7 @@ class QQuickPixmapKey
{
public:
const QUrl *url;
+ const QRect *region;
const QSize *size;
int frame;
QQuickImageProviderOptions options;
@@ -1004,12 +1026,20 @@ public:
inline bool operator==(const QQuickPixmapKey &lhs, const QQuickPixmapKey &rhs)
{
- return *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)
{
- return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.frame*23) ^ (key.options.autoTransform() * 0x5c5c5c5c);
+ return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.frame*23) ^
+ (key.region->x()*29) ^ (key.region->y()*31) ^ (key.options.autoTransform() * 0x5c5c5c5c);
+ // key.region.width() and height() are not included, because the hash function should be simple,
+ // and they are more likely to be held constant for some batches of images
+ // (e.g. tiles, or repeatedly cropping to the same viewport at different positions).
}
class QQuickPixmapStore : public QObject
@@ -1176,7 +1206,8 @@ void QQuickPixmap::purgeCache()
}
QQuickPixmapReply::QQuickPixmapReply(QQuickPixmapData *d)
-: data(d), engineForReader(nullptr), requestSize(d->requestSize), url(d->url), loading(false), providerOptions(d->providerOptions), redirectCount(0)
+ : data(d), engineForReader(nullptr), requestRegion(d->requestRegion), requestSize(d->requestSize),
+ url(d->url), loading(false), providerOptions(d->providerOptions), redirectCount(0)
{
if (finishedIndex == -1) {
finishedIndex = QMetaMethod::fromSignal(&QQuickPixmapReply::finished).methodIndex();
@@ -1271,7 +1302,7 @@ void QQuickPixmapData::release()
void QQuickPixmapData::addToCache()
{
if (!inCache) {
- QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
+ QQuickPixmapKey key = { &url, &requestRegion, &requestSize, frame, providerOptions };
pixmapStore()->m_cache.insert(key, this);
inCache = true;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
@@ -1282,7 +1313,7 @@ void QQuickPixmapData::addToCache()
void QQuickPixmapData::removeFromCache()
{
if (inCache) {
- QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
+ QQuickPixmapKey key = { &url, &requestRegion, &requestSize, frame, providerOptions };
pixmapStore()->m_cache.remove(key);
inCache = false;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
@@ -1290,7 +1321,9 @@ void QQuickPixmapData::removeFromCache()
}
}
-static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &providerOptions, int frame, bool *ok)
+static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url,
+ const QRect &requestRegion, const QSize &requestSize,
+ const QQuickImageProviderOptions &providerOptions, int frame, bool *ok)
{
if (url.scheme() == QLatin1String("image")) {
QSize readSize;
@@ -1305,7 +1338,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
switch (imageType) {
case QQuickImageProvider::Invalid:
- return new QQuickPixmapData(declarativePixmap, url, requestSize, providerOptions,
+ return new QQuickPixmapData(declarativePixmap, url, requestRegion, requestSize, providerOptions,
QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString()));
case QQuickImageProvider::Texture:
{
@@ -1313,7 +1346,8 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestTexture(imageId(url), &readSize, requestSize);
if (texture) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
+ return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestRegion, requestSize,
+ providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1324,7 +1358,9 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestImage(imageId(url), &readSize, requestSize);
if (!image.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image),
+ readSize, requestRegion, requestSize, providerOptions,
+ QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1334,7 +1370,9 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestPixmap(imageId(url), &readSize, requestSize);
if (!pixmap.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()),
+ readSize, requestRegion, requestSize, providerOptions,
+ QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1346,7 +1384,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
}
// provider has bad image type, or provider returned null image
- return new QQuickPixmapData(declarativePixmap, url, requestSize, providerOptions,
+ return new QQuickPixmapData(declarativePixmap, url, requestRegion, requestSize, providerOptions,
QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString()));
}
@@ -1364,7 +1402,8 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QQuickTextureFactory *factory = texReader.read();
if (factory) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
+ return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestRegion, requestSize,
+ providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
} else {
errorString = QQuickPixmap::tr("Error decoding: %1").arg(url.toString());
if (f.fileName() != localFile)
@@ -1374,9 +1413,10 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QImage image;
QQuickImageProviderOptions::AutoTransform appliedTransform = providerOptions.autoTransform();
int frameCount;
- if (readImage(url, &f, &image, &errorString, &readSize, &frameCount, requestSize, providerOptions, &appliedTransform, frame)) {
+ if (readImage(url, &f, &image, &errorString, &readSize, &frameCount, requestRegion, requestSize, providerOptions, &appliedTransform, frame)) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, appliedTransform, frame, frameCount);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestRegion, requestSize,
+ providerOptions, appliedTransform, frame, frameCount);
} else if (f.fileName() != localFile) {
errorString += QString::fromLatin1(" (%1)").arg(f.fileName());
}
@@ -1384,12 +1424,13 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
} else {
errorString = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
}
- return new QQuickPixmapData(declarativePixmap, url, requestSize, providerOptions, errorString);
+ return new QQuickPixmapData(declarativePixmap, url, requestRegion, requestSize, providerOptions, errorString);
}
struct QQuickPixmapNull {
QUrl url;
+ QRect region;
QSize size;
};
Q_GLOBAL_STATIC(QQuickPixmapNull, nullPixmap);
@@ -1405,15 +1446,16 @@ QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url)
load(engine, url);
}
-QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url, const QSize &size)
+QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url, const QRect &region, const QSize &size)
: d(nullptr)
{
- load(engine, url, size);
+ load(engine, url, region, size);
}
QQuickPixmap::QQuickPixmap(const QUrl &url, const QImage &image)
{
- d = new QQuickPixmapData(this, url, new QQuickDefaultTextureFactory(image), image.size(), QSize(), QQuickImageProviderOptions(), QQuickImageProviderOptions::UsePluginDefaultTransform);
+ d = new QQuickPixmapData(this, url, new QQuickDefaultTextureFactory(image), image.size(), QRect(), QSize(),
+ QQuickImageProviderOptions(), QQuickImageProviderOptions::UsePluginDefaultTransform);
d->addToCache();
}
@@ -1486,6 +1528,14 @@ const QSize &QQuickPixmap::requestSize() const
return nullPixmap()->size;
}
+const QRect &QQuickPixmap::requestRegion() const
+{
+ if (d)
+ return d->requestRegion;
+ else
+ return nullPixmap()->region;
+}
+
QQuickImageProviderOptions::AutoTransform QQuickPixmap::autoTransform() const
{
if (d)
@@ -1561,25 +1611,26 @@ QRect QQuickPixmap::rect() const
void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url)
{
- load(engine, url, QSize(), QQuickPixmap::Cache);
+ load(engine, url, QRect(), QSize(), QQuickPixmap::Cache);
}
void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, QQuickPixmap::Options options)
{
- load(engine, url, QSize(), options);
+ load(engine, url, QRect(), QSize(), options);
}
-void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &size)
+void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QRect &requestRegion, const QSize &requestSize)
{
- load(engine, url, size, QQuickPixmap::Cache);
+ load(engine, url, requestRegion, requestSize, QQuickPixmap::Cache);
}
-void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options)
+void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QRect &requestRegion, const QSize &requestSize, QQuickPixmap::Options options)
{
- load(engine, url, requestSize, options, QQuickImageProviderOptions());
+ load(engine, url, requestRegion, requestSize, options, QQuickImageProviderOptions());
}
-void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame, int frameCount)
+void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QRect &requestRegion, const QSize &requestSize,
+ QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame, int frameCount)
{
if (d) {
d->declarativePixmaps.remove(this);
@@ -1587,7 +1638,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
d = nullptr;
}
- QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
+ QQuickPixmapKey key = { &url, &requestRegion, &requestSize, frame, providerOptions };
QQuickPixmapStore *store = pixmapStore();
QHash<QQuickPixmapKey, QQuickPixmapData *>::Iterator iter = store->m_cache.end();
@@ -1596,10 +1647,11 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
// cached version. Unless it's an itemgrabber url, since the cache is used to pass
// the result between QQuickItemGrabResult and QQuickImage.
if (url.scheme() == itemGrabberScheme) {
- QSize dummy;
- if (requestSize != dummy)
+ QRect dummyRegion;
+ QSize dummySize;
+ if (requestSize != dummySize)
qWarning() << "Ignoring sourceSize request for image url that came from grabToImage. Use the targetSize parameter of the grabToImage() function instead.";
- const QQuickPixmapKey grabberKey = { &url, &dummy, 0, QQuickImageProviderOptions() };
+ const QQuickPixmapKey grabberKey = { &url, &dummyRegion, &dummySize, 0, QQuickImageProviderOptions() };
iter = store->m_cache.find(grabberKey);
} else if (options & QQuickPixmap::Cache)
iter = store->m_cache.find(key);
@@ -1621,7 +1673,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
if (!(options & QQuickPixmap::Asynchronous)) {
bool ok = false;
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
- d = createPixmapDataSync(this, engine, url, requestSize, providerOptions, frame, &ok);
+ d = createPixmapDataSync(this, engine, url, requestRegion, requestSize, providerOptions, frame, &ok);
if (ok) {
PIXMAP_PROFILE(pixmapLoadingFinished(url, QSize(width(), height())));
if (options & QQuickPixmap::Cache)
@@ -1638,7 +1690,8 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
return;
- d = new QQuickPixmapData(this, url, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame, frameCount);
+ d = new QQuickPixmapData(this, url, requestRegion, requestSize, providerOptions,
+ QQuickImageProviderOptions::UsePluginDefaultTransform, frame, frameCount);
if (options & QQuickPixmap::Cache)
d->addToCache();
@@ -1672,9 +1725,10 @@ void QQuickPixmap::clear(QObject *obj)
}
}
-bool QQuickPixmap::isCached(const QUrl &url, const QSize &requestSize, const int frame, const QQuickImageProviderOptions &options)
+bool QQuickPixmap::isCached(const QUrl &url, const QRect &requestRegion, const QSize &requestSize,
+ const int frame, const QQuickImageProviderOptions &options)
{
- QQuickPixmapKey key = { &url, &requestSize, frame, options };
+ QQuickPixmapKey key = { &url, &requestRegion, &requestSize, frame, options };
QQuickPixmapStore *store = pixmapStore();
return store->m_cache.contains(key);
@@ -1720,6 +1774,13 @@ bool QQuickPixmap::connectDownloadProgress(QObject *object, int method)
return QMetaObject::connect(d->reply, QQuickPixmapReply::downloadProgressIndex, object, method);
}
+QColorSpace QQuickPixmap::colorSpace() const
+{
+ if (!d || !d->textureFactory)
+ return QColorSpace();
+ return d->textureFactory->image().colorSpace();
+}
+
QT_END_NAMESPACE
#include <qquickpixmapcache.moc>
diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h
index ab5d391fa2..93dec63e94 100644
--- a/src/quick/util/qquickpixmapcache_p.h
+++ b/src/quick/util/qquickpixmapcache_p.h
@@ -117,6 +117,9 @@ public:
bool preserveAspectRatioFit() const;
void setPreserveAspectRatioFit(bool preserveAspectRatioFit);
+ QColorSpace targetColorSpace() const;
+ void setTargetColorSpace(const QColorSpace &colorSpace);
+
private:
QSharedDataPointer<QQuickImageProviderOptionsPrivate> d;
};
@@ -127,7 +130,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPixmap
public:
QQuickPixmap();
QQuickPixmap(QQmlEngine *, const QUrl &);
- QQuickPixmap(QQmlEngine *, const QUrl &, const QSize &);
+ QQuickPixmap(QQmlEngine *, const QUrl &, const QRect &region, const QSize &);
QQuickPixmap(const QUrl &, const QImage &image);
~QQuickPixmap();
@@ -148,6 +151,7 @@ public:
QString error() const;
const QUrl &url() const;
const QSize &implicitSize() const;
+ const QRect &requestRegion() const;
const QSize &requestSize() const;
QQuickImageProviderOptions::AutoTransform autoTransform() const;
int frameCount() const;
@@ -155,6 +159,8 @@ public:
void setImage(const QImage &);
void setPixmap(const QQuickPixmap &other);
+ QColorSpace colorSpace() const;
+
QQuickTextureFactory *textureFactory() const;
QRect rect() const;
@@ -163,9 +169,10 @@ public:
void load(QQmlEngine *, const QUrl &);
void load(QQmlEngine *, const QUrl &, QQuickPixmap::Options options);
- void load(QQmlEngine *, const QUrl &, const QSize &);
- void load(QQmlEngine *, const QUrl &, const QSize &, QQuickPixmap::Options options);
- void load(QQmlEngine *, const QUrl &, const QSize &, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame = 0, int frameCount = 1);
+ void load(QQmlEngine *, const QUrl &, const QRect &requestRegion, const QSize &requestSize);
+ void load(QQmlEngine *, const QUrl &, const QRect &requestRegion, const QSize &requestSize, QQuickPixmap::Options options);
+ void load(QQmlEngine *, const QUrl &, const QRect &requestRegion, const QSize &requestSize,
+ QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame = 0, int frameCount = 1);
void clear();
void clear(QObject *);
@@ -176,7 +183,8 @@ public:
bool connectDownloadProgress(QObject *, int);
static void purgeCache();
- static bool isCached(const QUrl &url, const QSize &requestSize, const int frame, const QQuickImageProviderOptions &options);
+ static bool isCached(const QUrl &url, const QRect &requestRegion, const QSize &requestSize,
+ const int frame, const QQuickImageProviderOptions &options);
static const QLatin1String itemGrabberScheme;
diff --git a/src/quick/util/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h
index 82a6ebffac..27a00420af 100644
--- a/src/quick/util/qquickpropertychanges_p.h
+++ b/src/quick/util/qquickpropertychanges_p.h
@@ -65,6 +65,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPropertyChanges : public QQuickStateOperation
Q_PROPERTY(QObject *target READ object WRITE setObject)
Q_PROPERTY(bool restoreEntryValues READ restoreEntryValues WRITE setRestoreEntryValues)
Q_PROPERTY(bool explicit READ isExplicit WRITE setIsExplicit)
+ QML_NAMED_ELEMENT(PropertyChanges)
+
public:
QQuickPropertyChanges();
~QQuickPropertyChanges();
@@ -107,6 +109,11 @@ public:
void applyBindings(QObject *obj, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
};
+template<>
+inline QQmlCustomParser *qmlCreateCustomParser<QQuickPropertyChanges>()
+{
+ return new QQuickPropertyChangesParser;
+}
QT_END_NAMESPACE
diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp
index 5d227b4613..8e135b4624 100644
--- a/src/quick/util/qquickshortcut.cpp
+++ b/src/quick/util/qquickshortcut.cpp
@@ -80,16 +80,12 @@
/*! \qmlsignal QtQuick::Shortcut::activated()
This signal is emitted when the shortcut is activated.
-
- The corresponding handler is \c onActivated.
*/
/*! \qmlsignal QtQuick::Shortcut::activatedAmbiguously()
This signal is emitted when the shortcut is activated ambigously,
meaning that it matches the start of more than one shortcut.
-
- The corresponding handler is \c onActivatedAmbiguously.
*/
static bool qQuickShortcutContextMatcher(QObject *obj, Qt::ShortcutContext context)
@@ -130,7 +126,7 @@ QT_BEGIN_NAMESPACE
static QKeySequence valueToKeySequence(const QVariant &value)
{
- if (value.type() == QVariant::Int)
+ if (value.userType() == QMetaType::Int)
return QKeySequence(static_cast<QKeySequence::StandardKey>(value.toInt()));
return QKeySequence::fromString(value.toString());
}
diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h
index 712cca7696..0e66a38e75 100644
--- a/src/quick/util/qquickshortcut_p.h
+++ b/src/quick/util/qquickshortcut_p.h
@@ -56,6 +56,7 @@
#include <QtCore/qvariant.h>
#include <QtGui/qkeysequence.h>
#include <QtQml/qqmlparserstatus.h>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -72,6 +73,8 @@ class QQuickShortcut : public QObject, public QQmlParserStatus
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL)
Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY autoRepeatChanged FINAL)
Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext NOTIFY contextChanged FINAL)
+ QML_NAMED_ELEMENT(Shortcut)
+ QML_ADDED_IN_MINOR_VERSION(5)
public:
explicit QQuickShortcut(QObject *parent = nullptr);
diff --git a/src/quick/util/qquicksmoothedanimation.cpp b/src/quick/util/qquicksmoothedanimation.cpp
index bae57172d1..254b1af0a2 100644
--- a/src/quick/util/qquicksmoothedanimation.cpp
+++ b/src/quick/util/qquicksmoothedanimation.cpp
@@ -313,7 +313,7 @@ void QSmoothedAnimation::init()
void QSmoothedAnimation::debugAnimation(QDebug d) const
{
- d << "SmoothedAnimationJob(" << hex << (const void *) this << dec << ")" << "duration:" << userDuration
+ d << "SmoothedAnimationJob(" << Qt::hex << (const void *) this << Qt::dec << ")" << "duration:" << userDuration
<< "velocity:" << velocity << "target:" << target.object() << "property:" << target.name()
<< "to:" << to << "current velocity:" << trackVelocity;
}
diff --git a/src/quick/util/qquicksmoothedanimation_p.h b/src/quick/util/qquicksmoothedanimation_p.h
index 7bceba387c..d7e637446d 100644
--- a/src/quick/util/qquicksmoothedanimation_p.h
+++ b/src/quick/util/qquicksmoothedanimation_p.h
@@ -68,6 +68,7 @@ class Q_AUTOTEST_EXPORT QQuickSmoothedAnimation : public QQuickNumberAnimation
Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged)
Q_PROPERTY(ReversingMode reversingMode READ reversingMode WRITE setReversingMode NOTIFY reversingModeChanged)
Q_PROPERTY(qreal maximumEasingTime READ maximumEasingTime WRITE setMaximumEasingTime NOTIFY maximumEasingTimeChanged)
+ QML_NAMED_ELEMENT(SmoothedAnimation)
public:
enum ReversingMode { Eased, Immediate, Sync };
diff --git a/src/quick/util/qquickspringanimation.cpp b/src/quick/util/qquickspringanimation.cpp
index 9012d20f9a..6f03d24750 100644
--- a/src/quick/util/qquickspringanimation.cpp
+++ b/src/quick/util/qquickspringanimation.cpp
@@ -319,7 +319,7 @@ void QSpringAnimation::updateState(QAbstractAnimationJob::State newState, QAbstr
void QSpringAnimation::debugAnimation(QDebug d) const
{
- d << "SpringAnimationJob(" << hex << (const void *) this << dec << ")" << "velocity:" << maxVelocity
+ d << "SpringAnimationJob(" << Qt::hex << (const void *) this << Qt::dec << ")" << "velocity:" << maxVelocity
<< "spring:" << spring << "damping:" << damping << "epsilon:" << epsilon << "modulus:" << modulus
<< "mass:" << mass << "target:" << target.object() << "property:" << target.name()
<< "to:" << to << "current velocity:" << velocity;
diff --git a/src/quick/util/qquickspringanimation_p.h b/src/quick/util/qquickspringanimation_p.h
index 2014a4311a..771b746622 100644
--- a/src/quick/util/qquickspringanimation_p.h
+++ b/src/quick/util/qquickspringanimation_p.h
@@ -71,6 +71,7 @@ class Q_AUTOTEST_EXPORT QQuickSpringAnimation : public QQuickNumberAnimation
Q_PROPERTY(qreal epsilon READ epsilon WRITE setEpsilon)
Q_PROPERTY(qreal modulus READ modulus WRITE setModulus NOTIFY modulusChanged)
Q_PROPERTY(qreal mass READ mass WRITE setMass NOTIFY massChanged)
+ QML_NAMED_ELEMENT(SpringAnimation)
public:
QQuickSpringAnimation(QObject *parent=nullptr);
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.h b/src/quick/util/qquickstate_p.h
index 576ba9834c..af49bb1c2f 100644
--- a/src/quick/util/qquickstate_p.h
+++ b/src/quick/util/qquickstate_p.h
@@ -125,6 +125,7 @@ class QQuickStateOperationPrivate;
class Q_QUICK_PRIVATE_EXPORT QQuickStateOperation : public QObject
{
Q_OBJECT
+ QML_ANONYMOUS
public:
QQuickStateOperation(QObject *parent = nullptr)
: QObject(parent) {}
@@ -157,6 +158,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickState : public QObject
Q_PROPERTY(QQmlListProperty<QQuickStateOperation> changes READ changes)
Q_CLASSINFO("DefaultProperty", "changes")
Q_CLASSINFO("DeferredPropertyNames", "changes")
+ QML_NAMED_ELEMENT(State)
public:
QQuickState(QObject *parent=nullptr);
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/qquickstatechangescript_p.h b/src/quick/util/qquickstatechangescript_p.h
index ff509a7cf5..931baaca4e 100644
--- a/src/quick/util/qquickstatechangescript_p.h
+++ b/src/quick/util/qquickstatechangescript_p.h
@@ -64,6 +64,7 @@ class Q_AUTOTEST_EXPORT QQuickStateChangeScript : public QQuickStateOperation, p
Q_PROPERTY(QQmlScriptString script READ script WRITE setScript)
Q_PROPERTY(QString name READ name WRITE setName)
+ QML_NAMED_ELEMENT(StateChangeScript)
public:
QQuickStateChangeScript(QObject *parent=nullptr);
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/qquickstategroup_p.h b/src/quick/util/qquickstategroup_p.h
index 7235066d99..11a0c5f442 100644
--- a/src/quick/util/qquickstategroup_p.h
+++ b/src/quick/util/qquickstategroup_p.h
@@ -65,6 +65,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStateGroup : public QObject, public QQmlParse
Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged)
Q_PROPERTY(QQmlListProperty<QQuickState> states READ statesProperty DESIGNABLE false)
Q_PROPERTY(QQmlListProperty<QQuickTransition> transitions READ transitionsProperty DESIGNABLE false)
+ QML_NAMED_ELEMENT(StateGroup)
public:
QQuickStateGroup(QObject * = nullptr);
diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp
index 7d545cdb2f..660852ba83 100644
--- a/src/quick/util/qquickstyledtext.cpp
+++ b/src/quick/util/qquickstyledtext.cpp
@@ -89,8 +89,8 @@ public:
QQmlContext *context,
bool preloadImages,
bool *fontSizeModified)
- : text(t), layout(l), imgTags(&imgTags), baseFont(layout.font()), baseUrl(baseUrl), hasNewLine(true), nbImages(0), updateImagePositions(false)
- , preFormat(false), prependSpace(false), hasSpace(true), preloadImages(preloadImages), fontSizeModified(fontSizeModified), context(context)
+ : text(t), layout(l), imgTags(&imgTags), baseFont(layout.font()), baseUrl(baseUrl),
+ fontSizeModified(fontSizeModified), context(context), preloadImages(preloadImages)
{
}
@@ -122,15 +122,15 @@ public:
QFont baseFont;
QStack<List> listStack;
QUrl baseUrl;
- bool hasNewLine;
- int nbImages;
- bool updateImagePositions;
- bool preFormat;
- bool prependSpace;
- bool hasSpace;
- bool preloadImages;
bool *fontSizeModified;
QQmlContext *context;
+ int nbImages = 0;
+ bool hasNewLine = true;
+ bool updateImagePositions = false;
+ bool preFormat = false;
+ bool prependSpace = false;
+ bool hasSpace = true;
+ bool preloadImages;
static const QChar lessThan;
static const QChar greaterThan;
@@ -706,7 +706,7 @@ void QQuickStyledTextPrivate::parseImageAttributes(const QChar *&ch, const QStri
// to avoid a relayout later on.
QUrl url = baseUrl.resolved(image->url);
if (url.isLocalFile()) {
- image->pix = new QQuickPixmap(context->engine(), url, image->size);
+ image->pix = new QQuickPixmap(context->engine(), url, QRect(), image->size);
if (image->pix && image->pix->isReady()) {
image->size = image->pix->implicitSize();
} else {
diff --git a/src/quick/util/qquicksystempalette_p.h b/src/quick/util/qquicksystempalette_p.h
index 9a3a520ed1..c6d9fc2604 100644
--- a/src/quick/util/qquicksystempalette_p.h
+++ b/src/quick/util/qquicksystempalette_p.h
@@ -79,6 +79,7 @@ class Q_AUTOTEST_EXPORT QQuickSystemPalette : public QObject
Q_PROPERTY(QColor shadow READ shadow NOTIFY paletteChanged)
Q_PROPERTY(QColor highlight READ highlight NOTIFY paletteChanged)
Q_PROPERTY(QColor highlightedText READ highlightedText NOTIFY paletteChanged)
+ QML_NAMED_ELEMENT(SystemPalette)
public:
QQuickSystemPalette(QObject *parent=nullptr);
diff --git a/src/quick/util/qquicktextmetrics_p.h b/src/quick/util/qquicktextmetrics_p.h
index 4fb6741996..a1d64e3d0a 100644
--- a/src/quick/util/qquicktextmetrics_p.h
+++ b/src/quick/util/qquicktextmetrics_p.h
@@ -74,6 +74,8 @@ class Q_AUTOTEST_EXPORT QQuickTextMetrics : public QObject
Q_PROPERTY(QString elidedText READ elidedText NOTIFY metricsChanged FINAL)
Q_PROPERTY(Qt::TextElideMode elide READ elide WRITE setElide NOTIFY elideChanged FINAL)
Q_PROPERTY(qreal elideWidth READ elideWidth WRITE setElideWidth NOTIFY elideWidthChanged FINAL)
+ QML_NAMED_ELEMENT(TextMetrics)
+ QML_ADDED_IN_MINOR_VERSION(4)
public:
explicit QQuickTextMetrics(QObject *parent = 0);
diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp
index ac9f75979e..7ec7c827eb 100644
--- a/src/quick/util/qquicktimeline.cpp
+++ b/src/quick/util/qquicktimeline.cpp
@@ -723,7 +723,7 @@ void QQuickTimeLine::updateCurrentTime(int v)
void QQuickTimeLine::debugAnimation(QDebug d) const
{
- d << "QuickTimeLine(" << hex << (const void *) this << dec << ")";
+ d << "QuickTimeLine(" << Qt::hex << (const void *) this << Qt::dec << ")";
}
bool operator<(const QPair<int, Update> &lhs,
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/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h
index c7d06b8832..6e45143126 100644
--- a/src/quick/util/qquicktransition_p.h
+++ b/src/quick/util/qquicktransition_p.h
@@ -103,6 +103,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTransition : public QObject
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
Q_CLASSINFO("DefaultProperty", "animations")
Q_CLASSINFO("DeferredPropertyNames", "animations")
+ QML_NAMED_ELEMENT(Transition)
public:
QQuickTransition(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp
deleted file mode 100644
index 93b6599506..0000000000
--- a/src/quick/util/qquickutilmodule.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick 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 "qquickutilmodule_p.h"
-#include "qquickanimation_p.h"
-#include "qquickanimation_p_p.h"
-#include "qquickbehavior_p.h"
-#include "qquicksmoothedanimation_p.h"
-#include "qquickfontloader_p.h"
-#include "qquickfontmetrics_p.h"
-#include "qquickpropertychanges_p.h"
-#include "qquickspringanimation_p.h"
-#include "qquickstategroup_p.h"
-#include "qquickstatechangescript_p.h"
-#include "qquickstate_p.h"
-#include "qquickstate_p_p.h"
-#include "qquicksystempalette_p.h"
-#include "qquicktextmetrics_p.h"
-#include "qquicktransition_p.h"
-#include "qquickanimator_p.h"
-#if QT_CONFIG(shortcut)
-#include "qquickshortcut_p.h"
-#endif
-#include "qquickvalidator_p.h"
-#include <qqmlinfo.h>
-#include <private/qqmltypenotavailable_p.h>
-#include <private/qquickanimationcontroller_p.h>
-#include <QtCore/qcoreapplication.h>
-#include <QtGui/QInputMethod>
-#include <QtGui/QKeySequence>
-
-#if QT_CONFIG(shortcut)
-Q_DECLARE_METATYPE(QKeySequence::StandardKey)
-#endif
-
-void QQuickUtilModule::defineModule()
-{
-#if QT_CONFIG(im)
- qmlRegisterUncreatableType<QInputMethod>("QtQuick",2,0,"InputMethod",
- QInputMethod::tr("InputMethod is an abstract class"));
-#endif
- qmlRegisterUncreatableType<QQuickAbstractAnimation>("QtQuick",2,0,"Animation",QQuickAbstractAnimation::tr("Animation is an abstract class"));
-
- qmlRegisterType<QQuickBehavior>("QtQuick",2,0,"Behavior");
- qmlRegisterType<QQuickColorAnimation>("QtQuick",2,0,"ColorAnimation");
- qmlRegisterType<QQuickSmoothedAnimation>("QtQuick",2,0,"SmoothedAnimation");
- qmlRegisterType<QQuickFontLoader>("QtQuick",2,0,"FontLoader");
- qmlRegisterType<QQuickNumberAnimation>("QtQuick",2,0,"NumberAnimation");
- qmlRegisterType<QQuickParallelAnimation>("QtQuick",2,0,"ParallelAnimation");
- qmlRegisterType<QQuickPauseAnimation>("QtQuick",2,0,"PauseAnimation");
- qmlRegisterType<QQuickPropertyAction>("QtQuick",2,0,"PropertyAction");
- qmlRegisterType<QQuickPropertyAnimation>("QtQuick",2,0,"PropertyAnimation");
- qmlRegisterType<QQuickRotationAnimation>("QtQuick",2,0,"RotationAnimation");
- qmlRegisterType<QQuickScriptAction>("QtQuick",2,0,"ScriptAction");
- qmlRegisterType<QQuickSequentialAnimation>("QtQuick",2,0,"SequentialAnimation");
- qmlRegisterType<QQuickSpringAnimation>("QtQuick",2,0,"SpringAnimation");
- qmlRegisterType<QQuickAnimationController>("QtQuick",2,0,"AnimationController");
- qmlRegisterType<QQuickStateChangeScript>("QtQuick",2,0,"StateChangeScript");
- qmlRegisterType<QQuickStateGroup>("QtQuick",2,0,"StateGroup");
- qmlRegisterType<QQuickState>("QtQuick",2,0,"State");
- qmlRegisterType<QQuickSystemPalette>("QtQuick",2,0,"SystemPalette");
- qmlRegisterType<QQuickTransition>("QtQuick",2,0,"Transition");
- qmlRegisterType<QQuickVector3dAnimation>("QtQuick",2,0,"Vector3dAnimation");
-
-#if QT_CONFIG(validator)
- qmlRegisterAnonymousType<QValidator>("QtQuick", 2);
- qmlRegisterType<QQuickIntValidator>("QtQuick",2,0,"IntValidator");
- qmlRegisterType<QQuickDoubleValidator>("QtQuick",2,0,"DoubleValidator");
- qmlRegisterType<QRegExpValidator>("QtQuick",2,0,"RegExpValidator");
-#if QT_CONFIG(regularexpression)
- qmlRegisterType<QRegularExpressionValidator>("QtQuick", 2, 14, "RegularExpressionValidator");
-#endif
-#endif
-
- qmlRegisterUncreatableType<QQuickAnimator>("QtQuick", 2, 2, "Animator", QQuickAbstractAnimation::tr("Animator is an abstract class"));
- qmlRegisterType<QQuickXAnimator>("QtQuick", 2, 2, "XAnimator");
- qmlRegisterType<QQuickYAnimator>("QtQuick", 2, 2, "YAnimator");
- qmlRegisterType<QQuickScaleAnimator>("QtQuick", 2, 2, "ScaleAnimator");
- qmlRegisterType<QQuickRotationAnimator>("QtQuick", 2, 2, "RotationAnimator");
- qmlRegisterType<QQuickOpacityAnimator>("QtQuick", 2, 2, "OpacityAnimator");
-#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
- qmlRegisterType<QQuickUniformAnimator>("QtQuick", 2, 2, "UniformAnimator");
-#endif
- qmlRegisterAnonymousType<QQuickStateOperation>("QtQuick", 2);
-
- qmlRegisterCustomType<QQuickPropertyChanges>("QtQuick",2,0,"PropertyChanges", new QQuickPropertyChangesParser);
-
-#if QT_CONFIG(shortcut)
- qRegisterMetaType<QKeySequence::StandardKey>();
- qmlRegisterUncreatableType<QKeySequence, 2>("QtQuick", 2, 2, "StandardKey", QStringLiteral("Cannot create an instance of StandardKey."));
-#endif
-
- qmlRegisterType<QQuickFontMetrics>("QtQuick", 2, 4, "FontMetrics");
- qmlRegisterType<QQuickTextMetrics>("QtQuick", 2, 4, "TextMetrics");
-
-#if QT_CONFIG(shortcut)
- qmlRegisterType<QQuickShortcut>("QtQuick", 2, 5, "Shortcut");
- qmlRegisterType<QQuickShortcut,6>("QtQuick", 2, 6, "Shortcut");
-
- qmlRegisterType<QQuickShortcut,9>("QtQuick", 2, 9, "Shortcut");
-#endif
-
- qmlRegisterUncreatableType<QQuickAbstractAnimation, 12>("QtQuick", 2, 12, "Animation",
- QQuickAbstractAnimation::tr("Animation is an abstract class"));
- // 5.13
- qmlRegisterType<QQuickBehavior, 13>("QtQuick", 2, 13, "Behavior");
-}
diff --git a/src/quick/util/qquickvalidator_p.h b/src/quick/util/qquickvalidator_p.h
index 9212efa044..a0dc2cd5ba 100644
--- a/src/quick/util/qquickvalidator_p.h
+++ b/src/quick/util/qquickvalidator_p.h
@@ -61,6 +61,7 @@ class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator
{
Q_OBJECT
Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
+ QML_NAMED_ELEMENT(IntValidator)
public:
QQuickIntValidator(QObject *parent = nullptr);
@@ -76,6 +77,7 @@ class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator
{
Q_OBJECT
Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
+ QML_NAMED_ELEMENT(DoubleValidator)
public:
QQuickDoubleValidator(QObject *parent = nullptr);
diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp
index 0af29aed1c..395385fa0d 100644
--- a/src/quick/util/qquickvaluetypes.cpp
+++ b/src/quick/util/qquickvaluetypes.cpp
@@ -41,6 +41,7 @@
#include <qtquickglobal.h>
#include <private/qqmlvaluetype_p.h>
+#include <private/qcolorspace_p.h>
#include <private/qfont_p.h>
@@ -50,7 +51,6 @@ namespace QQuickValueTypes {
void registerValueTypes()
{
QQmlValueTypeFactory::registerValueTypes("QtQuick", 2, 0);
- qmlRegisterValueTypeEnums<QQuickFontValueType>("QtQuick", 2, 0, "Font");
}
}
@@ -785,6 +785,47 @@ void QQuickFontValueType::setPreferShaping(bool enable)
v.setStyleStrategy(static_cast<QFont::StyleStrategy>(v.styleStrategy() | QFont::PreferNoShaping));
}
+QQuickColorSpaceValueType::NamedColorSpace QQuickColorSpaceValueType::namedColorSpace() const noexcept
+{
+ if (const auto *p = QColorSpacePrivate::get(v))
+ return (QQuickColorSpaceValueType::NamedColorSpace)p->namedColorSpace;
+ return QQuickColorSpaceValueType::Unknown;
+}
+void QQuickColorSpaceValueType::setNamedColorSpace(QQuickColorSpaceValueType::NamedColorSpace namedColorSpace)
+{
+ v = { (QColorSpace::NamedColorSpace)namedColorSpace };
+}
+
+QQuickColorSpaceValueType::Primaries QQuickColorSpaceValueType::primaries() const noexcept
+{
+ return (QQuickColorSpaceValueType::Primaries)v.primaries();
+}
+
+void QQuickColorSpaceValueType::setPrimaries(QQuickColorSpaceValueType::Primaries primariesId)
+{
+ v.setPrimaries((QColorSpace::Primaries)primariesId);
+}
+
+QQuickColorSpaceValueType::TransferFunction QQuickColorSpaceValueType::transferFunction() const noexcept
+{
+ return (QQuickColorSpaceValueType::TransferFunction)v.transferFunction();
+}
+
+void QQuickColorSpaceValueType::setTransferFunction(QQuickColorSpaceValueType::TransferFunction transferFunction)
+{
+ v.setTransferFunction((QColorSpace::TransferFunction)transferFunction, v.gamma());
+}
+
+float QQuickColorSpaceValueType::gamma() const noexcept
+{
+ return v.gamma();
+}
+
+void QQuickColorSpaceValueType::setGamma(float gamma)
+{
+ v.setTransferFunction(v.transferFunction(), gamma);
+}
+
QT_END_NAMESPACE
#include "moc_qquickvaluetypes_p.cpp"
diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h
index 4305006f91..638fdd2773 100644
--- a/src/quick/util/qquickvaluetypes_p.h
+++ b/src/quick/util/qquickvaluetypes_p.h
@@ -56,6 +56,7 @@
#include <private/qqmlvaluetype_p.h>
#include <QtGui/QColor>
+#include <QtGui/QColorSpace>
#include <QtGui/QVector2D>
#include <QtGui/QVector3D>
#include <QtGui/QVector4D>
@@ -328,6 +329,9 @@ class QQuickFontValueType
Q_PROPERTY(bool kerning READ kerning WRITE setKerning FINAL)
Q_PROPERTY(bool preferShaping READ preferShaping WRITE setPreferShaping FINAL)
+ QML_NAMED_ELEMENT(Font)
+ QML_UNCREATABLE("Element is not creatable.")
+
public:
enum FontWeight { Thin = QFont::Thin,
ExtraLight = QFont::ExtraLight,
@@ -405,6 +409,58 @@ public:
void setPreferShaping(bool b);
};
+class QQuickColorSpaceValueType
+{
+ QColorSpace v;
+ Q_GADGET
+
+ Q_PROPERTY(NamedColorSpace namedColorSpace READ namedColorSpace WRITE setNamedColorSpace FINAL)
+ Q_PROPERTY(Primaries primaries READ primaries WRITE setPrimaries FINAL)
+ Q_PROPERTY(TransferFunction transferFunction READ transferFunction WRITE setTransferFunction FINAL)
+ Q_PROPERTY(float gamma READ gamma WRITE setGamma FINAL)
+
+ QML_NAMED_ELEMENT(ColorSpace)
+ QML_ADDED_IN_MINOR_VERSION(15)
+ Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
+
+public:
+ enum NamedColorSpace {
+ Unknown = 0,
+ SRgb,
+ SRgbLinear,
+ AdobeRgb,
+ DisplayP3,
+ ProPhotoRgb
+ };
+ Q_ENUM(NamedColorSpace)
+
+ enum class Primaries {
+ Custom = 0,
+ SRgb,
+ AdobeRgb,
+ DciP3D65,
+ ProPhotoRgb
+ };
+ Q_ENUM(Primaries)
+ enum class TransferFunction {
+ Custom = 0,
+ Linear,
+ Gamma,
+ SRgb,
+ ProPhotoRgb
+ };
+ Q_ENUM(TransferFunction)
+
+ NamedColorSpace namedColorSpace() const noexcept;
+ void setNamedColorSpace(NamedColorSpace namedColorSpace);
+ Primaries primaries() const noexcept;
+ void setPrimaries(Primaries primariesId);
+ TransferFunction transferFunction() const noexcept;
+ void setTransferFunction(TransferFunction transferFunction);
+ float gamma() const noexcept;
+ void setGamma(float gamma);
+};
+
QT_END_NAMESPACE
#endif // QQUICKVALUETYPES_P_H
diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri
index 63d995e34c..f61a967959 100644
--- a/src/quick/util/util.pri
+++ b/src/quick/util/util.pri
@@ -1,6 +1,5 @@
SOURCES += \
$$PWD/qquickapplication.cpp\
- $$PWD/qquickutilmodule.cpp\
$$PWD/qquickanimation.cpp \
$$PWD/qquicksystempalette.cpp \
$$PWD/qquickspringanimation.cpp \
@@ -15,7 +14,6 @@ SOURCES += \
$$PWD/qquicktimeline.cpp \
$$PWD/qquickpixmapcache.cpp \
$$PWD/qquickbehavior.cpp \
- $$PWD/qquickboundaryrule.cpp \
$$PWD/qquickfontloader.cpp \
$$PWD/qquickstyledtext.cpp \
$$PWD/qquickimageprovider.cpp \
@@ -33,7 +31,6 @@ qtConfig(qml-debug): SOURCES += $$PWD/qquickprofiler.cpp
HEADERS += \
$$PWD/qquickapplication_p.h\
- $$PWD/qquickutilmodule_p.h\
$$PWD/qquickanimation_p.h \
$$PWD/qquickanimation_p_p.h \
$$PWD/qquicksystempalette_p.h \
@@ -51,7 +48,6 @@ HEADERS += \
$$PWD/qquicktimeline_p_p.h \
$$PWD/qquickpixmapcache_p.h \
$$PWD/qquickbehavior_p.h \
- $$PWD/qquickboundaryrule_p.h \
$$PWD/qquickfontloader_p.h \
$$PWD/qquickstyledtext_p.h \
$$PWD/qquickimageprovider.h \
@@ -65,7 +61,8 @@ HEADERS += \
$$PWD/qquickprofiler_p.h \
$$PWD/qquickfontmetrics_p.h \
$$PWD/qquicktextmetrics_p.h \
- $$PWD/qquickvalidator_p.h
+ $$PWD/qquickvalidator_p.h \
+ $$PWD/qquickforeignutils_p.h
qtConfig(shortcut) {
SOURCES += \
diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp
index a7db65f16f..dcd331b388 100644
--- a/src/quickshapes/qquickshape.cpp
+++ b/src/quickshapes/qquickshape.cpp
@@ -49,12 +49,12 @@
#include <QLoggingCategory>
#include <QtGui/private/qrhi_p.h>
-#if defined(QT_STATIC)
static void initResources()
{
+#if defined(QT_STATIC)
Q_INIT_RESOURCE(qtquickshapes);
-}
#endif
+}
QT_BEGIN_NAMESPACE
@@ -73,6 +73,11 @@ Q_LOGGING_CATEGORY(QQSHAPE_LOG_TIME_DIRTY_SYNC, "qt.shape.time.sync")
\endqml
*/
+void QQuickShapesModule::defineModule()
+{
+ initResources();
+}
+
QQuickShapeStrokeFillParams::QQuickShapeStrokeFillParams()
: strokeColor(Qt::white),
strokeWidth(1),
@@ -667,22 +672,9 @@ void QQuickShapePrivate::setStatus(QQuickShape::Status newStatus)
}
}
-struct QQuickShapeResourceInitializer
-{
- QQuickShapeResourceInitializer()
- {
-#if defined(QT_STATIC)
- initResources();
-#endif
- }
-};
-
-Q_GLOBAL_STATIC(QQuickShapeResourceInitializer, initQQuickShapeResources)
-
QQuickShape::QQuickShape(QQuickItem *parent)
: QQuickItem(*(new QQuickShapePrivate), parent)
{
- initQQuickShapeResources();
setFlag(ItemHasContents);
}
diff --git a/src/quickshapes/qquickshape_p.h b/src/quickshapes/qquickshape_p.h
index 7066ea0709..f86f2b03d6 100644
--- a/src/quickshapes/qquickshape_p.h
+++ b/src/quickshapes/qquickshape_p.h
@@ -63,12 +63,21 @@ QT_BEGIN_NAMESPACE
class QQuickShapePathPrivate;
class QQuickShapePrivate;
+class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapesModule
+{
+public:
+ static void defineModule();
+};
+
class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeGradient : public QQuickGradient
{
Q_OBJECT
Q_PROPERTY(SpreadMode spread READ spread WRITE setSpread NOTIFY spreadChanged)
Q_CLASSINFO("DefaultProperty", "stops")
+ QML_NAMED_ELEMENT(ShapeGradient)
+ QML_UNCREATABLE("ShapeGradient is an abstract base class.");
+
public:
enum SpreadMode {
PadSpread,
@@ -97,6 +106,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeLinearGradient : public QQuickShap
Q_PROPERTY(qreal x2 READ x2 WRITE setX2 NOTIFY x2Changed)
Q_PROPERTY(qreal y2 READ y2 WRITE setY2 NOTIFY y2Changed)
Q_CLASSINFO("DefaultProperty", "stops")
+ QML_NAMED_ELEMENT(LinearGradient)
public:
QQuickShapeLinearGradient(QObject *parent = nullptr);
@@ -131,6 +141,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeRadialGradient : public QQuickShap
Q_PROPERTY(qreal focalY READ focalY WRITE setFocalY NOTIFY focalYChanged)
Q_PROPERTY(qreal focalRadius READ focalRadius WRITE setFocalRadius NOTIFY focalRadiusChanged)
Q_CLASSINFO("DefaultProperty", "stops")
+ QML_NAMED_ELEMENT(RadialGradient)
public:
QQuickShapeRadialGradient(QObject *parent = nullptr);
@@ -175,6 +186,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeConicalGradient : public QQuickSha
Q_PROPERTY(qreal centerY READ centerY WRITE setCenterY NOTIFY centerYChanged)
Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
Q_CLASSINFO("DefaultProperty", "stops")
+ QML_NAMED_ELEMENT(ConicalGradient)
public:
QQuickShapeConicalGradient(QObject *parent = nullptr);
@@ -214,6 +226,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapePath : public QQuickPath
Q_PROPERTY(QVector<qreal> dashPattern READ dashPattern WRITE setDashPattern NOTIFY dashPatternChanged)
Q_PROPERTY(QQuickShapeGradient *fillGradient READ fillGradient WRITE setFillGradient RESET resetFillGradient)
Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION 14)
+ QML_NAMED_ELEMENT(ShapePath)
public:
enum FillRule {
@@ -308,6 +321,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShape : public QQuickItem
Q_PROPERTY(ContainsMode containsMode READ containsMode WRITE setContainsMode NOTIFY containsModeChanged REVISION 11)
Q_PROPERTY(QQmlListProperty<QObject> data READ data)
Q_CLASSINFO("DefaultProperty", "data")
+ QML_NAMED_ELEMENT(Shape)
public:
enum RendererType {
diff --git a/src/quickshapes/qquickshape_p_p.h b/src/quickshapes/qquickshape_p_p.h
index bfeb0d2f9f..e9b89d2ab3 100644
--- a/src/quickshapes/qquickshape_p_p.h
+++ b/src/quickshapes/qquickshape_p_p.h
@@ -89,7 +89,7 @@ public:
virtual void beginSync(int totalCount) = 0;
virtual void endSync(bool async) = 0;
virtual void setAsyncCallback(void (*)(void *), void *) { }
- virtual Flags flags() const { return 0; }
+ virtual Flags flags() const { return {}; }
virtual void setPath(int index, const QQuickPath *path) = 0;
virtual void setStrokeColor(int index, const QColor &color) = 0;
virtual void setStrokeWidth(int index, qreal w) = 0;
diff --git a/src/quickshapes/qquickshapegenericrenderer.cpp b/src/quickshapes/qquickshapegenericrenderer.cpp
index 06cc442fc7..e0df739987 100644
--- a/src/quickshapes/qquickshapegenericrenderer.cpp
+++ b/src/quickshapes/qquickshapegenericrenderer.cpp
@@ -470,14 +470,14 @@ void QQuickShapeGenericRenderer::triangulateStroke(const QPainterPath &path,
stroker.setInvScale(inverseScale);
if (pen.style() == Qt::SolidLine) {
- stroker.process(vp, pen, clip, nullptr);
+ stroker.process(vp, pen, clip, {});
} else {
QDashedStrokeProcessor dashStroker;
dashStroker.setInvScale(inverseScale);
- dashStroker.process(vp, pen, clip, nullptr);
+ dashStroker.process(vp, pen, clip, {});
QVectorPath dashStroke(dashStroker.points(), dashStroker.elementCount(),
dashStroker.elementTypes(), 0);
- stroker.process(dashStroke, pen, clip, nullptr);
+ stroker.process(dashStroke, pen, clip, {});
}
if (!stroker.vertexCount()) {
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/src/quickshapes/qquickshapesoftwarerenderer.cpp b/src/quickshapes/qquickshapesoftwarerenderer.cpp
index 0f5c3604b5..d6a9d85643 100644
--- a/src/quickshapes/qquickshapesoftwarerenderer.cpp
+++ b/src/quickshapes/qquickshapesoftwarerenderer.cpp
@@ -266,7 +266,7 @@ void QQuickShapeSoftwareRenderNode::render(const RenderState *state)
QSGRenderNode::StateFlags QQuickShapeSoftwareRenderNode::changedStates() const
{
- return nullptr;
+ return {};
}
QSGRenderNode::RenderingFlags QQuickShapeSoftwareRenderNode::flags() const
diff --git a/src/quickshapes/quickshapes.pro b/src/quickshapes/quickshapes.pro
index 5a59dec18e..4dbd3e5e46 100644
--- a/src/quickshapes/quickshapes.pro
+++ b/src/quickshapes/quickshapes.pro
@@ -31,3 +31,9 @@ qtConfig(opengl) {
RESOURCES += qtquickshapes.qrc
load(qt_module)
+
+QMLTYPES_FILENAME = plugins.qmltypes
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick/Shapes
+QML_IMPORT_NAME = QtQuick.Shapes
+IMPORT_VERSION = 1.$$QT_MINOR_VERSION
+CONFIG += qmltypes install_qmltypes install_metatypes
diff --git a/src/quickshapes/shaders_ng/conicalgradient.frag.qsb b/src/quickshapes/shaders_ng/conicalgradient.frag.qsb
index 9aa59ca651..f82d798d87 100644
--- a/src/quickshapes/shaders_ng/conicalgradient.frag.qsb
+++ b/src/quickshapes/shaders_ng/conicalgradient.frag.qsb
Binary files differ
diff --git a/src/quickshapes/shaders_ng/conicalgradient.vert.qsb b/src/quickshapes/shaders_ng/conicalgradient.vert.qsb
index 7f5985ef64..7d306e973b 100644
--- a/src/quickshapes/shaders_ng/conicalgradient.vert.qsb
+++ b/src/quickshapes/shaders_ng/conicalgradient.vert.qsb
Binary files differ
diff --git a/src/quickshapes/shaders_ng/lineargradient.frag.qsb b/src/quickshapes/shaders_ng/lineargradient.frag.qsb
index 470de007b5..640c3c334f 100644
--- a/src/quickshapes/shaders_ng/lineargradient.frag.qsb
+++ b/src/quickshapes/shaders_ng/lineargradient.frag.qsb
Binary files differ
diff --git a/src/quickshapes/shaders_ng/lineargradient.vert.qsb b/src/quickshapes/shaders_ng/lineargradient.vert.qsb
index 8d054efbb4..1b5b19ded8 100644
--- a/src/quickshapes/shaders_ng/lineargradient.vert.qsb
+++ b/src/quickshapes/shaders_ng/lineargradient.vert.qsb
Binary files differ
diff --git a/src/quickshapes/shaders_ng/radialgradient.frag.qsb b/src/quickshapes/shaders_ng/radialgradient.frag.qsb
index 166eb2f92d..1bcb8d55ef 100644
--- a/src/quickshapes/shaders_ng/radialgradient.frag.qsb
+++ b/src/quickshapes/shaders_ng/radialgradient.frag.qsb
Binary files differ
diff --git a/src/quickshapes/shaders_ng/radialgradient.vert.qsb b/src/quickshapes/shaders_ng/radialgradient.vert.qsb
index 293e23947a..7a77792e08 100644
--- a/src/quickshapes/shaders_ng/radialgradient.vert.qsb
+++ b/src/quickshapes/shaders_ng/radialgradient.vert.qsb
Binary files differ
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 083b7dbae1..35cf06927a 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -107,6 +107,7 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
renderControl = new QQuickWidgetRenderControl(q);
offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
+ offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
// Do not call create() on offscreenWindow.
// Check if the Software Adaptation is being used
@@ -525,7 +526,7 @@ QImage QQuickWidgetPrivate::grabFramebuffer()
*/
QQuickWidget::QQuickWidget(QWidget *parent)
-: QWidget(*(new QQuickWidgetPrivate), parent, nullptr)
+ : QWidget(*(new QQuickWidgetPrivate), parent, {})
{
setMouseTracking(true);
setFocusPolicy(Qt::StrongFocus);
@@ -553,7 +554,7 @@ QQuickWidget::QQuickWidget(const QUrl &source, QWidget *parent)
\sa Status, status(), errors()
*/
QQuickWidget::QQuickWidget(QQmlEngine* engine, QWidget *parent)
- : QWidget(*(new QQuickWidgetPrivate), parent, nullptr)
+ : QWidget(*(new QQuickWidgetPrivate), parent, {})
{
setMouseTracking(true);
setFocusPolicy(Qt::StrongFocus);
@@ -802,15 +803,29 @@ void QQuickWidgetPrivate::updateSize()
q->updateGeometry();
}
} else if (resizeMode == QQuickWidget::SizeRootObjectToView) {
- bool needToUpdateWidth = !qFuzzyCompare(q->width(), root->width());
- bool needToUpdateHeight = !qFuzzyCompare(q->height(), root->height());
-
- if (needToUpdateWidth && needToUpdateHeight)
- root->setSize(QSizeF(q->width(), q->height()));
- else if (needToUpdateWidth)
- root->setWidth(q->width());
- else if (needToUpdateHeight)
- root->setHeight(q->height());
+ const bool needToUpdateWidth = !qFuzzyCompare(q->width(), root->width());
+ const bool needToUpdateHeight = !qFuzzyCompare(q->height(), root->height());
+
+ if (needToUpdateWidth && needToUpdateHeight) {
+ // Make sure that we have realistic sizing behavior by following
+ // what on-screen windows would do and resize everything, not just
+ // the root item. We do this because other types may be relying on
+ // us to behave correctly.
+ const QSizeF newSize(q->width(), q->height());
+ offscreenWindow->resize(newSize.toSize());
+ offscreenWindow->contentItem()->setSize(newSize);
+ root->setSize(newSize);
+ } else if (needToUpdateWidth) {
+ const int newWidth = q->width();
+ offscreenWindow->setWidth(newWidth);
+ offscreenWindow->contentItem()->setWidth(newWidth);
+ root->setWidth(newWidth);
+ } else if (needToUpdateHeight) {
+ const int newHeight = q->height();
+ offscreenWindow->setHeight(newHeight);
+ offscreenWindow->contentItem()->setHeight(newHeight);
+ root->setHeight(newHeight);
+ }
}
}
@@ -848,13 +863,13 @@ QSize QQuickWidgetPrivate::rootObjectSize() const
return rootObjectSize;
}
-void QQuickWidgetPrivate::handleContextCreationFailure(const QSurfaceFormat &format, bool isEs)
+void QQuickWidgetPrivate::handleContextCreationFailure(const QSurfaceFormat &format)
{
Q_Q(QQuickWidget);
QString translatedMessage;
QString untranslatedMessage;
- QQuickWindowPrivate::contextCreationFailureMessage(format, &translatedMessage, &untranslatedMessage, isEs);
+ QQuickWindowPrivate::contextCreationFailureMessage(format, &translatedMessage, &untranslatedMessage);
static const QMetaMethod errorSignal = QMetaMethod::fromSignal(&QQuickWidget::sceneGraphError);
const bool signalConnected = q->isSignalConnected(errorSignal);
@@ -896,10 +911,9 @@ void QQuickWidgetPrivate::createContext()
context->setScreen(shareContext->screen());
}
if (!context->create()) {
- const bool isEs = context->isOpenGLES();
delete context;
context = nullptr;
- handleContextCreationFailure(offscreenWindow->requestedFormat(), isEs);
+ handleContextCreationFailure(offscreenWindow->requestedFormat());
return;
}
@@ -1096,14 +1110,14 @@ void QQuickWidgetPrivate::setRootObject(QObject *obj)
root = sgItem;
sgItem->setParentItem(offscreenWindow->contentItem());
} else if (qobject_cast<QWindow *>(obj)) {
- qWarning() << "QQuickWidget does not support using windows as a root item." << endl
- << endl
- << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << endl;
+ qWarning() << "QQuickWidget does not support using windows as a root item." << Qt::endl
+ << Qt::endl
+ << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << Qt::endl;
} else {
- qWarning() << "QQuickWidget only supports loading of root objects that derive from QQuickItem." << endl
- << endl
- << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << endl
- << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << endl;
+ qWarning() << "QQuickWidget only supports loading of root objects that derive from QQuickItem." << Qt::endl
+ << Qt::endl
+ << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << Qt::endl
+ << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << Qt::endl;
delete obj;
root = nullptr;
}
diff --git a/src/quickwidgets/qquickwidget_p.h b/src/quickwidgets/qquickwidget_p.h
index f4f9db7772..881f7f9220 100644
--- a/src/quickwidgets/qquickwidget_p.h
+++ b/src/quickwidgets/qquickwidget_p.h
@@ -97,7 +97,7 @@ public:
void renderSceneGraph();
void createContext();
void destroyContext();
- void handleContextCreationFailure(const QSurfaceFormat &format, bool isEs);
+ void handleContextCreationFailure(const QSurfaceFormat &format);
#if QT_CONFIG(opengl)
GLuint textureId() const override;
diff --git a/src/src.pro b/src/src.pro
index 98e1779dc5..2855102eff 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -3,7 +3,13 @@ CONFIG += ordered
include($$OUT_PWD/qml/qtqml-config.pri)
include($$OUT_PWD/quick/qtquick-config.pri)
QT_FOR_CONFIG += qml qml-private quick-private
+
+# Otherwise we cannot compile qmltyperegistrar
+requires(qtConfig(commandlineparser))
+
+# We need qmltyperegistrar for all type registrations, even in qml
SUBDIRS += \
+ qmltyperegistrar \
qml \
qmlmodels