aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/masm/assembler/ARM64Assembler.h4
-rw-r--r--src/3rdparty/masm/assembler/ARMv7Assembler.h4
-rw-r--r--src/3rdparty/masm/wtf/OSAllocatorPosix.cpp2
-rw-r--r--src/3rdparty/masm/wtf/Platform.h1
-rw-r--r--src/3rdparty/masm/yarr/YarrInterpreter.cpp4
-rw-r--r--src/3rdparty/masm/yarr/YarrParser.h2
-rw-r--r--src/CMakeLists.txt10
-rw-r--r--src/labs/animation/qquickboundaryrule.cpp4
-rw-r--r--src/labs/folderlistmodel/fileinfothread.cpp2
-rw-r--r--src/labs/folderlistmodel/qquickfolderlistmodel.cpp2
-rw-r--r--src/labs/models/qqmldelegatecomponent.cpp4
-rw-r--r--src/labs/models/qqmltablemodel.cpp2
-rw-r--r--src/labs/platform/doc/qtlabsplatform.qdocconf2
-rw-r--r--src/labs/platform/qquicklabsplatformdialog_p.h2
-rw-r--r--src/labs/platform/qquicklabsplatformfiledialog.cpp2
-rw-r--r--src/labs/platform/qquicklabsplatformfolderdialog.cpp1
-rw-r--r--src/labs/platform/qquicklabsplatformmenu.cpp16
-rw-r--r--src/labs/platform/qquicklabsplatformmenubar.cpp13
-rw-r--r--src/labs/platform/qquicklabsplatformmenuitem.cpp75
-rw-r--r--src/labs/platform/qquicklabsplatformmenuitem_p.h3
-rw-r--r--src/labs/platform/qquicklabsplatformmenuitemgroup.cpp10
-rw-r--r--src/labs/platform/qquicklabsplatformstandardpaths.cpp7
-rw-r--r--src/labs/platform/qquicklabsplatformstandardpaths_p.h4
-rw-r--r--src/labs/platform/widgets/qwidgetplatformfiledialog.cpp2
-rw-r--r--src/labs/platform/widgets/qwidgetplatformmenu.cpp5
-rw-r--r--src/labs/sharedimage/qsharedimageprovider.cpp2
-rw-r--r--src/labs/wavefrontmesh/qwavefrontmesh.cpp4
-rw-r--r--src/particles/qquickcustomaffector.cpp6
-rw-r--r--src/particles/qquickimageparticle.cpp27
-rw-r--r--src/particles/qquickimageparticle_p.h2
-rw-r--r--src/particles/qquickitemparticle.cpp8
-rw-r--r--src/particles/qquickmaskextruder.cpp4
-rw-r--r--src/particles/qquickparticleaffector.cpp4
-rw-r--r--src/particles/qquickparticlesystem.cpp48
-rw-r--r--src/particles/qquicktrailemitter.cpp2
-rw-r--r--src/plugins/qmllint/quick/quicklintplugin.cpp8
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp28
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlwatcher.cpp5
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp12
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp10
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp16
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp12
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp10
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/proxytranslator.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp38
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp14
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.cpp14
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp4
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp2
-rw-r--r--src/qml/Qt6AndroidQmlMacros.cmake20
-rw-r--r--src/qml/Qt6QmlMacros.cmake207
-rw-r--r--src/qml/animations/qabstractanimationjob.cpp10
-rw-r--r--src/qml/animations/qabstractanimationjob_p.h2
-rw-r--r--src/qml/common/qqmljsfixedpoolarray_p.h4
-rw-r--r--src/qml/common/qv4compileddata_p.h8
-rw-r--r--src/qml/common/qv4stringtoarrayindex_p.h2
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp8
-rw-r--r--src/qml/compiler/qv4compiler.cpp34
-rw-r--r--src/qml/compiler/qv4compilercontext.cpp14
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp22
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice_p.h2
-rw-r--r--src/qml/debugger/qqmldebugconnector.cpp2
-rw-r--r--src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp2
-rw-r--r--src/qml/doc/src/cmake/cmake-properties.qdoc18
-rw-r--r--src/qml/doc/src/cmake/cmake-variables.qdoc2
-rw-r--r--src/qml/doc/src/cmake/qt_add_qml_module.qdoc10
-rw-r--r--src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc2
-rw-r--r--src/qml/doc/src/cmake/qt_deploy_qml_imports.qdoc4
-rw-r--r--src/qml/doc/src/cmake/qt_generate_deploy_qml_app_script.qdoc4
-rw-r--r--src/qml/doc/src/cmake/qt_generate_foreign_qml_types.qdoc11
-rw-r--r--src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc2
-rw-r--r--src/qml/doc/src/cmake/qt_query_qml_module.qdoc2
-rw-r--r--src/qml/doc/src/cmake/qt_target_compile_qml_to_cpp.qdoc2
-rw-r--r--src/qml/doc/src/cmake/qt_target_qml_sources.qdoc2
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc69
-rw-r--r--src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.qdocinc (renamed from src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.cmake)3
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc8
-rw-r--r--src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc16
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc12
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc2
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc8
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc5
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/imports.qdoc16
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc1
-rw-r--r--src/qml/doc/src/qmllanguageref/typesystem/valuetypes.qdoc86
-rw-r--r--src/qml/doc/src/qmltypereference.qdoc5
-rw-r--r--src/qml/doc/src/qtqml.qdoc37
-rw-r--r--src/qml/jit/qv4baselinejit_p.h2
-rw-r--r--src/qml/jsapi/qjsengine.cpp2
-rw-r--r--src/qml/jsapi/qjsmanagedvalue.cpp6
-rw-r--r--src/qml/jsapi/qjsvalue.cpp14
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4arraybuffer_p.h5
-rw-r--r--src/qml/jsruntime/qv4arrayiterator_p.h2
-rw-r--r--src/qml/jsruntime/qv4compilationunitmapper.cpp11
-rw-r--r--src/qml/jsruntime/qv4compilationunitmapper_p.h1
-rw-r--r--src/qml/jsruntime/qv4context_p.h4
-rw-r--r--src/qml/jsruntime/qv4dataview_p.h2
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp65
-rw-r--r--src/qml/jsruntime/qv4engine_p.h13
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4executableallocator.cpp2
-rw-r--r--src/qml/jsruntime/qv4executableallocator_p.h4
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp22
-rw-r--r--src/qml/jsruntime/qv4function.cpp4
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp23
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4generatorobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp14
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp8
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp43
-rw-r--r--src/qml/jsruntime/qv4mapiterator_p.h2
-rw-r--r--src/qml/jsruntime/qv4memberdata_p.h2
-rw-r--r--src/qml/jsruntime/qv4module.cpp2
-rw-r--r--src/qml/jsruntime/qv4object.cpp2
-rw-r--r--src/qml/jsruntime/qv4persistent_p.h2
-rw-r--r--src/qml/jsruntime/qv4profiling.cpp2
-rw-r--r--src/qml/jsruntime/qv4promiseobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4propertykey.cpp2
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h4
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp110
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h62
-rw-r--r--src/qml/jsruntime/qv4reflect.cpp5
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp12
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp18
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp17
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h6
-rw-r--r--src/qml/jsruntime/qv4setiterator_p.h2
-rw-r--r--src/qml/jsruntime/qv4stringiterator.cpp2
-rw-r--r--src/qml/jsruntime/qv4stringiterator_p.h2
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp58
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4symbol_p.h2
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h2
-rw-r--r--src/qml/jsruntime/qv4urlobject.cpp16
-rw-r--r--src/qml/jsruntime/qv4urlobject_p.h4
-rw-r--r--src/qml/memory/qv4mm.cpp4
-rw-r--r--src/qml/parser/qqmljs.g12
-rw-r--r--src/qml/parser/qqmljsast_p.h2
-rw-r--r--src/qml/parser/qqmljslexer.cpp2
-rw-r--r--src/qml/qml/ftw/qbipointer_p.h5
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h10
-rw-r--r--src/qml/qml/ftw/qstringhash_p.h4
-rw-r--r--src/qml/qml/qqml.cpp16
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp4
-rw-r--r--src/qml/qml/qqmlbinding.cpp2
-rw-r--r--src/qml/qml/qqmlbinding_p.h8
-rw-r--r--src/qml/qml/qqmlcomponent.cpp44
-rw-r--r--src/qml/qml/qqmlcomponent.h2
-rw-r--r--src/qml/qml/qqmlcontext.cpp2
-rw-r--r--src/qml/qml/qqmlcontext_p.h2
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp65
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h2
-rw-r--r--src/qml/qml/qqmldata_p.h4
-rw-r--r--src/qml/qml/qqmldatablob.cpp14
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlerror.cpp4
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp23
-rw-r--r--src/qml/qml/qqmlfile.cpp101
-rw-r--r--src/qml/qml/qqmlimport.cpp94
-rw-r--r--src/qml/qml/qqmlincubator.cpp15
-rw-r--r--src/qml/qml/qqmlirloader.cpp10
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp2
-rw-r--r--src/qml/qml/qqmllist.h6
-rw-r--r--src/qml/qml/qqmllocale.cpp16
-rw-r--r--src/qml/qml/qqmllocale_p.h2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp17
-rw-r--r--src/qml/qml/qqmlmetatypedata.cpp14
-rw-r--r--src/qml/qml/qqmlnotifier.cpp4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp24
-rw-r--r--src/qml/qml/qqmlopenmetaobject.cpp22
-rw-r--r--src/qml/qml/qqmlpluginimporter.cpp10
-rw-r--r--src/qml/qml/qqmlproperty.cpp89
-rw-r--r--src/qml/qml/qqmlproperty.h2
-rw-r--r--src/qml/qml/qqmlpropertybinding.cpp8
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp53
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h18
-rw-r--r--src/qml/qml/qqmlpropertycachecreator.cpp6
-rw-r--r--src/qml/qml/qqmlpropertycachecreator_p.h27
-rw-r--r--src/qml/qml/qqmlpropertycachevector_p.h4
-rw-r--r--src/qml/qml/qqmlpropertydata_p.h1
-rw-r--r--src/qml/qml/qqmlpropertyresolver.cpp2
-rw-r--r--src/qml/qml/qqmlpropertyvalidator_p.h3
-rw-r--r--src/qml/qml/qqmlproxymetaobject.cpp8
-rw-r--r--src/qml/qml/qqmlscriptblob.cpp4
-rw-r--r--src/qml/qml/qqmlscriptdata.cpp4
-rw-r--r--src/qml/qml/qqmlscriptstring.cpp2
-rw-r--r--src/qml/qml/qqmltype.cpp22
-rw-r--r--src/qml/qml/qqmltypecompiler.cpp34
-rw-r--r--src/qml/qml/qqmltypecompiler_p.h2
-rw-r--r--src/qml/qml/qqmltypedata.cpp20
-rw-r--r--src/qml/qml/qqmltypeloader.cpp10
-rw-r--r--src/qml/qml/qqmltypemodule.cpp4
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp4
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp34
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h38
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp36
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp11
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp37
-rw-r--r--src/qml/qmldirparser/qqmldirparser.cpp6
-rw-r--r--src/qml/qmldirparser/qqmlimportresolver.cpp4
-rw-r--r--src/qml/types/qqmlbind.cpp13
-rw-r--r--src/qml/types/qqmlconnections.cpp32
-rw-r--r--src/qml/util/qqmlpropertymap.cpp2
-rw-r--r--src/qmlcompiler/qdeferredpointer_p.h6
-rw-r--r--src/qmlcompiler/qqmljsbasicblocks.cpp16
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp132
-rw-r--r--src/qmlcompiler/qqmljscodegenerator_p.h7
-rw-r--r--src/qmlcompiler/qqmljscompilepass_p.h6
-rw-r--r--src/qmlcompiler/qqmljscompiler.cpp32
-rw-r--r--src/qmlcompiler/qqmljscompiler_p.h1
-rw-r--r--src/qmlcompiler/qqmljsfunctioninitializer.cpp4
-rw-r--r--src/qmlcompiler/qqmljsimporter.cpp10
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp44
-rw-r--r--src/qmlcompiler/qqmljslinter.cpp34
-rw-r--r--src/qmlcompiler/qqmljslintercodegen.cpp1
-rw-r--r--src/qmlcompiler/qqmljsloadergenerator.cpp8
-rw-r--r--src/qmlcompiler/qqmljslogger.cpp6
-rw-r--r--src/qmlcompiler/qqmljslogger_p.h14
-rw-r--r--src/qmlcompiler/qqmljsmetatypes_p.h8
-rw-r--r--src/qmlcompiler/qqmljsresourcefilemapper.cpp2
-rw-r--r--src/qmlcompiler/qqmljsscope.cpp11
-rw-r--r--src/qmlcompiler/qqmljsscope_p.h28
-rw-r--r--src/qmlcompiler/qqmljsshadowcheck.cpp8
-rw-r--r--src/qmlcompiler/qqmljsstreamwriter.cpp2
-rw-r--r--src/qmlcompiler/qqmljstypepropagator.cpp43
-rw-r--r--src/qmlcompiler/qqmljstypepropagator_p.h9
-rw-r--r--src/qmlcompiler/qqmljstyperesolver.cpp171
-rw-r--r--src/qmlcompiler/qqmljstyperesolver_p.h7
-rw-r--r--src/qmlcompiler/qqmljsutils.cpp34
-rw-r--r--src/qmlcompiler/qqmljsutils_p.h2
-rw-r--r--src/qmldebug/qqmlprofilerclient_p_p.h2
-rw-r--r--src/qmldebug/qv4debugclient.cpp2
-rw-r--r--src/qmldom/qqmldomastcreator.cpp64
-rw-r--r--src/qmldom/qqmldomcomments.cpp10
-rw-r--r--src/qmldom/qqmldomcomments_p.h4
-rw-r--r--src/qmldom/qqmldomelements_p.h2
-rw-r--r--src/qmldom/qqmldomerrormessage.cpp14
-rw-r--r--src/qmldom/qqmldomexternalitems_p.h6
-rw-r--r--src/qmldom/qqmldomitem.cpp19
-rw-r--r--src/qmldom/qqmldomitem_p.h24
-rw-r--r--src/qmldom/qqmldomlinewriter.cpp12
-rw-r--r--src/qmldom/qqmldomlinewriter_p.h2
-rw-r--r--src/qmldom/qqmldommoduleindex.cpp4
-rw-r--r--src/qmldom/qqmldompath.cpp64
-rw-r--r--src/qmldom/qqmldomreformatter.cpp2
-rw-r--r--src/qmldom/qqmldomstringdumper.cpp8
-rw-r--r--src/qmldom/qqmldomtop.cpp2
-rw-r--r--src/qmldom/qqmldomtop_p.h4
-rw-r--r--src/qmldom/qqmldomtypesreader.cpp2
-rw-r--r--src/qmldom/standalone/private/qtqmlcompilerexports_p.h12
-rw-r--r--src/qmllocalstorage/qqmllocalstorage.cpp10
-rw-r--r--src/qmlmodels/qqmladaptormodel.cpp28
-rw-r--r--src/qmlmodels/qqmldelegatemodel.cpp59
-rw-r--r--src/qmlmodels/qqmlinstantiator.cpp18
-rw-r--r--src/qmlmodels/qqmllistaccessor.cpp8
-rw-r--r--src/qmlmodels/qqmllistmodel.cpp173
-rw-r--r--src/qmlmodels/qqmllistmodel_p_p.h47
-rw-r--r--src/qmlmodels/qqmlobjectmodel.cpp20
-rw-r--r--src/qmlmodels/qqmltableinstancemodel.cpp2
-rw-r--r--src/qmlmodels/qqmltreemodeltotablemodel.cpp133
-rw-r--r--src/qmlmodels/qqmltreemodeltotablemodel_p_p.h1
-rw-r--r--src/qmlmodels/qquickpackage.cpp6
-rw-r--r--src/qmltest/TestCase.qml36
-rw-r--r--src/qmltest/quicktest.cpp14
-rw-r--r--src/qmltest/quicktestevent.cpp6
-rw-r--r--src/qmltyperegistrar/metatypesjsonprocessor.cpp1
-rw-r--r--src/qmlworkerscript/qv4serialize.cpp4
-rw-r--r--src/qmlxmllistmodel/qqmlxmllistmodel.cpp16
-rw-r--r--src/quick/accessible/qaccessiblequickitem.cpp24
-rw-r--r--src/quick/accessible/qaccessiblequickview.cpp6
-rw-r--r--src/quick/designer/qqmldesignermetaobject.cpp6
-rw-r--r--src/quick/designer/qquickdesignersupportitems.cpp2
-rw-r--r--src/quick/doc/images/pointerHandlers/dragReleaseMenu.webpbin0 -> 86252 bytes
-rw-r--r--src/quick/doc/images/pointerHandlers/tapHandlerButtonReleaseWithinBounds.webpbin0 -> 53154 bytes
-rw-r--r--src/quick/doc/images/pointerHandlers/tapHandlerButtonWithinBounds.webpbin0 -> 27426 bytes
-rw-r--r--src/quick/doc/images/pointerHandlers/tapHandlerOverlappingButtons.webpbin0 -> 51008 bytes
-rw-r--r--src/quick/doc/snippets/pointerHandlers/dragReleaseMenu.qml72
-rw-r--r--src/quick/doc/snippets/pointerHandlers/pointHandler.qml5
-rw-r--r--src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedButtons.qml21
-rw-r--r--src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedModifiers.qml36
-rw-r--r--src/quick/doc/snippets/pointerHandlers/pointHandlerCanvasDrawing.qml54
-rw-r--r--src/quick/doc/snippets/pointerHandlers/pointHandlerMargin.qml36
-rw-r--r--src/quick/doc/snippets/pointerHandlers/tapHandlerButtonReleaseWithinBounds.qml51
-rw-r--r--src/quick/doc/snippets/pointerHandlers/tapHandlerButtonWithinBounds.qml51
-rw-r--r--src/quick/doc/snippets/pointerHandlers/tapHandlerOverlappingButtons.qml51
-rw-r--r--src/quick/doc/snippets/qml/item/itemGrab.qml39
-rw-r--r--src/quick/doc/snippets/qml/itemGrab.qml50
-rw-r--r--src/quick/doc/src/concepts/inputhandlers/qtquickhandlers-index.qdoc3
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc6
-rw-r--r--src/quick/doc/src/cppextensionpoints.qdoc19
-rw-r--r--src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc27
-rw-r--r--src/quick/doc/src/guidelines/qtquick-tool-qmllint.qdoc4
-rw-r--r--src/quick/doc/src/qmltypereference.qdoc4
-rw-r--r--src/quick/handlers/qquickdraghandler.cpp2
-rw-r--r--src/quick/handlers/qquickhandlerpoint.cpp39
-rw-r--r--src/quick/handlers/qquickhandlerpoint_p.h1
-rw-r--r--src/quick/handlers/qquickhoverhandler.cpp73
-rw-r--r--src/quick/handlers/qquickhoverhandler_p.h4
-rw-r--r--src/quick/handlers/qquickmultipointhandler.cpp12
-rw-r--r--src/quick/handlers/qquickpinchhandler.cpp21
-rw-r--r--src/quick/handlers/qquickpointerdevicehandler.cpp4
-rw-r--r--src/quick/handlers/qquickpointerdevicehandler_p.h7
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp10
-rw-r--r--src/quick/handlers/qquickpointerhandler_p_p.h4
-rw-r--r--src/quick/handlers/qquickpointhandler.cpp126
-rw-r--r--src/quick/handlers/qquicksinglepointhandler.cpp2
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp132
-rw-r--r--src/quick/handlers/qquickwheelhandler.cpp2
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp4
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp2
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h2
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture.cpp6
-rw-r--r--src/quick/items/qquickaccessibleattached.cpp34
-rw-r--r--src/quick/items/qquickcolorgroup.cpp4
-rw-r--r--src/quick/items/qquickdrag.cpp12
-rw-r--r--src/quick/items/qquickdrag_p.h3
-rw-r--r--src/quick/items/qquickdroparea.cpp2
-rw-r--r--src/quick/items/qquickflickable.cpp66
-rw-r--r--src/quick/items/qquickflickable_p_p.h34
-rw-r--r--src/quick/items/qquickflipable.cpp54
-rw-r--r--src/quick/items/qquickgridview.cpp48
-rw-r--r--src/quick/items/qquickimagebase.cpp4
-rw-r--r--src/quick/items/qquickitem.cpp199
-rw-r--r--src/quick/items/qquickitem_p.h7
-rw-r--r--src/quick/items/qquickitemanimation.cpp16
-rw-r--r--src/quick/items/qquickitemgrabresult.cpp14
-rw-r--r--src/quick/items/qquickitemsmodule.cpp134
-rw-r--r--src/quick/items/qquickitemview.cpp61
-rw-r--r--src/quick/items/qquicklistview.cpp113
-rw-r--r--src/quick/items/qquickloader.cpp2
-rw-r--r--src/quick/items/qquickmousearea.cpp74
-rw-r--r--src/quick/items/qquickmousearea_p_p.h1
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp24
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h2
-rw-r--r--src/quick/items/qquickpainteditem.cpp2
-rw-r--r--src/quick/items/qquickpalette.cpp10
-rw-r--r--src/quick/items/qquickpathview.cpp44
-rw-r--r--src/quick/items/qquickpincharea.cpp30
-rw-r--r--src/quick/items/qquickpositioners.cpp4
-rw-r--r--src/quick/items/qquickrectangle.cpp9
-rw-r--r--src/quick/items/qquickrendercontrol.cpp6
-rw-r--r--src/quick/items/qquickrendertarget.cpp2
-rw-r--r--src/quick/items/qquickrepeater.cpp20
-rw-r--r--src/quick/items/qquickshadereffect.cpp22
-rw-r--r--src/quick/items/qquickshadereffectmesh.cpp2
-rw-r--r--src/quick/items/qquickspriteengine.cpp47
-rw-r--r--src/quick/items/qquickspriteengine_p.h8
-rw-r--r--src/quick/items/qquickspritesequence.cpp2
-rw-r--r--src/quick/items/qquickstateoperations.cpp2
-rw-r--r--src/quick/items/qquicktableview.cpp238
-rw-r--r--src/quick/items/qquicktableview_p.h6
-rw-r--r--src/quick/items/qquicktableview_p_p.h21
-rw-r--r--src/quick/items/qquicktext.cpp98
-rw-r--r--src/quick/items/qquicktext_p_p.h2
-rw-r--r--src/quick/items/qquicktextcontrol.cpp11
-rw-r--r--src/quick/items/qquicktextdocument.cpp2
-rw-r--r--src/quick/items/qquicktextedit.cpp34
-rw-r--r--src/quick/items/qquicktextedit_p.h1
-rw-r--r--src/quick/items/qquicktextedit_p_p.h8
-rw-r--r--src/quick/items/qquicktextinput.cpp148
-rw-r--r--src/quick/items/qquicktextinput_p_p.h10
-rw-r--r--src/quick/items/qquicktextnode.cpp2
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp11
-rw-r--r--src/quick/items/qquicktreeview.cpp33
-rw-r--r--src/quick/items/qquicktreeview_p.h6
-rw-r--r--src/quick/items/qquickwindow.cpp46
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp12
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp14
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp2
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp28
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsggeometry.cpp31
-rw-r--r--src/quick/scenegraph/coreapi/qsggeometry.h1
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterialshader.cpp4
-rw-r--r--src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp4
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.cpp4
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp14
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp4
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp4
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp15
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h5
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode.cpp14
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp2
-rw-r--r--src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp27
-rw-r--r--src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h3
-rw-r--r--src/quick/scenegraph/qsgrhishadereffectnode.cpp70
-rw-r--r--src/quick/scenegraph/qsgrhishadereffectnode_p.h2
-rw-r--r--src/quick/scenegraph/qsgrhisupport.cpp2
-rw-r--r--src/quick/scenegraph/qsgrhitextureglyphcache.cpp25
-rw-r--r--src/quick/scenegraph/qsgrhitextureglyphcache_p.h1
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp3
-rw-r--r--src/quick/util/qquickanimation.cpp50
-rw-r--r--src/quick/util/qquickanimatorcontroller.cpp14
-rw-r--r--src/quick/util/qquickanimatorjob.cpp5
-rw-r--r--src/quick/util/qquickapplication.cpp6
-rw-r--r--src/quick/util/qquickdeliveryagent.cpp280
-rw-r--r--src/quick/util/qquickdeliveryagent_p_p.h2
-rw-r--r--src/quick/util/qquickframeanimation.cpp5
-rw-r--r--src/quick/util/qquickglobal.cpp6
-rw-r--r--src/quick/util/qquickimageprovider.cpp2
-rw-r--r--src/quick/util/qquickpath.cpp52
-rw-r--r--src/quick/util/qquickpixmapcache.cpp21
-rw-r--r--src/quick/util/qquickpropertychanges.cpp12
-rw-r--r--src/quick/util/qquickshortcut.cpp4
-rw-r--r--src/quick/util/qquickshortcut_p.h3
-rw-r--r--src/quick/util/qquicksmoothedanimation.cpp2
-rw-r--r--src/quick/util/qquickstate.cpp24
-rw-r--r--src/quick/util/qquickstate_p_p.h2
-rw-r--r--src/quick/util/qquickstategroup.cpp41
-rw-r--r--src/quick/util/qquickstyledtext.cpp107
-rw-r--r--src/quick/util/qquicksvgparser.cpp2
-rw-r--r--src/quick/util/qquicktimeline.cpp4
-rw-r--r--src/quick/util/qquicktransition.cpp8
-rw-r--r--src/quick/util/qquicktransitionmanager.cpp31
-rw-r--r--src/quickcontrols2/basic/HorizontalHeaderView.qml2
-rw-r--r--src/quickcontrols2/basic/TreeViewDelegate.qml8
-rw-r--r--src/quickcontrols2/basic/VerticalHeaderView.qml2
-rw-r--r--src/quickcontrols2/designer/qtquickcontrols2.metainfo40
-rw-r--r--src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate.qml3
-rw-r--r--src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc3
-rw-r--r--src/quickcontrols2/doc/src/includes/qquicktooltip.qdocinc6
-rw-r--r--src/quickcontrols2/doc/src/qtquickcontrols2-customize.qdoc9
-rw-r--r--src/quickcontrols2/doc/src/qtquickcontrols2-delegates.qdoc4
-rw-r--r--src/quickcontrols2/doc/src/qtquickcontrols2-ios.qdoc5
-rw-r--r--src/quickcontrols2/doc/src/qtquickcontrols2-macos.qdoc2
-rw-r--r--src/quickcontrols2/doc/src/qtquickcontrols2-windows.qdoc2
-rw-r--r--src/quickcontrols2/fusion/CMakeLists.txt1
-rw-r--r--src/quickcontrols2/fusion/HorizontalHeaderView.qml10
-rw-r--r--src/quickcontrols2/fusion/TreeViewDelegate.qml62
-rw-r--r--src/quickcontrols2/fusion/VerticalHeaderView.qml10
-rw-r--r--src/quickcontrols2/fusion/qquickfusiontheme.cpp14
-rw-r--r--src/quickcontrols2/fusion/qquickfusiontheme_p.h2
-rw-r--r--src/quickcontrols2/imagine/ComboBox.qml4
-rw-r--r--src/quickcontrols2/imagine/HorizontalHeaderView.qml2
-rw-r--r--src/quickcontrols2/imagine/VerticalHeaderView.qml2
-rw-r--r--src/quickcontrols2/imagine/impl/shaders/OpacityMask.frag3
-rw-r--r--src/quickcontrols2/ios/CMakeLists.txt5
-rw-r--r--src/quickcontrols2/ios/Menu.qml71
-rw-r--r--src/quickcontrols2/ios/MenuItem.qml104
-rw-r--r--src/quickcontrols2/ios/MenuSeparator.qml26
-rw-r--r--src/quickcontrols2/ios/ProgressBar.qml12
-rw-r--r--src/quickcontrols2/ios/TreeViewDelegate.qml9
-rw-r--r--src/quickcontrols2/ios/images/menu-background-dark.9.pngbin0 -> 350 bytes
-rw-r--r--src/quickcontrols2/ios/images/menu-background-dark@2x.9.pngbin0 -> 601 bytes
-rw-r--r--src/quickcontrols2/ios/images/menu-background-dark@3x.9.pngbin0 -> 723 bytes
-rw-r--r--src/quickcontrols2/ios/images/menu-background-light.9.pngbin0 -> 319 bytes
-rw-r--r--src/quickcontrols2/ios/images/menu-background-light@2x.9.pngbin0 -> 564 bytes
-rw-r--r--src/quickcontrols2/ios/images/menu-background-light@3x.9.pngbin0 -> 697 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-dark.9.pngbin0 -> 114 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-dark@2x.9.pngbin0 -> 117 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-dark@3x.9.pngbin0 -> 118 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-dark.9.pngbin0 -> 277 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-dark@2x.9.pngbin0 -> 377 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-dark@3x.9.pngbin0 -> 474 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-light.9.pngbin0 -> 265 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-light@2x.9.pngbin0 -> 381 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-light@3x.9.pngbin0 -> 465 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark.9.pngbin0 -> 253 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark@2x.9.pngbin0 -> 366 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark@3x.9.pngbin0 -> 467 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light.9.pngbin0 -> 253 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light@2x.9.pngbin0 -> 368 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light@3x.9.pngbin0 -> 452 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-light.9.pngbin0 -> 115 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-light@2x.9.pngbin0 -> 122 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-light@3x.9.pngbin0 -> 122 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-pressed-dark.9.pngbin0 -> 113 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-pressed-dark@2x.9.pngbin0 -> 118 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-pressed-dark@3x.9.pngbin0 -> 119 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-pressed-light.9.pngbin0 -> 114 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-pressed-light@2x.9.pngbin0 -> 122 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-pressed-light@3x.9.pngbin0 -> 123 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark.9.pngbin0 -> 322 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark@2x.9.pngbin0 -> 544 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark@3x.9.pngbin0 -> 645 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-single-pressed-light.9.pngbin0 -> 310 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-single-pressed-light@2x.9.pngbin0 -> 525 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuitem-background-single-pressed-light@3x.9.pngbin0 -> 648 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuseparator-separator-dark.9.pngbin0 -> 105 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuseparator-separator-dark@2x.9.pngbin0 -> 108 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuseparator-separator-dark@3x.9.pngbin0 -> 110 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuseparator-separator-light.9.pngbin0 -> 106 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuseparator-separator-light@2x.9.pngbin0 -> 109 bytes
-rw-r--r--src/quickcontrols2/ios/images/menuseparator-separator-light@3x.9.pngbin0 -> 110 bytes
-rw-r--r--src/quickcontrols2/ios/qquickiosstyle.cpp11
-rw-r--r--src/quickcontrols2/ios/qquickiosstyle_p.h3
-rw-r--r--src/quickcontrols2/macos/TreeViewDelegate.qml2
-rw-r--r--src/quickcontrols2/material/CMakeLists.txt1
-rw-r--r--src/quickcontrols2/material/HorizontalHeaderView.qml2
-rw-r--r--src/quickcontrols2/material/TreeViewDelegate.qml62
-rw-r--r--src/quickcontrols2/material/VerticalHeaderView.qml2
-rw-r--r--src/quickcontrols2/material/qt_attribution.json4
-rw-r--r--src/quickcontrols2/universal/HorizontalHeaderView.qml2
-rw-r--r--src/quickcontrols2/universal/VerticalHeaderView.qml2
-rw-r--r--src/quickcontrols2/windows/SpinBox.qml11
-rw-r--r--src/quickcontrols2impl/qquickimageselector.cpp14
-rw-r--r--src/quickcontrols2impl/qquickmnemoniclabel.cpp2
-rw-r--r--src/quickcontrols2impl/qquickninepatchimage.cpp66
-rw-r--r--src/quickcontrolstestutils/CMakeLists.txt8
-rw-r--r--src/quickcontrolstestutils/controlstestutils.cpp33
-rw-r--r--src/quickcontrolstestutils/controlstestutils_p.h12
-rw-r--r--src/quickcontrolstestutils/dialogstestutils.cpp12
-rw-r--r--src/quickcontrolstestutils/qtest_quickcontrols_p.h4
-rw-r--r--src/quickdialogs2/quickdialogs2/doc/qtquickdialogs.qdocconf2
-rw-r--r--src/quickdialogs2/quickdialogs2/doc/snippets/qtquickdialogs-filedialog.qml34
-rw-r--r--src/quickdialogs2/quickdialogs2/qquickfiledialog.cpp22
-rw-r--r--src/quickdialogs2/quickdialogs2/qquickfolderdialog.cpp8
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt5
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/ColorDialog.qml30
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml38
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/ColorDialog.qml29
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml40
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/ColorDialog.qml28
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml49
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/ColorDialog.qml28
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml35
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/ColorDialog.qml28
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/ColorInputs.qml434
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml52
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker.cpp36
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker_p.h2
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker_p_p.h16
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl.cpp105
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl_p.h20
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl_p_p.h13
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogutils.cpp24
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogutils_p.h36
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickcolorinputs.cpp509
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickcolorinputs_p.h171
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp70
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h18
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h5
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp16
-rw-r--r--src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp6
-rw-r--r--src/quicklayouts/qquickgridlayoutengine.cpp7
-rw-r--r--src/quicklayouts/qquickgridlayoutengine_p.h3
-rw-r--r--src/quicklayouts/qquicklayout.cpp16
-rw-r--r--src/quicklayouts/qquicklayout_p.h3
-rw-r--r--src/quicklayouts/qquicklinearlayout.cpp3
-rw-r--r--src/quicklayouts/qquicklinearlayout_p.h2
-rw-r--r--src/quicklayouts/qquickstacklayout.cpp41
-rw-r--r--src/quicklayouts/qquickstacklayout_p.h3
-rw-r--r--src/quicknativestyle/controls/DefaultTreeViewDelegate.qml2
-rw-r--r--src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm16
-rw-r--r--src/quicknativestyle/qstyle/qquickcommonstyle.cpp7
-rw-r--r--src/quickshapes/qquickshape.cpp12
-rw-r--r--src/quickshapes/qquickshape_p_p.h2
-rw-r--r--src/quickshapes/qquickshapegenericrenderer.cpp44
-rw-r--r--src/quickshapes/qquickshapesoftwarerenderer.cpp12
-rw-r--r--src/quicktemplates2/accessible/qaccessiblequickpage.cpp2
-rw-r--r--src/quicktemplates2/qquickaction.cpp10
-rw-r--r--src/quicktemplates2/qquickactiongroup.cpp6
-rw-r--r--src/quicktemplates2/qquickbuttongroup.cpp8
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp10
-rw-r--r--src/quicktemplates2/qquickcontainer.cpp4
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp30
-rw-r--r--src/quicktemplates2/qquickcontrol_p_p.h1
-rw-r--r--src/quicktemplates2/qquickdialog.cpp2
-rw-r--r--src/quicktemplates2/qquickdialogbuttonbox.cpp6
-rw-r--r--src/quicktemplates2/qquickdrawer.cpp16
-rw-r--r--src/quicktemplates2/qquickmenu.cpp8
-rw-r--r--src/quicktemplates2/qquickmenubar.cpp9
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp46
-rw-r--r--src/quicktemplates2/qquickoverlay_p_p.h10
-rw-r--r--src/quicktemplates2/qquickpane.cpp4
-rw-r--r--src/quicktemplates2/qquickpopup.cpp24
-rw-r--r--src/quicktemplates2/qquickpopuppositioner.cpp8
-rw-r--r--src/quicktemplates2/qquickpresshandler.cpp2
-rw-r--r--src/quicktemplates2/qquickscrollbar.cpp17
-rw-r--r--src/quicktemplates2/qquickshortcutcontext.cpp5
-rw-r--r--src/quicktemplates2/qquicksplitview.cpp86
-rw-r--r--src/quicktemplates2/qquickstackelement.cpp10
-rw-r--r--src/quicktemplates2/qquickstackelement_p_p.h1
-rw-r--r--src/quicktemplates2/qquickstackview.cpp30
-rw-r--r--src/quicktemplates2/qquickstackview_p.cpp8
-rw-r--r--src/quicktemplates2/qquickswipedelegate.cpp10
-rw-r--r--src/quicktemplates2/qquicktabbar.cpp2
-rw-r--r--src/quicktemplates2/qquicktextarea.cpp6
-rw-r--r--src/quicktemplates2/qquicktextfield.cpp15
-rw-r--r--src/quicktemplates2/qquicktooltip.cpp2
-rw-r--r--src/quicktemplates2/qquicktreeviewdelegate.cpp217
-rw-r--r--src/quicktemplates2/qquicktreeviewdelegate_p.h2
-rw-r--r--src/quicktestutils/qml/testhttpserver.cpp10
-rw-r--r--src/quicktestutils/quick/viewtestutils.cpp117
-rw-r--r--src/quicktestutils/quick/viewtestutils_p.h11
-rw-r--r--src/quicktestutils/quick/visualtestutils.cpp4
-rw-r--r--src/quicktestutils/quick/visualtestutils_p.h6
-rw-r--r--src/quickwidgets/qquickwidget.cpp24
607 files changed, 7769 insertions, 3952 deletions
diff --git a/src/3rdparty/masm/assembler/ARM64Assembler.h b/src/3rdparty/masm/assembler/ARM64Assembler.h
index 9928da3abd..847b0b09b0 100644
--- a/src/3rdparty/masm/assembler/ARM64Assembler.h
+++ b/src/3rdparty/masm/assembler/ARM64Assembler.h
@@ -657,6 +657,10 @@ public:
data.realTypes.m_bitNumber = bitNumber;
data.realTypes.m_compareRegister = compareRegister;
}
+ LinkRecord(const LinkRecord& other)
+ {
+ *this = other;
+ }
void operator=(const LinkRecord& other)
{
data.realTypes = other.data.realTypes;
diff --git a/src/3rdparty/masm/assembler/ARMv7Assembler.h b/src/3rdparty/masm/assembler/ARMv7Assembler.h
index 330b6c3629..fe0bc0ed74 100644
--- a/src/3rdparty/masm/assembler/ARMv7Assembler.h
+++ b/src/3rdparty/masm/assembler/ARMv7Assembler.h
@@ -481,6 +481,10 @@ public:
data.realTypes.m_linkType = LinkInvalid;
data.realTypes.m_condition = condition;
}
+ LinkRecord(const LinkRecord &other)
+ {
+ *this = other;
+ }
void operator=(const LinkRecord& other)
{
data.copyTypes.content[0] = other.data.copyTypes.content[0];
diff --git a/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp b/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp
index 868a101935..a8990a92b4 100644
--- a/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp
+++ b/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp
@@ -227,7 +227,7 @@ void OSAllocator::commit(void* address, size_t bytes, bool writable, bool execut
while (madvise(address, bytes, MADV_WILLNEED)) {
if (errno != EAGAIN)
- CRASH();
+ break; // We don't have to crash here. MADV_WILLNEED is only advisory
}
#elif HAVE(MADV_FREE_REUSE)
diff --git a/src/3rdparty/masm/wtf/Platform.h b/src/3rdparty/masm/wtf/Platform.h
index 29decfadcf..5c83dec2b9 100644
--- a/src/3rdparty/masm/wtf/Platform.h
+++ b/src/3rdparty/masm/wtf/Platform.h
@@ -224,6 +224,7 @@
|| defined(__ARM_ARCH_6K__) \
|| defined(__ARM_ARCH_6Z__) \
|| defined(__ARM_ARCH_6ZK__) \
+ || defined(__ARM_ARCH_6KZ__) \
|| defined(__ARM_ARCH_6T2__) \
|| defined(__ARMV6__)
#define WTF_ARM_ARCH_VERSION 6
diff --git a/src/3rdparty/masm/yarr/YarrInterpreter.cpp b/src/3rdparty/masm/yarr/YarrInterpreter.cpp
index cdcd16af64..f57fe363b4 100644
--- a/src/3rdparty/masm/yarr/YarrInterpreter.cpp
+++ b/src/3rdparty/masm/yarr/YarrInterpreter.cpp
@@ -2406,8 +2406,8 @@ unsigned interpret(BytecodePattern* bytecode, const String& input, unsigned star
{
SuperSamplerScope superSamplerScope(false);
if (input.is8Bit())
- return Interpreter<LChar>(bytecode, output, input.characters8(), input.length(), start).interpret();
- return Interpreter<UChar>(bytecode, output, input.characters16(), input.length(), start).interpret();
+ return Interpreter<LChar>(bytecode, output, input.characters8(), input.size(), start).interpret();
+ return Interpreter<UChar>(bytecode, output, input.characters16(), input.size(), start).interpret();
}
unsigned interpret(BytecodePattern* bytecode, const LChar* input, unsigned length, unsigned start, unsigned* output)
diff --git a/src/3rdparty/masm/yarr/YarrParser.h b/src/3rdparty/masm/yarr/YarrParser.h
index d5433286dd..a6044d49ac 100644
--- a/src/3rdparty/masm/yarr/YarrParser.h
+++ b/src/3rdparty/masm/yarr/YarrParser.h
@@ -215,7 +215,7 @@ private:
: m_delegate(delegate)
, m_backReferenceLimit(backReferenceLimit)
, m_data(pattern.characters<CharType>())
- , m_size(pattern.length())
+ , m_size(pattern.size())
, m_isUnicode(isUnicode)
{
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 71d6b0d910..dc3ea3494c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,10 +28,12 @@ if(TARGET Qt::Gui AND TARGET Qt::qsb AND QT_FEATURE_qml_animation)
add_subdirectory(quick)
add_subdirectory(quicklayouts)
- find_package(Qt6 ${PROJECT_VERSION} CONFIG COMPONENTS Test) # special case
- if(QT_FEATURE_testlib AND TARGET Qt::Test) # special case
+ find_package(Qt6 ${PROJECT_VERSION} QUIET CONFIG OPTIONAL_COMPONENTS Test)
+ if(QT_FEATURE_testlib AND TARGET Qt::Test)
add_subdirectory(qmltest)
- add_subdirectory(quicktestutils)
+ if(QT_FEATURE_network)
+ add_subdirectory(quicktestutils)
+ endif()
endif()
if(QT_FEATURE_quick_particles)
@@ -52,7 +54,7 @@ if(TARGET Qt::Gui AND TARGET Qt::qsb AND QT_FEATURE_qml_animation)
add_subdirectory(quickdialogs2)
add_subdirectory(quicknativestyle)
- if(TARGET Qt::QuickControls2)
+ if(QT_FEATURE_testlib AND QT_FEATURE_network AND TARGET Qt::Test AND TARGET Qt::QuickControls2)
add_subdirectory(quickcontrolstestutils)
endif()
else()
diff --git a/src/labs/animation/qquickboundaryrule.cpp b/src/labs/animation/qquickboundaryrule.cpp
index fbf82023bc..08fa5f56ac 100644
--- a/src/labs/animation/qquickboundaryrule.cpp
+++ b/src/labs/animation/qquickboundaryrule.cpp
@@ -318,7 +318,7 @@ qreal QQuickBoundaryRule::peakOvershoot() const
}
/*!
- \qmlproperty enum QtQuick::BoundaryRule::overshootFilter
+ \qmlproperty enumeration QtQuick::BoundaryRule::overshootFilter
This property specifies the aggregation function that will be applied to
the intercepted property value.
@@ -384,7 +384,7 @@ bool QQuickBoundaryRule::returnToBounds()
}
/*!
- \qmlproperty qreal QtQuick::BoundaryRule::easing
+ \qmlproperty enumeration QtQuick::BoundaryRule::easing
This property holds the easing curve to be applied in overshoot mode
(whenever the \l minimum or \l maximum constraint is violated, while
diff --git a/src/labs/folderlistmodel/fileinfothread.cpp b/src/labs/folderlistmodel/fileinfothread.cpp
index fa726d95c3..edde6422e8 100644
--- a/src/labs/folderlistmodel/fileinfothread.cpp
+++ b/src/labs/folderlistmodel/fileinfothread.cpp
@@ -268,7 +268,7 @@ void FileInfoThread::getFileInfos(const QString &path)
const QFileInfoList fileInfoList = currentDir.entryInfoList(nameFilters, filter, sortFlags);
if (!fileInfoList.isEmpty()) {
- filePropertyList.reserve(fileInfoList.count());
+ filePropertyList.reserve(fileInfoList.size());
for (const QFileInfo &info : fileInfoList) {
//qDebug() << "Adding file : " << info.fileName() << "to list ";
filePropertyList << FileProperty(info);
diff --git a/src/labs/folderlistmodel/qquickfolderlistmodel.cpp b/src/labs/folderlistmodel/qquickfolderlistmodel.cpp
index c1070e3f4f..3b07efab77 100644
--- a/src/labs/folderlistmodel/qquickfolderlistmodel.cpp
+++ b/src/labs/folderlistmodel/qquickfolderlistmodel.cpp
@@ -175,7 +175,7 @@ QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path)
QString localPath = QQmlFile::urlToLocalFileOrQrc(path);
QUrl localUrl = QUrl(localPath);
QString fullPath = localUrl.path();
- if (localUrl.scheme().length())
+ if (localUrl.scheme().size())
fullPath = localUrl.scheme() + QLatin1Char(':') + fullPath;
return QDir::cleanPath(fullPath);
}
diff --git a/src/labs/models/qqmldelegatecomponent.cpp b/src/labs/models/qqmldelegatecomponent.cpp
index 45e64995fb..3a9bb647c6 100644
--- a/src/labs/models/qqmldelegatecomponent.cpp
+++ b/src/labs/models/qqmldelegatecomponent.cpp
@@ -239,7 +239,7 @@ void QQmlDelegateChooser::choices_append(QQmlListProperty<QQmlDelegateChoice> *p
qsizetype QQmlDelegateChooser::choices_count(QQmlListProperty<QQmlDelegateChoice> *prop)
{
QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser*>(prop->object);
- return q->m_choices.count();
+ return q->m_choices.size();
}
QQmlDelegateChoice *QQmlDelegateChooser::choices_at(QQmlListProperty<QQmlDelegateChoice> *prop, qsizetype index)
@@ -294,7 +294,7 @@ QQmlComponent *QQmlDelegateChooser::delegate(QQmlAdaptorModel *adaptorModel, int
}
// loop through choices, finding first one that fits
- for (int i = 0; i < m_choices.count(); ++i) {
+ for (int i = 0; i < m_choices.size(); ++i) {
const QQmlDelegateChoice *choice = m_choices.at(i);
if (choice->match(row, column, v))
return choice->delegate();
diff --git a/src/labs/models/qqmltablemodel.cpp b/src/labs/models/qqmltablemodel.cpp
index e95ea46c84..2822087439 100644
--- a/src/labs/models/qqmltablemodel.cpp
+++ b/src/labs/models/qqmltablemodel.cpp
@@ -627,7 +627,7 @@ void QQmlTableModel::columns_append(QQmlListProperty<QQmlTableModelColumn> *prop
qsizetype QQmlTableModel::columns_count(QQmlListProperty<QQmlTableModelColumn> *property)
{
const QQmlTableModel *model = static_cast<QQmlTableModel*>(property->object);
- return model->mColumns.count();
+ return model->mColumns.size();
}
QQmlTableModelColumn *QQmlTableModel::columns_at(QQmlListProperty<QQmlTableModelColumn> *property, qsizetype index)
diff --git a/src/labs/platform/doc/qtlabsplatform.qdocconf b/src/labs/platform/doc/qtlabsplatform.qdocconf
index f159fff9bf..b7f056521c 100644
--- a/src/labs/platform/doc/qtlabsplatform.qdocconf
+++ b/src/labs/platform/doc/qtlabsplatform.qdocconf
@@ -19,7 +19,7 @@ qhp.QtLabsPlatform.subprojects.qmltypes.indexTitle = Qt Labs Platform QML Types
qhp.QtLabsPlatform.subprojects.qmltypes.selectors = qmlclass
qhp.QtLabsPlatform.subprojects.qmltypes.sortPages = true
-depends = qtcore qtgui qtdoc qtqml qtqmlmodels qtquick qtquickcontrols qtwidgets
+depends = qtcore qtgui qtdoc qtqml qtqmlcore qtqmlmodels qtquick qtquickcontrols qtwidgets
# This module has no documented C++ types, clear the module header
moduleheader =
diff --git a/src/labs/platform/qquicklabsplatformdialog_p.h b/src/labs/platform/qquicklabsplatformdialog_p.h
index a8d810696c..e04b097694 100644
--- a/src/labs/platform/qquicklabsplatformdialog_p.h
+++ b/src/labs/platform/qquicklabsplatformdialog_p.h
@@ -116,7 +116,7 @@ private:
QPlatformDialogHelper *m_handle;
};
-class QPlatformDialogHelperForeign
+class QPlatformDialogHelperQuickLabsForeign
{
Q_GADGET
QML_FOREIGN(QPlatformDialogHelper)
diff --git a/src/labs/platform/qquicklabsplatformfiledialog.cpp b/src/labs/platform/qquicklabsplatformfiledialog.cpp
index 540da2b3bc..4cd3172820 100644
--- a/src/labs/platform/qquicklabsplatformfiledialog.cpp
+++ b/src/labs/platform/qquicklabsplatformfiledialog.cpp
@@ -308,7 +308,7 @@ void QQuickLabsPlatformFileDialog::setNameFilters(const QStringList &filters)
m_options->setNameFilters(filters);
if (m_selectedNameFilter) {
int index = m_selectedNameFilter->index();
- if (index < 0 || index >= filters.count())
+ if (index < 0 || index >= filters.size())
index = 0;
m_selectedNameFilter->update(filters.value(index));
}
diff --git a/src/labs/platform/qquicklabsplatformfolderdialog.cpp b/src/labs/platform/qquicklabsplatformfolderdialog.cpp
index f152213ff2..512f241b7d 100644
--- a/src/labs/platform/qquicklabsplatformfolderdialog.cpp
+++ b/src/labs/platform/qquicklabsplatformfolderdialog.cpp
@@ -91,7 +91,6 @@ void QQuickLabsPlatformFolderDialog::setFolder(const QUrl &folder)
return;
m_folder = folder;
- setCurrentFolder(folder);
emit folderChanged();
}
diff --git a/src/labs/platform/qquicklabsplatformmenu.cpp b/src/labs/platform/qquicklabsplatformmenu.cpp
index 04f1abd15d..cd23813d63 100644
--- a/src/labs/platform/qquicklabsplatformmenu.cpp
+++ b/src/labs/platform/qquicklabsplatformmenu.cpp
@@ -194,7 +194,7 @@ QQuickLabsPlatformMenu::~QQuickLabsPlatformMenu()
void QQuickLabsPlatformMenu::unparentSubmenus()
{
- for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) {
+ for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items)) {
if (QQuickLabsPlatformMenu *subMenu = item->subMenu())
subMenu->setParentMenu(nullptr);
item->setMenu(nullptr);
@@ -234,7 +234,7 @@ QPlatformMenu * QQuickLabsPlatformMenu::create()
connect(m_handle, &QPlatformMenu::aboutToShow, this, &QQuickLabsPlatformMenu::aboutToShow);
connect(m_handle, &QPlatformMenu::aboutToHide, this, &QQuickLabsPlatformMenu::aboutToHide);
- for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items))
+ for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items))
m_handle->insertMenuItem(item->create(), nullptr);
if (m_menuItem) {
@@ -278,7 +278,7 @@ void QQuickLabsPlatformMenu::sync()
m_systemTrayIcon->handle()->updateMenu(m_handle);
#endif
- for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items))
+ for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items))
item->sync();
}
@@ -564,7 +564,7 @@ void QQuickLabsPlatformMenu::setIcon(const QQuickLabsPlatformIcon &icon)
*/
void QQuickLabsPlatformMenu::addItem(QQuickLabsPlatformMenuItem *item)
{
- insertItem(m_items.count(), item);
+ insertItem(m_items.size(), item);
}
/*!
@@ -613,7 +613,7 @@ void QQuickLabsPlatformMenu::removeItem(QQuickLabsPlatformMenuItem *item)
*/
void QQuickLabsPlatformMenu::addMenu(QQuickLabsPlatformMenu *menu)
{
- insertMenu(m_items.count(), menu);
+ insertMenu(m_items.size(), menu);
}
/*!
@@ -654,7 +654,7 @@ void QQuickLabsPlatformMenu::clear()
if (m_items.isEmpty())
return;
- for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) {
+ for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items)) {
m_data.removeOne(item);
if (m_handle)
m_handle->removeMenuItem(item->handle());
@@ -809,7 +809,7 @@ void QQuickLabsPlatformMenu::data_append(QQmlListProperty<QObject> *property, QO
qsizetype QQuickLabsPlatformMenu::data_count(QQmlListProperty<QObject> *property)
{
QQuickLabsPlatformMenu *menu = static_cast<QQuickLabsPlatformMenu *>(property->object);
- return menu->m_data.count();
+ return menu->m_data.size();
}
QObject *QQuickLabsPlatformMenu::data_at(QQmlListProperty<QObject> *property, qsizetype index)
@@ -833,7 +833,7 @@ void QQuickLabsPlatformMenu::items_append(QQmlListProperty<QQuickLabsPlatformMen
qsizetype QQuickLabsPlatformMenu::items_count(QQmlListProperty<QQuickLabsPlatformMenuItem> *property)
{
QQuickLabsPlatformMenu *menu = static_cast<QQuickLabsPlatformMenu *>(property->object);
- return menu->m_items.count();
+ return menu->m_items.size();
}
QQuickLabsPlatformMenuItem *QQuickLabsPlatformMenu::items_at(QQmlListProperty<QQuickLabsPlatformMenuItem> *property, qsizetype index)
diff --git a/src/labs/platform/qquicklabsplatformmenubar.cpp b/src/labs/platform/qquicklabsplatformmenubar.cpp
index ed7ebf9de3..8c0b4fd042 100644
--- a/src/labs/platform/qquicklabsplatformmenubar.cpp
+++ b/src/labs/platform/qquicklabsplatformmenubar.cpp
@@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE
\li macOS
\li Android
\li Linux (only available on desktop environments that provide a global D-Bus menu bar)
+ \li Windows
\endlist
\labs
@@ -84,7 +85,7 @@ QQuickLabsPlatformMenuBar::QQuickLabsPlatformMenuBar(QObject *parent)
QQuickLabsPlatformMenuBar::~QQuickLabsPlatformMenuBar()
{
- for (QQuickLabsPlatformMenu *menu : qAsConst(m_menus))
+ for (QQuickLabsPlatformMenu *menu : std::as_const(m_menus))
menu->setMenuBar(nullptr);
delete m_handle;
m_handle = nullptr;
@@ -153,7 +154,7 @@ void QQuickLabsPlatformMenuBar::setWindow(QWindow *window)
*/
void QQuickLabsPlatformMenuBar::addMenu(QQuickLabsPlatformMenu *menu)
{
- insertMenu(m_menus.count(), menu);
+ insertMenu(m_menus.size(), menu);
}
/*!
@@ -203,7 +204,7 @@ void QQuickLabsPlatformMenuBar::clear()
if (m_menus.isEmpty())
return;
- for (QQuickLabsPlatformMenu *menu : qAsConst(m_menus)) {
+ for (QQuickLabsPlatformMenu *menu : std::as_const(m_menus)) {
m_data.removeOne(menu);
if (m_handle)
m_handle->removeMenu(menu->handle());
@@ -222,7 +223,7 @@ void QQuickLabsPlatformMenuBar::classBegin()
void QQuickLabsPlatformMenuBar::componentComplete()
{
m_complete = true;
- for (QQuickLabsPlatformMenu *menu : qAsConst(m_menus))
+ for (QQuickLabsPlatformMenu *menu : std::as_const(m_menus))
menu->sync();
if (!m_window)
setWindow(findWindow());
@@ -256,7 +257,7 @@ void QQuickLabsPlatformMenuBar::data_append(QQmlListProperty<QObject> *property,
qsizetype QQuickLabsPlatformMenuBar::data_count(QQmlListProperty<QObject> *property)
{
QQuickLabsPlatformMenuBar *menuBar = static_cast<QQuickLabsPlatformMenuBar *>(property->object);
- return menuBar->m_data.count();
+ return menuBar->m_data.size();
}
QObject *QQuickLabsPlatformMenuBar::data_at(QQmlListProperty<QObject> *property, qsizetype index)
@@ -280,7 +281,7 @@ void QQuickLabsPlatformMenuBar::menus_append(QQmlListProperty<QQuickLabsPlatform
qsizetype QQuickLabsPlatformMenuBar::menus_count(QQmlListProperty<QQuickLabsPlatformMenu> *property)
{
QQuickLabsPlatformMenuBar *menuBar = static_cast<QQuickLabsPlatformMenuBar *>(property->object);
- return menuBar->m_menus.count();
+ return menuBar->m_menus.size();
}
QQuickLabsPlatformMenu *QQuickLabsPlatformMenuBar::menus_at(QQmlListProperty<QQuickLabsPlatformMenu> *property, qsizetype index)
diff --git a/src/labs/platform/qquicklabsplatformmenuitem.cpp b/src/labs/platform/qquicklabsplatformmenuitem.cpp
index 43afaa0f9f..31e91add36 100644
--- a/src/labs/platform/qquicklabsplatformmenuitem.cpp
+++ b/src/labs/platform/qquicklabsplatformmenuitem.cpp
@@ -90,16 +90,7 @@ QQuickLabsPlatformMenuItem::~QQuickLabsPlatformMenuItem()
m_menu->removeItem(this);
if (m_group)
m_group->removeItem(this);
-#if QT_CONFIG(shortcut)
- if (m_shortcutId != -1) {
- QKeySequence sequence;
- if (m_shortcut.metaType().id() == QMetaType::Int)
- sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
- else
- sequence = QKeySequence::fromString(m_shortcut.toString());
- QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_shortcutId, this, sequence);
- }
-#endif
+ removeShortcut();
delete m_iconLoader;
m_iconLoader = nullptr;
delete m_handle;
@@ -266,8 +257,15 @@ void QQuickLabsPlatformMenuItem::setEnabled(bool enabled)
if (m_enabled == enabled)
return;
+ if (!enabled)
+ removeShortcut();
+
bool wasEnabled = isEnabled();
m_enabled = enabled;
+
+ if (enabled)
+ addShortcut();
+
sync();
if (isEnabled() != wasEnabled)
emit enabledChanged();
@@ -473,31 +471,10 @@ void QQuickLabsPlatformMenuItem::setShortcut(const QVariant& shortcut)
if (m_shortcut == shortcut)
return;
-#if QT_CONFIG(shortcut)
- if (m_shortcutId != -1) {
- QKeySequence sequence;
- if (m_shortcut.metaType().id() == QMetaType::Int)
- sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
- else
- sequence = QKeySequence::fromString(m_shortcut.toString());
- QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_shortcutId, this, sequence);
- }
-#endif
+ removeShortcut();
m_shortcut = shortcut;
sync();
-#if QT_CONFIG(shortcut)
- QKeySequence sequence;
- if (m_shortcut.metaType().id() == QMetaType::Int)
- sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
- else
- sequence = QKeySequence::fromString(m_shortcut.toString());
- if (!sequence.isEmpty()) {
- m_shortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, sequence,
- Qt::WindowShortcut, QQuickShortcutContext::matcher);
- } else {
- m_shortcutId = -1;
- }
-#endif
+ addShortcut();
emit shortcutChanged();
}
@@ -603,6 +580,38 @@ void QQuickLabsPlatformMenuItem::updateIcon()
sync();
}
+void QQuickLabsPlatformMenuItem::addShortcut()
+{
+#if QT_CONFIG(shortcut)
+ QKeySequence sequence;
+ if (m_shortcut.metaType().id() == QMetaType::Int)
+ sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
+ else
+ sequence = QKeySequence::fromString(m_shortcut.toString());
+ if (!sequence.isEmpty() && m_enabled) {
+ m_shortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, sequence,
+ Qt::WindowShortcut, QQuickShortcutContext::matcher);
+ } else {
+ m_shortcutId = -1;
+ }
+#endif
+}
+
+void QQuickLabsPlatformMenuItem::removeShortcut()
+{
+#if QT_CONFIG(shortcut)
+ if (m_shortcutId == -1)
+ return;
+
+ QKeySequence sequence;
+ if (m_shortcut.metaType().id() == QMetaType::Int)
+ sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
+ else
+ sequence = QKeySequence::fromString(m_shortcut.toString());
+ QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_shortcutId, this, sequence);
+#endif
+}
+
QT_END_NAMESPACE
#include "moc_qquicklabsplatformmenuitem_p.cpp"
diff --git a/src/labs/platform/qquicklabsplatformmenuitem_p.h b/src/labs/platform/qquicklabsplatformmenuitem_p.h
index 48c03eca33..f02f2536fd 100644
--- a/src/labs/platform/qquicklabsplatformmenuitem_p.h
+++ b/src/labs/platform/qquicklabsplatformmenuitem_p.h
@@ -131,6 +131,9 @@ private Q_SLOTS:
void updateIcon();
private:
+ void addShortcut();
+ void removeShortcut();
+
bool m_complete;
bool m_enabled;
bool m_visible;
diff --git a/src/labs/platform/qquicklabsplatformmenuitemgroup.cpp b/src/labs/platform/qquicklabsplatformmenuitemgroup.cpp
index df121e47ff..33580dd04e 100644
--- a/src/labs/platform/qquicklabsplatformmenuitemgroup.cpp
+++ b/src/labs/platform/qquicklabsplatformmenuitemgroup.cpp
@@ -131,7 +131,7 @@ void QQuickLabsPlatformMenuItemGroup::setEnabled(bool enabled)
m_enabled = enabled;
emit enabledChanged();
- for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) {
+ for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items)) {
if (item->m_enabled) {
item->sync();
emit item->enabledChanged();
@@ -160,7 +160,7 @@ void QQuickLabsPlatformMenuItemGroup::setVisible(bool visible)
m_visible = visible;
emit visibleChanged();
- for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) {
+ for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items)) {
if (item->m_visible) {
item->sync();
emit item->visibleChanged();
@@ -189,7 +189,7 @@ void QQuickLabsPlatformMenuItemGroup::setExclusive(bool exclusive)
m_exclusive = exclusive;
emit exclusiveChanged();
- for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items))
+ for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items))
item->sync();
}
@@ -284,7 +284,7 @@ void QQuickLabsPlatformMenuItemGroup::clear()
if (m_items.isEmpty())
return;
- for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) {
+ for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items)) {
item->setGroup(nullptr);
disconnect(item, &QQuickLabsPlatformMenuItem::checkedChanged, this, &QQuickLabsPlatformMenuItemGroup::updateCurrent);
disconnect(item, &QQuickLabsPlatformMenuItem::triggered, this, &QQuickLabsPlatformMenuItemGroup::activateItem);
@@ -339,7 +339,7 @@ void QQuickLabsPlatformMenuItemGroup::items_append(QQmlListProperty<QQuickLabsPl
qsizetype QQuickLabsPlatformMenuItemGroup::items_count(QQmlListProperty<QQuickLabsPlatformMenuItem> *prop)
{
QQuickLabsPlatformMenuItemGroup *group = static_cast<QQuickLabsPlatformMenuItemGroup *>(prop->object);
- return group->m_items.count();
+ return group->m_items.size();
}
QQuickLabsPlatformMenuItem *QQuickLabsPlatformMenuItemGroup::items_at(QQmlListProperty<QQuickLabsPlatformMenuItem> *prop, qsizetype index)
diff --git a/src/labs/platform/qquicklabsplatformstandardpaths.cpp b/src/labs/platform/qquicklabsplatformstandardpaths.cpp
index e44c1b87d1..3133cdd306 100644
--- a/src/labs/platform/qquicklabsplatformstandardpaths.cpp
+++ b/src/labs/platform/qquicklabsplatformstandardpaths.cpp
@@ -3,6 +3,8 @@
#include "qquicklabsplatformstandardpaths_p.h"
+#if QT_DEPRECATED_SINCE(6, 4)
+
#include <QtQml/qqmlengine.h>
QT_BEGIN_NAMESPACE
@@ -13,6 +15,7 @@ QT_BEGIN_NAMESPACE
//! \instantiates QQuickLabsPlatformStandardPaths
\inqmlmodule Qt.labs.platform
\since 5.8
+ \deprecated [6.4] Use QtCore::StandardPaths instead.
\brief Provides access to the standard system paths.
The StandardPaths singleton type provides methods for querying the standard
@@ -27,7 +30,7 @@ QT_BEGIN_NAMESPACE
\labs
- \sa FileDialog, FolderDialog, QStandardPaths
+ \sa QtCore::StandardPaths, FileDialog, FolderDialog, QStandardPaths
*/
static QList<QUrl> toUrlList(const QStringList &paths)
@@ -137,3 +140,5 @@ QUrl QQuickLabsPlatformStandardPaths::writableLocation(QStandardPaths::StandardL
QT_END_NAMESPACE
#include "moc_qquicklabsplatformstandardpaths_p.cpp"
+
+#endif // QT_DEPRECATED_SINCE(6, 4)
diff --git a/src/labs/platform/qquicklabsplatformstandardpaths_p.h b/src/labs/platform/qquicklabsplatformstandardpaths_p.h
index 1e0d96b953..9941c3081e 100644
--- a/src/labs/platform/qquicklabsplatformstandardpaths_p.h
+++ b/src/labs/platform/qquicklabsplatformstandardpaths_p.h
@@ -21,6 +21,8 @@
#include <QtQml/qqml.h>
#include <QtCore/private/qglobal_p.h>
+#if QT_DEPRECATED_SINCE(6, 4)
+
QT_BEGIN_NAMESPACE
class QQmlEngine;
@@ -56,4 +58,6 @@ QML_DECLARE_TYPE(QQuickLabsPlatformStandardPaths)
Q_DECLARE_METATYPE(QStandardPaths::StandardLocation)
Q_DECLARE_METATYPE(QStandardPaths::LocateOptions)
+#endif // QT_DEPRECATED_SINCE(6, 4)
+
#endif // QQUICKLABSPLATFORMSTANDARDPATHS_P_H
diff --git a/src/labs/platform/widgets/qwidgetplatformfiledialog.cpp b/src/labs/platform/widgets/qwidgetplatformfiledialog.cpp
index ae9d7d3cb0..738982b5c6 100644
--- a/src/labs/platform/widgets/qwidgetplatformfiledialog.cpp
+++ b/src/labs/platform/widgets/qwidgetplatformfiledialog.cpp
@@ -21,7 +21,7 @@ QWidgetPlatformFileDialog::QWidgetPlatformFileDialog(QObject *parent)
});
connect(m_dialog.data(), &QFileDialog::filesSelected, [this](const QList<QString> &files) {
QList<QUrl> urls;
- urls.reserve(files.count());
+ urls.reserve(files.size());
for (const QString &file : files)
urls += QUrl::fromLocalFile(file);
emit filesSelected(urls);
diff --git a/src/labs/platform/widgets/qwidgetplatformmenu.cpp b/src/labs/platform/widgets/qwidgetplatformmenu.cpp
index 1db01a5e79..a154775b94 100644
--- a/src/labs/platform/widgets/qwidgetplatformmenu.cpp
+++ b/src/labs/platform/widgets/qwidgetplatformmenu.cpp
@@ -6,6 +6,7 @@
#include <QtGui/qaction.h>
#include <QtGui/qwindow.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtWidgets/qmenu.h>
QT_BEGIN_NAMESPACE
@@ -38,7 +39,7 @@ void QWidgetPlatformMenu::insertMenuItem(QPlatformMenuItem *item, QPlatformMenuI
m_menu->insertAction(widgetBefore ? widgetBefore->action() : nullptr, widgetItem->action());
int index = m_items.indexOf(widgetBefore);
if (index < 0)
- index = m_items.count();
+ index = m_items.size();
m_items.insert(index, widgetItem);
}
@@ -112,7 +113,7 @@ void QWidgetPlatformMenu::showPopup(const QWindow *window, const QRect &targetRe
QPoint targetPos = targetRect.bottomLeft();
if (window)
- targetPos = window->mapToGlobal(targetPos);
+ targetPos = window->mapToGlobal(QHighDpi::fromNativeLocalPosition(targetPos, window));
const QWidgetPlatformMenuItem *widgetItem = qobject_cast<const QWidgetPlatformMenuItem *>(item);
m_menu->popup(targetPos, widgetItem ? widgetItem->action() : nullptr);
diff --git a/src/labs/sharedimage/qsharedimageprovider.cpp b/src/labs/sharedimage/qsharedimageprovider.cpp
index 7bac6d4e03..69f0013b06 100644
--- a/src/labs/sharedimage/qsharedimageprovider.cpp
+++ b/src/labs/sharedimage/qsharedimageprovider.cpp
@@ -45,7 +45,7 @@ QImage QuickSharedImageLoader::loadFile(const QString &path, ImageParameters *pa
}
}
- if (params && params->count() > OriginalSize)
+ if (params && params->size() > OriginalSize)
params->replace(OriginalSize, realSize);
return image;
diff --git a/src/labs/wavefrontmesh/qwavefrontmesh.cpp b/src/labs/wavefrontmesh/qwavefrontmesh.cpp
index 536447c26d..844ebfbd84 100644
--- a/src/labs/wavefrontmesh/qwavefrontmesh.cpp
+++ b/src/labs/wavefrontmesh/qwavefrontmesh.cpp
@@ -245,7 +245,7 @@ void QWavefrontMesh::readData()
d->textureCoordinates.append(QVector2D(u, v));
} else if (command == "v") {
// Format: v <x> <y> <z> [w]
- if (tokens.length() < 4 || tokens.length() > 5) {
+ if (tokens.size() < 4 || tokens.size() > 5) {
setLastError(InvalidSourceError);
return;
}
@@ -438,7 +438,7 @@ QString QWavefrontMesh::log() const
bool QWavefrontMesh::validateAttributes(const QList<QByteArray> &attributes, int *posIndex)
{
Q_D(QWavefrontMesh);
- const int attrCount = attributes.count();
+ const int attrCount = attributes.size();
int positionIndex = attributes.indexOf(qtPositionAttributeName());
int texCoordIndex = attributes.indexOf(qtTexCoordAttributeName());
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp
index 92b52065bb..71ada8a5b9 100644
--- a/src/particles/qquickcustomaffector.cpp
+++ b/src/particles/qquickcustomaffector.cpp
@@ -84,7 +84,7 @@ void QQuickCustomAffector::affectSystem(qreal dt)
updateOffsets();
QList<QQuickParticleData*> toAffect;
- for (const QQuickParticleGroupData *gd : qAsConst(m_system->groupData)) {
+ for (const QQuickParticleGroupData *gd : std::as_const(m_system->groupData)) {
if (activeGroup(gd->index)) {
for (QQuickParticleData *d : gd->data) {
if (shouldAffect(d)) {
@@ -98,7 +98,7 @@ void QQuickCustomAffector::affectSystem(qreal dt)
return;
if (justAffected) {
- for (const QQuickParticleData *d : qAsConst(toAffect)) {//Not postAffect to avoid saying the particle changed
+ for (const QQuickParticleData *d : std::as_const(toAffect)) {//Not postAffect to avoid saying the particle changed
if (m_onceOff)
m_onceOffed << qMakePair(d->groupId, d->index);
emit affected(d->curX(m_system), d->curY(m_system));
@@ -140,7 +140,7 @@ void QQuickCustomAffector::affectSystem(qreal dt)
doAffect(dt);
}
- for (QQuickParticleData *d : qAsConst(toAffect))
+ for (QQuickParticleData *d : std::as_const(toAffect))
if (d->update == 1.0)
postAffect(d);
}
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index b4461f5a7e..07076c6d29 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -730,6 +730,7 @@ void QQuickImageParticle::sceneGraphInvalidated()
m_material = nullptr;
delete m_outgoingNode;
m_outgoingNode = nullptr;
+ m_apiChecked = false;
}
void QQuickImageParticle::setImage(const QUrl &image)
@@ -981,7 +982,7 @@ void QQuickImageParticle::resetColor()
{
m_explicitColor = false;
for (auto groupId : groupIds()) {
- for (QQuickParticleData* d : qAsConst(m_system->groupData[groupId]->data)) {
+ for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
if (d->colorOwner == this) {
d->colorOwner = nullptr;
}
@@ -1000,7 +1001,7 @@ void QQuickImageParticle::resetRotation()
{
m_explicitRotation = false;
for (auto groupId : groupIds()) {
- for (QQuickParticleData* d : qAsConst(m_system->groupData[groupId]->data)) {
+ for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
if (d->rotationOwner == this) {
d->rotationOwner = nullptr;
}
@@ -1017,7 +1018,7 @@ void QQuickImageParticle::resetDeformation()
{
m_explicitDeformation = false;
for (auto groupId : groupIds()) {
- for (QQuickParticleData* d : qAsConst(m_system->groupData[groupId]->data)) {
+ for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
if (d->deformationOwner == this) {
d->deformationOwner = nullptr;
}
@@ -1038,11 +1039,17 @@ void QQuickImageParticle::reset()
update();
}
+
+void QQuickImageParticle::invalidateSceneGraph()
+{
+ reset();
+}
+
void QQuickImageParticle::createEngine()
{
if (m_spriteEngine)
delete m_spriteEngine;
- if (m_sprites.count()) {
+ if (m_sprites.size()) {
m_spriteEngine = new QQuickSpriteEngine(m_sprites, this);
connect(m_spriteEngine, SIGNAL(stateChanged(int)),
this, SLOT(spriteAdvance(int)), Qt::DirectConnection);
@@ -1244,7 +1251,7 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
m_debugMode = m_system->m_debugMode;
- if (m_sprites.count() || m_bypassOptimizations) {
+ if (m_sprites.size() || m_bypassOptimizations) {
perfLevel = Sprites;
} else if (m_colorTable || m_sizeTable || m_opacityTable) {
perfLevel = Tabled;
@@ -1261,7 +1268,7 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
for (auto groupId : groupIds()) {
//For sharing higher levels, need to have highest used so it renders
- for (QQuickParticlePainter* p : qAsConst(m_system->groupData[groupId]->painters)) {
+ for (QQuickParticlePainter* p : std::as_const(m_system->groupData[groupId]->painters)) {
QQuickImageParticle* other = qobject_cast<QQuickImageParticle*>(p);
if (other){
if (other->perfLevel > perfLevel) {
@@ -1616,7 +1623,7 @@ void QQuickImageParticle::spritesUpdate(qreal time)
ImageMaterialData *state = getState(m_material);
// Sprite progression handled CPU side, so as to have per-frame control.
for (auto groupId : groupIds()) {
- for (QQuickParticleData* mainDatum : qAsConst(m_system->groupData[groupId]->data)) {
+ for (QQuickParticleData* mainDatum : std::as_const(m_system->groupData[groupId]->data)) {
QSGGeometryNode *node = m_nodes[groupId];
if (!node)
continue;
@@ -1624,7 +1631,7 @@ void QQuickImageParticle::spritesUpdate(qreal time)
// This is particularly important for cut-up sprites.
QQuickParticleData* datum = (mainDatum->animationOwner == this ? mainDatum : getShadowDatum(mainDatum));
int spriteIdx = 0;
- for (int i = 0; i<m_startsIdx.count(); i++) {
+ for (int i = 0; i<m_startsIdx.size(); i++) {
if (m_startsIdx[i].second == groupId){
spriteIdx = m_startsIdx[i].first + datum->index;
break;
@@ -1677,12 +1684,12 @@ void QQuickImageParticle::spritesUpdate(qreal time)
void QQuickImageParticle::spriteAdvance(int spriteIdx)
{
- if (!m_startsIdx.count())//Probably overly defensive
+ if (!m_startsIdx.size())//Probably overly defensive
return;
int gIdx = -1;
int i;
- for (i = 0; i<m_startsIdx.count(); i++) {
+ for (i = 0; i<m_startsIdx.size(); i++) {
if (spriteIdx < m_startsIdx[i].first) {
gIdx = m_startsIdx[i-1].second;
break;
diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h
index 9b80aef0a1..b380bca821 100644
--- a/src/particles/qquickimageparticle_p.h
+++ b/src/particles/qquickimageparticle_p.h
@@ -359,6 +359,8 @@ private Q_SLOTS:
void spritesUpdate(qreal time = 0 );
void mainThreadFetchImageData();
void finishBuildParticleNodes(QSGNode **n);
+ void invalidateSceneGraph();
+
private:
struct ImageData {
QUrl source;
diff --git a/src/particles/qquickitemparticle.cpp b/src/particles/qquickitemparticle.cpp
index dd8d989378..cd48095b18 100644
--- a/src/particles/qquickitemparticle.cpp
+++ b/src/particles/qquickitemparticle.cpp
@@ -125,7 +125,7 @@ void QQuickItemParticle::take(QQuickItem *item, bool prioritize)
void QQuickItemParticle::give(QQuickItem *item)
{
for (auto groupId : groupIds()) {
- for (QQuickParticleData* data : qAsConst(m_system->groupData[groupId]->data)) {
+ for (QQuickParticleData* data : std::as_const(m_system->groupData[groupId]->data)) {
if (data->delegate == item){
m_deletables << item;
data->delegate = nullptr;
@@ -173,7 +173,7 @@ 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)) {
+ for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
if (!d->delegate && d->t != -1 && d->stillAlive(m_system)) {
QQuickItem* parentItem = nullptr;
if (!m_pendingItems.isEmpty()){
@@ -214,7 +214,7 @@ void QQuickItemParticle::reset()
// but leave it alone if the logical particle is maintained
QSet<QQuickItem*> lost = QSet<QQuickItem*>(m_managed.cbegin(), m_managed.cend());
for (auto groupId : groupIds()) {
- for (QQuickParticleData* d : qAsConst(m_system->groupData[groupId]->data)) {
+ for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
lost.remove(d->delegate);
}
}
@@ -251,7 +251,7 @@ void QQuickItemParticle::prepareNextFrame()
//TODO: Size, better fade?
for (auto groupId : groupIds()) {
- for (QQuickParticleData* data : qAsConst(m_system->groupData[groupId]->data)) {
+ for (QQuickParticleData* data : std::as_const(m_system->groupData[groupId]->data)) {
QQuickItem* item = data->delegate;
if (!item)
continue;
diff --git a/src/particles/qquickmaskextruder.cpp b/src/particles/qquickmaskextruder.cpp
index 36b6413503..b7b245758f 100644
--- a/src/particles/qquickmaskextruder.cpp
+++ b/src/particles/qquickmaskextruder.cpp
@@ -69,9 +69,9 @@ void QQuickMaskExtruder::finishMaskLoading()
QPointF QQuickMaskExtruder::extrude(const QRectF &r)
{
ensureInitialized(r);
- if (!m_mask.count() || m_img.isNull())
+ if (!m_mask.size() || m_img.isNull())
return r.topLeft();
- const QPointF p = m_mask[QRandomGenerator::global()->bounded(m_mask.count())];
+ const QPointF p = m_mask[QRandomGenerator::global()->bounded(m_mask.size())];
//### Should random sub-pixel positioning be added?
return p + r.topLeft();
}
diff --git a/src/particles/qquickparticleaffector.cpp b/src/particles/qquickparticleaffector.cpp
index d3594a7bac..17038f4593 100644
--- a/src/particles/qquickparticleaffector.cpp
+++ b/src/particles/qquickparticleaffector.cpp
@@ -177,9 +177,9 @@ void QQuickParticleAffector::affectSystem(qreal dt)
updateOffsets();//### Needed if an ancestor is transformed.
if (m_onceOff)
dt = 1.0;
- for (QQuickParticleGroupData* gd : qAsConst(m_system->groupData)) {
+ for (QQuickParticleGroupData* gd : std::as_const(m_system->groupData)) {
if (activeGroup(gd->index)) {
- for (QQuickParticleData* d : qAsConst(gd->data)) {
+ for (QQuickParticleData* d : std::as_const(gd->data)) {
if (shouldAffect(d)) {
bool affected = false;
qreal myDt = dt;
diff --git a/src/particles/qquickparticlesystem.cpp b/src/particles/qquickparticlesystem.cpp
index 2bceb2456a..655cd4a78e 100644
--- a/src/particles/qquickparticlesystem.cpp
+++ b/src/particles/qquickparticlesystem.cpp
@@ -288,7 +288,7 @@ QQuickParticleGroupData::QQuickParticleGroupData(const QString &name, QQuickPart
QQuickParticleGroupData::~QQuickParticleGroupData()
{
- for (QQuickParticleData *d : qAsConst(data))
+ for (QQuickParticleData *d : std::as_const(data))
delete d;
}
@@ -311,7 +311,7 @@ void QQuickParticleGroupData::setSize(int newSize)
}
int delta = newSize - m_size;
m_size = newSize;
- for (QQuickParticlePainter *p : qAsConst(painters))
+ for (QQuickParticlePainter *p : std::as_const(painters))
p->setCount(p->count() + delta);
}
@@ -324,7 +324,7 @@ void QQuickParticleGroupData::kill(QQuickParticleData* d)
{
Q_ASSERT(d->groupId == index);
d->lifeSpan = 0;//Kill off
- for (QQuickParticlePainter *p : qAsConst(painters))
+ for (QQuickParticlePainter *p : std::as_const(painters))
p->reload(d);
freeList.free(d->index);
}
@@ -543,7 +543,7 @@ QQuickParticleSystem::QQuickParticleSystem(QQuickItem *parent) :
QQuickParticleSystem::~QQuickParticleSystem()
{
- for (QQuickParticleGroupData *gd : qAsConst(groupData))
+ for (QQuickParticleGroupData *gd : std::as_const(groupData))
delete gd;
}
@@ -557,10 +557,10 @@ void QQuickParticleSystem::initGroups()
groupIds.clear();
nextFreeGroupId = 0;
- for (auto e : qAsConst(m_emitters)) {
+ for (auto e : std::as_const(m_emitters)) {
e->reclaculateGroupId();
}
- for (QQuickParticlePainter *p : qAsConst(m_painters)) {
+ for (QQuickParticlePainter *p : std::as_const(m_painters)) {
p->recalculateGroupIds();
}
@@ -632,7 +632,7 @@ void QQuickParticleSystem::setPaused(bool arg) {
if (m_animation && m_animation->state() != QAbstractAnimation::Stopped)
m_paused ? m_animation->pause() : m_animation->resume();
if (!m_paused) {
- for (QQuickParticlePainter *p : qAsConst(m_painters)) {
+ for (QQuickParticlePainter *p : std::as_const(m_painters)) {
if (p) {
p->update();
}
@@ -741,12 +741,12 @@ void QQuickParticleSystem::reset()
if (!m_running)
return;
- for (QQuickParticleEmitter *e : qAsConst(m_emitters))
+ for (QQuickParticleEmitter *e : std::as_const(m_emitters))
e->reset();
emittersChanged();
- for (QQuickParticlePainter *p : qAsConst(m_painters)) {
+ for (QQuickParticlePainter *p : std::as_const(m_painters)) {
loadPainter(p);
p->reset();
}
@@ -807,7 +807,7 @@ void QQuickParticleSystem::emittersChanged()
}
// Populate groups and set sizes.
- for (int i = 0; i < m_emitters.count(); ) {
+ for (int i = 0; i < m_emitters.size(); ) {
QQuickParticleEmitter *e = m_emitters.at(i);
if (!e) {
m_emitters.removeAt(i);
@@ -839,13 +839,13 @@ void QQuickParticleSystem::emittersChanged()
if (particleCount > bySysIdx.size())//New datum requests haven't updated it
bySysIdx.resize(particleCount);
- for (QQuickParticleAffector *a : qAsConst(m_affectors)) {//Groups may have changed
+ for (QQuickParticleAffector *a : std::as_const(m_affectors)) {//Groups may have changed
if (a) {
a->m_updateIntSet = true;
}
}
- for (QQuickParticlePainter *p : qAsConst(m_painters))
+ for (QQuickParticlePainter *p : std::as_const(m_painters))
loadPainter(p);
if (!m_groups.isEmpty())
@@ -860,7 +860,7 @@ void QQuickParticleSystem::createEngine()
if (stateEngine && m_debugMode)
qDebug() << "Resetting Existing Sprite Engine...";
//### Solve the losses if size/states go down
- for (QQuickParticleGroup *group : qAsConst(m_groups)) {
+ for (QQuickParticleGroup *group : std::as_const(m_groups)) {
bool exists = false;
for (auto it = groupIds.keyBegin(), end = groupIds.keyEnd(); it != end; ++it) {
if (group->name() == *it) {
@@ -873,14 +873,14 @@ void QQuickParticleSystem::createEngine()
}
}
- if (m_groups.count()) {
+ if (m_groups.size()) {
//Reorder groups List so as to have the same order as groupData
// TODO: can't we just merge the two lists?
QList<QQuickParticleGroup*> newList;
for (int i = 0, ei = groupData.size(); i != ei; ++i) {
bool exists = false;
QString name = groupData[i]->name();
- for (QQuickParticleGroup *existing : qAsConst(m_groups)) {
+ for (QQuickParticleGroup *existing : std::as_const(m_groups)) {
if (existing->name() == name) {
newList << existing;
exists = true;
@@ -893,8 +893,8 @@ void QQuickParticleSystem::createEngine()
}
m_groups = newList;
QList<QQuickStochasticState*> states;
- states.reserve(m_groups.count());
- for (QQuickParticleGroup *g : qAsConst(m_groups))
+ states.reserve(m_groups.size());
+ for (QQuickParticleGroup *g : std::as_const(m_groups))
states << (QQuickStochasticState*)g;
if (!stateEngine)
@@ -952,7 +952,7 @@ int QQuickParticleSystem::nextSystemIndex()
QQuickParticleData* QQuickParticleSystem::newDatum(int groupId, bool respectLimits, int sysIndex)
{
- Q_ASSERT(groupId < groupData.count());//XXX shouldn't really be an assert
+ Q_ASSERT(groupId < groupData.size());//XXX shouldn't really be an assert
QQuickParticleData* ret = groupData[groupId]->newDatum(respectLimits);
if (!ret) {
@@ -999,10 +999,10 @@ void QQuickParticleSystem::finishNewDatum(QQuickParticleData *pd)
Q_ASSERT(pd);
groupData[pd->groupId]->prepareRecycler(pd);
- for (QQuickParticleAffector *a : qAsConst(m_affectors))
+ for (QQuickParticleAffector *a : std::as_const(m_affectors))
if (a && a->m_needsReset)
a->reset(pd);
- for (QQuickParticlePainter *p : qAsConst(groupData[pd->groupId]->painters))
+ for (QQuickParticlePainter *p : std::as_const(groupData[pd->groupId]->painters))
if (p)
p->load(pd);
}
@@ -1025,18 +1025,18 @@ void QQuickParticleSystem::updateCurrentTime( int currentTime )
bool oldClear = m_empty;
m_empty = true;
- for (QQuickParticleGroupData *gd : qAsConst(groupData))//Recycle all groups and see if they're out of live particles
+ for (QQuickParticleGroupData *gd : std::as_const(groupData))//Recycle all groups and see if they're out of live particles
m_empty = gd->recycle() && m_empty;
if (stateEngine)
stateEngine->updateSprites(timeInt);
- for (QQuickParticleEmitter *emitter : qAsConst(m_emitters))
+ for (QQuickParticleEmitter *emitter : std::as_const(m_emitters))
emitter->emitWindow(timeInt);
- for (QQuickParticleAffector *a : qAsConst(m_affectors))
+ for (QQuickParticleAffector *a : std::as_const(m_affectors))
a->affectSystem(dt);
for (QQuickParticleData *d : needsReset)
- for (QQuickParticlePainter *p : qAsConst(groupData[d->groupId]->painters))
+ for (QQuickParticlePainter *p : std::as_const(groupData[d->groupId]->painters))
p->reload(d);
if (oldClear != m_empty)
diff --git a/src/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp
index 97d1e11baf..4deb96c1e5 100644
--- a/src/particles/qquicktrailemitter.cpp
+++ b/src/particles/qquicktrailemitter.cpp
@@ -147,7 +147,7 @@ void QQuickTrailEmitter::emitWindow(int timeStamp)
int gId = m_system->groupIds[m_follow];
int gId2 = groupId();
- for (int i=0; i<m_system->groupData[gId]->data.count(); i++) {
+ for (int i=0; i<m_system->groupData[gId]->data.size(); i++) {
QQuickParticleData *d = m_system->groupData[gId]->data[i];
if (!d->stillAlive(m_system)){
m_lastEmission[i] = time; //Should only start emitting when it returns to life
diff --git a/src/plugins/qmllint/quick/quicklintplugin.cpp b/src/plugins/qmllint/quick/quicklintplugin.cpp
index fca4fecc36..c266bfbe11 100644
--- a/src/plugins/qmllint/quick/quicklintplugin.cpp
+++ b/src/plugins/qmllint/quick/quicklintplugin.cpp
@@ -132,10 +132,10 @@ void AttachedPropertyTypeValidatorPass::onRead(const QQmlSA::Element &element,
const QQmlSA::Element &readScope,
QQmlJS::SourceLocation location)
{
- Q_UNUSED(readScope)
- Q_UNUSED(propertyName)
-
- checkWarnings(element, readScope, location);
+ // If the attachment does not have such a property or method then
+ // it's either a more general error or an enum. Enums are fine.
+ if (element->hasProperty(propertyName) || element->hasMethod(propertyName))
+ checkWarnings(element, readScope, location);
}
void AttachedPropertyTypeValidatorPass::onWrite(const QQmlSA::Element &element,
diff --git a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
index 3a7cda534c..0bc017b3d2 100644
--- a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
+++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
@@ -129,7 +129,7 @@ void QPacketProtocol::send(const QByteArray &data)
qint64 QPacketProtocol::packetsAvailable() const
{
Q_D(const QPacketProtocol);
- return d->packets.count();
+ return d->packets.size();
}
/*!
@@ -223,7 +223,7 @@ void QPacketProtocol::readyToRead()
static_cast<qint64>(d->inProgressSize - d->inProgress.size())));
QByteArray toRead(bytesToRead, Qt::Uninitialized);
- if (!d->readFromDevice(toRead.data(), toRead.length())) {
+ if (!d->readFromDevice(toRead.data(), toRead.size())) {
emit error();
return;
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
index 7708260f8c..1fcc1e7772 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
@@ -122,7 +122,7 @@ QDataStream &operator>>(QDataStream &ds,
static inline bool isSignalPropertyName(const QString &signalName)
{
// see QmlCompiler::isSignalPropertyName
- return signalName.length() >= 3 && signalName.startsWith(QLatin1String("on")) &&
+ return signalName.size() >= 3 && signalName.startsWith(QLatin1String("on")) &&
signalName.at(2).isLetter() && signalName.at(2).isUpper();
}
@@ -259,8 +259,8 @@ void QQmlEngineDebugServiceImpl::buildObjectDump(QDataStream &message,
QObjectList children = object->children();
- int childrenCount = children.count();
- for (int ii = 0; ii < children.count(); ++ii) {
+ int childrenCount = children.size();
+ for (int ii = 0; ii < children.size(); ++ii) {
if (qobject_cast<QQmlContext*>(children[ii]))
--childrenCount;
}
@@ -269,7 +269,7 @@ void QQmlEngineDebugServiceImpl::buildObjectDump(QDataStream &message,
QList<QQmlObjectProperty> fakeProperties;
- for (int ii = 0; ii < children.count(); ++ii) {
+ for (int ii = 0; ii < children.size(); ++ii) {
QObject *child = children.at(ii);
if (qobject_cast<QQmlContext*>(child))
continue;
@@ -318,12 +318,12 @@ void QQmlEngineDebugServiceImpl::buildObjectDump(QDataStream &message,
}
}
- message << int(propertyIndexes.size() + fakeProperties.count());
+ message << int(propertyIndexes.size() + fakeProperties.size());
for (int ii = 0; ii < propertyIndexes.size(); ++ii)
message << propertyData(object, propertyIndexes.at(ii));
- for (int ii = 0; ii < fakeProperties.count(); ++ii)
+ for (int ii = 0; ii < fakeProperties.size(); ++ii)
message << fakeProperties[ii];
}
@@ -332,7 +332,7 @@ void QQmlEngineDebugServiceImpl::prepareDeferredObjects(QObject *obj)
qmlExecuteDeferred(obj);
QObjectList children = obj->children();
- for (int ii = 0; ii < children.count(); ++ii) {
+ for (int ii = 0; ii < children.size(); ++ii) {
QObject *child = children.at(ii);
prepareDeferredObjects(child);
}
@@ -343,7 +343,7 @@ void QQmlEngineDebugServiceImpl::storeObjectIds(QObject *co)
{
QQmlDebugService::idForObject(co);
QObjectList children = co->children();
- for (int ii = 0; ii < children.count(); ++ii)
+ for (int ii = 0; ii < children.size(); ++ii)
storeObjectIds(children.at(ii));
}
@@ -380,14 +380,14 @@ void QQmlEngineDebugServiceImpl::buildObjectList(QDataStream &message,
}
count = 0;
- for (int ii = 0; ii < instances.count(); ++ii) {
+ for (int ii = 0; ii < instances.size(); ++ii) {
QQmlData *data = QQmlData::get(instances.at(ii));
if (data->context == p.data())
count ++;
}
message << count;
- for (int ii = 0; ii < instances.count(); ++ii) {
+ for (int ii = 0; ii < instances.size(); ++ii) {
QQmlData *data = QQmlData::get(instances.at(ii));
if (data->context == p.data())
message << objectData(instances.at(ii));
@@ -465,9 +465,9 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
if (type == "LIST_ENGINES") {
rs << QByteArray("LIST_ENGINES_R");
- rs << queryId << int(m_engines.count());
+ rs << queryId << int(m_engines.size());
- for (int ii = 0; ii < m_engines.count(); ++ii) {
+ for (int ii = 0; ii < m_engines.size(); ++ii) {
QJSEngine *engine = m_engines.at(ii);
QString engineName = engine->objectName();
@@ -523,7 +523,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
const QList<QObject*> objects = objectForLocationInfo(file, lineNumber, columnNumber);
rs << QByteArray("FETCH_OBJECTS_FOR_LOCATION_R") << queryId
- << int(objects.count());
+ << int(objects.size());
for (QObject *object : objects) {
if (recurse)
@@ -755,7 +755,7 @@ bool QQmlEngineDebugServiceImpl::setMethodBody(int objectId, const QString &meth
QList<QByteArray> paramNames = metaMethod.parameterNames();
QString paramStr;
- for (int ii = 0; ii < paramNames.count(); ++ii) {
+ for (int ii = 0; ii < paramNames.size(); ++ii) {
if (ii != 0) paramStr.append(QLatin1Char(','));
paramStr.append(QString::fromUtf8(paramNames.at(ii)));
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlwatcher.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlwatcher.cpp
index 7a7d2f37b4..d72c11d439 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlwatcher.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlwatcher.cpp
@@ -40,7 +40,6 @@ private:
int m_id;
QQmlWatcher *m_watch;
QObject *m_object;
- bool m_isGadget;
int m_debugId;
QMetaProperty m_property;
@@ -52,7 +51,6 @@ QQmlWatchProxy::QQmlWatchProxy(int id, QQmlExpression *exp, int debugId, QQmlWat
m_id(id),
m_watch(parent),
m_object(nullptr),
- m_isGadget(false),
m_debugId(debugId),
m_expr(exp)
{
@@ -66,7 +64,6 @@ QQmlWatchProxy::QQmlWatchProxy(int id, QObject *object, int debugId, const QMeta
m_id(id),
m_watch(parent),
m_object(object),
- m_isGadget(typeid(*m_object) == typeid(QQmlGadgetPtrWrapper)),
m_debugId(debugId),
m_property(prop),
m_expr(nullptr)
@@ -84,8 +81,6 @@ void QQmlWatchProxy::notifyValueChanged()
QVariant v;
if (m_expr)
v = m_expr->evaluate();
- else if (m_isGadget)
- v = static_cast<QQmlGadgetPtrWrapper *>(m_object)->readOnGadget(m_property);
else
v = m_property.read(m_object);
emit m_watch->propertyChanged(m_id, m_debugId, m_property, v);
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index b78a09f0fb..904749d7f6 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -242,7 +242,7 @@ QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int
// Only type and index are used by Qt Creator, so we keep it easy:
QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes = getScopeTypes(frameNr);
- for (int i = 0, ei = scopeTypes.count(); i != ei; ++i) {
+ for (int i = 0, ei = scopeTypes.size(); i != ei; ++i) {
int type = encodeScopeType(scopeTypes[i]);
if (type == -1)
continue;
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
index 6ad9c6f0ac..a1d07e6654 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
@@ -73,7 +73,7 @@ void QV4DebuggerAgent::addDebugger(QV4Debugger *debugger)
debugger->setBreakOnThrow(m_breakOnThrow);
- for (const BreakPoint &breakPoint : qAsConst(m_breakPoints))
+ for (const BreakPoint &breakPoint : std::as_const(m_breakPoints))
if (breakPoint.enabled)
debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition);
@@ -120,7 +120,7 @@ void QV4DebuggerAgent::resumeAll() const
int QV4DebuggerAgent::addBreakPoint(const QString &fileName, int lineNumber, bool enabled, const QString &condition)
{
if (enabled) {
- for (QV4Debugger *debugger : qAsConst(m_debuggers))
+ for (QV4Debugger *debugger : std::as_const(m_debuggers))
debugger->addBreakPoint(fileName, lineNumber, condition);
}
@@ -138,7 +138,7 @@ void QV4DebuggerAgent::removeBreakPoint(int id)
m_breakPoints.remove(id);
if (breakPoint.enabled)
- for (QV4Debugger *debugger : qAsConst(m_debuggers))
+ for (QV4Debugger *debugger : std::as_const(m_debuggers))
debugger->removeBreakPoint(breakPoint.fileName, breakPoint.lineNr);
}
@@ -155,7 +155,7 @@ void QV4DebuggerAgent::enableBreakPoint(int id, bool onoff)
return;
breakPoint.enabled = onoff;
- for (QV4Debugger *debugger : qAsConst(m_debuggers)) {
+ for (QV4Debugger *debugger : std::as_const(m_debuggers)) {
if (onoff)
debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition);
else
@@ -178,14 +178,14 @@ void QV4DebuggerAgent::setBreakOnThrow(bool onoff)
{
if (onoff != m_breakOnThrow) {
m_breakOnThrow = onoff;
- for (QV4Debugger *debugger : qAsConst(m_debuggers))
+ for (QV4Debugger *debugger : std::as_const(m_debuggers))
debugger->setBreakOnThrow(onoff);
}
}
void QV4DebuggerAgent::clearAllPauseRequests()
{
- for (QV4Debugger *debugger : qAsConst(m_debuggers))
+ for (QV4Debugger *debugger : std::as_const(m_debuggers))
debugger->clearPauseRequest();
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
index 647804d62e..6ed24f29d1 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
@@ -124,7 +124,7 @@ FrameJob::FrameJob(QV4DataCollector *collector, int frameNr) :
void FrameJob::run()
{
QVector<QV4::StackFrame> frames = collector->engine()->stackTrace(frameNr + 1);
- if (frameNr >= frames.length()) {
+ if (frameNr >= frames.size()) {
success = false;
} else {
result = collector->buildFrame(frames[frameNr], frameNr);
@@ -175,8 +175,8 @@ void ValueLookupJob::run()
QScopedPointer<QObject> scopeObject;
QV4::ExecutionEngine *engine = collector->engine();
QV4::Scope scope(engine);
- QV4::Heap::ExecutionContext *qmlContext = nullptr;
- if (engine->qmlEngine() && !engine->qmlContext()) {
+ QV4::Heap::ExecutionContext *qmlContext = engine->qmlContext();
+ if (engine->qmlEngine() && !qmlContext) {
scopeObject.reset(new QObject);
qmlContext = QV4::QmlContext::create(engine->currentContext(),
QQmlContextData::get(engine->qmlEngine()->rootContext()),
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index 2488a10c0d..7b9d74a030 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -395,10 +395,10 @@ public:
QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
if (!debugger) {
const QList<QV4Debugger *> &debuggers = debugService->debuggerAgent.debuggers();
- if (debuggers.count() > 1) {
+ if (debuggers.size() > 1) {
createErrorResponse(QStringLiteral("Cannot lookup values if multiple debuggers are running and none is paused"));
return;
- } else if (debuggers.count() == 0) {
+ } else if (debuggers.size() == 0) {
createErrorResponse(QStringLiteral("No debuggers available to lookup values"));
return;
}
@@ -611,10 +611,10 @@ public:
QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
if (!debugger) {
const QList<QV4Debugger *> &debuggers = debugService->debuggerAgent.debuggers();
- if (debuggers.count() > 1) {
+ if (debuggers.size() > 1) {
createErrorResponse(QStringLiteral("Cannot evaluate expressions if multiple debuggers are running and none is paused"));
return;
- } else if (debuggers.count() == 0) {
+ } else if (debuggers.size() == 0) {
createErrorResponse(QStringLiteral("No debuggers available to evaluate expressions"));
return;
}
@@ -734,7 +734,7 @@ void QV4DebugServiceImpl::signalEmitted(const QString &signal)
//Normalize to Lower case.
QString signalName = signal.left(signal.indexOf(QLatin1Char('('))).toLower();
- for (const QString &signal : qAsConst(breakOnSignals)) {
+ for (const QString &signal : std::as_const(breakOnSignals)) {
if (signal == signalName) {
// TODO: pause debugger
break;
diff --git a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
index 72b9fa5f4c..fb9ec74dc6 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
@@ -60,7 +60,7 @@ void GlobalInspector::setSelectedItems(const QList<QQuickItem *> &items)
return;
QList<QObject*> objectList;
- objectList.reserve(items.count());
+ objectList.reserve(items.size());
for (QQuickItem *item : items)
objectList << item;
@@ -81,7 +81,7 @@ void GlobalInspector::sendCurrentObjects(const QList<QObject*> &objects)
ds << QByteArray(EVENT) << m_eventId++ << QByteArray(SELECT);
QList<int> debugIds;
- debugIds.reserve(objects.count());
+ debugIds.reserve(objects.size());
for (QObject *object : objects)
debugIds << QQmlDebugService::idForObject(object);
ds << debugIds;
@@ -192,7 +192,7 @@ void GlobalInspector::removeWindow(QQuickWindow *window)
void GlobalInspector::setParentWindow(QQuickWindow *window, QWindow *parentWindow)
{
- for (QmlJSDebugger::QQuickWindowInspector *inspector : qAsConst(m_windowInspectors)) {
+ for (QmlJSDebugger::QQuickWindowInspector *inspector : std::as_const(m_windowInspectors)) {
if (inspector->quickWindow() == window)
inspector->setParentWindow(parentWindow);
}
@@ -222,7 +222,7 @@ bool GlobalInspector::syncSelectedItems(const QList<QQuickItem *> &items)
selectionChanged = true;
connect(item, &QObject::destroyed, this, &GlobalInspector::removeFromSelectedItems);
m_selectedItems.append(item);
- for (QQuickWindowInspector *inspector : qAsConst(m_windowInspectors)) {
+ for (QQuickWindowInspector *inspector : std::as_const(m_windowInspectors)) {
if (inspector->isEnabled() && inspector->quickWindow() == item->window()) {
m_highlightItems.insert(item, new SelectionHighlight(titleForItem(item), item,
inspector->overlay()));
@@ -284,12 +284,12 @@ void GlobalInspector::processMessage(const QByteArray &message)
ds >> requestId >> command;
if (command == ENABLE) {
- for (QQuickWindowInspector *inspector : qAsConst(m_windowInspectors))
+ for (QQuickWindowInspector *inspector : std::as_const(m_windowInspectors))
inspector->setEnabled(true);
success = !m_windowInspectors.isEmpty();
} else if (command == DISABLE) {
setSelectedItems(QList<QQuickItem*>());
- for (QQuickWindowInspector *inspector : qAsConst(m_windowInspectors))
+ for (QQuickWindowInspector *inspector : std::as_const(m_windowInspectors))
inspector->setEnabled(false);
success = !m_windowInspectors.isEmpty();
} else if (command == SELECT) {
@@ -297,7 +297,7 @@ void GlobalInspector::processMessage(const QByteArray &message)
ds >> debugIds;
QList<QQuickItem *> selectedObjects;
- for (int debugId : qAsConst(debugIds)) {
+ for (int debugId : std::as_const(debugIds)) {
if (QQuickItem *obj =
qobject_cast<QQuickItem *>(QQmlDebugService::objectForId(debugId)))
selectedObjects << obj;
@@ -311,7 +311,7 @@ void GlobalInspector::processMessage(const QByteArray &message)
} else if (command == SHOW_APP_ON_TOP) {
bool showOnTop;
ds >> showOnTop;
- for (QmlJSDebugger::QQuickWindowInspector *inspector : qAsConst(m_windowInspectors))
+ for (QmlJSDebugger::QQuickWindowInspector *inspector : std::as_const(m_windowInspectors))
inspector->setShowAppOnTop(showOnTop);
success = !m_windowInspectors.isEmpty();
} else if (command == CREATE_OBJECT) {
diff --git a/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp b/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp
index 2bf043d9b9..cedb17e150 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp
@@ -86,7 +86,7 @@ void InspectTool::touchEvent(QTouchEvent *event)
switch (event->type()) {
case QEvent::TouchBegin:
- if (touchPoints.count() == 1 && (event->touchPointStates() & QEventPoint::State::Pressed)) {
+ if (touchPoints.size() == 1 && (event->touchPointStates() & QEventPoint::State::Pressed)) {
m_mousePosition = touchPoints.first().position();
m_tapEvent = true;
} else {
@@ -94,14 +94,14 @@ void InspectTool::touchEvent(QTouchEvent *event)
}
break;
case QEvent::TouchUpdate: {
- if (touchPoints.count() > 1)
+ if (touchPoints.size() > 1)
m_tapEvent = false;
- else if ((touchPoints.count() == 1) && (event->touchPointStates() & QEventPoint::State::Updated))
+ else if ((touchPoints.size() == 1) && (event->touchPointStates() & QEventPoint::State::Updated))
m_mousePosition = touchPoints.first().position();
break;
}
case QEvent::TouchEnd: {
- if (touchPoints.count() == 1 && m_tapEvent) {
+ if (touchPoints.size() == 1 && m_tapEvent) {
m_tapEvent = false;
bool doubleTap = event->timestamp() - m_touchTimestamp
< static_cast<ulong>(QGuiApplication::styleHints()->mouseDoubleClickInterval());
@@ -125,9 +125,9 @@ void InspectTool::selectNextItem()
if (m_lastClickedItem != inspector()->topVisibleItemAt(m_mousePosition))
return;
QList<QQuickItem*> items = inspector()->itemsAt(m_mousePosition);
- for (int i = 0; i < items.count(); i++) {
+ for (int i = 0; i < items.size(); i++) {
if (m_lastItem == items[i]) {
- if (i + 1 < items.count())
+ if (i + 1 < items.size())
m_lastItem = items[i+1];
else
m_lastItem = items[0];
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.cpp
index 945fe4e985..b9ba13c9e7 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.cpp
@@ -29,7 +29,7 @@ static QQuickItem *itemAt(QQuickItem *item, const QPointF &pos,
}
QList<QQuickItem *> children = QQuickItemPrivate::get(item)->paintOrderChildItems();
- for (int i = children.count() - 1; i >= 0; --i) {
+ for (int i = children.size() - 1; i >= 0; --i) {
QQuickItem *child = children.at(i);
if (QQuickItem *betterCandidate = itemAt(child, item->mapToItem(child, pos),
overlay))
@@ -60,7 +60,7 @@ static void collectItemsAt(QQuickItem *item, const QPointF &pos,
}
QList<QQuickItem *> children = QQuickItemPrivate::get(item)->paintOrderChildItems();
- for (int i = children.count() - 1; i >= 0; --i) {
+ for (int i = children.size() - 1; i >= 0; --i) {
QQuickItem *child = children.at(i);
collectItemsAt(child, item->mapToItem(child, pos), overlay, resultList);
}
diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
index 73a7c28b09..68dcd1add0 100644
--- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
+++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
@@ -172,7 +172,7 @@ QQmlNativeDebugConnector::QQmlNativeDebugConnector()
QQmlNativeDebugConnector::~QQmlNativeDebugConnector()
{
- for (QQmlDebugService *service : qAsConst(m_services)) {
+ for (QQmlDebugService *service : std::as_const(m_services)) {
service->stateAboutToBeChanged(QQmlDebugService::NotConnected);
service->setState(QQmlDebugService::NotConnected);
service->stateChanged(QQmlDebugService::NotConnected);
@@ -199,12 +199,12 @@ void QQmlNativeDebugConnector::addEngine(QJSEngine *engine)
Q_ASSERT(!m_engines.contains(engine));
TRACE_PROTOCOL("Add engine to connector:" << engine);
- for (QQmlDebugService *service : qAsConst(m_services))
+ for (QQmlDebugService *service : std::as_const(m_services))
service->engineAboutToBeAdded(engine);
announceObjectAvailability(QLatin1String("qmlengine"), engine, true);
- for (QQmlDebugService *service : qAsConst(m_services))
+ for (QQmlDebugService *service : std::as_const(m_services))
service->engineAdded(engine);
m_engines.append(engine);
@@ -215,12 +215,12 @@ void QQmlNativeDebugConnector::removeEngine(QJSEngine *engine)
Q_ASSERT(m_engines.contains(engine));
TRACE_PROTOCOL("Remove engine from connector:" << engine);
- for (QQmlDebugService *service : qAsConst(m_services))
+ for (QQmlDebugService *service : std::as_const(m_services))
service->engineAboutToBeRemoved(engine);
announceObjectAvailability(QLatin1String("qmlengine"), engine, false);
- for (QQmlDebugService *service : qAsConst(m_services))
+ for (QQmlDebugService *service : std::as_const(m_services))
service->engineRemoved(engine);
m_engines.removeOne(engine);
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
index 16f62d00d2..10d52c75ee 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
@@ -260,7 +260,7 @@ void NativeDebugger::signalEmitted(const QString &signal)
//Normalize to Lower case.
QString signalName = signal.left(signal.indexOf(QLatin1Char('('))).toLower();
- for (const QString &signal : qAsConst(breakOnSignals)) {
+ for (const QString &signal : std::as_const(breakOnSignals)) {
if (signal == signalName) {
// TODO: pause debugger
break;
@@ -710,7 +710,7 @@ void QQmlNativeDebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
void QQmlNativeDebugServiceImpl::stateAboutToBeChanged(QQmlDebugService::State state)
{
if (state == Enabled) {
- for (NativeDebugger *debugger : qAsConst(m_debuggers)) {
+ for (NativeDebugger *debugger : std::as_const(m_debuggers)) {
QV4::ExecutionEngine *engine = debugger->engine();
if (!engine->debugger())
engine->setDebugger(debugger);
@@ -734,7 +734,7 @@ void QQmlNativeDebugServiceImpl::messageReceived(const QByteArray &message)
} else if (cmd == QLatin1String("echo")) {
response.insert(QStringLiteral("result"), arguments);
} else {
- for (NativeDebugger *debugger : qAsConst(m_debuggers))
+ for (NativeDebugger *debugger : std::as_const(m_debuggers))
if (debugger)
debugger->handleCommand(&response, cmd, arguments);
}
diff --git a/src/plugins/qmltooling/qmldbg_preview/proxytranslator.cpp b/src/plugins/qmltooling/qmldbg_preview/proxytranslator.cpp
index 557d6a0082..d0004455d7 100644
--- a/src/plugins/qmltooling/qmldbg_preview/proxytranslator.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/proxytranslator.cpp
@@ -64,14 +64,14 @@ void ProxyTranslator::setLanguage(const QUrl &context, const QLocale &locale)
}
// unfortunately setUiLanguage set new translators, so do this first
- for (QQmlEngine *engine : qAsConst(m_engines))
+ for (QQmlEngine *engine : std::as_const(m_engines))
engine->setUiLanguage(locale.bcp47Name());
// make sure proxy translator is the first used translator
QCoreApplication::removeTranslator(this);
QCoreApplication::installTranslator(this);
- for (QQmlEngine *engine : qAsConst(m_engines)) {
+ for (QQmlEngine *engine : std::as_const(m_engines)) {
// have two retranslate runs to get elided warning even the same language was set
m_enable = false;
engine->retranslate();
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp
index 859f89367f..04d18b66ef 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp
@@ -109,7 +109,7 @@ public:
if (s == false)
qWarning() << "disable WatchTextElides is not implemented";
watchTextElides = s;
- for (auto &&information : qAsConst(objectTranslationBindingMultiMap)) {
+ for (auto &&information : std::as_const(objectTranslationBindingMultiMap)) {
QObject *scopeObject = information.scopeObject;
int elideIndex = scopeObject->metaObject()->indexOfProperty("elide");
if (elideIndex >= 0) {
@@ -143,7 +143,7 @@ public:
QVector<QmlElement> qmlElements;
- for (auto &&information : qAsConst(objectTranslationBindingMultiMap)) {
+ for (auto &&information : std::as_const(objectTranslationBindingMultiMap)) {
QObject *scopeObject = information.scopeObject;
auto compilationUnit = information.compilationUnit;
@@ -209,7 +209,7 @@ public:
packet << Reply::TranslationIssues;
QVector<TranslationIssue> issues;
- for (auto &&information : qAsConst(objectTranslationBindingMultiMap)) {
+ for (auto &&information : std::as_const(objectTranslationBindingMultiMap)) {
if (!proxyTranslator->hasTranslation(information)) {
TranslationIssue issue;
issue.type = TranslationIssue::Type::Missing;
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp
index 9f83ae8db9..3afdaa53f1 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp
@@ -18,7 +18,7 @@ static bool isRelative(const QString &path)
return true;
if (path.at(0) == '/')
return false;
- if (path.at(0) == ':' && path.length() >= 2 && path.at(1) == '/')
+ if (path.at(0) == ':' && path.size() >= 2 && path.at(1) == '/')
return false;
#ifdef Q_OS_WIN
if (path.length() >= 2 && path.at(1) == ':')
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.cpp
index 2acef4f781..7601c59cac 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.cpp
@@ -104,7 +104,7 @@ void QQmlPreviewHandler::loadUrl(const QUrl &url)
m_component.reset(nullptr);
QQuickPixmap::purgeCache();
- const int numEngines = m_engines.count();
+ const int numEngines = m_engines.size();
if (numEngines > 1) {
emit error(QString::fromLatin1("%1 QML engines available. We cannot decide which one "
"should load the component.").arg(numEngines));
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
index 164d01970e..819d46b124 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
@@ -91,10 +91,10 @@ void QQmlEngineControlServiceImpl::stateChanged(State)
{
// We flush everything for any kind of state change, to avoid complicated timing issues.
QMutexLocker lock(&dataMutex);
- for (QJSEngine *engine : qAsConst(startingEngines))
+ for (QJSEngine *engine : std::as_const(startingEngines))
emit attachedToEngine(engine);
startingEngines.clear();
- for (QJSEngine *engine : qAsConst(stoppingEngines))
+ for (QJSEngine *engine : std::as_const(stoppingEngines))
emit detachedFromEngine(engine);
stoppingEngines.clear();
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
index 9836672b4c..be753ed10f 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
@@ -92,9 +92,9 @@ static void qQmlProfilerDataToByteArrays(const QQmlProfilerData &d,
qint64 QQmlProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
{
- while (next != data.length()) {
+ while (next != data.size()) {
const QQmlProfilerData &nextData = data.at(next);
- if (nextData.time > until || messages.length() > s_numMessagesPerBatch)
+ if (nextData.time > until || messages.size() > s_numMessagesPerBatch)
return nextData.time;
qQmlProfilerDataToByteArrays(nextData, locations, messages);
++next;
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
index 6d7edd88bd..614890a8fd 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
@@ -67,8 +67,8 @@ void QQmlProfilerServiceImpl::dataReady(QQmlAbstractProfilerAdapter *profiler)
m_startTimes.insert(0, profiler);
if (dataComplete) {
QList<QJSEngine *> enginesToRelease;
- for (QJSEngine *engine : qAsConst(m_stoppingEngines)) {
- const auto range = qAsConst(m_engineProfilers).equal_range(engine);
+ for (QJSEngine *engine : std::as_const(m_stoppingEngines)) {
+ const auto range = std::as_const(m_engineProfilers).equal_range(engine);
const auto startTimesEnd = m_startTimes.cend();
for (auto it = range.first; it != range.second; ++it) {
if (std::find(m_startTimes.cbegin(), startTimesEnd, *it) != startTimesEnd) {
@@ -78,7 +78,7 @@ void QQmlProfilerServiceImpl::dataReady(QQmlAbstractProfilerAdapter *profiler)
}
}
sendMessages();
- for (QJSEngine *engine : qAsConst(enginesToRelease)) {
+ for (QJSEngine *engine : std::as_const(enginesToRelease)) {
m_stoppingEngines.removeOne(engine);
emit detachedFromEngine(engine);
}
@@ -114,7 +114,7 @@ void QQmlProfilerServiceImpl::engineAdded(QJSEngine *engine)
if (m_globalEnabled)
startProfiling(engine, m_globalFeatures);
- const auto range = qAsConst(m_engineProfilers).equal_range(engine);
+ const auto range = std::as_const(m_engineProfilers).equal_range(engine);
for (auto it = range.first; it != range.second; ++it)
(*it)->stopWaiting();
}
@@ -126,7 +126,7 @@ void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
QMutexLocker lock(&m_configMutex);
bool isRunning = false;
- const auto range = qAsConst(m_engineProfilers).equal_range(engine);
+ const auto range = std::as_const(m_engineProfilers).equal_range(engine);
for (auto it = range.first; it != range.second; ++it) {
QQmlAbstractProfilerAdapter *profiler = *it;
if (profiler->isRunning())
@@ -147,7 +147,7 @@ void QQmlProfilerServiceImpl::engineRemoved(QJSEngine *engine)
"QML profilers have to be removed from the engine thread");
QMutexLocker lock(&m_configMutex);
- const auto range = qAsConst(m_engineProfilers).equal_range(engine);
+ const auto range = std::as_const(m_engineProfilers).equal_range(engine);
for (auto it = range.first; it != range.second; ++it) {
QQmlAbstractProfilerAdapter *profiler = *it;
removeProfilerFromStartTimes(profiler);
@@ -172,7 +172,7 @@ void QQmlProfilerServiceImpl::addGlobalProfiler(QQmlAbstractProfilerAdapter *pro
// Global profilers are started whenever any engine profiler is started and stopped when
// all engine profilers are stopped.
quint64 features = 0;
- for (QQmlAbstractProfilerAdapter *engineProfiler : qAsConst(m_engineProfilers))
+ for (QQmlAbstractProfilerAdapter *engineProfiler : std::as_const(m_engineProfilers))
features |= engineProfiler->features();
if (features != 0)
@@ -220,7 +220,7 @@ void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features
d << m_timer.nsecsElapsed() << static_cast<qint32>(Event) << static_cast<qint32>(StartTrace);
bool startedAny = false;
if (engine != nullptr) {
- const auto range = qAsConst(m_engineProfilers).equal_range(engine);
+ const auto range = std::as_const(m_engineProfilers).equal_range(engine);
for (auto it = range.first; it != range.second; ++it) {
QQmlAbstractProfilerAdapter *profiler = *it;
if (!profiler->isRunning()) {
@@ -243,12 +243,12 @@ void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features
startedAny = true;
}
}
- for (QJSEngine *profiledEngine : qAsConst(engines))
+ for (QJSEngine *profiledEngine : std::as_const(engines))
d << idForObject(profiledEngine);
}
if (startedAny) {
- for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_globalProfilers)) {
+ for (QQmlAbstractProfilerAdapter *profiler : std::as_const(m_globalProfilers)) {
if (!profiler->isRunning())
profiler->startProfiling(features);
}
@@ -291,7 +291,7 @@ void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine)
if (stopping.isEmpty())
return;
- for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_globalProfilers)) {
+ for (QQmlAbstractProfilerAdapter *profiler : std::as_const(m_globalProfilers)) {
if (!profiler->isRunning())
continue;
m_startTimes.insert(-1, profiler);
@@ -305,10 +305,10 @@ void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine)
emit stopFlushTimer();
m_waitingForStop = true;
- for (QQmlAbstractProfilerAdapter *profiler : qAsConst(reporting))
+ for (QQmlAbstractProfilerAdapter *profiler : std::as_const(reporting))
profiler->reportData();
- for (QQmlAbstractProfilerAdapter *profiler : qAsConst(stopping))
+ for (QQmlAbstractProfilerAdapter *profiler : std::as_const(stopping))
profiler->stopProfiling();
}
@@ -325,7 +325,7 @@ void QQmlProfilerServiceImpl::sendMessages()
<< static_cast<qint32>(EndTrace);
QSet<QJSEngine *> seen;
- for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_startTimes)) {
+ for (QQmlAbstractProfilerAdapter *profiler : std::as_const(m_startTimes)) {
for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin());
i != m_engineProfilers.end(); ++i) {
if (i.value() == profiler && !seen.contains(i.key())) {
@@ -345,14 +345,14 @@ void QQmlProfilerServiceImpl::sendMessages()
if (next != -1)
m_startTimes.insert(next, first);
- if (messages.length() >= QQmlAbstractProfilerAdapter::s_numMessagesPerBatch) {
+ if (messages.size() >= QQmlAbstractProfilerAdapter::s_numMessagesPerBatch) {
emit messagesToClient(name(), messages);
messages.clear();
}
}
bool stillRunning = false;
- for (const QQmlAbstractProfilerAdapter *profiler : qAsConst(m_engineProfilers)) {
+ for (const QQmlAbstractProfilerAdapter *profiler : std::as_const(m_engineProfilers)) {
if (profiler->isRunning()) {
stillRunning = true;
break;
@@ -446,21 +446,21 @@ void QQmlProfilerServiceImpl::flush()
QMutexLocker lock(&m_configMutex);
QList<QQmlAbstractProfilerAdapter *> reporting;
- for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_engineProfilers)) {
+ for (QQmlAbstractProfilerAdapter *profiler : std::as_const(m_engineProfilers)) {
if (profiler->isRunning()) {
m_startTimes.insert(-1, profiler);
reporting.append(profiler);
}
}
- for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_globalProfilers)) {
+ for (QQmlAbstractProfilerAdapter *profiler : std::as_const(m_globalProfilers)) {
if (profiler->isRunning()) {
m_startTimes.insert(-1, profiler);
reporting.append(profiler);
}
}
- for (QQmlAbstractProfilerAdapter *profiler : qAsConst(reporting))
+ for (QQmlAbstractProfilerAdapter *profiler : std::as_const(reporting))
profiler->reportData();
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
index 945a9bee95..1a3e17fcbc 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
@@ -38,14 +38,14 @@ qint64 QV4ProfilerAdapter::appendMemoryEvents(qint64 until, QList<QByteArray> &m
// Make it const, so that we cannot accidentally detach it.
const QVector<QV4::Profiling::MemoryAllocationProperties> &memoryData = m_memoryData;
- while (memoryData.length() > m_memoryPos && memoryData[m_memoryPos].timestamp <= until) {
+ while (memoryData.size() > m_memoryPos && memoryData[m_memoryPos].timestamp <= until) {
const QV4::Profiling::MemoryAllocationProperties &props = memoryData[m_memoryPos];
d << props.timestamp << int(MemoryAllocation) << int(props.type) << props.size;
++m_memoryPos;
messages.append(d.squeezedData());
d.clear();
}
- return memoryData.length() == m_memoryPos ? -1 : memoryData[m_memoryPos].timestamp;
+ return memoryData.size() == m_memoryPos ? -1 : memoryData[m_memoryPos].timestamp;
}
qint64 QV4ProfilerAdapter::finalizeMessages(qint64 until, QList<QByteArray> &messages,
@@ -80,9 +80,9 @@ qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &message
while (true) {
while (!m_stack.isEmpty() &&
- (m_functionCallPos == functionCallData.length() ||
+ (m_functionCallPos == functionCallData.size() ||
m_stack.top() <= functionCallData[m_functionCallPos].start)) {
- if (m_stack.top() > until || messages.length() > s_numMessagesPerBatch)
+ if (m_stack.top() > until || messages.size() > s_numMessagesPerBatch)
return finalizeMessages(until, messages, m_stack.top(), d);
appendMemoryEvents(m_stack.top(), messages, d);
@@ -90,11 +90,11 @@ qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &message
messages.append(d.squeezedData());
d.clear();
}
- while (m_functionCallPos != functionCallData.length() &&
+ while (m_functionCallPos != functionCallData.size() &&
(m_stack.empty() || functionCallData[m_functionCallPos].start < m_stack.top())) {
const QV4::Profiling::FunctionCallProperties &props =
functionCallData[m_functionCallPos];
- if (props.start > until || messages.length() > s_numMessagesPerBatch)
+ if (props.start > until || messages.size() > s_numMessagesPerBatch)
return finalizeMessages(until, messages, props.start, d);
appendMemoryEvents(props.start, messages, d);
@@ -117,7 +117,7 @@ qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &message
m_stack.push(props.end);
++m_functionCallPos;
}
- if (m_stack.empty() && m_functionCallPos == functionCallData.length())
+ if (m_stack.empty() && m_functionCallPos == functionCallData.size())
return finalizeMessages(until, messages, -1, d);
}
}
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
index a7fe757df6..9eba1e23a6 100644
--- a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
@@ -119,7 +119,7 @@ static void qQuickProfilerDataToByteArrays(const QQuickProfilerData &data,
qint64 QQuickProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
{
while (next < m_data.size()) {
- if (m_data[next].time <= until && messages.length() <= s_numMessagesPerBatch)
+ if (m_data[next].time <= until && messages.size() <= s_numMessagesPerBatch)
qQuickProfilerDataToByteArrays(m_data[next++], messages);
else
return m_data[next].time;
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.cpp
index 2583f005a7..9107715f28 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.cpp
@@ -442,7 +442,7 @@ void QQmlDebugServerImpl::receiveMessage()
QStringList pluginNames;
QList<float> pluginVersions;
if (clientSupportsMultiPackets) { // otherwise, disable all plugins
- const int count = m_plugins.count();
+ const int count = m_plugins.size();
pluginNames.reserve(count);
pluginVersions.reserve(count);
for (QHash<QString, QQmlDebugService *>::ConstIterator i = m_plugins.constBegin();
@@ -558,12 +558,12 @@ void QQmlDebugServerImpl::addEngine(QJSEngine *engine)
QMutexLocker locker(&m_helloMutex);
Q_ASSERT(!m_engineConditions.contains(engine));
- for (QQmlDebugService *service : qAsConst(m_plugins))
+ for (QQmlDebugService *service : std::as_const(m_plugins))
service->engineAboutToBeAdded(engine);
- m_engineConditions[engine].waitForServices(&m_helloMutex, m_plugins.count());
+ m_engineConditions[engine].waitForServices(&m_helloMutex, m_plugins.size());
- for (QQmlDebugService *service : qAsConst(m_plugins))
+ for (QQmlDebugService *service : std::as_const(m_plugins))
service->engineAdded(engine);
}
@@ -575,12 +575,12 @@ void QQmlDebugServerImpl::removeEngine(QJSEngine *engine)
QMutexLocker locker(&m_helloMutex);
Q_ASSERT(m_engineConditions.contains(engine));
- for (QQmlDebugService *service : qAsConst(m_plugins))
+ for (QQmlDebugService *service : std::as_const(m_plugins))
service->engineAboutToBeRemoved(engine);
- m_engineConditions[engine].waitForServices(&m_helloMutex, m_plugins.count());
+ m_engineConditions[engine].waitForServices(&m_helloMutex, m_plugins.size());
- for (QQmlDebugService *service : qAsConst(m_plugins))
+ for (QQmlDebugService *service : std::as_const(m_plugins))
service->engineRemoved(engine);
m_engineConditions.remove(engine);
diff --git a/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp
index 7eb9cfd4a5..988a999e19 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp
@@ -73,7 +73,7 @@ void QSGOpenVGInternalRectangleNode::setGradientStops(const QGradientStops &stop
//normalize stops
bool needsNormalization = false;
- for (const QGradientStop &stop : qAsConst(stops)) {
+ for (const QGradientStop &stop : std::as_const(stops)) {
if (stop.first < 0.0 || stop.first > 1.0) {
needsNormalization = true;
continue;
@@ -218,7 +218,7 @@ void QSGOpenVGInternalRectangleNode::render()
vgSetParameteri(m_rectanglePaint, VG_PAINT_COLOR_RAMP_PREMULTIPLIED, false);
QVector<VGfloat> stops;
- for (const QGradientStop &stop : qAsConst(m_gradientStops)) {
+ for (const QGradientStop &stop : std::as_const(m_gradientStops)) {
// offset
stops.append(stop.first);
// color
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp
index 1aac62675c..39905673ff 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp
@@ -81,7 +81,7 @@ void QSGOpenVGNodeVisitor::endVisit(QSGClipNode *)
vgMask(0,VG_FILL_MASK, 0, 0, VG_MAXINT, VG_MAXINT);
vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
vgLoadIdentity();
- for (auto path : qAsConst(m_clipStack)) {
+ for (auto path : std::as_const(m_clipStack)) {
vgRenderToMask(path, VG_FILL_PATH, VG_INTERSECT_MASK);
}
}
diff --git a/src/qml/Qt6AndroidQmlMacros.cmake b/src/qml/Qt6AndroidQmlMacros.cmake
index 5284c3e71c..787b358975 100644
--- a/src/qml/Qt6AndroidQmlMacros.cmake
+++ b/src/qml/Qt6AndroidQmlMacros.cmake
@@ -26,18 +26,16 @@ function(_qt_internal_generate_android_qml_deployment_settings out_var target)
get_target_property(target_source_dir ${target} SOURCE_DIR)
# QML import paths
- if(NOT "${QT_QML_OUTPUT_DIRECTORY}" STREQUAL "")
- # Need to prepend the default qml module output directory to take precedence
- # over other qml import paths.
- get_target_property(native_qml_import_paths "${target}" _qt_native_qml_import_paths)
- if(native_qml_import_paths)
- list(PREPEND native_qml_import_paths "${QT_QML_OUTPUT_DIRECTORY}")
- else()
- set(native_qml_import_paths "${QT_QML_OUTPUT_DIRECTORY}")
- endif()
- set_property(TARGET "${target}" PROPERTY
- "_qt_native_qml_import_paths" "${native_qml_import_paths}")
+ _qt_internal_collect_target_qml_import_paths(qml_import_paths ${target})
+ get_target_property(native_qml_import_paths "${target}" _qt_native_qml_import_paths)
+ if(native_qml_import_paths)
+ list(PREPEND native_qml_import_paths "${qml_import_paths}")
+ else()
+ set(native_qml_import_paths "${qml_import_paths}")
endif()
+ list(REMOVE_DUPLICATES native_qml_import_paths)
+ set_property(TARGET "${target}" PROPERTY
+ _qt_native_qml_import_paths "${native_qml_import_paths}")
_qt_internal_add_android_deployment_multi_value_property(${out_var} "qml-import-paths"
${target} "_qt_native_qml_import_paths")
diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake
index 20b8101103..f307c1f4be 100644
--- a/src/qml/Qt6QmlMacros.cmake
+++ b/src/qml/Qt6QmlMacros.cmake
@@ -715,16 +715,18 @@ macro(_qt_internal_genex_getoption var target property)
set(${var} "$<BOOL:$<TARGET_PROPERTY:${target},${property}>>")
endmacro()
+# Gets the Qt import paths, prepends -I, appends the values to the given import_paths_var output
+# variable.
function(_qt_internal_extend_qml_import_paths import_paths_var)
set(local_var ${${import_paths_var}})
- # prepend extra import path which is a current module's build dir: we need
- # this to ensure correct importing of QML modules when having a prefix-build
- # with QLibraryInfo::path(QLibraryInfo::QmlImportsPath) pointing to the
- # install location
- if(QT_BUILDING_QT AND QT_WILL_INSTALL)
- list(PREPEND local_var -I "${QT_BUILD_DIR}/${INSTALL_QMLDIR}")
- endif()
+ _qt_internal_get_main_qt_qml_import_paths(qt_import_paths)
+
+ # Append the paths instead of prepending them, to ensure Qt import paths are searched after
+ # any target or build dir specific import paths.
+ foreach(import_path IN LISTS qt_import_paths)
+ list(APPEND local_var -I "${import_path}")
+ endforeach()
set(${import_paths_var} ${local_var} PARENT_SCOPE)
endfunction()
@@ -780,9 +782,11 @@ function(_qt_internal_target_enable_qmllint target)
_qt_internal_extend_qml_import_paths(import_args)
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
set(cmd
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
- ${QT_CMAKE_EXPORT_NAMESPACE}::qmllint
+ ${tool_wrapper}
+ $<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmllint>
+ --bare
${import_args}
${qrc_args}
${qmllint_files}
@@ -918,8 +922,10 @@ function(_qt_internal_target_enable_qmlcachegen target output_targets_var qmlcac
if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config" AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.20")
set(qmlcachegen "$<COMMAND_CONFIG:${qmlcachegen}>")
endif()
+
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
set(cmd
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
+ ${tool_wrapper}
${qmlcachegen}
--resource-name "${qmlcache_resource_name}"
${qrc_resource_args}
@@ -1342,12 +1348,14 @@ function(_qt_internal_target_enable_qmltc target)
set(compiled_cpp "${target_binary_dir}/.qmltc/${target}/${file_name}.cpp")
get_filename_component(out_dir ${compiled_header} DIRECTORY)
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
add_custom_command(
OUTPUT ${compiled_header} ${compiled_cpp}
COMMAND ${CMAKE_COMMAND} -E make_directory ${out_dir}
COMMAND
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
+ ${tool_wrapper}
${qmltc_executable}
+ --bare
--header "${compiled_header}"
--impl "${compiled_cpp}"
${common_args}
@@ -1598,12 +1606,18 @@ function(qt6_add_qml_plugin target)
)
endif()
+ get_target_property(install_rpath ${target} INSTALL_RPATH)
# Ignore any CMAKE_INSTALL_RPATH and set a better default RPATH on platforms
# that support it, if allowed. Projects will often set CMAKE_INSTALL_RPATH
# for executables or backing libraries, but forget about plugins. Because
# the path for QML plugins depends on their URI, it is unlikely that
# CMAKE_INSTALL_RPATH would ever be intended for use with QML plugins.
- if(NOT WIN32 AND NOT QT_NO_QML_PLUGIN_RPATH)
+ #
+ # Avoid setting INSTALL_RPATH if it was set before. This is mostly
+ # applicable for the Qml plugins built in Qt tree, that got INSTALL_RPATH
+ # from the qt_internal_add_plugin function, but also can be the case for the
+ # user Qml plugins created manually.
+ if(NOT WIN32 AND NOT QT_NO_QML_PLUGIN_RPATH AND NOT install_rpath)
# Construct a relative path from a default install location (assumed to
# be qml/target-path) to ${CMAKE_INSTALL_LIBDIR}. This would be
# applicable for Apple too (although unusual) if this is a bare install
@@ -1690,13 +1704,13 @@ function(qt6_add_qml_plugin target)
string(APPEND qt_qml_plugin_outro "} // namespace ${arg_NAMESPACE}")
endif()
- string(APPEND qt_qml_plugin_intro "extern void ${register_types_function_name}();\nQ_GHS_KEEP_REFERENCE(${register_types_function_name});")
+ string(APPEND qt_qml_plugin_intro "extern void ${register_types_function_name}();\nQ_GHS_KEEP_REFERENCE(${register_types_function_name})")
# Indenting here is deliberately different so as to make the generated
# file have sensible indenting
set(qt_qml_plugin_constructor_content
"volatile auto registration = &${register_types_function_name};
- Q_UNUSED(registration);"
+ Q_UNUSED(registration)"
)
set(generated_cpp_file
@@ -2040,6 +2054,12 @@ function(qt6_target_qml_sources target)
get_source_file_property(qml_file_singleton ${qml_file_src} QT_QML_SINGLETON_TYPE)
get_source_file_property(qml_file_internal ${qml_file_src} QT_QML_INTERNAL_TYPE)
+ if (qml_file_singleton AND qml_file_internal)
+ message(FATAL_ERROR
+ "${qml_file_src} is marked as both internal and as a "
+ "singleton, but singletons cannot be internal!")
+ endif()
+
if (NOT qml_file_versions)
set(qml_file_versions ${qml_module_files_versions})
endif()
@@ -2095,12 +2115,15 @@ function(qt6_target_qml_sources target)
else()
set(qmlcachegen_cmd "${qmlcachegen}")
endif()
+
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
add_custom_command(
OUTPUT ${compiled_file}
COMMAND ${CMAKE_COMMAND} -E make_directory ${out_dir}
COMMAND
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
+ ${tool_wrapper}
${qmlcachegen_cmd}
+ --bare
--resource-path "${file_resource_path}"
${cachegen_args}
-o "${compiled_file}"
@@ -2226,9 +2249,19 @@ function(qt6_generate_foreign_qml_types source_target destination_qml_target)
message(FATAL_ERROR "Need target metatypes.json file")
endif()
+ get_target_property(automoc_enabled ${destination_qml_target} AUTOMOC)
+ if(NOT automoc_enabled)
+ message(FATAL_ERROR "qt6_generate_foreign_qml_types requires AUTOMOC to be enabled "
+ "on target '${destination_qml_target}'.")
+ endif()
+
set(registration_files_base ${source_target}_${destination_qml_target})
- set(additional_sources ${registration_files_base}.cpp ${registration_files_base}.h)
+ set(additional_sources
+ "${CMAKE_CURRENT_BINARY_DIR}/${registration_files_base}.cpp"
+ "${CMAKE_CURRENT_BINARY_DIR}/${registration_files_base}.h"
+ )
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
add_custom_command(
OUTPUT
${additional_sources}
@@ -2237,7 +2270,7 @@ function(qt6_generate_foreign_qml_types source_target destination_qml_target)
${target_metatypes_json_file}
${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar
COMMAND
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
+ ${tool_wrapper}
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar>
"--extract"
-o ${registration_files_base}
@@ -2247,7 +2280,6 @@ function(qt6_generate_foreign_qml_types source_target destination_qml_target)
)
target_sources(${destination_qml_target} PRIVATE ${additional_sources})
- qt6_wrap_cpp(${additional_sources} TARGET ${destination_qml_target})
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
@@ -2399,6 +2431,11 @@ function(_qt_internal_qml_type_registration target)
if (TARGET ${target}Private)
list(APPEND cmd_args --private-includes)
+ else()
+ string(REGEX MATCH "Private$" privateSuffix ${target})
+ if (privateSuffix)
+ list(APPEND cmd_args --private-includes)
+ endif()
endif()
get_target_property(target_metatypes_json_file ${target} INTERFACE_QT_META_TYPES_BUILD_FILE)
@@ -2428,6 +2465,7 @@ function(_qt_internal_qml_type_registration target)
)
endif()
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
add_custom_command(
OUTPUT
${type_registration_cpp_file}
@@ -2438,7 +2476,7 @@ function(_qt_internal_qml_type_registration target)
${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar
"$<$<BOOL:${genex_list}>:${genex_list}>"
COMMAND
- ${QT_TOOL_COMMAND_WRAPPER_PATH}
+ ${tool_wrapper}
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar>
${cmd_args}
-o ${type_registration_cpp_file}
@@ -2540,6 +2578,84 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
endfunction()
endif()
+# Get Qt provided QML import paths.
+# The appending order is important. Build dirs are preferred over install dirs.
+function(_qt_internal_get_main_qt_qml_import_paths out_var)
+ set(qml_import_paths "")
+
+ # When building a qml module as part of a prefix Qt build that is not yet installed, add an
+ # extra import path which is the current module's build dir: we need
+ # this to ensure correct importing of QML modules when having a prefix-build
+ # with QLibraryInfo::path(QLibraryInfo::QmlImportsPath) pointing to the
+ # install location.
+ if(QT_BUILDING_QT AND QT_WILL_INSTALL)
+ set(build_dir_import_path "${QT_BUILD_DIR}/${INSTALL_QMLDIR}")
+ if(IS_DIRECTORY "${build_dir_import_path}")
+ list(APPEND qml_import_paths "${build_dir_import_path}")
+ endif()
+ endif()
+
+ # We could have multiple additional installation prefixes: one per Qt repository (conan).
+ # Or just extra ones, that might be needed during cross-compilation or example building.
+ # Add those that have a "qml" subdirectory.
+ # The additional prefixes have priority over the main Qt prefix, so they come first.
+ if(NOT "${_qt_additional_packages_prefix_paths}" STREQUAL "")
+ __qt_internal_prefix_paths_to_roots(
+ additional_root_paths "${_qt_additional_packages_prefix_paths}")
+ foreach(root IN ITEMS ${additional_root_paths})
+ set(candidate "${root}/${QT6_INSTALL_QML}")
+ if(IS_DIRECTORY "${candidate}")
+ list(APPEND qml_import_paths "${candidate}")
+ endif()
+ endforeach()
+ endif()
+
+ # Add the main Qt "<prefix>/qml" import path.
+ if(QT6_INSTALL_PREFIX)
+ set(main_import_path "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_QML}")
+ if(IS_DIRECTORY "${main_import_path}")
+ list(APPEND qml_import_paths "${main_import_path}")
+ endif()
+ endif()
+
+ set(${out_var} "${qml_import_paths}" PARENT_SCOPE)
+endfunction()
+
+function(_qt_internal_collect_target_qml_import_paths out_var target)
+ set(qml_import_paths "")
+ # Get custom import paths provided during qt_add_qml_module call.
+ get_target_property(qml_import_path ${target} QT_QML_IMPORT_PATH)
+ if(qml_import_path)
+ list(APPEND qml_import_paths ${qml_import_path})
+ endif()
+
+ # Facilitate self-import so we can find the qmldir file
+ get_target_property(module_out_dir ${target} QT_QML_MODULE_OUTPUT_DIRECTORY)
+ if(module_out_dir)
+ list(APPEND qml_import_paths "${module_out_dir}")
+ endif()
+
+ # Find qmldir files we copied to the build directory
+ if(NOT "${QT_QML_OUTPUT_DIRECTORY}" STREQUAL "")
+ if(EXISTS "${QT_QML_OUTPUT_DIRECTORY}")
+ list(APPEND qml_import_paths "${QT_QML_OUTPUT_DIRECTORY}")
+ endif()
+ else()
+ list(APPEND qml_import_paths "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+
+ set(${out_var} "${qml_import_paths}" PARENT_SCOPE)
+endfunction()
+
+function(_qt_internal_collect_qml_import_paths out_var target)
+ _qt_internal_collect_target_qml_import_paths(qml_import_paths ${target})
+
+ # Add the Qt import paths last.
+ _qt_internal_get_main_qt_qml_import_paths(qt_main_import_paths)
+ list(APPEND qml_import_paths ${qt_main_import_paths})
+
+ set(${out_var} "${qml_import_paths}" PARENT_SCOPE)
+endfunction()
function(_qt_internal_scan_qml_imports target imports_file_var when_to_scan)
if(NOT "${ARGN}" STREQUAL "")
@@ -2577,29 +2693,6 @@ but this file does not exist. Possible reasons include:
")
endif()
- # Find QML import paths.
- if("${_qt_additional_packages_prefix_paths}" STREQUAL "")
- # We have one installation prefix for all Qt modules. Add the "<prefix>/qml" directory.
- set(qml_import_paths "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_QML}")
- else()
- # We have multiple installation prefixes: one per Qt repository (conan). Add those that have
- # a "qml" subdirectory.
- set(qml_import_paths)
- foreach(root IN ITEMS ${QT6_INSTALL_PREFIX} ${_qt_additional_packages_prefix_paths})
- set(candidate "${root}/${QT6_INSTALL_QML}")
- if(IS_DIRECTORY "${candidate}")
- list(APPEND qml_import_paths "${candidate}")
- endif()
- endforeach()
- endif()
-
- # Construct the -importPath arguments.
- set(import_path_arguments)
- foreach(path IN LISTS qml_import_paths)
- list(APPEND import_path_arguments -importPath ${path})
- endforeach()
-
- # Run qmlimportscanner to generate the cmake file that records the import entries
get_target_property(target_source_dir ${target} SOURCE_DIR)
get_target_property(target_binary_dir ${target} BINARY_DIR)
set(out_dir "${target_binary_dir}/.qt_plugins")
@@ -2611,28 +2704,18 @@ but this file does not exist. Possible reasons include:
-rootPath "${target_source_dir}"
-cmake-output
-output-file "${imports_file}"
- ${import_path_arguments}
)
- get_target_property(qml_import_path ${target} QT_QML_IMPORT_PATH)
- if (qml_import_path)
- list(APPEND cmd_args ${qml_import_path})
- endif()
+ _qt_internal_collect_qml_import_paths(qml_import_paths ${target})
+ list(REMOVE_DUPLICATES qml_import_paths)
- # Facilitate self-import so we can find the qmldir file
- get_target_property(module_out_dir ${target} QT_QML_MODULE_OUTPUT_DIRECTORY)
- if(module_out_dir)
- list(APPEND cmd_args "${module_out_dir}")
- endif()
+ # Construct the -importPath arguments.
+ set(import_path_arguments)
+ foreach(path IN LISTS qml_import_paths)
+ list(APPEND import_path_arguments -importPath ${path})
+ endforeach()
- # Find qmldir files we copied to the build directory
- if(NOT "${QT_QML_OUTPUT_DIRECTORY}" STREQUAL "")
- if(EXISTS "${QT_QML_OUTPUT_DIRECTORY}")
- list(APPEND cmd_args "${QT_QML_OUTPUT_DIRECTORY}")
- endif()
- else()
- list(APPEND cmd_args "${CMAKE_CURRENT_BINARY_DIR}")
- endif()
+ list(APPEND cmd_args ${import_path_arguments})
# All of the module's .qml files will be listed in one of the generated
# .qrc files, so there's no need to list the files individually. We provide
@@ -2653,8 +2736,10 @@ but this file does not exist. Possible reasons include:
set(cmd_args "@${rsp_file}")
endif()
- set(import_scanner_args ${QT_TOOL_COMMAND_WRAPPER_PATH} ${tool_path} ${cmd_args})
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
+ set(import_scanner_args ${tool_wrapper} ${tool_path} ${cmd_args})
+ # Run qmlimportscanner to generate the cmake file that records the import entries
if(scan_at_build_time)
add_custom_command(
OUTPUT "${imports_file}"
diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp
index 196fe7ed4a..7bb2af476c 100644
--- a/src/qml/animations/qabstractanimationjob.cpp
+++ b/src/qml/animations/qabstractanimationjob.cpp
@@ -48,11 +48,11 @@ void QQmlAnimationTimer::unsetJobTimer(QAbstractAnimationJob *animation)
QQmlAnimationTimer::~QQmlAnimationTimer()
{
- for (const auto &animation : qAsConst(animations))
+ for (const auto &animation : std::as_const(animations))
unsetJobTimer(animation);
- for (const auto &animation : qAsConst(animationsToStart))
+ for (const auto &animation : std::as_const(animationsToStart))
unsetJobTimer(animation);
- for (const auto &animation : qAsConst(runningPauseAnimations))
+ for (const auto &animation : std::as_const(runningPauseAnimations))
unsetJobTimer(animation);
}
@@ -93,7 +93,7 @@ void QQmlAnimationTimer::updateAnimationsTime(qint64 delta)
//when the CPU load is high
if (delta) {
insideTick = true;
- for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) {
+ for (currentAnimationIdx = 0; currentAnimationIdx < animations.size(); ++currentAnimationIdx) {
QAbstractAnimationJob *animation = animations.at(currentAnimationIdx);
int elapsed = animation->m_totalCurrentTime
+ (animation->direction() == QAbstractAnimationJob::Forward ? delta : -delta);
@@ -101,7 +101,7 @@ void QQmlAnimationTimer::updateAnimationsTime(qint64 delta)
}
if (animationTickDump()) {
qDebug() << "***** Dumping Animation Tree ***** ( tick:" << lastTick << "delta:" << delta << ")";
- for (int i = 0; i < animations.count(); ++i)
+ for (int i = 0; i < animations.size(); ++i)
qDebug() << animations.at(i);
}
insideTick = false;
diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h
index a933f49be3..6330b01bb1 100644
--- a/src/qml/animations/qabstractanimationjob_p.h
+++ b/src/qml/animations/qabstractanimationjob_p.h
@@ -193,7 +193,7 @@ public:
void updateAnimationsTime(qint64 timeStep) override;
//useful for profiling/debugging
- int runningAnimationCount() override { return animations.count(); }
+ int runningAnimationCount() override { return animations.size(); }
bool hasStartAnimationPending() const { return startAnimationPending; }
diff --git a/src/qml/common/qqmljsfixedpoolarray_p.h b/src/qml/common/qqmljsfixedpoolarray_p.h
index 16f60c002e..e946b1ecfd 100644
--- a/src/qml/common/qqmljsfixedpoolarray_p.h
+++ b/src/qml/common/qqmljsfixedpoolarray_p.h
@@ -44,7 +44,7 @@ public:
void allocate(MemoryPool *pool, const QVector<T> &vector)
{
- count = vector.count();
+ count = vector.size();
data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
if (QTypeInfo<T>::isComplex) {
@@ -58,7 +58,7 @@ public:
template <typename Container>
void allocate(MemoryPool *pool, const Container &container)
{
- count = container.count();
+ count = container.size();
data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
typename Container::ConstIterator it = container.constBegin();
for (int i = 0; i < count; ++i)
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h
index 2edb73f7b0..23c75d705f 100644
--- a/src/qml/common/qv4compileddata_p.h
+++ b/src/qml/common/qv4compileddata_p.h
@@ -222,7 +222,7 @@ struct String
qint32_le size;
static int calculateSize(const QString &str) {
- return (sizeof(String) + (str.length() + 1) * sizeof(quint16) + 7) & ~0x7;
+ return (sizeof(String) + (str.size() + 1) * sizeof(quint16) + 7) & ~0x7;
}
};
@@ -578,7 +578,7 @@ struct Binding
static QString escapedString(const QString &string)
{
QString tmp = QLatin1String("\"");
- for (int i = 0; i < string.length(); ++i) {
+ for (int i = 0; i < string.size(); ++i) {
const QChar &c = string.at(i);
switch (c.unicode()) {
case 0x08:
@@ -1047,8 +1047,8 @@ public:
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); };
+ RequiredPropertyExtraDataIterator requiredPropertyExtraDataBegin() const {return RequiredPropertyExtraDataIterator(this, 0); }
+ RequiredPropertyExtraDataIterator requiredPropertyExtraDataEnd() const {return RequiredPropertyExtraDataIterator(this, nRequiredPropertyExtraData); }
int namedObjectsInComponentCount() const { return nNamedObjectsInComponent; }
// ---
diff --git a/src/qml/common/qv4stringtoarrayindex_p.h b/src/qml/common/qv4stringtoarrayindex_p.h
index ba5642a27d..fc71ca7072 100644
--- a/src/qml/common/qv4stringtoarrayindex_p.h
+++ b/src/qml/common/qv4stringtoarrayindex_p.h
@@ -52,7 +52,7 @@ uint stringToArrayIndex(const T *ch, const T *end)
inline uint stringToArrayIndex(const QString &str)
{
- return stringToArrayIndex(str.constData(), str.constData() + str.length());
+ return stringToArrayIndex(str.constData(), str.constData() + str.size());
}
} // namespace QV4
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 5beeda930f..92b1d897e3 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1391,7 +1391,7 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O
// If it's a namespace, prepend the qualifier and we'll resolve it later to the correct type.
QString currentName = qualifiedIdElement->name.toString();
if (qualifiedIdElement->next) {
- for (const QV4::CompiledData::Import* import : qAsConst(_imports))
+ for (const QV4::CompiledData::Import* import : std::as_const(_imports))
if (import->qualifierIndex != emptyStringIndex
&& stringAt(import->qualifierIndex) == currentName) {
qualifiedIdElement = qualifiedIdElement->next;
@@ -1522,7 +1522,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
jsUnit = createdUnit = output.jsGenerator.generateUnit();
// enable flag if we encountered pragma Singleton
- for (Pragma *p : qAsConst(output.pragmas)) {
+ for (Pragma *p : std::as_const(output.pragmas)) {
switch (p->type) {
case Pragma::Singleton:
createdUnit->flags |= Unit::IsSingleton;
@@ -1579,7 +1579,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
const unsigned int objectOffset = sizeof(QV4::CompiledData::QmlUnit) + importSize;
uint nextOffset = objectOffset + objectOffsetTableSize;
- for (Object *o : qAsConst(output.objects)) {
+ for (Object *o : std::as_const(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(), o->inlineComponentCount(), o->requiredPropertyExtraDataCount());
@@ -1607,7 +1607,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
// write imports
char *importPtr = data + qmlUnit->offsetToImports;
- for (const QV4::CompiledData::Import *imp : qAsConst(output.imports)) {
+ for (const QV4::CompiledData::Import *imp : std::as_const(output.imports)) {
QV4::CompiledData::Import *importToWrite = reinterpret_cast<QV4::CompiledData::Import*>(importPtr);
*importToWrite = *imp;
importPtr += sizeof(QV4::CompiledData::Import);
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index c0026aba1f..bab1f026c3 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -74,8 +74,8 @@ void QV4::Compiler::StringTableGenerator::serialize(CompiledData::Unit *unit)
QV4::CompiledData::String *s = reinterpret_cast<QV4::CompiledData::String *>(stringData);
Q_ASSERT(reinterpret_cast<uintptr_t>(s) % alignof(QV4::CompiledData::String) == 0);
- Q_ASSERT(qstr.length() >= 0);
- s->size = qstr.length();
+ Q_ASSERT(qstr.size() >= 0);
+ s->size = qstr.size();
ushort *uc = reinterpret_cast<ushort *>(reinterpret_cast<char *>(s) + sizeof(*s));
qToLittleEndian<ushort>(qstr.constData(), s->size, uc);
@@ -209,7 +209,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
{
registerString(module->fileName);
registerString(module->finalUrl);
- for (Context *f : qAsConst(module->functions)) {
+ for (Context *f : std::as_const(module->functions)) {
registerString(f->name);
registerString(f->returnType);
for (int i = 0; i < f->arguments.size(); ++i) {
@@ -219,7 +219,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
for (int i = 0; i < f->locals.size(); ++i)
registerString(f->locals.at(i));
}
- for (Context *c : qAsConst(module->blocks)) {
+ for (Context *c : std::as_const(module->blocks)) {
for (int i = 0; i < c->locals.size(); ++i)
registerString(c->locals.at(i));
}
@@ -290,7 +290,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
}
CompiledData::Lookup *lookupsToWrite = reinterpret_cast<CompiledData::Lookup*>(dataPtr + unit->offsetToLookupTable);
- for (const CompiledData::Lookup &l : qAsConst(lookups))
+ for (const CompiledData::Lookup &l : std::as_const(lookups))
*lookupsToWrite++ = l;
CompiledData::RegExp *regexpTable = reinterpret_cast<CompiledData::RegExp *>(dataPtr + unit->offsetToRegexpTable);
@@ -313,12 +313,12 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
// write js classes and js class lookup table
quint32_le *jsClassOffsetTable = reinterpret_cast<quint32_le *>(dataPtr + unit->offsetToJSClassTable);
- for (int i = 0; i < jsClassOffsets.count(); ++i)
+ for (int i = 0; i < jsClassOffsets.size(); ++i)
jsClassOffsetTable[i] = jsClassDataOffset + jsClassOffsets.at(i);
}
- if (translations.count()) {
- memcpy(dataPtr + unit->offsetToTranslationTable, translations.constData(), translations.count() * sizeof(CompiledData::TranslationData));
+ if (translations.size()) {
+ memcpy(dataPtr + unit->offsetToTranslationTable, translations.constData(), translations.size() * sizeof(CompiledData::TranslationData));
}
{
@@ -588,7 +588,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
unit.offsetToBlockTable = nextOffset;
nextOffset += unit.blockTableSize * sizeof(uint);
- unit.lookupTableSize = lookups.count();
+ unit.lookupTableSize = lookups.size();
unit.offsetToLookupTable = nextOffset;
nextOffset += unit.lookupTableSize * sizeof(CompiledData::Lookup);
@@ -603,7 +603,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
unit.offsetToConstantTable = nextOffset;
nextOffset += unit.constantTableSize * sizeof(ReturnedValue);
- unit.jsClassTableSize = jsClassOffsets.count();
+ unit.jsClassTableSize = jsClassOffsets.size();
unit.offsetToJSClassTable = nextOffset;
nextOffset += unit.jsClassTableSize * sizeof(uint);
@@ -612,7 +612,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));
- unit.translationTableSize = translations.count();
+ unit.translationTableSize = translations.size();
unit.offsetToTranslationTable = nextOffset;
nextOffset += unit.translationTableSize * sizeof(CompiledData::TranslationData);
@@ -625,16 +625,16 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));
};
- reserveExportTable(module->localExportEntries.count(), &unit.localExportEntryTableSize, &unit.offsetToLocalExportEntryTable);
- reserveExportTable(module->indirectExportEntries.count(), &unit.indirectExportEntryTableSize, &unit.offsetToIndirectExportEntryTable);
- reserveExportTable(module->starExportEntries.count(), &unit.starExportEntryTableSize, &unit.offsetToStarExportEntryTable);
+ reserveExportTable(module->localExportEntries.size(), &unit.localExportEntryTableSize, &unit.offsetToLocalExportEntryTable);
+ reserveExportTable(module->indirectExportEntries.size(), &unit.indirectExportEntryTableSize, &unit.offsetToIndirectExportEntryTable);
+ reserveExportTable(module->starExportEntries.size(), &unit.starExportEntryTableSize, &unit.offsetToStarExportEntryTable);
- unit.importEntryTableSize = module->importEntries.count();
+ unit.importEntryTableSize = module->importEntries.size();
unit.offsetToImportEntryTable = nextOffset;
nextOffset += unit.importEntryTableSize * sizeof(CompiledData::ImportEntry);
nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));
- unit.moduleRequestTableSize = module->moduleRequests.count();
+ unit.moduleRequestTableSize = module->moduleRequests.size();
unit.offsetToModuleRequestTable = nextOffset;
nextOffset += unit.moduleRequestTableSize * sizeof(uint);
nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));
@@ -696,7 +696,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
if (showStats) {
qDebug() << "Generated JS unit that is" << unit.unitSize << "bytes contains:";
qDebug() << " " << functionSize << "bytes for non-code function data for" << unit.functionTableSize << "functions";
- qDebug() << " " << translations.count() * sizeof(CompiledData::TranslationData) << "bytes for" << translations.count() << "translations";
+ qDebug() << " " << translations.size() * sizeof(CompiledData::TranslationData) << "bytes for" << translations.size() << "translations";
}
return unit;
diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp
index cb32f9ad43..1d4b0bde17 100644
--- a/src/qml/compiler/qv4compilercontext.cpp
+++ b/src/qml/compiler/qv4compilercontext.cpp
@@ -147,7 +147,7 @@ Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::So
return result;
if (c->contextType == ContextType::ESModule) {
- for (int i = 0; i < c->importEntries.count(); ++i) {
+ for (int i = 0; i < c->importEntries.size(); ++i) {
if (c->importEntries.at(i).localName == name) {
result.index = i;
result.type = ResolvedName::Import;
@@ -180,7 +180,7 @@ void Context::emitBlockHeader(Codegen *codegen)
if (requiresExecutionContext) {
if (blockIndex < 0) {
codegen->module()->blocks.append(this);
- blockIndex = codegen->module()->blocks.count() - 1;
+ blockIndex = codegen->module()->blocks.size() - 1;
}
if (contextType == ContextType::Global) {
@@ -272,7 +272,7 @@ void Context::emitBlockHeader(Codegen *codegen)
codegen->referenceForName(QStringLiteral("arguments"), false).storeConsumeAccumulator();
}
- for (const Context::Member &member : qAsConst(members)) {
+ for (const Context::Member &member : std::as_const(members)) {
if (member.function) {
const int function = codegen->defineFunction(member.function->name.toString(), member.function, member.function->formals, member.function->body);
codegen->loadClosure(function);
@@ -360,8 +360,8 @@ void Context::setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator)
break;
}
- sizeOfLocalTemporalDeadZone = localsInTDZ.count();
- for (auto &member: qAsConst(localsInTDZ)) {
+ sizeOfLocalTemporalDeadZone = localsInTDZ.size();
+ for (auto &member: std::as_const(localsInTDZ)) {
member->index = locals.size();
locals.append(member.key());
}
@@ -375,9 +375,9 @@ void Context::setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator)
}
}
- sizeOfRegisterTemporalDeadZone = registersInTDZ.count();
+ sizeOfRegisterTemporalDeadZone = registersInTDZ.size();
firstTemporalDeadZoneRegister = bytecodeGenerator->currentRegister();
- for (auto &member: qAsConst(registersInTDZ))
+ for (auto &member: std::as_const(registersInTDZ))
member->index = bytecodeGenerator->newRegister();
nRegisters = bytecodeGenerator->currentRegister() - registerOffset;
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp
index 29bc3918ea..157d2896aa 100644
--- a/src/qml/compiler/qv4compilerscanfunctions.cpp
+++ b/src/qml/compiler/qv4compilerscanfunctions.cpp
@@ -308,7 +308,7 @@ bool ScanFunctions::visit(PatternElement *ast)
declarationLocation.length = ast->lastSourceLocation().end() - declarationLocation.offset;
}
- for (const auto &name : qAsConst(names)) {
+ for (const auto &name : std::as_const(names)) {
if (_context->isStrict && (name.id == QLatin1String("eval") || name.id == QLatin1String("arguments")))
_cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Variable name may not be eval or arguments in strict mode"));
checkName(QStringView(name.id), ast->identifierToken);
@@ -721,7 +721,7 @@ void ScanFunctions::calcEscapingVariables()
{
Module *m = _cg->_module;
- for (Context *inner : qAsConst(m->contextMap)) {
+ for (Context *inner : std::as_const(m->contextMap)) {
if (inner->usesArgumentsObject != Context::ArgumentsObjectUsed)
continue;
if (inner->contextType != ContextType::Block && !inner->isArrowFunction)
@@ -733,7 +733,7 @@ void ScanFunctions::calcEscapingVariables()
c->usesArgumentsObject = Context::ArgumentsObjectUsed;
inner->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
}
- for (Context *inner : qAsConst(m->contextMap)) {
+ for (Context *inner : std::as_const(m->contextMap)) {
if (!inner->parent || inner->usesArgumentsObject == Context::ArgumentsObjectUnknown)
inner->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
if (inner->usesArgumentsObject == Context::ArgumentsObjectUsed) {
@@ -746,7 +746,7 @@ void ScanFunctions::calcEscapingVariables()
}
}
- for (Context *c : qAsConst(m->contextMap)) {
+ for (Context *c : std::as_const(m->contextMap)) {
if (c->contextType != ContextType::ESModule)
continue;
for (const auto &entry: c->exportEntries) {
@@ -757,8 +757,8 @@ void ScanFunctions::calcEscapingVariables()
break;
}
- for (Context *inner : qAsConst(m->contextMap)) {
- for (const QString &var : qAsConst(inner->usedVariables)) {
+ for (Context *inner : std::as_const(m->contextMap)) {
+ for (const QString &var : std::as_const(inner->usedVariables)) {
Context *c = inner;
while (c) {
Context *current = c;
@@ -820,7 +820,7 @@ void ScanFunctions::calcEscapingVariables()
c->innerFunctionAccessesThis |= innerFunctionAccessesThis;
}
}
- for (Context *c : qAsConst(m->contextMap)) {
+ for (Context *c : std::as_const(m->contextMap)) {
if (c->innerFunctionAccessesThis) {
// add an escaping 'this' variable
c->addLocalVar(QStringLiteral("this"), Context::VariableDefinition, VariableScope::Let);
@@ -846,7 +846,7 @@ void ScanFunctions::calcEscapingVariables()
c->requiresExecutionContext = true;
c->argumentsCanEscape = true;
} else {
- for (const auto &m : qAsConst(c->members)) {
+ for (const auto &m : std::as_const(c->members)) {
if (m.isLexicallyScoped()) {
c->requiresExecutionContext = true;
break;
@@ -861,13 +861,13 @@ void ScanFunctions::calcEscapingVariables()
mIt->canEscape = true;
}
const QLatin1String exprForOn("expression for on");
- if (c->contextType == ContextType::Binding && c->name.length() > exprForOn.size() &&
+ if (c->contextType == ContextType::Binding && c->name.size() > exprForOn.size() &&
c->name.startsWith(exprForOn) && c->name.at(exprForOn.size()).isUpper())
// we don't really need this for bindings, but we do for signal handlers, and in this case,
// we don't know if the code is a signal handler or not.
c->requiresExecutionContext = true;
if (c->allVarsEscape) {
- for (const auto &m : qAsConst(c->members))
+ for (const auto &m : std::as_const(c->members))
m.canEscape = true;
}
}
@@ -875,7 +875,7 @@ void ScanFunctions::calcEscapingVariables()
static const bool showEscapingVars = qEnvironmentVariableIsSet("QV4_SHOW_ESCAPING_VARS");
if (showEscapingVars) {
qDebug() << "==== escaping variables ====";
- for (Context *c : qAsConst(m->contextMap)) {
+ for (Context *c : std::as_const(m->contextMap)) {
qDebug() << "Context" << c << c->name << "requiresExecutionContext" << c->requiresExecutionContext << "isStrict" << c->isStrict;
qDebug() << " isArrowFunction" << c->isArrowFunction << "innerFunctionAccessesThis" << c->innerFunctionAccessesThis;
qDebug() << " parent:" << c->parent;
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index c7fdec1a4d..75408fd348 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -503,7 +503,7 @@ void dumpBytecode(const char *bytecode, int len, int nLocals, int nFormals, int
const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping = QVector<CompiledData::CodeOffsetToLine>());
inline void dumpBytecode(const QByteArray &bytecode, int nLocals, int nFormals, int startLine = 1,
const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping = QVector<CompiledData::CodeOffsetToLine>()) {
- dumpBytecode(bytecode.constData(), bytecode.length(), nLocals, nFormals, startLine, lineNumberMapping);
+ dumpBytecode(bytecode.constData(), bytecode.size(), nLocals, nFormals, startLine, lineNumberMapping);
}
union Instr
diff --git a/src/qml/debugger/qqmlconfigurabledebugservice_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
index 8451f4e800..ce911c5baf 100644
--- a/src/qml/debugger/qqmlconfigurabledebugservice_p.h
+++ b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
@@ -37,7 +37,7 @@ protected:
{
QMutexLocker lock(&m_configMutex);
m_waitingForConfiguration = false;
- for (QJSEngine *engine : qAsConst(m_waitingEngines))
+ for (QJSEngine *engine : std::as_const(m_waitingEngines))
Q_EMIT Base::attachedToEngine(engine);
m_waitingEngines.clear();
}
diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp
index add0396228..0b66a29e18 100644
--- a/src/qml/debugger/qqmldebugconnector.cpp
+++ b/src/qml/debugger/qqmldebugconnector.cpp
@@ -95,7 +95,7 @@ QQmlDebugConnector *QQmlDebugConnector::instance()
int connectorEnd = params->arguments.indexOf(QLatin1Char(','), connectorBegin);
if (connectorEnd == -1)
- connectorEnd = params->arguments.length();
+ connectorEnd = params->arguments.size();
params->instance = loadQQmlDebugConnector(params->arguments.mid(
connectorBegin,
diff --git a/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp b/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp
index c933adfcaf..f82b9f6d39 100644
--- a/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp
+++ b/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp
@@ -162,7 +162,7 @@ void tst_qmltc_examples::helloWorld()
QVERIFY(!documentationCode.isEmpty());
auto begin = generatedCode.cbegin();
- for (const QString &existingString : qAsConst(documentationCode)) {
+ for (const QString &existingString : std::as_const(documentationCode)) {
auto pos = std::find(begin, generatedCode.cend(), existingString);
QVERIFY2(pos != generatedCode.cend(), qPrintable(u"Could not find: " + existingString));
begin = std::next(pos);
diff --git a/src/qml/doc/src/cmake/cmake-properties.qdoc b/src/qml/doc/src/cmake/cmake-properties.qdoc
index 0b8d2c9367..98858ca6d1 100644
--- a/src/qml/doc/src/cmake/cmake-properties.qdoc
+++ b/src/qml/doc/src/cmake/cmake-properties.qdoc
@@ -13,7 +13,7 @@ CMake source file properties:
/*!
-\page cmake-source-file-property-QT_QML_INTERNAL_TYPE.html
+\page cmake-source-file-property-qt-qml-internal-type.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_INTERNAL_TYPE
@@ -30,7 +30,7 @@ Set this property to \c TRUE to indicate that the \c{.qml} file provides an inte
/*!
-\page cmake-source-file-property-QT_QML_SINGLETON_TYPE.html
+\page cmake-source-file-property-qt-qml-singleton-type.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SINGLETON_TYPE
@@ -53,7 +53,7 @@ how to set the \c QT_QML_SINGLETON_TYPE property.
/*!
-\page cmake-source-file-property-QT_QML_SKIP_CACHEGEN.html
+\page cmake-source-file-property-qt-qml-skip-cachegen.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SKIP_CACHEGEN
@@ -72,7 +72,7 @@ The file will still be added to the \c target as a resource in uncompiled form
/*!
-\page cmake-source-file-property-QT_QML_SKIP_QMLDIR_ENTRY.html
+\page cmake-source-file-property-qt-qml-skip-qmldir-entry.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SKIP_QMLDIR_ENTRY
@@ -91,7 +91,7 @@ the \c{.qml} file from being added as a type to the QML module's typeinfo file
/*!
-\page cmake-source-file-property-QT_QML_SKIP_QMLLINT.html
+\page cmake-source-file-property-qt-qml-skip-qmllint.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SKIP_QMLLINT
@@ -109,7 +109,7 @@ Set this property to \c TRUE to prevent the file from being included in
/*!
-\page cmake-source-file-property-QT_QML_SOURCE_TYPENAME.html
+\page cmake-source-file-property-qt-qml-source-typename.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SOURCE_TYPENAME
@@ -126,7 +126,7 @@ Use this property to override the \c QML type name provided by this file.
/*!
-\page cmake-source-file-property-QT_QML_SOURCE_VERSIONS.html
+\page cmake-source-file-property-qt-qml-source-versions.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SOURCE_VERSIONS
@@ -145,7 +145,7 @@ version after the \c{.0} release, specify those versions using this property.
/*!
-\page cmake-source-file-property-QT_QMLTC_FILE_BASENAME.html
+\page cmake-source-file-property-qt-qmltc-file-basename.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QMLTC_FILE_BASENAME
@@ -163,7 +163,7 @@ conflicting file names.
*/
/*!
-\page cmake-source-file-property-QT_QML_SKIP_TYPE_COMPILER.html
+\page cmake-source-file-property-qt-qml-skip-type-compiler.html
\ingroup cmake-source-file-properties-qtqml
\title QT_QML_SKIP_TYPE_COMPILER
diff --git a/src/qml/doc/src/cmake/cmake-variables.qdoc b/src/qml/doc/src/cmake/cmake-variables.qdoc
index 15f73f074e..574b24e970 100644
--- a/src/qml/doc/src/cmake/cmake-variables.qdoc
+++ b/src/qml/doc/src/cmake/cmake-variables.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page cmake-variable-QT_QML_OUTPUT_DIRECTORY.html
+\page cmake-variable-qt-qml-output-directory.html
\ingroup cmake-variables-qtqml
\title QT_QML_OUTPUT_DIRECTORY
diff --git a/src/qml/doc/src/cmake/qt_add_qml_module.qdoc b/src/qml/doc/src/cmake/qt_add_qml_module.qdoc
index 20c343a1bd..e20876fede 100644
--- a/src/qml/doc/src/cmake/qt_add_qml_module.qdoc
+++ b/src/qml/doc/src/cmake/qt_add_qml_module.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_add_qml_module.html
+\page qt-add-qml-module.html
\ingroup cmake-commands-qtqml
\title qt_add_qml_module
@@ -364,8 +364,12 @@ been created. When \c NO_CREATE_PLUGIN_TARGET is given, \c PLUGIN_TARGET must
also be provided to explicitly name the plugin target.
Every QML module must define a \c URI. It should be specified in dotted URI
-notation, such as \c{QtQuick.Layouts}. It must not contain anything other than
-alphanumeric or dot characters. Other QML modules may use this name in
+notation, such as \c{QtQuick.Layouts}. Each segment must be a well-formed
+ECMAScript Identifier Name. This means, for example, the segments
+must not start with a number and they must not contain \e{-} (minus)
+characters. As the \c URI will be translated into directory names, you
+should restrict it to alphanumeric characters of the latin alphabet,
+underscores, and dots. Other QML modules may use this name in
\l{qtqml-syntax-imports.html}{import statements} to import the module. The
\c URI will be used in the \c module line of the generated
\l{Module Definition qmldir Files}{qmldir} file. The \c URI is also used to
diff --git a/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc b/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc
index cb98406a9d..2ce744559c 100644
--- a/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc
+++ b/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_add_qml_plugin.html
+\page qt-add-qml-plugin.html
\ingroup cmake-commands-qtqml
\title qt_add_qml_plugin
diff --git a/src/qml/doc/src/cmake/qt_deploy_qml_imports.qdoc b/src/qml/doc/src/cmake/qt_deploy_qml_imports.qdoc
index 92da84733e..cc3c61863c 100644
--- a/src/qml/doc/src/cmake/qt_deploy_qml_imports.qdoc
+++ b/src/qml/doc/src/cmake/qt_deploy_qml_imports.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_deploy_qml_imports.html
+\page qt-deploy-qml-imports.html
\ingroup cmake-commands-qtqml
\title qt_deploy_qml_imports
@@ -18,7 +18,7 @@ project.
\preliminarycmakecommand
-\include cmake-qml-qt-finalize-target-warning.cmake
+\include cmake-qml-qt-finalize-target-warning.qdocinc
\section1 Synopsis
diff --git a/src/qml/doc/src/cmake/qt_generate_deploy_qml_app_script.qdoc b/src/qml/doc/src/cmake/qt_generate_deploy_qml_app_script.qdoc
index 493a4fc029..fc78baddcd 100644
--- a/src/qml/doc/src/cmake/qt_generate_deploy_qml_app_script.qdoc
+++ b/src/qml/doc/src/cmake/qt_generate_deploy_qml_app_script.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_generate_deploy_qml_app_script.html
+\page qt-generate-deploy-qml-app-script.html
\ingroup cmake-commands-qtqml
\title qt_generate_deploy_qml_app_script
@@ -15,7 +15,7 @@
\cmakecommandsince 6.3
\preliminarycmakecommand
-\include cmake-qml-qt-finalize-target-warning.cmake
+\include cmake-qml-qt-finalize-target-warning.qdocinc
\section1 Synopsis
diff --git a/src/qml/doc/src/cmake/qt_generate_foreign_qml_types.qdoc b/src/qml/doc/src/cmake/qt_generate_foreign_qml_types.qdoc
index 856f0fe2b1..9bd412d36d 100644
--- a/src/qml/doc/src/cmake/qt_generate_foreign_qml_types.qdoc
+++ b/src/qml/doc/src/cmake/qt_generate_foreign_qml_types.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_generate_foreign_qml_types.html
+\page qt-generate-foreign-qml-types.html
\ingroup cmake-commands-qtqml
\title qt_generate_foreign_qml_types
@@ -67,4 +67,13 @@ the \c QML_ELEMENT macro).
The effect is equivalent to using \c QML_FOREIGN with custom structs in the QML library to expose
the types.
+
+\note In order to implement custom behavior, such as exposing an existing
+singleton instance with its own life cycle to QML, you should add custom types
+to your QML library (mylib_declarative in the above example). In turn, you
+should omit the \l QML_ELEMENT and similar macros from the original C++ classes
+so that qt_generate_foreign_qml_types() does not generate more QML integration
+structs for them. The QML macros, as well as any singleton factory functions,
+can be added to the structs that contain the \l QML_FOREIGN.
+
*/
diff --git a/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc b/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc
index b45e47ce55..8d6b32f903 100644
--- a/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc
+++ b/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_import_qml_plugins.html
+\page qt-import-qml-plugins.html
\ingroup cmake-commands-qtqml
\title qt_import_qml_plugins
diff --git a/src/qml/doc/src/cmake/qt_query_qml_module.qdoc b/src/qml/doc/src/cmake/qt_query_qml_module.qdoc
index 50996745c8..44d0a7f8da 100644
--- a/src/qml/doc/src/cmake/qt_query_qml_module.qdoc
+++ b/src/qml/doc/src/cmake/qt_query_qml_module.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_query_qml_module.html
+\page qt-query-qml-module.html
\ingroup cmake-commands-qtqml
\title qt_query_qml_module
diff --git a/src/qml/doc/src/cmake/qt_target_compile_qml_to_cpp.qdoc b/src/qml/doc/src/cmake/qt_target_compile_qml_to_cpp.qdoc
index d989c80fcf..0ef6e421ed 100644
--- a/src/qml/doc/src/cmake/qt_target_compile_qml_to_cpp.qdoc
+++ b/src/qml/doc/src/cmake/qt_target_compile_qml_to_cpp.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_target_compile_qml_to_cpp.html
+\page qt-target-compile-qml-to-cpp.html
\ingroup cmake-commands-qtqml
\title qt_target_compile_qml_to_cpp
diff --git a/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc b/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc
index 126c9767a0..35854d4b95 100644
--- a/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc
+++ b/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_target_qml_sources.html
+\page qt-target-qml-sources.html
\ingroup cmake-commands-qtqml
\title qt_target_qml_sources
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index 5799fda87e..ac1c751bf2 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -77,15 +77,18 @@ 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, add
-\c QML_ELEMENT or \c QML_NAMED_ELEMENT(<name>) to the class declaration and
+\c QML_ELEMENT or \c QML_NAMED_ELEMENT(<name>) to the class declaration. You
+also need to make adjustments in the build system. For qmake, add
\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
+\c QML_IMPORT_MAJOR_VERSION to your project file. For CMake, the file containing
+the class should be part of a target set-up with
+\l{qt_add_qml_module}{qt_add_qml_module()}.
+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
@@ -107,26 +110,52 @@ 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
-CONFIG += qmltypes
-QML_IMPORT_NAME = com.mycompany.messaging
-QML_IMPORT_MAJOR_VERSION = 1
-\endcode
+\if defined(onlinedocs)
+ \tab {build-qt-app}{tab-cmake}{CMake}{selected}
+ \tab {build-qt-app}{tab-qmake}{qmake}{}
+ \tabcontent {tab-cmake}
+ \else
+ \section3 Using CMake
+\endif
+ \badcode
+ qt_add_qml_module(messaging
+ URI com.mycompany.messaging
+ VERSION 1.0
+ SOURCES
+ message.cpp message.h
+ )
+ \endcode
+\if defined(onlinedocs)
+ \endtabcontent
+ \tabcontent {tab-qmake}
+\else
+ \section3 Using QMake
+\endif
+ \code
+ CONFIG += qmltypes
+ QML_IMPORT_NAME = com.mycompany.messaging
+ QML_IMPORT_MAJOR_VERSION = 1
+ \endcode
+
+ If the header the class is declared in is not accessible from your project's
+ include path, you may have to amend the include path so that the generated
+ registration code can be compiled.
+
+ \code
+ INCLUDEPATH += com/mycompany/messaging
+ \endcode
+\if defined(onlinedocs)
+ \endtabcontent
+\endif
-If the header the class is declared in is not accessible from your project's
-include path, you may have to amend the include path so that the generated
-registration code can be compiled:
-\code
-INCLUDEPATH += com/mycompany/messaging
-\endcode
The type can be used in an \l{qtqml-syntax-basics.html#object-declarations}
{object declaration} from QML, and its properties can be read and written to,
as per the example below:
\qml
-import com.mycompany.messaging 1.0
+import com.mycompany.messaging
Message {
author: "Amelie"
diff --git a/src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.cmake b/src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.qdocinc
index d3c7383d2e..9152726398 100644
--- a/src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.cmake
+++ b/src/qml/doc/src/includes/cmake-qml-qt-finalize-target-warning.qdocinc
@@ -1,3 +1,6 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
\warning If you are using a CMake version lower than 3.19, make sure that you
pass the \c MANUAL_FINALIZATION option to
\l{qt_add_executable}{qt6_add_executable()}, and then call
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 89b52131d9..005bd0be94 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -173,7 +173,9 @@
\c{T *create(QQmlEngine *, QJSEngine *)} when the type is first accessed.
If both do exist and are accessible, the default constructor is preferred.
If there is no default constructor and no factory function the singleton is
- inaccessible.
+ inaccessible. The QML engine generally assumes ownership of the singleton and
+ will delete it when the engine itself is destroyed. You can prevent this by
+ calling QJSEngine::setObjectOwnership() on the singleton.
In order to declare a default-constructible class as singleton, all you have
to do is add \l QML_SINGLETON:
@@ -260,7 +262,7 @@
// Initialize this using myObject where you would previously
// call qmlRegisterSingletonInstance().
- static MySingleton *s_singletonInstance = nullptr;
+ inline static MySingleton *s_singletonInstance = nullptr;
static MySingleton *create(QQmlEngine *, QJSEngine *engine)
{
@@ -284,7 +286,7 @@
}
private:
- static QJSEngine *s_engine = nullptr;
+ inline static QJSEngine *s_engine = nullptr;
};
\endcode
diff --git a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
index 80dabe45b9..58e2027e1c 100644
--- a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
@@ -29,8 +29,12 @@ The type name has the following requirements:
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.
+available to other QML files within the same local directory as the engine
+searches within the immediate directory when resolving QML type names.
+
+\note The QML engine does not automatically search remote directories this way.
+You have to add a qmldir file if your documents are loaded over the network. See
+\l{Importing QML Document Directories}.
\section2 Custom QML Type Definition
@@ -251,14 +255,14 @@ The same declaration can also be given for C++-defined types. See
\section2 ComponentBehavior
With this pragma you can restrict components defined in this file to only
-create objects within the context of the same file. This holds for inline
+create objects within their original context. This holds for inline
components as well as Component elements explicitly or implicitly created
-as properties. If a component is bound to a file context, you can safely
+as properties. If a component is bound to its context, you can safely
use IDs from the rest of the file within the component. Otherwise, the
engine and the QML tooling cannot know in advance what type, if any, such
IDs will resolve to at run time.
-In order to bind the components to the file scope specify the \c{Bound}
+In order to bind the components to their context specify the \c{Bound}
argument:
\qml
@@ -268,7 +272,7 @@ pragma ComponentBehavior: Bound
The default is \c{Unbound}. You can also specify it explicitly. In a
future version of Qt the default will change to \c{Bound}.
-Delegate components bound to the file context don't receive their own
+Delegate components bound to their context don't receive their own
private contexts on instantiation. This means that model data can only
be passed via \l{Required Properties}{required properties} in this case.
Passing model data via context properties will not work. This concerns
diff --git a/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc b/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc
index 6e8751af70..93461f1ed7 100644
--- a/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc
+++ b/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc
@@ -20,6 +20,12 @@ Identified modules must be installed into the
\l{qtqml-syntax-imports.html#qml-import-path}{import path} in order to be found
by the QML engine.
+Syntactically, each dot-separated segment of the URI must be a well-formed
+ECMAScript Identifier Name. This means, for example, the segments must not start
+with a number and they must not contain \e{-} (minus) characters. As the URI
+will be translated into directory names, you should restrict it to alphanumeric
+characters of the latin alphabet, underscores, and dots.
+
\section1 Locally Installed Identified Modules
A directory of QML and/or C++ files can be shared as an identified module if it
@@ -147,7 +153,6 @@ An identified module has several restrictions upon it:
\li the module must register its types into the module identifier type
namespace
\li the module may not register types into any other module's namespace
-\li clients must specify a version when importing the module
\endlist
For example, if an identified module is installed into
@@ -164,10 +169,9 @@ module com.example.CustomUi
\endcode
Clients will then be able to import the above module with the following import
-statement (assuming that the module registers types into version 1.0 of its
-namespace):
+statement:
\qml
-import com.example.CustomUi 1.0
+import com.example.CustomUi
\endqml
*/
diff --git a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
index c6d5e1446b..ac82d8136e 100644
--- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
+++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
@@ -419,7 +419,7 @@ documentation on this, no further action is needed. qmltyperegistrar will
automatically generate the \c .qmltypes files.
Example:
-If your module is in \c /tmp/imports/My/Module, a file caled \c plugins.qmltypes
+If your module is in \c /tmp/imports/My/Module, a file called \c plugins.qmltypes
should be generated alongside the actual plugin binary.
Add the line
diff --git a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc
index c37fb81401..fca702a278 100644
--- a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc
+++ b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc
@@ -38,6 +38,14 @@ plugins. Library plugins should limit themselves to registering types, as
any manipulation of the engine's root context may cause conflicts or other
issues in the library user's code.
+\note When using the CMake \l qt_add_qml_module API, a plugin will be generated
+automatically for you. It will take care of type registration.
+You only need to write a custom plugin if you have special
+requirements, such as registering custom image
+providers. In that case, pass
+\l{NO_GENERATE_PLUGIN_SOURCE} to the \c qt_add_qml_module
+call to disable the generation of the default plugin.
+
The linker might erroneously remove the generated type registration
function as an optimization. You can prevent that by declaring a synthetic
volatile pointer to the function somewhere in your code. If your module is
diff --git a/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc
index 37298c8caf..7126033431 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc
@@ -85,6 +85,11 @@ a file system path.
A directory of QML files can also be imported from a remote location if the
directory contains a directory listing \c qmldir file.
+\note This also holds for the implicit import of the directory a QML document
+resides in. If your QML documents are loaded from a remote location, you need
+to add qmldir files even if they don't contain any explicit directory import
+statements. Otherwise your QML documents won't see each other.
+
For example, if the \c myapp directory in the previous example was hosted at
"http://www.my-example-server.com", and the \c mycomponents directory
contained a \c qmldir file defined as follows:
diff --git a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
index a6158b14af..6e6088049c 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
@@ -12,12 +12,10 @@ resources and component directories are used within a QML document. The types
which may be used within a document depends on which modules, resources and
directories are imported by the document.
-\section2 Import Types
-
There are three different types of imports. Each import type has a slightly
different syntax, and different semantics apply to different import types.
-\section3 Module (Namespace) Imports
+\section2 Module (Namespace) Imports
The most common type of import is a module import. Clients can import
\l{qtqml-modules-identifiedmodules.html}{QML modules} which register QML object
@@ -112,7 +110,7 @@ Rectangle {
In this case, the engine will emit an error and refuse to load the file.
-\section4 C++ Module Imports
+\section3 C++ Module Imports
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
@@ -122,7 +120,7 @@ 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++.
-\section4 Importing into a Qualified Local Namespace
+\section3 Importing into a Qualified Local Namespace
The \c import statement may optionally use the \c as keyword to specify that
the types should be imported into a particular document-local namespace. If a
@@ -172,7 +170,7 @@ way that multiple modules can be imported into the global namespace. For example
\snippet qml/imports/merged-named-imports.qml imports
-\section3 Directory Imports
+\section2 Directory Imports
A directory which contains QML documents may also be imported directly in a
QML document. This provides a simple way for QML types to be segmented into
@@ -198,7 +196,7 @@ section about \l{Importing into a Qualified Local Namespace}.
For more information about directory imports, please see the in-depth
documentation about \l{qtqml-syntax-directoryimports.html}{directory imports}.
-\section3 JavaScript Resource Imports
+\section2 JavaScript Resource Imports
JavaScript resources may be imported directly in a QML document. Every
JavaScript resource must have an identifier by which it is accessed.
@@ -211,7 +209,7 @@ import "<JavaScriptFile>" as <Identifier>
Note that the \c <Identifier> must be unique within a QML document, unlike the
local namespace qualifier which can be applied to module imports.
-\section4 JavaScript Resources from Modules
+\section3 JavaScript Resources from Modules
Javascript files can be provided by modules, by adding identifier
definitions to the \c qmldir file which specifies the module.
@@ -254,7 +252,7 @@ Item {
}
\endqml
-\section4 Further Information
+\section3 Further Information
For more information about JavaScript resources, please see the documentation
about \l{qtqml-javascript-resources.html}
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index bbc5aae0f0..60e90217f4 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
@@ -32,6 +32,7 @@ The set of QML object-type attribute types is as follows:
These attributes are discussed in detail below.
\section2 The \e id Attribute
+\keyword QML.id
Every QML object type has exactly one \e id attribute. This attribute is
provided by the language itself, and cannot be redefined or overridden by any
diff --git a/src/qml/doc/src/qmllanguageref/typesystem/valuetypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/valuetypes.qdoc
index ef10620422..e497d5d5c8 100644
--- a/src/qml/doc/src/qmllanguageref/typesystem/valuetypes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/typesystem/valuetypes.qdoc
@@ -40,7 +40,7 @@ the client to import the module which provides them.
All of the value types listed below may be used as a \c property type in a QML
document, with the following exceptions:
\list
- \li \c list must be used in conjunction with a QML object type
+ \li \c list must be used in conjunction with an object or value type as element
\li \c enumeration cannot be used directly as the enumeration must be defined by a registered QML object type
\endlist
@@ -285,16 +285,7 @@ property is only invoked when the property is reassigned to a different object v
The \c list type refers to a list of QML objects or values.
- A list value can be accessed in a similar way to a JavaScript array:
-
- \list
- \li Values are assigned using the \c[] square bracket syntax with comma-separated values
- \li The \c length property provides the number of items in the list
- \li Values in the list are accessed using the \c [index] syntax
- \endlist
-
- Values can be dynamically added to the list by using the \c push method,
- as if it were a JavaScript Array
+ Properties of type \c list are empty by default.
A \c list can store QML objects or \l{QML Value Types}{value type} values.
@@ -311,7 +302,7 @@ property is only invoked when the property is reassigned to a different object v
can be assigned to and used as follows:
\qml
- import QtQuick 2.0
+ import QtQuick
Item {
width: 100; height: 100
@@ -335,7 +326,7 @@ property is only invoked when the property is reassigned to a different object v
If the list only contains one object, the square brackets may be omitted:
\qml
- import QtQuick 2.0
+ import QtQuick
Item {
width: 100; height: 100
@@ -343,17 +334,38 @@ property is only invoked when the property is reassigned to a different object v
}
\endqml
- Objects and values in a list can be replaced with the \c{[]} operator, just
- like entries of JavaScript arrays. You can also use \c{push()} to append
- entries, or you can set the \c length property of the list to truncate or
- extend it. You can not automatically extend the list by assigning to an
- index currently out of range, though. Furthermore, if you insert \c null
- values into a list of objects, those are converted to \c nullptr entries in
+ You can also declare your own list properties in QML:
+
+ \qml
+ import QtQml
+
+ QtObject {
+ property list<int> intList: [1, 2, 3, 4]
+ property list<QtObject> objectList
+ }
+ \endqml
+
+ Lists can be used much like JavaScript arrays. For example:
+
+ \list
+ \li Values are assigned using the \c[] square bracket syntax with comma-separated values
+ \li The \c length property provides the number of items in the list
+ \li Values in the list are accessed using the \c [index] syntax
+ \li You can use \c{push()} to append entries
+ \li You can set the \c length property of the list to truncate or extend it.
+ \endlist
+
+ However, you can \e{not} automatically extend the list by assigning to an
+ index currently out of range. Furthermore, if you insert \c null values
+ into a list of objects, those are converted to \c nullptr entries in
the underlying QQmlListProperty.
- A list of value types is different from a JavaScript array in one important
- aspect: Growing it by setting its length does not produce undefined entries,
- but rather default-constructed instances of the value type.
+ A list of value types is different from a JavaScript array in one further
+ important aspect: Growing it by setting its length does not produce undefined
+ entries, but rather default-constructed instances of the value type.
+
+ Similarly, growing a list of object types this way produces null entries,
+ rather than undefined entries.
This value type is provided by the QML language.
@@ -461,6 +473,36 @@ property is only invoked when the property is reassigned to a different object v
*/
/*!
+ \qmlvaluetype variant
+ \ingroup qmlvaluetypes
+ \brief a generic property type.
+
+ The \c variant type is the same as the \c var type. Use \c var instead.
+
+ \sa {QML Value Types}
+*/
+
+/*!
+ \qmlvaluetype void
+ \ingroup qmlvaluetypes
+ \brief The empty value type.
+
+ The \c void type is exclusively used to type-annotate JavaScript functions
+ returning \c undefined. For example:
+
+ \qml
+ function doThings() : void { console.log("hello") }
+ \endqml
+
+ This is to help tooling analyze calls to such functions and compile them and
+ their callers to C++.
+
+ You cannot declare \c void properties in QML.
+
+ \sa {QML Value Types}
+*/
+
+/*!
\qmlvaluetype enumeration
\ingroup qmlvaluetypes
\brief a named enumeration value.
diff --git a/src/qml/doc/src/qmltypereference.qdoc b/src/qml/doc/src/qmltypereference.qdoc
index a89f89f9f7..da9d08d4e6 100644
--- a/src/qml/doc/src/qmltypereference.qdoc
+++ b/src/qml/doc/src/qmltypereference.qdoc
@@ -60,8 +60,7 @@ provided:
/*!
\qmlvaluetype date
-\ingroup qtqmlvaluetypes
-\ingroup qtquickvaluetypes
+\ingroup qmlvaluetypes
\brief a date value.
The \c date type refers to a date value, including the time of the day.
@@ -130,7 +129,7 @@ is automatically converted into a QPointF value.
\qmlvaluetype size
\ingroup qtqmlvaluetypes
\ingroup qtquickvaluetypes
-\brief a value with width and height attributes
+\brief a value with width and height attributes.
The \c size type refers to a value with has \c width and \c height attributes.
diff --git a/src/qml/doc/src/qtqml.qdoc b/src/qml/doc/src/qtqml.qdoc
index 9d0a0e67a8..2da6a8c9e0 100644
--- a/src/qml/doc/src/qtqml.qdoc
+++ b/src/qml/doc/src/qtqml.qdoc
@@ -128,6 +128,20 @@ the QML code to interact with C++ code.
\endlist
\endomit
+\section1 Licenses and Attributions
+
+Qt QML is available under commercial licenses from \l{The Qt Company}.
+In addition, it is available under free software licenses. Since Qt 5.4,
+these free software licenses are
+\l{GNU Lesser General Public License, version 3}, or
+the \l{GNU General Public License, version 2}.
+See \l{Qt Licensing} for further details.
+
+Furthermore Qt QML in Qt \QtVersion may contain third party
+modules under following permissive licenses:
+
+\generatelist{groupsbymodule attributions-qtqml}
+
\section1 Related Articles and Guides
Further information for writing QML applications:
@@ -146,30 +160,11 @@ Further information for writing QML applications:
results
\endlist
-\section1 Examples
-
-\list
- \li \l {Qt QML Examples} {Examples}
-\endlist
-
-\section2 Reference
+\section1 Reference
\list
\li \l {Qt QML C++ Classes} {C++ Classes}
\li \l {Qt QML QML Types} {QML Types}
+ \li \l {Qt QML Examples} {Examples}
\endlist
-
-\section1 Licenses and Attributions
-
-Qt QML is available under commercial licenses from \l{The Qt Company}.
-In addition, it is available under free software licenses. Since Qt 5.4,
-these free software licenses are
-\l{GNU Lesser General Public License, version 3}, or
-the \l{GNU General Public License, version 2}.
-See \l{Qt Licensing} for further details.
-
-Furthermore Qt QML in Qt \QtVersion may contain third party
-modules under following permissive licenses:
-
-\generatelist{groupsbymodule attributions-qtqml}
*/
diff --git a/src/qml/jit/qv4baselinejit_p.h b/src/qml/jit/qv4baselinejit_p.h
index 99cdcaa0fc..537a493127 100644
--- a/src/qml/jit/qv4baselinejit_p.h
+++ b/src/qml/jit/qv4baselinejit_p.h
@@ -34,7 +34,7 @@ class BaselineJIT final: public Moth::ByteCodeHandler
{
public:
BaselineJIT(QV4::Function *);
- virtual ~BaselineJIT() Q_DECL_OVERRIDE;
+ ~BaselineJIT() override;
void generate();
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index f82c2cba26..7363703544 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -829,7 +829,7 @@ static bool convertString(const QString &string, QMetaType metaType, void *ptr)
{
// have a string based value without engine. Do conversion manually
if (metaType == QMetaType::fromType<bool>()) {
- *reinterpret_cast<bool*>(ptr) = string.length() != 0;
+ *reinterpret_cast<bool*>(ptr) = string.size() != 0;
return true;
}
if (metaType == QMetaType::fromType<QString>()) {
diff --git a/src/qml/jsapi/qjsmanagedvalue.cpp b/src/qml/jsapi/qjsmanagedvalue.cpp
index 8b2f367304..0bb01f1835 100644
--- a/src/qml/jsapi/qjsmanagedvalue.cpp
+++ b/src/qml/jsapi/qjsmanagedvalue.cpp
@@ -958,7 +958,7 @@ QJSValue QJSManagedValue::call(const QJSValueList &arguments) const
QV4::ExecutionEngine *engine = f->engine();
QV4::Scope scope(engine);
- QV4::JSCallArguments jsCallData(scope, arguments.length());
+ QV4::JSCallArguments jsCallData(scope, arguments.size());
*jsCallData.thisObject = engine->globalObject;
int i = 0;
for (const QJSValue &arg : arguments) {
@@ -997,7 +997,7 @@ QJSValue QJSManagedValue::callWithInstance(const QJSValue &instance,
}
QV4::Scope scope(engine);
- QV4::JSCallArguments jsCallData(scope, arguments.length());
+ QV4::JSCallArguments jsCallData(scope, arguments.size());
*jsCallData.thisObject = QJSValuePrivate::convertToReturnedValue(engine, instance);
int i = 0;
for (const QJSValue &arg : arguments) {
@@ -1030,7 +1030,7 @@ QJSValue QJSManagedValue::callAsConstructor(const QJSValueList &arguments) const
QV4::ExecutionEngine *engine = f->engine();
QV4::Scope scope(engine);
- QV4::JSCallArguments jsCallData(scope, arguments.length());
+ QV4::JSCallArguments jsCallData(scope, arguments.size());
int i = 0;
for (const QJSValue &arg : arguments) {
if (Q_UNLIKELY(!QJSValuePrivate::checkEngine(engine, arg))) {
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index 388cc1a21a..ea0381e886 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -106,6 +106,16 @@
integers.append(jsArray.property(i).toInt());
}
\endcode
+
+ \section2 Converting to JSON
+
+ It's possible to convert a QJSValue to a JSON type. For example,
+ to convert to an array, use \l QJSEngine::fromScriptValue():
+
+ \code
+ const QJsonValue jsonValue = engine.fromScriptValue<QJsonValue>(jsValue);
+ const QJsonArray jsonArray = jsonValue.toArray();
+ \endcode
*/
/*!
@@ -490,7 +500,7 @@ double QJSValue::toNumber() const
bool QJSValue::toBool() const
{
if (const QString *string = QJSValuePrivate::asQString(this))
- return string->length() > 0;
+ return string->size() > 0;
return caughtResult<bool>(this, &QV4::Value::toBoolean);
}
@@ -664,7 +674,7 @@ QJSValue QJSValue::call(const QJSValueList &args) const
Q_ASSERT(engine);
Scope scope(engine);
- JSCallArguments jsCallData(scope, args.length());
+ JSCallArguments jsCallData(scope, args.size());
*jsCallData.thisObject = engine->globalObject;
for (int i = 0; i < args.size(); ++i) {
if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 4edfe2a763..dc17ea4e54 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -30,7 +30,7 @@ namespace Heap {
Member(class, NoMark, quint64, mapped)
DECLARE_HEAP_OBJECT(ArgumentsObject, Object) {
- DECLARE_MARKOBJECTS(ArgumentsObject);
+ DECLARE_MARKOBJECTS(ArgumentsObject)
enum {
LengthPropertyIndex = 0,
SymbolIteratorPropertyIndex = 1,
diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h
index cc322b3f01..b955618cbe 100644
--- a/src/qml/jsruntime/qv4arraybuffer_p.h
+++ b/src/qml/jsruntime/qv4arraybuffer_p.h
@@ -60,7 +60,10 @@ private:
return *reinterpret_cast<QArrayDataPointer<char> *>(&arrayDataPointerStorage);
}
- std::aligned_storage_t<sizeof(QArrayDataPointer<char>), alignof(QArrayDataPointer<char>)>
+ template <typename T>
+ struct storage_t { alignas(T) unsigned char data[sizeof(T)]; };
+
+ storage_t<QArrayDataPointer<char>>
arrayDataPointerStorage;
bool isShared;
};
diff --git a/src/qml/jsruntime/qv4arrayiterator_p.h b/src/qml/jsruntime/qv4arrayiterator_p.h
index 2682dc79d0..ff00f99bea 100644
--- a/src/qml/jsruntime/qv4arrayiterator_p.h
+++ b/src/qml/jsruntime/qv4arrayiterator_p.h
@@ -33,7 +33,7 @@ namespace Heap {
Member(class, NoMark, quint32, nextIndex)
DECLARE_HEAP_OBJECT(ArrayIteratorObject, Object) {
- DECLARE_MARKOBJECTS(ArrayIteratorObject);
+ DECLARE_MARKOBJECTS(ArrayIteratorObject)
void init(Object *obj, QV4::ExecutionEngine *engine)
{
Object::init();
diff --git a/src/qml/jsruntime/qv4compilationunitmapper.cpp b/src/qml/jsruntime/qv4compilationunitmapper.cpp
index 0479b8b8f1..61b0f1d497 100644
--- a/src/qml/jsruntime/qv4compilationunitmapper.cpp
+++ b/src/qml/jsruntime/qv4compilationunitmapper.cpp
@@ -29,6 +29,11 @@ public:
s_staticUnits.insert(file, staticUnit);
}
+ void remove(const QString &file)
+ {
+ s_staticUnits.remove(file);
+ }
+
private:
QMutexLocker<QMutex> m_lock;
@@ -69,4 +74,10 @@ CompiledData::Unit *CompilationUnitMapper::get(
return data;
}
+void CompilationUnitMapper::invalidate(const QString &cacheFilePath)
+{
+ StaticUnitCache cache;
+ cache.remove(cacheFilePath);
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4compilationunitmapper_p.h b/src/qml/jsruntime/qv4compilationunitmapper_p.h
index 0d3ec4eeee..07952be62c 100644
--- a/src/qml/jsruntime/qv4compilationunitmapper_p.h
+++ b/src/qml/jsruntime/qv4compilationunitmapper_p.h
@@ -33,6 +33,7 @@ public:
CompiledData::Unit *get(
const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString);
+ static void invalidate(const QString &cacheFilePath);
private:
CompiledData::Unit *open(
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 66f06ff96a..82a9472223 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -29,7 +29,7 @@ namespace Heap {
Member(class, Pointer, Object *, activation)
DECLARE_HEAP_OBJECT(ExecutionContext, Base) {
- DECLARE_MARKOBJECTS(ExecutionContext);
+ DECLARE_MARKOBJECTS(ExecutionContext)
enum ContextType {
Type_GlobalContext = 0x1,
@@ -68,7 +68,7 @@ Q_STATIC_ASSERT(offsetof(ExecutionContextData, activation) == offsetof(Execution
Member(class, ValueArray, ValueArray, locals)
DECLARE_HEAP_OBJECT(CallContext, ExecutionContext) {
- DECLARE_MARKOBJECTS(CallContext);
+ DECLARE_MARKOBJECTS(CallContext)
void init()
{
diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h
index 73f31d8f8c..ab2e1e589a 100644
--- a/src/qml/jsruntime/qv4dataview_p.h
+++ b/src/qml/jsruntime/qv4dataview_p.h
@@ -33,7 +33,7 @@ struct DataViewCtor : FunctionObject {
Member(class, NoMark, uint, byteOffset)
DECLARE_HEAP_OBJECT(DataView, Object) {
- DECLARE_MARKOBJECTS(DataView);
+ DECLARE_MARKOBJECTS(DataView)
void init() { Object::init(); }
};
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 769b8c161a..1fb6d92183 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -343,7 +343,7 @@ static inline double ParseString(const QString &s, double localTZA)
};
const QChar *ch = s.constData();
- const QChar *end = ch + s.length();
+ const QChar *end = ch + s.size();
uint format = Year;
int current = 0;
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 17cea99fd8..30924dd76d 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -324,6 +324,9 @@ void ExecutionEngine::initializeStaticMembers()
#elif defined(Q_OS_ANDROID)
// In experiments, it started crashing at 1059.
s_maxCallDepth = 1000;
+#elif defined(Q_OS_WIN)
+ // We've seen crashes around 750.
+ s_maxCallDepth = 640;
#else
s_maxCallDepth = 1234;
#endif
@@ -391,12 +394,15 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
}
}
+ // We allocate guard pages around our stacks.
+ const size_t guardPages = 2 * WTF::pageSize();
+
memoryManager = new QV4::MemoryManager(this);
// reserve space for the JS stack
// we allow it to grow to a bit more than m_maxJSStackSize, as we can overshoot due to ScopedValues
// allocated outside of JIT'ed methods.
*jsStack = WTF::PageAllocation::allocate(
- s_maxJSStackSize + 256*1024, WTF::OSAllocator::JSVMStackPages,
+ s_maxJSStackSize + 256*1024 + guardPages, WTF::OSAllocator::JSVMStackPages,
/* writable */ true, /* executable */ false, /* includesGuardPages */ true);
jsStackBase = (Value *)jsStack->base();
#ifdef V4_USE_VALGRIND
@@ -405,9 +411,9 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
jsStackTop = jsStackBase;
- *gcStack = WTF::PageAllocation::allocate(s_maxGCStackSize, WTF::OSAllocator::JSVMStackPages,
- /* writable */ true, /* executable */ false,
- /* includesGuardPages */ true);
+ *gcStack = WTF::PageAllocation::allocate(
+ s_maxGCStackSize + guardPages, WTF::OSAllocator::JSVMStackPages,
+ /* writable */ true, /* executable */ false, /* includesGuardPages */ true);
exceptionValue = jsAlloca(1);
*exceptionValue = Encode::undefined();
@@ -949,13 +955,13 @@ Heap::Object *ExecutionEngine::newObject(Heap::InternalClass *internalClass)
Heap::String *ExecutionEngine::newString(const QString &s)
{
- return memoryManager->allocWithStringData<String>(s.length() * sizeof(QChar), s);
+ return memoryManager->allocWithStringData<String>(s.size() * sizeof(QChar), s);
}
Heap::String *ExecutionEngine::newIdentifier(const QString &text)
{
Scope scope(this);
- ScopedString s(scope, memoryManager->allocWithStringData<String>(text.length() * sizeof(QChar), text));
+ ScopedString s(scope, memoryManager->allocWithStringData<String>(text.size() * sizeof(QChar), text));
s->toPropertyKey();
return s->d();
}
@@ -1511,6 +1517,12 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet
if (metaType == QMetaType::fromType<bool>())
return QVariant(value.toBoolean());
+ if (metaType == QMetaType::fromType<double>())
+ return QVariant(value.toNumber());
+
+ if (metaType == QMetaType::fromType<float>())
+ return QVariant(float(value.toNumber()));
+
if (metaType == QMetaType::fromType<QJsonValue>())
return QVariant::fromValue(QV4::JsonObject::toJsonValue(value));
@@ -1842,23 +1854,17 @@ QV4::ReturnedValue ExecutionEngine::fromData(
// directly against QList<QObject*>?
const QList<QObject *> &list = *(const QList<QObject *>*)ptr;
QV4::ScopedArrayObject a(scope, newArrayObject());
- a->arrayReserve(list.count());
+ a->arrayReserve(list.size());
QV4::ScopedValue v(scope);
- for (int ii = 0; ii < list.count(); ++ii)
+ for (int ii = 0; ii < list.size(); ++ii)
a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(this, list.at(ii))));
- a->setArrayLengthUnchecked(list.count());
+ a->setArrayLengthUnchecked(list.size());
return a.asReturnedValue();
} else if (auto flags = metaType.flags(); flags & QMetaType::PointerToQObject) {
- QV4::ReturnedValue ret = QV4::QObjectWrapper::wrap(this, *reinterpret_cast<QObject* const *>(ptr));
- if (!flags.testFlag(QMetaType::IsConst))
- return ret;
- QV4::ScopedValue v(scope, ret);
- if (auto obj = v->as<Object>()) {
- obj->setInternalClass(obj->internalClass()->cryopreserved());
- return obj->asReturnedValue();
- } else {
- return ret;
- }
+ if (flags.testFlag(QMetaType::IsConst))
+ return QV4::QObjectWrapper::wrapConst(this, *reinterpret_cast<QObject* const *>(ptr));
+ else
+ return QV4::QObjectWrapper::wrap(this, *reinterpret_cast<QObject* const *>(ptr));
}
bool succeeded = false;
@@ -1981,6 +1987,25 @@ int ExecutionEngine::maxGCStackSize() const
return s_maxGCStackSize;
}
+/*!
+ \internal
+ Returns \a length converted to int if its safe to
+ pass to \c Scope::alloc.
+ Otherwise it throws a RangeError, and returns 0.
+ */
+int ExecutionEngine::safeForAllocLength(qint64 len64)
+{
+ if (len64 < 0ll || len64 > qint64(std::numeric_limits<int>::max())) {
+ throwRangeError(QStringLiteral("Invalid array length."));
+ return 0;
+ }
+ if (len64 > qint64(this->jsStackLimit - this->jsStackTop)) {
+ throwRangeError(QStringLiteral("Array too large for apply()."));
+ return 0;
+ }
+ return len64;
+}
+
ReturnedValue ExecutionEngine::global()
{
return globalObject->asReturnedValue();
@@ -2252,7 +2277,7 @@ int ExecutionEngine::consoleCountHelper(const QString &file, quint16 line, quint
void ExecutionEngine::setExtensionData(int index, Deletable *data)
{
- if (m_extensionData.count() <= index)
+ if (m_extensionData.size() <= index)
m_extensionData.resize(index + 1);
if (m_extensionData.at(index))
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index d00495eff0..c6b97273e3 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -650,6 +650,7 @@ public:
int maxGCStackSize() const;
bool checkStackLimits();
+ int safeForAllocLength(qint64 len64);
bool canJIT(Function *f = nullptr)
{
@@ -702,7 +703,7 @@ public:
void setExtensionData(int, Deletable *);
Deletable *extensionData(int index) const
{
- if (index < m_extensionData.count())
+ if (index < m_extensionData.size())
return m_extensionData[index];
else
return nullptr;
@@ -736,6 +737,9 @@ public:
QV4::ExecutionContext *ctxt, int argc, const QV4::Value *argv);
private:
+ template<int Frames>
+ friend struct ExecutionEngineCallDepthRecorder;
+
QV4::ReturnedValue fromData(QMetaType type, const void *ptr, const QVariant *variant = nullptr);
static void initializeStaticMembers();
@@ -772,12 +776,15 @@ private:
#define CHECK_STACK_LIMITS(v4) if ((v4)->checkStackLimits()) return Encode::undefined(); \
ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4);
+template<int Frames = 1>
struct ExecutionEngineCallDepthRecorder
{
ExecutionEngine *ee;
- ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ++ee->callDepth; }
- ~ExecutionEngineCallDepthRecorder() { --ee->callDepth; }
+ ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ee->callDepth += Frames; }
+ ~ExecutionEngineCallDepthRecorder() { ee->callDepth -= Frames; }
+
+ bool hasOverflow() const { return ee->callDepth >= ExecutionEngine::s_maxCallDepth; }
};
inline bool ExecutionEngine::checkStackLimits()
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index f3adadc887..eb449ba293 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -120,7 +120,7 @@ ReturnedValue ErrorObject::method_get_stack(const FunctionObject *b, const Value
return v4->throwTypeError();
if (!This->d()->stack) {
QString trace;
- for (int i = 0; i < This->d()->stackTrace->count(); ++i) {
+ for (int i = 0; i < This->d()->stackTrace->size(); ++i) {
if (i > 0)
trace += QLatin1Char('\n');
const StackFrame &frame = This->d()->stackTrace->at(i);
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index c8ebe11f30..3d9069b587 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -31,7 +31,7 @@ namespace Heap {
Member(class, Pointer, String *, stack)
DECLARE_HEAP_OBJECT(ErrorObject, Object) {
- DECLARE_MARKOBJECTS(ErrorObject);
+ DECLARE_MARKOBJECTS(ErrorObject)
enum ErrorType {
Error,
EvalError,
diff --git a/src/qml/jsruntime/qv4executableallocator.cpp b/src/qml/jsruntime/qv4executableallocator.cpp
index f8b005e914..5a63230858 100644
--- a/src/qml/jsruntime/qv4executableallocator.cpp
+++ b/src/qml/jsruntime/qv4executableallocator.cpp
@@ -125,7 +125,7 @@ ExecutableAllocator::ExecutableAllocator()
ExecutableAllocator::~ExecutableAllocator()
{
- for (ChunkOfPages *chunk : qAsConst(chunks)) {
+ for (ChunkOfPages *chunk : std::as_const(chunks)) {
for (Allocation *allocation = chunk->firstAllocation; allocation; allocation = allocation->next)
if (!allocation->free)
allocation->invalidate();
diff --git a/src/qml/jsruntime/qv4executableallocator_p.h b/src/qml/jsruntime/qv4executableallocator_p.h
index d6551599e7..7fd8a10cdb 100644
--- a/src/qml/jsruntime/qv4executableallocator_p.h
+++ b/src/qml/jsruntime/qv4executableallocator_p.h
@@ -79,8 +79,8 @@ public:
};
// for debugging / unit-testing
- int freeAllocationCount() const { return freeAllocations.count(); }
- int chunkCount() const { return chunks.count(); }
+ int freeAllocationCount() const { return freeAllocations.size(); }
+ int chunkCount() const { return chunks.size(); }
struct ChunkOfPages
{
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp
index 3fe031501f..2affa4f6dd 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit.cpp
+++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp
@@ -297,7 +297,7 @@ void ExecutableCompilationUnit::unlink()
delete [] runtimeLookups;
runtimeLookups = nullptr;
- for (QV4::Function *f : qAsConst(runtimeFunctions))
+ for (QV4::Function *f : std::as_const(runtimeFunctions))
f->destroy();
runtimeFunctions.clear();
@@ -325,14 +325,14 @@ void ExecutableCompilationUnit::markObjects(QV4::MarkStack *markStack)
if (runtimeClasses[i])
runtimeClasses[i]->mark(markStack);
}
- for (QV4::Function *f : qAsConst(runtimeFunctions))
+ for (QV4::Function *f : std::as_const(runtimeFunctions))
if (f && f->internalClass)
f->internalClass->mark(markStack);
- for (QV4::Heap::InternalClass *c : qAsConst(runtimeBlocks))
+ for (QV4::Heap::InternalClass *c : std::as_const(runtimeBlocks))
if (c)
c->mark(markStack);
- for (QV4::Heap::Object *o : qAsConst(templateObjects))
+ for (QV4::Heap::Object *o : std::as_const(templateObjects))
if (o)
o->mark(markStack);
@@ -819,8 +819,14 @@ bool ExecutableCompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorSt
return CompiledData::SaveableUnitPointer(unitData()).saveToDisk<char>(
[&unitUrl, errorString](const char *data, quint32 size) {
- return CompiledData::SaveableUnitPointer::writeDataToFile(localCacheFilePath(unitUrl), data,
- size, errorString);
+ const QString cachePath = localCacheFilePath(unitUrl);
+ if (CompiledData::SaveableUnitPointer::writeDataToFile(
+ cachePath, data, size, errorString)) {
+ CompilationUnitMapper::invalidate(cachePath);
+ return true;
+ }
+
+ return false;
});
}
@@ -832,7 +838,7 @@ bool ExecutableCompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorSt
bool ResolvedTypeReferenceMap::addToHash(
QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) const
{
- std::vector<int> keys (count());
+ std::vector<int> keys (size());
int i = 0;
for (auto it = constBegin(), end = constEnd(); it != end; ++it) {
keys[i] = it.key();
@@ -864,7 +870,7 @@ QString ExecutableCompilationUnit::bindingValueAsString(const CompiledData::Bind
// This code must match that in the qsTr() implementation
const QString &path = fileName();
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
- QStringView context = (lastSlash > -1) ? QStringView{path}.mid(lastSlash + 1, path.length() - lastSlash - 5)
+ QStringView context = (lastSlash > -1) ? QStringView{path}.mid(lastSlash + 1, path.size() - lastSlash - 5)
: QStringView();
QByteArray contextUtf8 = context.toUtf8();
QByteArray comment = stringAt(translation.commentIndex).toUtf8();
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 1be093f0a4..f756575ea8 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -111,7 +111,7 @@ Function::Function(ExecutionEngine *engine, const QQmlPrivate::AOTCompiledFuncti
, aotFunction(aotFunction)
{
internalClass = engine->internalClasses(EngineBase::Class_CallContext);
- nFormals = aotFunction->argumentTypes.length();
+ nFormals = aotFunction->argumentTypes.size();
}
Function::~Function()
@@ -127,7 +127,7 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr
QStringList parameterNames;
// Resolve duplicate parameter names:
- for (int i = 0, ei = parameters.count(); i != ei; ++i) {
+ for (int i = 0, ei = parameters.size(); i != ei; ++i) {
const QByteArray &param = parameters.at(i);
int duplicate = -1;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 186535cb82..b38c29a6c5 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -351,36 +351,31 @@ ReturnedValue FunctionPrototype::method_apply(const QV4::FunctionObject *b, cons
if (!arr)
return v4->throwTypeError();
- const qint64 len64 = arr->getLength();
- if (len64 < 0ll || len64 > qint64(std::numeric_limits<int>::max()))
- return v4->throwRangeError(QStringLiteral("Invalid array length."));
- if (len64 > qint64(v4->jsStackLimit - v4->jsStackTop))
- return v4->throwRangeError(QStringLiteral("Array too large for apply()."));
-
- const uint len = uint(len64);
-
Scope scope(v4);
+ const int len = v4->safeForAllocLength(arr->getLength());
+ CHECK_EXCEPTION();
+
Value *arguments = scope.alloc<Scope::Uninitialized>(len);
if (len) {
if (ArgumentsObject::isNonStrictArgumentsObject(arr) && !arr->cast<ArgumentsObject>()->fullyCreated()) {
QV4::ArgumentsObject *a = arr->cast<ArgumentsObject>();
- int l = qMin(len, (uint)a->d()->context->argc());
+ int l = qMin(len, a->d()->context->argc());
memcpy(arguments, a->d()->context->args(), l*sizeof(Value));
- for (quint32 i = l; i < len; ++i)
+ for (int i = l; i < len; ++i)
arguments[i] = Value::undefinedValue();
} else if (arr->arrayType() == Heap::ArrayData::Simple && !arr->protoHasArray()) {
auto sad = static_cast<Heap::SimpleArrayData *>(arr->arrayData());
- uint alen = sad ? sad->values.size : 0;
+ int alen = sad ? sad->values.size : 0;
if (alen > len)
alen = len;
- for (uint i = 0; i < alen; ++i)
+ for (int i = 0; i < alen; ++i)
arguments[i] = sad->data(i);
- for (quint32 i = alen; i < len; ++i)
+ for (int i = alen; i < len; ++i)
arguments[i] = Value::undefinedValue();
} else {
// need to init the arguments array, as the get() calls below can have side effects
memset(arguments, 0, len*sizeof(Value));
- for (quint32 i = 0; i < len; ++i)
+ for (int i = 0; i < len; ++i)
arguments[i] = arr->get(i);
}
}
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index b42c55f5a8..e32fce28ba 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -40,7 +40,7 @@ namespace Heap {
Member(class, NoMark, bool, canBeTailCalled)
DECLARE_HEAP_OBJECT(FunctionObject, Object) {
- DECLARE_MARKOBJECTS(FunctionObject);
+ DECLARE_MARKOBJECTS(FunctionObject)
enum {
Index_ProtoConstructor = 0,
Index_Prototype = 0,
@@ -125,7 +125,7 @@ struct DefaultClassConstructorFunction : FunctionObject
Member(class, Pointer, MemberData *, boundArgs)
DECLARE_HEAP_OBJECT(BoundFunction, FunctionObject) {
- DECLARE_MARKOBJECTS(BoundFunction);
+ DECLARE_MARKOBJECTS(BoundFunction)
void init(QV4::ExecutionContext *scope, QV4::FunctionObject *target, const Value &boundThis, QV4::MemberData *boundArgs);
};
diff --git a/src/qml/jsruntime/qv4generatorobject_p.h b/src/qml/jsruntime/qv4generatorobject_p.h
index 4a84bec748..55ccc133aa 100644
--- a/src/qml/jsruntime/qv4generatorobject_p.h
+++ b/src/qml/jsruntime/qv4generatorobject_p.h
@@ -57,7 +57,7 @@ struct GeneratorPrototype : FunctionObject {
Member(class, Pointer, ArrayObject *, jsFrame)
DECLARE_HEAP_OBJECT(GeneratorObject, Object) {
- DECLARE_MARKOBJECTS(GeneratorObject);
+ DECLARE_MARKOBJECTS(GeneratorObject)
};
}
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 0112347053..7ea90a2ddd 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -32,7 +32,7 @@ static QString escape(const QString &input)
{
QString output;
output.reserve(input.size() * 3);
- const int length = input.length();
+ const int length = input.size();
for (int i = 0; i < length; ++i) {
ushort uc = input.at(i).unicode();
if (uc < 0x100) {
@@ -63,9 +63,9 @@ static QString escape(const QString &input)
static QString unescape(const QString &input)
{
QString result;
- result.reserve(input.length());
+ result.reserve(input.size());
int i = 0;
- const int length = input.length();
+ const int length = input.size();
while (i < length) {
QChar c = input.at(i++);
if ((c == u'%') && (i + 1 < length)) {
@@ -113,7 +113,7 @@ static QString encode(const QString &input, const char *unescapedSet, bool *ok)
{
*ok = true;
QString output;
- const int length = input.length();
+ const int length = input.size();
int i = 0;
while (i < length) {
const QChar c = input.at(i);
@@ -187,8 +187,8 @@ static QString decode(const QString &input, DecodeMode decodeMode, bool *ok)
{
*ok = true;
QString output;
- output.reserve(input.length());
- const int length = input.length();
+ output.reserve(input.size());
+ const int length = input.size();
int i = 0;
const QChar percent = QLatin1Char('%');
while (i < length) {
@@ -381,7 +381,7 @@ ReturnedValue GlobalFunctions::method_parseInt(const FunctionObject *b, const Va
CHECK_EXCEPTION();
const QChar *pos = trimmed.constData();
- const QChar *end = pos + trimmed.length();
+ const QChar *end = pos + trimmed.size();
int sign = 1; // 3
if (pos != end) {
diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp
index 5b0c2f25ee..96aa54018b 100644
--- a/src/qml/jsruntime/qv4identifiertable.cpp
+++ b/src/qml/jsruntime/qv4identifiertable.cpp
@@ -25,7 +25,7 @@ IdentifierTable::~IdentifierTable()
{
free(entriesByHash);
free(entriesById);
- for (const auto &h : qAsConst(idHashes))
+ for (const auto &h : std::as_const(idHashes))
h->identifierTable = nullptr;
}
@@ -100,7 +100,7 @@ void IdentifierTable::addEntry(Heap::StringOrSymbol *str)
Heap::String *IdentifierTable::insertString(const QString &s)
{
uint subtype;
- uint hash = String::createHashValue(s.constData(), s.length(), &subtype);
+ uint hash = String::createHashValue(s.constData(), s.size(), &subtype);
if (subtype == Heap::String::StringType_ArrayIndex) {
Heap::String *str = engine->newString(s);
str->stringHash = hash;
@@ -133,7 +133,7 @@ Heap::Symbol *IdentifierTable::insertSymbol(const QString &s)
Q_ASSERT(s.at(0) == QLatin1Char('@'));
uint subtype;
- uint hash = String::createHashValue(s.constData(), s.length(), &subtype);
+ uint hash = String::createHashValue(s.constData(), s.size(), &subtype);
uint idx = hash % alloc;
while (Heap::StringOrSymbol *e = entriesByHash[idx]) {
if (e->stringHash == hash && e->toQString() == s)
@@ -252,7 +252,7 @@ void IdentifierTable::sweep()
PropertyKey IdentifierTable::asPropertyKey(const QString &s)
{
uint subtype;
- const uint hash = String::createHashValue(s.constData(), s.length(), &subtype);
+ const uint hash = String::createHashValue(s.constData(), s.size(), &subtype);
if (subtype == Heap::String::StringType_ArrayIndex)
return PropertyKey::fromArrayIndex(hash);
return resolveStringEntry(s, hash, subtype)->identifier;
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 693cc436ef..57ff8c44ec 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -610,10 +610,32 @@ struct Stringify
QString makeMember(const QString &key, const Value &v);
};
+class [[nodiscard]] CallDepthAndCycleChecker
+{
+ Q_DISABLE_COPY_MOVE(CallDepthAndCycleChecker);
+
+public:
+ CallDepthAndCycleChecker(Stringify *stringify, Object *o)
+ : m_callDepthRecorder(stringify->v4)
+ {
+ if (stringify->stackContains(o)) {
+ stringify->v4->throwTypeError(
+ QStringLiteral("Cannot convert circular structure to JSON"));
+ }
+
+ stringify->v4->checkStackLimits();
+ }
+
+ bool foundProblem() const { return m_callDepthRecorder.ee->hasException; }
+
+private:
+ ExecutionEngineCallDepthRecorder<1> m_callDepthRecorder;
+};
+
static QString quote(const QString &str)
{
QString product;
- const int length = str.length();
+ const int length = str.size();
product.reserve(length + 2);
product += u'"';
for (int i = 0; i < length; ++i) {
@@ -740,10 +762,9 @@ QString Stringify::makeMember(const QString &key, const Value &v)
QString Stringify::JO(Object *o)
{
- if (stackContains(o)) {
- v4->throwTypeError();
+ CallDepthAndCycleChecker check(this, o);
+ if (check.foundProblem())
return QString();
- }
Scope scope(v4);
@@ -800,10 +821,9 @@ QString Stringify::JO(Object *o)
QString Stringify::JA(Object *a)
{
- if (stackContains(a)) {
- v4->throwTypeError();
+ CallDepthAndCycleChecker check(this, a);
+ if (check.foundProblem())
return QString();
- }
Scope scope(a->engine());
@@ -865,7 +885,7 @@ ReturnedValue JsonObject::method_parse(const FunctionObject *b, const Value *, c
jtext = argv[0].toQString();
DEBUG << "parsing source = " << jtext;
- JsonParser parser(v4, jtext.constData(), jtext.length());
+ JsonParser parser(v4, jtext.constData(), jtext.size());
QJsonParseError error;
ReturnedValue result = parser.parse(&error);
if (error.error != QJsonParseError::NoError) {
@@ -885,9 +905,10 @@ ReturnedValue JsonObject::method_stringify(const FunctionObject *b, const Value
if (o) {
stringify.replacerFunction = o->as<FunctionObject>();
if (o->isArrayObject()) {
- uint arrayLen = o->getLength();
+ int arrayLen = scope.engine->safeForAllocLength(o->getLength());
+ CHECK_EXCEPTION();
stringify.propertyList = static_cast<QV4::String *>(scope.alloc(arrayLen));
- for (uint i = 0; i < arrayLen; ++i) {
+ for (int i = 0; i < arrayLen; ++i) {
Value *v = stringify.propertyList + i;
*v = o->get(i);
if (v->as<NumberObject>() || v->as<StringObject>() || v->isNumber())
@@ -895,7 +916,7 @@ ReturnedValue JsonObject::method_stringify(const FunctionObject *b, const Value
if (!v->isString()) {
v->setM(nullptr);
} else {
- for (uint j = 0; j <i; ++j) {
+ for (int j = 0; j <i; ++j) {
if (stringify.propertyList[j].m() == v->m()) {
v->setM(nullptr);
break;
diff --git a/src/qml/jsruntime/qv4mapiterator_p.h b/src/qml/jsruntime/qv4mapiterator_p.h
index 2269473d4c..97a72db85c 100644
--- a/src/qml/jsruntime/qv4mapiterator_p.h
+++ b/src/qml/jsruntime/qv4mapiterator_p.h
@@ -30,7 +30,7 @@ namespace Heap {
Member(class, NoMark, quint32, mapNextIndex)
DECLARE_HEAP_OBJECT(MapIteratorObject, Object) {
- DECLARE_MARKOBJECTS(MapIteratorObject);
+ DECLARE_MARKOBJECTS(MapIteratorObject)
void init(Object *obj, QV4::ExecutionEngine *engine)
{
Object::init();
diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h
index adcd1e8cf9..672b058fef 100644
--- a/src/qml/jsruntime/qv4memberdata_p.h
+++ b/src/qml/jsruntime/qv4memberdata_p.h
@@ -27,7 +27,7 @@ namespace Heap {
Member(class, ValueArray, ValueArray, values)
DECLARE_HEAP_OBJECT(MemberData, Base) {
- DECLARE_MARKOBJECTS(MemberData);
+ DECLARE_MARKOBJECTS(MemberData)
};
Q_STATIC_ASSERT(std::is_trivial_v<MemberData>);
diff --git a/src/qml/jsruntime/qv4module.cpp b/src/qml/jsruntime/qv4module.cpp
index 779eb77a36..1e1a059dfa 100644
--- a/src/qml/jsruntime/qv4module.cpp
+++ b/src/qml/jsruntime/qv4module.cpp
@@ -195,7 +195,7 @@ struct ModuleNamespaceIterator : ObjectOwnPropertyKeyIterator
PropertyKey ModuleNamespaceIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs)
{
const Module *module = static_cast<const Module *>(o);
- if (exportIndex < exportedNames.count()) {
+ if (exportIndex < exportedNames.size()) {
if (attrs)
*attrs = Attr_Data;
Scope scope(module->engine());
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index aec04b167d..6a39b9e27f 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -1104,7 +1104,7 @@ void Heap::ArrayObject::init(const QStringList &list)
// The result is a new Array object with length equal to the length
// of the QStringList, and the elements being the QStringList's
// elements converted to JS Strings.
- int len = list.count();
+ int len = list.size();
a->arrayReserve(len);
ScopedValue v(scope);
for (int ii = 0; ii < len; ++ii)
diff --git a/src/qml/jsruntime/qv4persistent_p.h b/src/qml/jsruntime/qv4persistent_p.h
index e7b653b6f6..7e208bd4fd 100644
--- a/src/qml/jsruntime/qv4persistent_p.h
+++ b/src/qml/jsruntime/qv4persistent_p.h
@@ -69,7 +69,7 @@ public:
PersistentValue(PersistentValue &&other) noexcept : val(std::exchange(other.val, nullptr)) {}
void swap(PersistentValue &other) noexcept { qt_ptr_swap(val, other.val); }
- QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(PersistentValue);
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(PersistentValue)
~PersistentValue() { PersistentValueStorage::free(val); }
PersistentValue &operator=(const WeakValue &other);
diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp
index 19da26989f..db33cd27f9 100644
--- a/src/qml/jsruntime/qv4profiling.cpp
+++ b/src/qml/jsruntime/qv4profiling.cpp
@@ -60,7 +60,7 @@ void Profiler::reportData()
FunctionLocationHash locations;
properties.reserve(m_data.size());
- for (const FunctionCall &call : qAsConst(m_data)) {
+ for (const FunctionCall &call : std::as_const(m_data)) {
properties.append(call.properties());
Function *function = call.function();
SentMarker &marker = m_sentLocations[reinterpret_cast<quintptr>(function)];
diff --git a/src/qml/jsruntime/qv4promiseobject_p.h b/src/qml/jsruntime/qv4promiseobject_p.h
index c0599987e5..1c11ebbfd6 100644
--- a/src/qml/jsruntime/qv4promiseobject_p.h
+++ b/src/qml/jsruntime/qv4promiseobject_p.h
@@ -34,7 +34,7 @@ class ReactionHandler : public QObject
public:
ReactionHandler(QObject *parent = nullptr);
- virtual ~ReactionHandler() override;
+ ~ReactionHandler() override;
void addReaction(ExecutionEngine *e, const Value *reaction, const Value *value);
void addResolveThenable(ExecutionEngine *e, const PromiseObject *promise, const Object *thenable, const FunctionObject *then);
diff --git a/src/qml/jsruntime/qv4propertykey.cpp b/src/qml/jsruntime/qv4propertykey.cpp
index 8a3e1adc65..e07df07543 100644
--- a/src/qml/jsruntime/qv4propertykey.cpp
+++ b/src/qml/jsruntime/qv4propertykey.cpp
@@ -66,7 +66,7 @@ QV4::Heap::String *QV4::PropertyKey::asFunctionName(ExecutionEngine *engine, Fun
QString str = s->toQString();
if (s->internalClass->vtable->isString)
n += s->toQString();
- else if (str.length() > 1)
+ else if (str.size() > 1)
n += QChar::fromLatin1('[') + QStringView{str}.mid(1) + QChar::fromLatin1(']');
}
return engine->newString(n);
diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h
index a89e7f6f2f..bd4b5c2585 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -34,7 +34,7 @@ namespace Heap {
Member(class, Pointer, Module *, module)
DECLARE_HEAP_OBJECT(QQmlContextWrapper, Object) {
- DECLARE_MARKOBJECTS(QQmlContextWrapper);
+ DECLARE_MARKOBJECTS(QQmlContextWrapper)
void init(QQmlRefPointer<QQmlContextData> context, QObject *scopeObject);
void destroy();
@@ -47,7 +47,7 @@ DECLARE_HEAP_OBJECT(QQmlContextWrapper, Object) {
#define QmlContextMembers(class, Member)
DECLARE_HEAP_OBJECT(QmlContext, ExecutionContext) {
- DECLARE_MARKOBJECTS(QmlContext);
+ DECLARE_MARKOBJECTS(QmlContext)
QQmlContextWrapper *qml() { return static_cast<QQmlContextWrapper *>(activation.get()); }
void init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index d5e6c1b84a..b9b552576c 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -99,15 +99,10 @@ static ReturnedValue loadProperty(ExecutionEngine *v4, QObject *object,
if (property.isQObject()) {
QObject *rv = nullptr;
property.readProperty(object, &rv);
- ReturnedValue ret = QObjectWrapper::wrap(v4, rv);
- if (propMetaType.flags().testFlag(QMetaType::IsConst)) {
- ScopedValue v(scope, ret);
- if (auto obj = v->as<Object>()) {
- obj->setInternalClass(obj->internalClass()->cryopreserved());
- return obj->asReturnedValue();
- }
- }
- return ret;
+ if (propMetaType.flags().testFlag(QMetaType::IsConst))
+ return QObjectWrapper::wrapConst(v4, rv);
+ else
+ return QObjectWrapper::wrap(v4, rv);
}
if (property.isQList() && propMetaType.flags().testFlag(QMetaType::IsQmlList))
@@ -669,6 +664,29 @@ ReturnedValue QObjectWrapper::wrap_slowPath(ExecutionEngine *engine, QObject *ob
}
}
+ReturnedValue QObjectWrapper::wrapConst_slowPath(ExecutionEngine *engine, QObject *object)
+{
+ const QObject *constObject = object;
+
+ QQmlData *ddata = QQmlData::get(object, true);
+
+ Scope scope(engine);
+ ScopedObject constWrapper(scope);
+ if (engine->m_multiplyWrappedQObjects && ddata->hasConstWrapper)
+ constWrapper = engine->m_multiplyWrappedQObjects->value(constObject);
+
+ if (!constWrapper) {
+ constWrapper = create(engine, object);
+ constWrapper->setInternalClass(constWrapper->internalClass()->cryopreserved());
+ if (!engine->m_multiplyWrappedQObjects)
+ engine->m_multiplyWrappedQObjects = new MultiplyWrappedQObjectMap;
+ engine->m_multiplyWrappedQObjects->insert(constObject, constWrapper->d());
+ ddata->hasConstWrapper = true;
+ }
+
+ return constWrapper.asReturnedValue();
+}
+
void QObjectWrapper::markWrapper(QObject *object, MarkStack *markStack)
{
if (QQmlData::wasDeleted(object))
@@ -683,6 +701,8 @@ void QObjectWrapper::markWrapper(QObject *object, MarkStack *markStack)
ddata->jsWrapper.markOnce(markStack);
else if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object)
engine->m_multiplyWrappedQObjects->mark(object, markStack);
+ if (ddata->hasConstWrapper)
+ engine->m_multiplyWrappedQObjects->mark(static_cast<const QObject *>(object), markStack);
}
void QObjectWrapper::setProperty(ExecutionEngine *engine, int propertyIndex, const Value &value)
@@ -710,14 +730,13 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, int p
bool QObjectWrapper::virtualIsEqualTo(Managed *a, Managed *b)
{
Q_ASSERT(a->as<QObjectWrapper>());
- QObjectWrapper *qobjectWrapper = static_cast<QObjectWrapper *>(a);
- Object *o = b->as<Object>();
- if (o) {
- if (QQmlTypeWrapper *qmlTypeWrapper = o->as<QQmlTypeWrapper>())
- return qmlTypeWrapper->toVariant().value<QObject*>() == qobjectWrapper->object();
- }
+ const QObjectWrapper *aobjectWrapper = static_cast<QObjectWrapper *>(a);
+ if (const QQmlTypeWrapper *qmlTypeWrapper = b->as<QQmlTypeWrapper>())
+ return qmlTypeWrapper->object() == aobjectWrapper->object();
- return false;
+ // We can have a const and a non-const wrapper for the same object.
+ const QObjectWrapper *bobjectWrapper = b->as<QObjectWrapper>();
+ return bobjectWrapper && aobjectWrapper->object() == bobjectWrapper->object();
}
ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QObject *object)
@@ -1176,7 +1195,7 @@ ReturnedValue QObjectWrapper::method_disconnect(const FunctionObject *b, const V
static void markChildQObjectsRecursively(QObject *parent, MarkStack *markStack)
{
const QObjectList &children = parent->children();
- for (int i = 0; i < children.count(); ++i) {
+ for (int i = 0; i < children.size(); ++i) {
QObject *child = children.at(i);
if (!child)
continue;
@@ -1350,8 +1369,8 @@ static ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index, QMe
}
}
}
- QVarLengthArray<void *, 9> argData(args.count());
- for (int ii = 0; ii < args.count(); ++ii)
+ QVarLengthArray<void *, 9> argData(args.size());
+ for (int ii = 0; ii < args.size(); ++ii)
argData[ii] = args[ii].dataPtr();
object.metacall(callType, index, argData.data());
@@ -1903,14 +1922,16 @@ bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine, const
// Convert via QVariant below.
// TODO: Can't we just do qobjectPtr = qmlTypeWrapper->object() instead?
break;
+ } else if (QObject *obj = qmlTypeWrapper->object()) {
+ // attached object case
+ qobjectPtr = obj;
+ return true;
}
// If this is a plain type wrapper without an instance,
- // then indeed it's an undefined parameter.
- // (although we might interpret that as const QMetaObject *).
- // TODO: But what if it's an attached object?
+ // then we got a namespace, and that's a type error
type = QMetaType::UnknownType;
- return true;
+ return false;
}
qobjectPtr = nullptr;
@@ -2025,7 +2046,7 @@ bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine, const
}
const QQmlMetaObject mo = QQmlMetaType::rawMetaObjectForType(metaType);
- if (!mo.isNull()) {
+ if (!mo.isNull() && v.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
QObject *obj = QQmlMetaType::toQObject(v);
if (obj != nullptr && !QQmlMetaObject::canConvert(obj, mo)) {
@@ -2095,11 +2116,11 @@ ReturnedValue CallArgument::toValue(ExecutionEngine *engine)
QList<QObject *> &list = *qlistPtr;
Scope scope(engine);
ScopedArrayObject array(scope, engine->newArrayObject());
- array->arrayReserve(list.count());
+ array->arrayReserve(list.size());
ScopedValue v(scope);
- for (int ii = 0; ii < list.count(); ++ii)
+ for (int ii = 0; ii < list.size(); ++ii)
array->arrayPut(ii, (v = QObjectWrapper::wrap(engine, list.at(ii))));
- array->setArrayLengthUnchecked(list.count());
+ array->setArrayLengthUnchecked(list.size());
return array.asReturnedValue();
}
@@ -2429,39 +2450,20 @@ void QmlSignalHandler::initProto(ExecutionEngine *engine)
engine->jsObjects[ExecutionEngine::SignalHandlerProto] = o->d();
}
-void MultiplyWrappedQObjectMap::insert(QObject *key, Heap::Object *value)
-{
- QHash<QObject*, WeakValue>::operator[](key).set(value->internalClass->engine, value);
- connect(key, SIGNAL(destroyed(QObject*)), this, SLOT(removeDestroyedObject(QObject*)));
-}
-
-
-MultiplyWrappedQObjectMap::Iterator MultiplyWrappedQObjectMap::erase(MultiplyWrappedQObjectMap::Iterator it)
+MultiplyWrappedQObjectMap::Iterator MultiplyWrappedQObjectMap::erase(
+ MultiplyWrappedQObjectMap::Iterator it)
{
- disconnect(it.key(), SIGNAL(destroyed(QObject*)), this, SLOT(removeDestroyedObject(QObject*)));
- return QHash<QObject*, WeakValue>::erase(it);
-}
-
-void MultiplyWrappedQObjectMap::remove(QObject *key)
-{
- Iterator it = find(key);
- if (it == end())
- return;
- erase(it);
-}
-
-void MultiplyWrappedQObjectMap::mark(QObject *key, MarkStack *markStack)
-{
- Iterator it = find(key);
- if (it == end())
- return;
- it->markOnce(markStack);
+ const QObjectBiPointer key = it.key();
+ const QObject *obj = key.isT1() ? key.asT1() : key.asT2();
+ disconnect(obj, &QObject::destroyed, this, &MultiplyWrappedQObjectMap::removeDestroyedObject);
+ return QHash<QObjectBiPointer, WeakValue>::erase(it);
}
void MultiplyWrappedQObjectMap::removeDestroyedObject(QObject *object)
{
- QHash<QObject*, WeakValue>::remove(object);
+ QHash<QObjectBiPointer, WeakValue>::remove(object);
+ QHash<QObjectBiPointer, WeakValue>::remove(static_cast<const QObject *>(object));
}
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 4477c3c836..5a0d837746 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -65,7 +65,7 @@ private:
Member(class, NoMark, int, index)
DECLARE_HEAP_OBJECT(QObjectMethod, FunctionObject) {
- DECLARE_MARKOBJECTS(QObjectMethod);
+ DECLARE_MARKOBJECTS(QObjectMethod)
QQmlPropertyData *methods;
int methodCount;
@@ -140,6 +140,7 @@ struct Q_QML_EXPORT QObjectWrapper : public Object
QObject *object, String *name, RevisionMode revisionMode, const Value &value);
static ReturnedValue wrap(ExecutionEngine *engine, QObject *object);
+ static ReturnedValue wrapConst(ExecutionEngine *engine, QObject *object);
static void markWrapper(QObject *object, MarkStack *markStack);
using Object::get;
@@ -181,6 +182,7 @@ protected:
private:
Q_NEVER_INLINE static ReturnedValue wrap_slowPath(ExecutionEngine *engine, QObject *object);
+ Q_NEVER_INLINE static ReturnedValue wrapConst_slowPath(ExecutionEngine *engine, QObject *object);
};
inline ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object)
@@ -197,6 +199,15 @@ inline ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *obje
return wrap_slowPath(engine, object);
}
+// Unfortunately we still need a non-const QObject* here because QQmlData needs to register itself in QObjectPrivate.
+inline ReturnedValue QObjectWrapper::wrapConst(ExecutionEngine *engine, QObject *object)
+{
+ if (Q_UNLIKELY(QQmlData::wasDeleted(object)))
+ return QV4::Encode::null();
+
+ return wrapConst_slowPath(engine, object);
+}
+
template <typename ReversalFunctor>
inline ReturnedValue QObjectWrapper::lookupGetterImpl(Lookup *lookup, ExecutionEngine *engine, const Value &object, bool useOriginalProperty, ReversalFunctor revertLookup)
{
@@ -292,23 +303,32 @@ struct Q_QML_EXPORT QmlSignalHandler : public QV4::Object
static void initProto(ExecutionEngine *v4);
};
+using QObjectBiPointer = QBiPointer<QObject, const QObject>;
+
class MultiplyWrappedQObjectMap : public QObject,
- private QHash<QObject*, QV4::WeakValue>
+ private QHash<QObjectBiPointer, QV4::WeakValue>
{
Q_OBJECT
public:
- typedef QHash<QObject*, QV4::WeakValue>::ConstIterator ConstIterator;
- typedef QHash<QObject*, QV4::WeakValue>::Iterator Iterator;
+ typedef QHash<QObjectBiPointer, QV4::WeakValue>::ConstIterator ConstIterator;
+ typedef QHash<QObjectBiPointer, QV4::WeakValue>::Iterator Iterator;
+
+ using value_type = QHash<QObjectBiPointer, QV4::WeakValue>::value_type;
- using value_type = QHash<QObject*, QV4::WeakValue>::value_type;
+ ConstIterator begin() const { return QHash<QObjectBiPointer, QV4::WeakValue>::constBegin(); }
+ Iterator begin() { return QHash<QObjectBiPointer, QV4::WeakValue>::begin(); }
+ ConstIterator end() const { return QHash<QObjectBiPointer, QV4::WeakValue>::constEnd(); }
+ Iterator end() { return QHash<QObjectBiPointer, QV4::WeakValue>::end(); }
- ConstIterator begin() const { return QHash<QObject*, QV4::WeakValue>::constBegin(); }
- Iterator begin() { return QHash<QObject*, QV4::WeakValue>::begin(); }
- ConstIterator end() const { return QHash<QObject*, QV4::WeakValue>::constEnd(); }
- Iterator end() { return QHash<QObject*, QV4::WeakValue>::end(); }
+ template<typename Pointer>
+ void insert(Pointer key, Heap::Object *value)
+ {
+ QHash<QObjectBiPointer, WeakValue>::operator[](key).set(value->internalClass->engine, value);
+ connect(key, SIGNAL(destroyed(QObject*)), this, SLOT(removeDestroyedObject(QObject*)));
+ }
- void insert(QObject *key, Heap::Object *value);
- ReturnedValue value(QObject *key) const
+ template<typename Pointer>
+ ReturnedValue value(Pointer key) const
{
ConstIterator it = find(key);
return it == end()
@@ -317,8 +337,24 @@ public:
}
Iterator erase(Iterator it);
- void remove(QObject *key);
- void mark(QObject *key, MarkStack *markStack);
+
+ template<typename Pointer>
+ void remove(Pointer key)
+ {
+ Iterator it = find(key);
+ if (it == end())
+ return;
+ erase(it);
+ }
+
+ template<typename Pointer>
+ void mark(Pointer key, MarkStack *markStack)
+ {
+ Iterator it = find(key);
+ if (it == end())
+ return;
+ it->markOnce(markStack);
+ }
private Q_SLOTS:
void removeDestroyedObject(QObject*);
diff --git a/src/qml/jsruntime/qv4reflect.cpp b/src/qml/jsruntime/qv4reflect.cpp
index abcc60726a..179663a0e1 100644
--- a/src/qml/jsruntime/qv4reflect.cpp
+++ b/src/qml/jsruntime/qv4reflect.cpp
@@ -40,7 +40,10 @@ struct CallArgs {
static CallArgs createListFromArrayLike(Scope &scope, const Object *o)
{
- int len = o->getLength();
+ int len = scope.engine->safeForAllocLength(o->getLength());
+ if (scope.engine->hasException)
+ return {nullptr, 0};
+
Value *arguments = scope.alloc(len);
for (int i = 0; i < len; ++i) {
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index 0c039967ba..be7ff77603 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -49,7 +49,7 @@ uint RegExp::match(const QString &string, int start, uint *matchOffsets)
uint ret = JSC::Yarr::offsetNoMatch;
#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
char buffer[8192];
- ret = uint(priv->jitCode->execute(s.characters16(), start, s.length(),
+ ret = uint(priv->jitCode->execute(s.characters16(), start, s.size(),
(int*)matchOffsets, buffer, 8192).start);
#else
ret = uint(priv->jitCode->execute(s.characters16(), start, s.length(),
@@ -74,18 +74,18 @@ uint RegExp::match(const QString &string, int start, uint *matchOffsets)
}
#endif // ENABLE(YARR_JIT)
- return JSC::Yarr::interpret(byteCode(), s.characters16(), string.length(), start, matchOffsets);
+ return JSC::Yarr::interpret(byteCode(), s.characters16(), string.size(), start, matchOffsets);
}
QString RegExp::getSubstitution(const QString &matched, const QString &str, int position, const Value *captures, int nCaptures, const QString &replacement)
{
QString result;
- int matchedLength = matched.length();
- Q_ASSERT(position >= 0 && position <= str.length());
+ int matchedLength = matched.size();
+ Q_ASSERT(position >= 0 && position <= str.size());
int tailPos = position + matchedLength;
int seenDollar = -1;
- for (int i = 0; i < replacement.length(); ++i) {
+ for (int i = 0; i < replacement.size(); ++i) {
QChar ch = replacement.at(i);
if (seenDollar >= 0) {
if (ch.unicode() == '$') {
@@ -98,7 +98,7 @@ QString RegExp::getSubstitution(const QString &matched, const QString &str, int
result += str.mid(tailPos);
} else if (ch.unicode() >= '0' && ch.unicode() <= '9') {
int n = ch.unicode() - '0';
- if (i + 1 < replacement.length()) {
+ if (i + 1 < replacement.size()) {
ch = replacement.at(i + 1);
if (ch.unicode() >= '0' && ch.unicode() <= '9') {
n = n*10 + (ch.unicode() - '0');
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 365593e207..0fab40a281 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -48,7 +48,7 @@ void Heap::RegExpObject::init(QV4::RegExp *value)
static QString minimalPattern(const QString &pattern)
{
QString ecmaPattern;
- int len = pattern.length();
+ int len = pattern.size();
ecmaPattern.reserve(len);
int i = 0;
const QChar *wc = pattern.unicode();
@@ -146,7 +146,7 @@ ReturnedValue RegExpObject::builtinExec(ExecutionEngine *engine, const String *s
Scope scope(engine);
int offset = (global() || sticky()) ? lastIndex() : 0;
- if (offset < 0 || offset > s.length()) {
+ if (offset < 0 || offset > s.size()) {
setLastIndex(0);
RETURN_RESULT(Encode::null());
}
@@ -170,7 +170,7 @@ ReturnedValue RegExpObject::builtinExec(ExecutionEngine *engine, const String *s
int len = value()->captureCount();
array->arrayReserve(len);
ScopedValue v(scope);
- int strlen = s.length();
+ int strlen = s.size();
for (int i = 0; i < len; ++i) {
int start = matchOffsets[i * 2];
int end = matchOffsets[i * 2 + 1];
@@ -232,7 +232,7 @@ uint parseFlags(Scope &scope, const QV4::Value *f)
if (scope.hasException())
return flags;
QString str = s->toQString();
- for (int i = 0; i < str.length(); ++i) {
+ for (int i = 0; i < str.size(); ++i) {
if (str.at(i) == QLatin1Char('g') && !(flags & CompiledData::RegExp::RegExp_Global)) {
flags |= CompiledData::RegExp::RegExp_Global;
} else if (str.at(i) == QLatin1Char('i') && !(flags & CompiledData::RegExp::RegExp_IgnoreCase)) {
@@ -382,7 +382,7 @@ ReturnedValue RegExpPrototype::execFirstMatch(const FunctionObject *b, const Val
QString s = str->toQString();
int offset = r->lastIndex();
- if (offset < 0 || offset > s.length()) {
+ if (offset < 0 || offset > s.size()) {
r->setLastIndex(0);
RETURN_RESULT(Encode::null());
}
@@ -518,7 +518,7 @@ ReturnedValue RegExpPrototype::method_get_ignoreCase(const FunctionObject *f, co
static int advanceStringIndex(int index, const QString &str, bool unicode)
{
if (unicode) {
- if (index < str.length() - 1 &&
+ if (index < str.size() - 1 &&
str.at(index).isHighSurrogate() &&
str.at(index + 1).isLowSurrogate())
++index;
@@ -607,7 +607,7 @@ ReturnedValue RegExpPrototype::method_replace(const FunctionObject *f, const Val
if (scope.hasException())
return Encode::undefined();
- int lengthS = s->toQString().length();
+ int lengthS = s->toQString().size();
ScopedString replaceValue(scope);
ScopedFunctionObject replaceFunction(scope, (argc > 1 ? argv[1] : Value::undefinedValue()));
@@ -659,7 +659,7 @@ ReturnedValue RegExpPrototype::method_replace(const FunctionObject *f, const Val
if (scope.hasException())
return Encode::undefined();
QString m = matchString->toQString();
- int matchLength = m.length();
+ int matchLength = m.size();
v = resultObject->get(scope.engine->id_index());
int position = v->toInt32();
position = qMax(qMin(position, lengthS), 0);
@@ -786,7 +786,7 @@ ReturnedValue RegExpPrototype::method_split(const FunctionObject *f, const Value
return A->asReturnedValue();
QString S = s->toQString();
- int size = S.length();
+ int size = S.size();
if (size == 0) {
ScopedValue z(scope, exec(scope.engine, splitter, s));
if (z->isNull())
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index 2f278f70a7..3171367351 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -56,7 +56,7 @@ DECLARE_HEAP_OBJECT(RegExpObject, Object) {
Member(class, NoMark, int, lastMatchEnd)
DECLARE_HEAP_OBJECT(RegExpCtor, FunctionObject) {
- DECLARE_MARKOBJECTS(RegExpCtor);
+ DECLARE_MARKOBJECTS(RegExpCtor)
void init(QV4::ExecutionContext *scope);
void clearLastMatch();
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index bd81c56bbd..f07f7e38a1 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -144,7 +144,7 @@ struct RuntimeCounters::Data {
}
std::sort(lines.begin(), lines.end(), Line::less);
outs << lines.size() << " counters:" << endl;
- for (const Line &line : qAsConst(lines))
+ for (const Line &line : std::as_const(lines))
outs << qSetFieldWidth(10) << line.count << qSetFieldWidth(0)
<< " | " << line.func
<< " | " << pretty(line.tag1)
@@ -217,7 +217,7 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
*result = qdtoa(num, &decpt, &sign);
if (decpt <= ecma_shortest_low || decpt > ecma_shortest_high) {
- if (result->length() > 1)
+ if (result->size() > 1)
result->insert(1, dot);
result->append(QLatin1Char('e'));
if (decpt > 0)
@@ -225,10 +225,10 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
result->append(QString::number(decpt - 1));
} else if (decpt <= 0) {
result->prepend(QLatin1String("0.") + QString(-decpt, zero));
- } else if (decpt < result->length()) {
+ } else if (decpt < result->size()) {
result->insert(decpt, dot);
} else {
- result->append(QString(decpt - result->length(), zero));
+ result->append(QString(decpt - result->size(), zero));
}
if (sign && num)
@@ -392,7 +392,7 @@ double RuntimeHelpers::stringToNumber(const QString &string)
// libdoubleconversion sources. The same maximum value would be represented by roughly 3.5 times
// as many binary digits.
const int excessiveLength = 16 * 1024;
- if (string.length() > excessiveLength)
+ if (string.size() > excessiveLength)
return qQNaN();
const QStringView s = QStringView(string).trimmed();
@@ -642,7 +642,7 @@ static Q_NEVER_INLINE ReturnedValue getElementIntFallback(ExecutionEngine *engin
ScopedObject o(scope, object);
if (!o) {
if (const String *str = object.as<String>()) {
- if (idx >= (uint)str->toQString().length()) {
+ if (idx >= (uint)str->toQString().size()) {
return Encode::undefined();
}
const QString s = str->toQString().mid(idx, 1);
@@ -1561,6 +1561,11 @@ static CallArgs createSpreadArguments(Scope &scope, Value *argv, int argc)
if (done->booleanValue())
break;
++argCount;
+ constexpr auto safetyMargin = 100; // leave some space on the stack for actual work with the elements
+ if (qint64(scope.engine->jsStackLimit - scope.engine->jsStackTop) < safetyMargin) {
+ scope.engine->throwRangeError(QLatin1String("Too many elements in array to use it with the spread operator"));
+ return { nullptr, 0 };
+ }
v = scope.alloc<Scope::Uninitialized>();
}
}
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 09e8b60c91..eee7fd8414 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -88,6 +88,10 @@ struct Scope {
/* Be careful when using Uninitialized, the stack has to be fully initialized before calling into the memory manager again */
Uninitialized
};
+
+ template <AllocMode mode = Undefined>
+ Value *alloc(qint64 nValues) const = delete; // use safeForAllocLength
+
template <AllocMode mode = Undefined>
QML_NEARLY_ALWAYS_INLINE Value *alloc(int nValues) const
{
@@ -408,7 +412,7 @@ struct ScopedProperty
{
ScopedProperty(Scope &scope)
{
- property = reinterpret_cast<Property*>(scope.alloc(sizeof(Property) / sizeof(Value)));
+ property = reinterpret_cast<Property*>(scope.alloc(int(sizeof(Property) / sizeof(Value))));
}
Property *operator->() { return property; }
diff --git a/src/qml/jsruntime/qv4setiterator_p.h b/src/qml/jsruntime/qv4setiterator_p.h
index e7ab85accb..37f912e01a 100644
--- a/src/qml/jsruntime/qv4setiterator_p.h
+++ b/src/qml/jsruntime/qv4setiterator_p.h
@@ -30,7 +30,7 @@ namespace Heap {
Member(class, NoMark, quint32, setNextIndex)
DECLARE_HEAP_OBJECT(SetIteratorObject, Object) {
- DECLARE_MARKOBJECTS(SetIteratorObject);
+ DECLARE_MARKOBJECTS(SetIteratorObject)
void init(Object *obj, QV4::ExecutionEngine *engine)
{
Object::init();
diff --git a/src/qml/jsruntime/qv4stringiterator.cpp b/src/qml/jsruntime/qv4stringiterator.cpp
index 99f10c55b4..9cb2711efb 100644
--- a/src/qml/jsruntime/qv4stringiterator.cpp
+++ b/src/qml/jsruntime/qv4stringiterator.cpp
@@ -35,7 +35,7 @@ ReturnedValue StringIteratorPrototype::method_next(const FunctionObject *b, cons
quint32 index = thisObject->d()->nextIndex;
QString str = s->toQString();
- quint32 len = str.length();
+ quint32 len = str.size();
if (index >= len) {
thisObject->d()->iteratedString.set(scope.engine, nullptr);
diff --git a/src/qml/jsruntime/qv4stringiterator_p.h b/src/qml/jsruntime/qv4stringiterator_p.h
index a445381ba6..742b8a895d 100644
--- a/src/qml/jsruntime/qv4stringiterator_p.h
+++ b/src/qml/jsruntime/qv4stringiterator_p.h
@@ -30,7 +30,7 @@ namespace Heap {
Member(class, NoMark, quint32, nextIndex)
DECLARE_HEAP_OBJECT(StringIteratorObject, Object) {
- DECLARE_MARKOBJECTS(StringIteratorObject);
+ DECLARE_MARKOBJECTS(StringIteratorObject)
void init(String *str, QV4::ExecutionEngine *engine)
{
Object::init();
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 5e1d764aed..bec4132b5f 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -51,7 +51,7 @@ void Heap::StringObject::init(const QV4::String *str)
Heap::String *Heap::StringObject::getIndex(uint index) const
{
QString str = string->toQString();
- if (index >= (uint)str.length())
+ if (index >= (uint)str.size())
return nullptr;
return internalClass->engine->newString(str.mid(index, 1));
}
@@ -67,7 +67,7 @@ bool StringObject::virtualDeleteProperty(Managed *m, PropertyKey id)
if (id.isArrayIndex()) {
StringObject *o = static_cast<StringObject *>(m);
uint index = id.asArrayIndex();
- if (index < static_cast<uint>(o->d()->string->toQString().length()))
+ if (index < static_cast<uint>(o->d()->string->toQString().size()))
return false;
}
return Object::virtualDeleteProperty(m, id);
@@ -83,7 +83,7 @@ struct StringObjectOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
PropertyKey StringObjectOwnPropertyKeyIterator::next(const QV4::Object *o, Property *pd, PropertyAttributes *attrs)
{
const StringObject *s = static_cast<const StringObject *>(o);
- uint slen = s->d()->string->toQString().length();
+ uint slen = s->d()->string->toQString().size();
if (arrayIndex < slen) {
uint index = arrayIndex;
++arrayIndex;
@@ -119,7 +119,7 @@ PropertyAttributes StringObject::virtualGetOwnProperty(const Managed *m, Propert
if (id.isArrayIndex()) {
const uint index = id.asArrayIndex();
const auto s = static_cast<const StringObject *>(m);
- if (index < uint(s->d()->string->toQString().length())) {
+ if (index < uint(s->d()->string->toQString().size())) {
if (p)
p->value = s->getIndex(index);
return Attr_NotConfigurable|Attr_NotWritable;
@@ -338,7 +338,7 @@ ReturnedValue StringPrototype::method_charAt(const FunctionObject *b, const Valu
pos = (int) argv[0].toInteger();
QString result;
- if (pos >= 0 && pos < str.length())
+ if (pos >= 0 && pos < str.size())
result += str.at(pos);
return Encode(v4->newString(result));
@@ -356,7 +356,7 @@ ReturnedValue StringPrototype::method_charCodeAt(const FunctionObject *b, const
pos = (int) argv[0].toInteger();
- if (pos >= 0 && pos < str.length())
+ if (pos >= 0 && pos < str.size())
RETURN_RESULT(Encode(str.at(pos).unicode()));
return Encode(qt_qnan());
@@ -419,11 +419,11 @@ ReturnedValue StringPrototype::method_endsWith(const FunctionObject *b, const Va
if (v4->hasException)
return Encode::undefined();
- int pos = value.length();
+ int pos = value.size();
if (argc > 1)
pos = (int) argv[1].toInteger();
- if (pos == value.length())
+ if (pos == value.size())
RETURN_RESULT(Encode(value.endsWith(searchString)));
QStringView stringToSearch = QStringView{value}.left(pos);
@@ -447,7 +447,7 @@ ReturnedValue StringPrototype::method_indexOf(const FunctionObject *b, const Val
int index = -1;
if (! value.isEmpty())
- index = value.indexOf(searchString, qMin(qMax(pos, 0), value.length()));
+ index = value.indexOf(searchString, qMin(qMax(pos, 0), value.size()));
return Encode(index);
}
@@ -470,7 +470,7 @@ ReturnedValue StringPrototype::method_includes(const FunctionObject *b, const Va
const Value &posArg = argv[1];
pos = (int) posArg.toInteger();
if (!posArg.isInteger() && posArg.isNumber() && qIsInf(posArg.toNumber()))
- pos = value.length();
+ pos = value.size();
}
if (pos == 0)
@@ -497,8 +497,8 @@ ReturnedValue StringPrototype::method_lastIndexOf(const FunctionObject *b, const
else
position = std::trunc(position);
- int pos = std::trunc(qMin(qMax(position, 0.0), double(value.length())));
- if (!searchString.isEmpty() && pos == value.length())
+ int pos = std::trunc(qMin(qMax(position, 0.0), double(value.size())));
+ if (!searchString.isEmpty() && pos == value.size())
--pos;
if (searchString.isNull() && pos == 0)
RETURN_RESULT(Encode(-1));
@@ -607,12 +607,12 @@ ReturnedValue StringPrototype::method_padEnd(const FunctionObject *f, const Valu
return s->asReturnedValue();
QString padded = s->toQString();
- int oldLength = padded.length();
+ int oldLength = padded.size();
int toFill = maxLen - oldLength;
padded.resize(maxLen);
QChar *ch = padded.data() + oldLength;
while (toFill) {
- int copy = qMin(fillString.length(), toFill);
+ int copy = qMin(fillString.size(), toFill);
memcpy(ch, fillString.constData(), copy*sizeof(QChar));
toFill -= copy;
ch += copy;
@@ -646,13 +646,13 @@ ReturnedValue StringPrototype::method_padStart(const FunctionObject *f, const Va
return s->asReturnedValue();
QString original = s->toQString();
- int oldLength = original.length();
+ int oldLength = original.size();
int toFill = maxLen - oldLength;
QString padded;
padded.resize(maxLen);
QChar *ch = padded.data();
while (toFill) {
- int copy = qMin(fillString.length(), toFill);
+ int copy = qMin(fillString.size(), toFill);
memcpy(ch, fillString.constData(), copy*sizeof(QChar));
toFill -= copy;
ch += copy;
@@ -682,9 +682,9 @@ ReturnedValue StringPrototype::method_repeat(const FunctionObject *b, const Valu
static void appendReplacementString(QString *result, const QString &input, const QString& replaceValue, uint* matchOffsets, int captureCount)
{
- result->reserve(result->length() + replaceValue.length());
- for (int i = 0; i < replaceValue.length(); ++i) {
- if (replaceValue.at(i) == QLatin1Char('$') && i < replaceValue.length() - 1) {
+ result->reserve(result->size() + replaceValue.size());
+ for (int i = 0; i < replaceValue.size(); ++i) {
+ if (replaceValue.at(i) == QLatin1Char('$') && i < replaceValue.size() - 1) {
ushort ch = replaceValue.at(i + 1).unicode();
uint substStart = JSC::Yarr::offsetNoMatch;
uint substEnd = JSC::Yarr::offsetNoMatch;
@@ -703,12 +703,12 @@ static void appendReplacementString(QString *result, const QString &input, const
skip = 1;
} else if (ch == '\'') {
substStart = matchOffsets[1];
- substEnd = input.length();
+ substEnd = input.size();
skip = 1;
} else if (ch >= '0' && ch <= '9') {
uint capture = ch - '0';
skip = 1;
- if (i < replaceValue.length() - 2) {
+ if (i < replaceValue.size() - 2) {
ch = replaceValue.at(i + 2).unicode();
if (ch >= '0' && ch <= '9') {
uint c = capture*10 + ch - '0';
@@ -793,7 +793,7 @@ ReturnedValue StringPrototype::method_replace(const FunctionObject *b, const Val
if (idx != -1) {
numStringMatches = 1;
matchOffsets[0] = idx;
- matchOffsets[1] = idx + searchString.length();
+ matchOffsets[1] = idx + searchString.size();
}
}
@@ -802,7 +802,7 @@ ReturnedValue StringPrototype::method_replace(const FunctionObject *b, const Val
ScopedValue replaceValue(scope, argc > 1 ? argv[1] : Value::undefinedValue());
ScopedFunctionObject searchCallback(scope, replaceValue);
if (!!searchCallback) {
- result.reserve(string.length() + 10*numStringMatches);
+ result.reserve(string.size() + 10*numStringMatches);
ScopedValue entry(scope);
Value *arguments = scope.alloc(numCaptures + 2);
int lastEnd = 0;
@@ -832,7 +832,7 @@ ReturnedValue StringPrototype::method_replace(const FunctionObject *b, const Val
result += QStringView{string}.mid(lastEnd);
} else {
QString newString = replaceValue->toQString();
- result.reserve(string.length() + numStringMatches*newString.size());
+ result.reserve(string.size() + numStringMatches*newString.size());
int lastEnd = 0;
for (int i = 0; i < numStringMatches; ++i) {
@@ -975,7 +975,7 @@ ReturnedValue StringPrototype::method_split(const FunctionObject *b, const Value
} else {
QString separator = separatorValue->toQString();
if (separator.isEmpty()) {
- for (uint i = 0; i < qMin(limit, uint(text.length())); ++i)
+ for (uint i = 0; i < qMin(limit, uint(text.size())); ++i)
array->push_back((s = scope.engine->newString(text.mid(i, 1))));
return array.asReturnedValue();
}
@@ -1033,7 +1033,7 @@ ReturnedValue StringPrototype::method_substr(const FunctionObject *b, const Valu
if (argc > 1)
length = argv[1].toInteger();
- double count = value.length();
+ double count = value.size();
if (start < 0)
start = qMax(count + start, 0.0);
@@ -1051,7 +1051,7 @@ ReturnedValue StringPrototype::method_substring(const FunctionObject *b, const V
if (v4->hasException)
return QV4::Encode::undefined();
- int length = value.length();
+ int length = value.size();
double start = 0;
double end = length;
@@ -1124,11 +1124,11 @@ ReturnedValue StringPrototype::method_trim(const FunctionObject *b, const Value
const QChar *chars = s.constData();
int start, end;
- for (start = 0; start < s.length(); ++start) {
+ for (start = 0; start < s.size(); ++start) {
if (!chars[start].isSpace() && chars[start].unicode() != 0xfeff)
break;
}
- for (end = s.length() - 1; end >= start; --end) {
+ for (end = s.size() - 1; end >= start; --end) {
if (!chars[end].isSpace() && chars[end].unicode() != 0xfeff)
break;
}
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index e0c0e37815..451a989ef4 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -28,7 +28,7 @@ namespace Heap {
Member(class, Pointer, String *, string)
DECLARE_HEAP_OBJECT(StringObject, Object) {
- DECLARE_MARKOBJECTS(StringObject);
+ DECLARE_MARKOBJECTS(StringObject)
enum {
LengthPropertyIndex = 0
diff --git a/src/qml/jsruntime/qv4symbol_p.h b/src/qml/jsruntime/qv4symbol_p.h
index b85ddb3b36..e56510bd69 100644
--- a/src/qml/jsruntime/qv4symbol_p.h
+++ b/src/qml/jsruntime/qv4symbol_p.h
@@ -36,7 +36,7 @@ struct Symbol : StringOrSymbol {
Member(class, Pointer, Symbol *, symbol)
DECLARE_HEAP_OBJECT(SymbolObject, Object) {
- DECLARE_MARKOBJECTS(SymbolObject);
+ DECLARE_MARKOBJECTS(SymbolObject)
void init(const QV4::Symbol *s);
};
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index d7e9d7466c..0284dceb7b 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -80,7 +80,7 @@ namespace Heap {
Member(class, NoMark, uint, arrayType)
DECLARE_HEAP_OBJECT(TypedArray, Object) {
- DECLARE_MARKOBJECTS(TypedArray);
+ DECLARE_MARKOBJECTS(TypedArray)
using Type = TypedArrayType;
void init(Type t);
diff --git a/src/qml/jsruntime/qv4urlobject.cpp b/src/qml/jsruntime/qv4urlobject.cpp
index bc59b7a839..7f4a078d13 100644
--- a/src/qml/jsruntime/qv4urlobject.cpp
+++ b/src/qml/jsruntime/qv4urlobject.cpp
@@ -131,7 +131,7 @@ void UrlObject::setUrl(const QUrl &url)
d()->port.set(engine(),
engine()->newString(url.port() == -1 ? QLatin1String("")
: QString::number(url.port())));
- d()->protocol.set(engine(), engine()->newString(url.scheme()));
+ d()->protocol.set(engine(), engine()->newString(url.scheme() + QLatin1Char(':')));
d()->search.set(engine(), engine()->newString(url.query()));
d()->username.set(engine(), engine()->newString(url.userName()));
@@ -186,15 +186,23 @@ bool UrlObject::setPort(QString port)
return true;
}
-bool UrlObject::setProtocol(QString protocol)
+bool UrlObject::setProtocol(QString protocolOrScheme)
{
QUrl url = toQUrl();
- url.setScheme(protocol);
+ // If there is one or several ':' in the protocolOrScheme,
+ // everything from the first colon is removed.
+
+ qsizetype firstColonPos = protocolOrScheme.indexOf(QLatin1Char(':'));
+
+ if (firstColonPos != -1)
+ protocolOrScheme.truncate(firstColonPos);
+
+ url.setScheme(protocolOrScheme);
if (!url.isValid())
return false;
- d()->protocol.set(engine(), engine()->newString(url.scheme()));
+ d()->protocol.set(engine(), engine()->newString(url.scheme() + QLatin1Char(':')));
d()->href.set(engine(), engine()->newString(url.toString()));
updateOrigin();
diff --git a/src/qml/jsruntime/qv4urlobject_p.h b/src/qml/jsruntime/qv4urlobject_p.h
index 3b210547b3..e4a3ba073b 100644
--- a/src/qml/jsruntime/qv4urlobject_p.h
+++ b/src/qml/jsruntime/qv4urlobject_p.h
@@ -41,7 +41,7 @@ namespace Heap {
DECLARE_HEAP_OBJECT(UrlObject, Object)
{
- DECLARE_MARKOBJECTS(UrlObject);
+ DECLARE_MARKOBJECTS(UrlObject)
void init() { Object::init(); }
};
@@ -59,7 +59,7 @@ struct UrlCtor : FunctionObject
DECLARE_HEAP_OBJECT(UrlSearchParamsObject, Object)
{
- DECLARE_MARKOBJECTS(UrlSearchParamsObject);
+ DECLARE_MARKOBJECTS(UrlSearchParamsObject)
void init() { Object::init(); }
};
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index c41c6fafad..aaace7e9f6 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -943,7 +943,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
}
// Now it is time to free QV4::QObjectWrapper Value, we must check the Value's tag to make sure its object has been destroyed
- const int pendingCount = m_pendingFreedObjectWrapperValue.count();
+ const int pendingCount = m_pendingFreedObjectWrapperValue.size();
if (pendingCount) {
QVector<Value *> remainingWeakQObjectWrappers;
remainingWeakQObjectWrappers.reserve(pendingCount);
@@ -1078,7 +1078,7 @@ void MemoryManager::runGC()
std::swap(freedObjectStats, *freedObjectStatsGlobal());
typedef std::pair<const char*, int> ObjectStatInfo;
std::vector<ObjectStatInfo> freedObjectsSorted;
- freedObjectsSorted.reserve(freedObjectStats.count());
+ freedObjectsSorted.reserve(freedObjectStats.size());
for (auto it = freedObjectStats.constBegin(); it != freedObjectStats.constEnd(); ++it) {
freedObjectsSorted.push_back(std::make_pair(it.key(), it.value()));
}
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 93d110c19f..8c694af082 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -368,6 +368,7 @@ protected:
SavedToken *last_token = nullptr;
int functionNestingLevel = 0;
+ int classNestingLevel = 0;
enum CoverExpressionType {
CE_Invalid,
@@ -4278,16 +4279,16 @@ ClassDeclaration_Default: ClassDeclaration;
ClassLBrace: T_LBRACE;
/.
case $rule_number: {
- lexer->setStaticIsKeyword(true);
+ if (++classNestingLevel == 1)
+ lexer->setStaticIsKeyword(true);
} break;
./
ClassRBrace: T_RBRACE;
-/. case $rule_number: ./
-ClassStaticQualifier: T_STATIC;
/.
case $rule_number: {
- lexer->setStaticIsKeyword(false);
+ if (--classNestingLevel == 0)
+ lexer->setStaticIsKeyword(false);
} break;
./
@@ -4342,10 +4343,9 @@ ClassElement: MethodDefinition;
} break;
./
-ClassElement: ClassStaticQualifier MethodDefinition;
+ClassElement: T_STATIC MethodDefinition;
/.
case $rule_number: {
- lexer->setStaticIsKeyword(true);
AST::ClassElementList *node = new (pool) AST::ClassElementList(sym(2).PatternProperty, true);
sym(1).Node = node;
} break;
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index e764ebfb06..c2aa8f2aaa 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -367,7 +367,7 @@ public:
TypeArgumentList(Type *typeId)
: typeId(typeId)
- , next(nullptr)
+ , next(this)
{ kind = K; }
TypeArgumentList(TypeArgumentList *previous, Type *typeId)
diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp
index d44b5a29da..db5f1b92dd 100644
--- a/src/qml/parser/qqmljslexer.cpp
+++ b/src/qml/parser/qqmljslexer.cpp
@@ -75,7 +75,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
_state.rawString = QStringView();
_state.codePtr = code.unicode();
- _endPtr = _state.codePtr + code.length();
+ _endPtr = _state.codePtr + code.size();
_state.tokenStartPtr = _state.codePtr;
_state.currentChar = u'\n';
diff --git a/src/qml/qml/ftw/qbipointer_p.h b/src/qml/qml/ftw/qbipointer_p.h
index 79a6676ebd..4039d6b60d 100644
--- a/src/qml/qml/ftw/qbipointer_p.h
+++ b/src/qml/qml/ftw/qbipointer_p.h
@@ -87,6 +87,11 @@ public:
inline T *asT1() const;
inline T2 *asT2() const;
+ friend size_t qHash(const QBiPointer<T, T2> &ptr, size_t seed = 0)
+ {
+ return qHash(ptr.isNull() ? quintptr(0) : ptr.ptr_value, seed);
+ }
+
private:
quintptr ptr_value = 0;
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index 9beaffc2ae..5e002fcbee 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -200,12 +200,12 @@ QHashedStringRef::QHashedStringRef()
}
QHashedStringRef::QHashedStringRef(const QString &str)
-: m_data(str.constData()), m_length(str.length()), m_hash(0)
+: m_data(str.constData()), m_length(str.size()), m_hash(0)
{
}
QHashedStringRef::QHashedStringRef(QStringView str)
-: m_data(str.constData()), m_length(str.length()), m_hash(0)
+: m_data(str.constData()), m_length(str.size()), m_hash(0)
{
}
@@ -220,7 +220,7 @@ QHashedStringRef::QHashedStringRef(const QChar *data, int length, quint32 hash)
}
QHashedStringRef::QHashedStringRef(const QHashedString &string)
-: m_data(string.constData()), m_length(string.length()), m_hash(string.m_hash)
+: m_data(string.constData()), m_length(string.size()), m_hash(string.m_hash)
{
}
@@ -248,7 +248,7 @@ bool QHashedStringRef::operator==(const QHashedString &string) const
if (m_hash && string.m_hash && m_hash != string.m_hash)
return false;
QStringView view {m_data, m_length};
- QStringView otherView {string.constData(), string.length()};
+ QStringView otherView {string.constData(), string.size()};
return view == otherView;
}
@@ -424,7 +424,7 @@ quint32 QHashedString::stringHash(const char *data, int length)
void QHashedString::computeHash() const
{
- m_hash = stringHash(constData(), length());
+ m_hash = stringHash(constData(), size());
}
namespace QtPrivate {
diff --git a/src/qml/qml/ftw/qstringhash_p.h b/src/qml/qml/ftw/qstringhash_p.h
index 1d0e7d6e97..ee2928ee59 100644
--- a/src/qml/qml/ftw/qstringhash_p.h
+++ b/src/qml/qml/ftw/qstringhash_p.h
@@ -38,7 +38,7 @@ public:
}
QStringHashNode(const QHashedString &key)
- : length(key.length()), hash(key.hash()), symbolId(0)
+ : length(key.size()), hash(key.hash()), symbolId(0)
, arrayData(mutableStringData(key).d_ptr())
, strData(mutableStringData(key).data())
{
@@ -491,7 +491,7 @@ int QStringHash<T>::numBuckets() const
template<class T>
void QStringHash<T>::initializeNode(Node *node, const QHashedString &key)
{
- node->length = key.length();
+ node->length = key.size();
node->hash = key.hash();
node->arrayData = mutableStringData(key).d_ptr();
node->strData = mutableStringData(key).data();
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 72a287c318..f0435ede45 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -581,7 +581,7 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
auto revisions = prepareRevisions(type.instanceMetaObject, added) + furtherRevisions;
uniqueRevisions(&revisions, type.version, added);
- for (QTypeRevision revision : qAsConst(revisions)) {
+ for (QTypeRevision revision : std::as_const(revisions)) {
if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
break;
@@ -624,7 +624,7 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
revisions.append(added);
uniqueRevisions(&revisions, type.version, added);
- for (QTypeRevision revision : qAsConst(revisions)) {
+ for (QTypeRevision revision : std::as_const(revisions)) {
if (revision < added)
continue;
if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
@@ -976,7 +976,8 @@ static ObjectLookupResult initObjectLookup(
// & 1 to tell the gc that this is not heap allocated; see markObjects in qv4lookup_p.h
l->qobjectFallbackLookup.metaObject = quintptr(metaObject) + 1;
l->qobjectFallbackLookup.coreIndex = coreIndex;
- l->qobjectFallbackLookup.notifyIndex = property.notifySignalIndex();
+ l->qobjectFallbackLookup.notifyIndex =
+ QMetaObjectPrivate::signalIndex(property.notifySignal());
l->qobjectFallbackLookup.isConstant = property.isConstant() ? 1 : 0;
return ObjectLookupResult::Fallback;
}
@@ -997,7 +998,7 @@ static bool initValueLookup(QV4::Lookup *l, QV4::ExecutableCompilationUnit *comp
const QByteArray name = compilationUnit->runtimeStrings[l->nameIndex]->toQString().toUtf8();
const int coreIndex = metaObject->indexOfProperty(name.constData());
QMetaType lookupType = metaObject->property(coreIndex).metaType();
- if (type.isValid() && lookupType != type)
+ if (!isTypeCompatible(type, lookupType))
return false;
l->qgadgetLookup.metaObject = quintptr(metaObject) + 1;
l->qgadgetLookup.coreIndex = coreIndex;
@@ -1587,7 +1588,12 @@ void AOTCompiledContext::initGetEnumLookup(
{
Q_ASSERT(!engine->hasError());
QV4::Lookup *l = compilationUnit->runtimeLookups + index;
- Q_ASSERT(metaObject);
+ if (!metaObject) {
+ engine->handle()->throwTypeError(
+ QStringLiteral("Cannot read property '%1' of undefined")
+ .arg(QString::fromUtf8(enumValue)));
+ return;
+ }
const int enumIndex = metaObject->indexOfEnumerator(enumerator);
const int value = metaObject->enumerator(enumIndex).keyToValue(enumValue);
l->qmlEnumValueLookup.encodedEnumValue = value;
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index df8c64dab0..2b94da14a5 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -26,7 +26,7 @@ QQmlApplicationEnginePrivate::~QQmlApplicationEnginePrivate()
void QQmlApplicationEnginePrivate::cleanUp()
{
Q_Q(QQmlApplicationEngine);
- for (auto obj : qAsConst(objects))
+ for (auto obj : std::as_const(objects))
obj->disconnect(q);
qDeleteAll(objects);
@@ -214,7 +214,7 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
QQmlApplicationEngine engine;
// quit on error
- QObject::connect(&app, QQmlApplicationEngine::objectCreationFailed,
+ QObject::connect(&engine, QQmlApplicationEngine::objectCreationFailed,
QCoreApplication::instance(), QCoreApplication::quit,
Qt::QueuedConnection);
engine.load(QUrl());
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 49a72c17e9..10a9e60819 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -339,7 +339,7 @@ protected:
break;
default:
if (const QV4::QQmlValueTypeWrapper *vtw = result.as<const QV4::QQmlValueTypeWrapper>()) {
- if (vtw->d()->valueType()->metaType == pd->propType()) {
+ if (vtw->d()->valueType()->metaType() == pd->propType()) {
return vtw->write(m_target.data(), pd->coreIndex());
}
}
diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h
index 4c8c0f4e61..9b468f3f17 100644
--- a/src/qml/qml/qqmlbinding_p.h
+++ b/src/qml/qml/qqmlbinding_p.h
@@ -76,6 +76,10 @@ public:
};
QVariant evaluate();
+ bool evaluate(void *result, QMetaType type)
+ {
+ return QQmlJavaScriptExpression::evaluate(&result, &type, 0);
+ }
void expressionChanged() override;
@@ -110,10 +114,6 @@ protected:
QQmlPropertyData::WriteFlags flags);
QV4::ReturnedValue evaluate(bool *isUndefined);
- bool evaluate(void *result, QMetaType type)
- {
- return QQmlJavaScriptExpression::evaluate(&result, &type, 0);
- }
private:
static QQmlBinding *newBinding(const QQmlPropertyData *property);
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 8c74272457..8f1ed8b31c 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -350,7 +350,7 @@ bool QQmlComponentPrivate::setInitialProperty(
QV4::ScopedObject object(scope, QV4::QObjectWrapper::wrap(scope.engine, base));
QV4::ScopedString segment(scope);
- for (int i = 0; i < properties.length() - 1; ++i) {
+ for (int i = 0; i < properties.size() - 1; ++i) {
segment = scope.engine->newString(properties.at(i));
object = object->get(segment);
if (scope.engine->hasException)
@@ -408,7 +408,7 @@ QQmlComponent::~QQmlComponent()
if (isError()) {
qWarning() << "This may have been caused by one of the following errors:";
- for (const QQmlError &error : qAsConst(d->state.errors))
+ for (const QQmlError &error : std::as_const(d->state.errors))
qWarning().nospace().noquote() << QLatin1String(" ") << error;
}
@@ -489,6 +489,16 @@ bool QQmlComponent::isLoading() const
}
/*!
+ Returns true if the component was created in a QML files that specifies
+ \c{pragma ComponentBehavior: Bound}, otherwise returns false.
+ */
+bool QQmlComponent::isBound() const
+{
+ Q_D(const QQmlComponent);
+ return d->isBound();
+}
+
+/*!
\qmlproperty real Component::progress
The progress of loading the component, from 0.0 (nothing loaded)
to 1.0 (finished).
@@ -914,7 +924,7 @@ QObject *QQmlComponentPrivate::beginCreate(QQmlRefPointer<QQmlContextData> conte
Q_Q(QQmlComponent);
auto cleanup = qScopeGuard([this] {
if (!state.errors.isEmpty() && lcQmlComponentGeneral().isDebugEnabled()) {
- for (const auto &e : qAsConst(state.errors)) {
+ for (const auto &e : std::as_const(state.errors)) {
qCDebug(lcQmlComponentGeneral) << "QQmlComponent: " << e.toString();
}
}
@@ -986,7 +996,7 @@ void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv,
deferredState->reserve(ddata->deferredData.size());
- for (QQmlData::DeferredData *deferredData : qAsConst(ddata->deferredData)) {
+ for (QQmlData::DeferredData *deferredData : std::as_const(ddata->deferredData)) {
enginePriv->inProgressCreations++;
ConstructionState state;
@@ -1270,7 +1280,7 @@ namespace Heap {
Member(class, NoMark, QV4QPointer<QObject>, parent)
DECLARE_HEAP_OBJECT(QmlIncubatorObject, Object) {
- DECLARE_MARKOBJECTS(QmlIncubatorObject);
+ DECLARE_MARKOBJECTS(QmlIncubatorObject)
void init(QQmlIncubator::IncubationMode = QQmlIncubator::Asynchronous);
inline void destroy();
@@ -1331,7 +1341,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
QList<APF> functions = QQmlMetaType::parentFunctions();
bool needParent = false;
- for (int ii = 0; ii < functions.count(); ++ii) {
+ for (int ii = 0; ii < functions.size(); ++ii) {
QQmlPrivate::AutoParentResult res = functions.at(ii)(me, parent);
if (res == QQmlPrivate::Parented) {
needParent = false;
@@ -1375,12 +1385,12 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
The \a properties argument is specified as a map of property-value items. For example, the code
below creates an object with initial \c x and \c y values of 100 and 100, respectively:
- \js
+ \qml
const component = Qt.createComponent("Button.qml");
if (component.status === Component.Ready) {
component.createObject(parent, { x: 100, y: 100 });
}
- \endjs
+ \endqml
Dynamically created instances can be deleted with the \c destroy() method.
See \l {Dynamic QML Object Creation from JavaScript} for more information.
@@ -1410,17 +1420,25 @@ void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV
object = o;
const QStringList properties = name->toQString().split(QLatin1Char('.'));
bool isTopLevelProperty = properties.size() == 1;
- for (int i = 0; i < properties.length() - 1; ++i) {
+ for (int i = 0; i < properties.size() - 1; ++i) {
name = engine->newString(properties.at(i));
object = object->get(name);
if (engine->hasException || !object) {
break;
}
}
- if (engine->hasException || !object) {
+ if (engine->hasException) {
qmlWarning(createdComponent, engine->catchExceptionAsQmlError());
continue;
}
+ if (!object) {
+ QQmlError error;
+ error.setUrl(qmlContext ? qmlContext->qmlContext()->url() : QUrl());
+ error.setDescription(QLatin1String("Cannot resolve property \"%1\".")
+ .arg(properties.join(u'.')));
+ qmlWarning(createdComponent, error);
+ continue;
+ }
name = engine->newString(properties.last());
object->put(name, val);
if (engine->hasException) {
@@ -1568,7 +1586,7 @@ QObject *QQmlComponent::createObject(QObject *parent, const QVariantMap &propert
if (!d->requiredProperties().empty()) {
QList<QQmlError> errors;
- for (const auto &requiredProperty: qAsConst(d->requiredProperties())) {
+ for (const auto &requiredProperty: std::as_const(d->requiredProperties())) {
errors.push_back(QQmlComponentPrivate::unsetRequiredPropertyToQQmlError(
requiredProperty));
}
@@ -1622,7 +1640,7 @@ QObject *QQmlComponent::createObject(QObject *parent, const QVariantMap &propert
The following example demonstrates how to use an incubator:
- \js
+ \qml
const component = Qt.createComponent("Button.qml");
const incubator = component.incubateObject(parent, { x: 10, y: 10 });
@@ -1635,7 +1653,7 @@ QObject *QQmlComponent::createObject(QObject *parent, const QVariantMap &propert
} else {
print("Object", incubator.object, "is ready immediately!");
}
- \endjs
+ \endqml
Dynamically created instances can be deleted with the \c destroy() method.
See \l {Dynamic QML Object Creation from JavaScript} for more information.
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index ccfece00f9..ca95d756a5 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -63,6 +63,8 @@ public:
bool isError() const;
bool isLoading() const;
+ bool isBound() const;
+
QList<QQmlError> errors() const;
Q_INVOKABLE QString errorString() const;
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index baa8d6133e..0c9286693f 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -481,7 +481,7 @@ qsizetype QQmlContextPrivate::context_count(QQmlListProperty<QObject> *prop)
if (d->propertyValue(contextProperty).userType() != qMetaTypeId<QList<QObject*> >())
return 0;
else
- return ((const QList<QObject> *)d->propertyValue(contextProperty).constData())->count();
+ return ((const QList<QObject> *)d->propertyValue(contextProperty).constData())->size();
}
QObject *QQmlContextPrivate::context_at(QQmlListProperty<QObject> *prop, qsizetype index)
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index aa50485a00..5489afb892 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -50,7 +50,7 @@ public:
int notifyIndex() const { return m_notifyIndex; }
void setNotifyIndex(int notifyIndex) { m_notifyIndex = notifyIndex; }
- int numPropertyValues() const { return m_propertyValues.count(); }
+ int numPropertyValues() const { return m_propertyValues.size(); }
void appendPropertyValue(const QVariant &value) { m_propertyValues.append(value); }
void setPropertyValue(int index, const QVariant &value) { m_propertyValues[index] = value; }
QVariant propertyValue(int index) const { return m_propertyValues[index]; }
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index fba805f084..f284a82dbe 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "qml/qqmlpropertyvalidator_p.h"
#include "qqmlcustomparser_p.h"
#include <private/qv4compileddata_p.h>
@@ -81,7 +82,7 @@ void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const
A valid \a ok must be provided, or the function will assert.
*/
-int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
+int QQmlCustomParser::evaluateEnum(const QString &script, bool *ok) const
{
Q_ASSERT_X(ok, "QQmlCustomParser::evaluateEnum", "ok must not be a null pointer");
*ok = false;
@@ -91,15 +92,15 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
// * <TypeName>.<ScopedEnumName>.<EnumValue>
auto nextDot = [&](int dot) {
- const int nextDot = script.indexOf('.', dot + 1);
- return (nextDot == script.length() - 1) ? -1 : nextDot;
+ const int nextDot = script.indexOf(u'.', dot + 1);
+ return (nextDot == script.size() - 1) ? -1 : nextDot;
};
int dot = nextDot(-1);
if (dot == -1)
return -1;
- QString scope = QString::fromUtf8(script.left(dot));
+ const QString scope = script.left(dot);
if (scope != QLatin1String("Qt")) {
if (imports.isNull())
@@ -108,23 +109,35 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
if (imports.isT1()) {
QQmlImportNamespace *ns = nullptr;
- if (!imports.asT1()->resolveType(scope, &type, nullptr, &ns))
+
+ // Pass &recursionDetected to resolveType because that implicitly allows recursion.
+ // This way we can find the QQmlType of the document we're currently validating.
+ bool recursionDetected = false;
+
+ if (!imports.asT1()->resolveType(
+ scope, &type, nullptr, &ns, nullptr,
+ QQmlType::AnyRegistrationType, &recursionDetected)) {
return -1;
+ }
+
if (!type.isValid() && ns != nullptr) {
dot = nextDot(dot);
- if (dot == -1 || !imports.asT1()->resolveType(QString::fromUtf8(script.left(dot)),
- &type, nullptr, nullptr)) {
+ if (dot == -1 || !imports.asT1()->resolveType(
+ script.left(dot), &type, nullptr, nullptr, nullptr,
+ QQmlType::AnyRegistrationType, &recursionDetected)) {
return -1;
}
}
} else {
- QQmlTypeNameCache::Result result = imports.asT2()->query(scope);
+ // Allow recursion so that we can find enums from the same document.
+ const QQmlTypeNameCache::Result result
+ = imports.asT2()->query<QQmlImport::AllowRecursion>(scope);
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;
+ type = imports.asT2()->query<QQmlImport::AllowRecursion>(script.left(dot)).type;
}
}
@@ -133,19 +146,43 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
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());
+ const QString enumValue = script.mid(dot2Valid ? dot2 + 1 : dot + 1);
+ const QString scopedEnumName = dot2Valid ? script.mid(dot + 1, dot2 - dot - 1) : QString();
+
+ // If we're currently validating the same document, we won't be able to find its enums using
+ // the QQmlType. However, we do have the property cache already, and that one contains the
+ // enums.
+ const QUrl documentUrl = validator ? validator->documentSourceUrl() : QUrl();
+ if (documentUrl.isValid() && documentUrl == type.sourceUrl()) {
+ const QQmlPropertyCache::ConstPtr rootCache = validator->rootPropertyCache();
+ const int count = rootCache->qmlEnumCount();
+ for (int ii = 0; ii < count; ++ii) {
+ const QQmlEnumData *enumData = rootCache->qmlEnum(ii);
+ if (!scopedEnumName.isEmpty() && scopedEnumName != enumData->name)
+ continue;
+
+ for (int jj = 0; jj < enumData->values.size(); ++jj) {
+ const QQmlEnumValue value = enumData->values.at(jj);
+ if (value.namedValue == enumValue) {
+ *ok = true;
+ return value.value;
+ }
+ }
+ }
+ return -1;
+ }
+
if (!scopedEnumName.isEmpty())
return type.scopedEnumValue(engine, scopedEnumName, enumValue, ok);
else
- return type.enumValue(engine, QHashedCStringRef(enumValue.constData(), enumValue.length()), ok);
+ return type.enumValue(engine, enumValue, ok);
}
- QByteArray enumValue = script.mid(dot + 1);
+ const QString enumValue = script.mid(dot + 1);
const QMetaObject *mo = &Qt::staticMetaObject;
int i = mo->enumeratorCount();
while (i--) {
- int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok);
+ int v = mo->enumerator(i).keyToValue(enumValue.toUtf8().constData(), ok);
if (*ok)
return v;
}
diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index afb5b810c2..98a9f21ae9 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -56,7 +56,7 @@ protected:
{ error(object->location, description); }
void error(const QV4::CompiledData::Location &location, const QString& description);
- int evaluateEnum(const QByteArray&, bool *ok) const;
+ int evaluateEnum(const QString &, bool *ok) const;
const QMetaObject *resolveType(const QString&) const;
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index f72feb2ce6..5b7c05c61e 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -103,7 +103,9 @@ public:
// set when at least one of the object's properties is intercepted
quint32 hasInterceptorMetaObject:1;
quint32 hasVMEMetaObject:1;
- quint32 dummy:8;
+ // If we have another wrapper for a const QObject * in the multiply wrapped QObjects.
+ quint32 hasConstWrapper: 1;
+ quint32 dummy:7;
// When bindingBitsSize < sizeof(ptr), we store the binding bit flags inside
// bindingBitsValue. When we need more than sizeof(ptr) bits, we allocated
diff --git a/src/qml/qml/qqmldatablob.cpp b/src/qml/qml/qqmldatablob.cpp
index 6114c2846a..a8a4537844 100644
--- a/src/qml/qml/qqmldatablob.cpp
+++ b/src/qml/qml/qqmldatablob.cpp
@@ -254,7 +254,7 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors)
Q_ASSERT(m_errors.isEmpty());
// m_errors must be set before the m_data fence
- m_errors.reserve(errors.count());
+ m_errors.reserve(errors.size());
for (const QQmlError &error : errors) {
if (error.url().isEmpty()) {
QQmlError mutableError = error;
@@ -269,7 +269,7 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors)
if (dumpErrors()) {
qWarning().nospace() << "Errors for " << urlString();
- for (int ii = 0; ii < errors.count(); ++ii)
+ for (int ii = 0; ii < errors.size(); ++ii)
qWarning().nospace() << " " << qPrintable(errors.at(ii).toString());
}
cancelAllWaitingFor();
@@ -313,7 +313,7 @@ void QQmlDataBlob::addDependency(QQmlDataBlob *blob)
status() == Error || status() == Complete || m_isDone)
return;
- for (const auto &existingDep: qAsConst(m_waitingFor))
+ for (const auto &existingDep: std::as_const(m_waitingFor))
if (existingDep.data() == blob)
return;
@@ -503,7 +503,7 @@ void QQmlDataBlob::tryDone()
void QQmlDataBlob::cancelAllWaitingFor()
{
- while (m_waitingFor.count()) {
+ while (m_waitingFor.size()) {
QQmlRefPointer<QQmlDataBlob> blob = m_waitingFor.takeLast();
Q_ASSERT(blob->m_waitingOnMe.contains(this));
@@ -514,7 +514,7 @@ void QQmlDataBlob::cancelAllWaitingFor()
void QQmlDataBlob::notifyAllWaitingOnMe()
{
- while (m_waitingOnMe.count()) {
+ while (m_waitingOnMe.size()) {
QQmlDataBlob *blob = m_waitingOnMe.takeLast();
Q_ASSERT(std::any_of(blob->m_waitingFor.constBegin(), blob->m_waitingFor.constEnd(),
@@ -533,7 +533,7 @@ void QQmlDataBlob::notifyComplete(QQmlDataBlob *blob)
m_inCallback = true;
QQmlRefPointer<QQmlDataBlob> blobRef;
- for (int i = 0; i < m_waitingFor.count(); ++i) {
+ for (int i = 0; i < m_waitingFor.size(); ++i) {
if (m_waitingFor.at(i).data() == blob) {
blobRef = m_waitingFor.takeAt(i);
break;
@@ -576,7 +576,7 @@ QString QQmlDataBlob::SourceCodeData::readAll(QString *error) const
}
QByteArray data(fileSize, Qt::Uninitialized);
- if (f.read(data.data(), data.length()) != data.length()) {
+ if (f.read(data.data(), data.size()) != data.size()) {
*error = f.errorString();
return QString();
}
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 57df383257..4e12ab93d8 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -245,7 +245,7 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o)
QQmlData::QQmlData()
: ownMemory(true), indestructible(true), explicitIndestructibleSet(false),
hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false),
- hasInterceptorMetaObject(false), hasVMEMetaObject(false),
+ hasInterceptorMetaObject(false), hasVMEMetaObject(false), hasConstWrapper(false),
bindingBitsArraySize(InlineBindingArraySize), notifyList(nullptr),
bindings(nullptr), signalHandlers(nullptr), nextContextObject(nullptr), prevContextObject(nullptr),
lineNumber(0), columnNumber(0), jsEngineId(0),
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 66192ff06c..a0b6440e7d 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -295,13 +295,13 @@ QDebug operator<<(QDebug debug, const QQmlError &error)
const QString code = stream.readAll();
const auto lines = QStringView{code}.split(QLatin1Char('\n'));
- if (lines.count() >= error.line()) {
+ if (lines.size() >= error.line()) {
const QStringView &line = lines.at(error.line() - 1);
debug << "\n " << line.toLocal8Bit().constData();
if(error.column() > 0) {
int column = qMax(0, error.column() - 1);
- column = qMin(column, line.length());
+ column = qMin(column, line.size());
QByteArray ind;
ind.reserve(column);
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index 6229c0a0e4..319accb768 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -7,6 +7,21 @@
QT_BEGIN_NAMESPACE
/*!
+ \since 5.0
+ \inmodule QtQml
+ \class QQmlExtensionPlugin
+ \brief The QQmlExtensionPlugin class provides an abstract base for custom QML extension plugins
+ with custom type registration functions.
+
+ \ingroup plugins
+
+ \note If you need to write a plugin manually (which is rare) you should always use
+ \l{QQmlEngineExtensionPlugin}. QQmlExtensionPlugin only provides the registerTypes() and
+ unregisterTypes() functions in addition. You should not use them, but rather declare your
+ types with \l{QML_ELEMENT} and friends and have the build system take care of the registration.
+*/
+
+/*!
\since 5.14
\inmodule QtQml
\class QQmlEngineExtensionPlugin
@@ -25,7 +40,6 @@ 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
@@ -107,9 +121,10 @@ void QQmlExtensionPlugin::unregisterTypes()
}
/*!
- \internal
-*/
-
+ 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)
{
Q_UNUSED(engine);
diff --git a/src/qml/qml/qqmlfile.cpp b/src/qml/qml/qqmlfile.cpp
index af2f4d8510..d616616ebd 100644
--- a/src/qml/qml/qqmlfile.cpp
+++ b/src/qml/qml/qqmlfile.cpp
@@ -29,6 +29,9 @@ static char file_string[] = "file";
#if defined(Q_OS_ANDROID)
static char assets_string[] = "assets";
static char content_string[] = "content";
+static char authority_externalstorage[] = "com.android.externalstorage.documents";
+static char authority_downloads_documents[] = "com.android.providers.downloads.documents";
+static char authority_media_documents[] = "com.android.providers.media.documents";
#endif
class QQmlFilePrivate;
@@ -410,8 +413,8 @@ bool QQmlFile::isSynchronous(const QUrl &url)
{
QString scheme = url.scheme();
- if ((scheme.length() == 4 && 0 == scheme.compare(QLatin1String(file_string), Qt::CaseInsensitive)) ||
- (scheme.length() == 3 && 0 == scheme.compare(QLatin1String(qrc_string), Qt::CaseInsensitive))) {
+ if ((scheme.size() == 4 && 0 == scheme.compare(QLatin1String(file_string), Qt::CaseInsensitive)) ||
+ (scheme.size() == 3 && 0 == scheme.compare(QLatin1String(qrc_string), Qt::CaseInsensitive))) {
return true;
#if defined(Q_OS_ANDROID)
@@ -435,20 +438,20 @@ Synchronous urls have a qrc:/ or file:// scheme.
*/
bool QQmlFile::isSynchronous(const QString &url)
{
- if (url.length() < 5 /* qrc:/ */)
+ if (url.size() < 5 /* qrc:/ */)
return false;
QChar f = url[0];
if (f == QLatin1Char('f') || f == QLatin1Char('F')) {
- return url.length() >= 7 /* file:// */ &&
+ return url.size() >= 7 /* file:// */ &&
url.startsWith(QLatin1String(file_string), Qt::CaseInsensitive) &&
url[4] == QLatin1Char(':') && url[5] == QLatin1Char('/') && url[6] == QLatin1Char('/');
} else if (f == QLatin1Char('q') || f == QLatin1Char('Q')) {
- return url.length() >= 5 /* qrc:/ */ &&
+ return url.size() >= 5 /* qrc:/ */ &&
url.startsWith(QLatin1String(qrc_string), Qt::CaseInsensitive) &&
url[3] == QLatin1Char(':') && url[4] == QLatin1Char('/');
@@ -469,6 +472,17 @@ bool QQmlFile::isSynchronous(const QString &url)
return false;
}
+#if defined(Q_OS_ANDROID)
+static bool hasLocalContentAuthority(const QUrl &url)
+{
+ const QString authority = url.authority();
+ return authority.isEmpty()
+ || authority == QLatin1String(authority_externalstorage)
+ || authority == QLatin1String(authority_downloads_documents)
+ || authority == QLatin1String(authority_media_documents);
+}
+#endif
+
/*!
Returns true if \a url is a local file that can be opened with QFile.
@@ -483,27 +497,27 @@ bool QQmlFile::isLocalFile(const QUrl &url)
// file: URLs with two slashes following the scheme can be interpreted as local files
// where the slashes are part of the path. Therefore, disregard the authority.
// See QUrl::toLocalFile().
- if (scheme.length() == 4 && scheme.startsWith(QLatin1String(file_string), Qt::CaseInsensitive))
+ if (scheme.size() == 4 && scheme.startsWith(QLatin1String(file_string), Qt::CaseInsensitive))
return true;
- if (scheme.length() == 3 && scheme.startsWith(QLatin1String(qrc_string), Qt::CaseInsensitive))
+ if (scheme.size() == 3 && scheme.startsWith(QLatin1String(qrc_string), Qt::CaseInsensitive))
return url.authority().isEmpty();
#if defined(Q_OS_ANDROID)
- if ((scheme.length() == 6
+ if (scheme.length() == 6
&& scheme.startsWith(QLatin1String(assets_string), Qt::CaseInsensitive))
- || (scheme.length() == 7
- && scheme.startsWith(QLatin1String(content_string), Qt::CaseInsensitive))) {
return url.authority().isEmpty();
- }
+ if (scheme.length() == 7
+ && scheme.startsWith(QLatin1String(content_string), Qt::CaseInsensitive))
+ return hasLocalContentAuthority(url);
#endif
return false;
}
-static bool hasSchemeAndNoAuthority(const QString &url, const char *scheme, qsizetype schemeLength)
+static bool hasScheme(const QString &url, const char *scheme, qsizetype schemeLength)
{
- const qsizetype urlLength = url.length();
+ const qsizetype urlLength = url.size();
if (urlLength < schemeLength + 1)
return false;
@@ -514,19 +528,41 @@ static bool hasSchemeAndNoAuthority(const QString &url, const char *scheme, qsiz
if (url[schemeLength] != QLatin1Char(':'))
return false;
+ return true;
+}
+
+static qsizetype authorityOffset(const QString &url, qsizetype schemeLength)
+{
+ const qsizetype urlLength = url.size();
+
if (urlLength < schemeLength + 3)
- return true;
+ return -1;
const QLatin1Char slash('/');
if (url[schemeLength + 1] == slash && url[schemeLength + 2] == slash) {
- // Exactly two slashes denote an authority. We don't want that.
+ // Exactly two slashes denote an authority.
if (urlLength < schemeLength + 4 || url[schemeLength + 3] != slash)
- return false;
+ return schemeLength + 3;
}
- return true;
+ return -1;
+}
+
+#if defined(Q_OS_ANDROID)
+static bool hasLocalContentAuthority(const QString &url, qsizetype schemeLength)
+{
+ const qsizetype offset = authorityOffset(url, schemeLength);
+ if (offset == -1)
+ return true; // no authority is a local authority.
+
+ const QString authorityAndPath = url.sliced(offset);
+ return authorityAndPath.startsWith(QLatin1String(authority_externalstorage))
+ || authorityAndPath.startsWith(QLatin1String(authority_downloads_documents))
+ || authorityAndPath.startsWith(QLatin1String(authority_media_documents));
}
+#endif
+
/*!
Returns true if \a url is a local file that can be opened with QFile.
@@ -536,7 +572,7 @@ Local file urls have either a qrc: or file: scheme.
*/
bool QQmlFile::isLocalFile(const QString &url)
{
- if (url.length() < 4 /* qrc: */)
+ if (url.size() < 4 /* qrc: */)
return false;
switch (url[0].toLatin1()) {
@@ -548,19 +584,22 @@ bool QQmlFile::isLocalFile(const QString &url)
const qsizetype fileLength = strlen(file_string);
return url.startsWith(QLatin1String(file_string, file_string + fileLength),
Qt::CaseInsensitive)
- && url.length() > fileLength
+ && url.size() > fileLength
&& url[fileLength] == QLatin1Char(':');
}
case 'q':
case 'Q':
- return hasSchemeAndNoAuthority(url, qrc_string, strlen(qrc_string));
+ return hasScheme(url, qrc_string, strlen(qrc_string))
+ && authorityOffset(url, strlen(qrc_string)) == -1;
#if defined(Q_OS_ANDROID)
case 'a':
case 'A':
- return hasSchemeAndNoAuthority(url, assets_string, strlen(assets_string));
+ return hasScheme(url, assets_string, strlen(assets_string))
+ && authorityOffset(url, strlen(assets_string)) == -1;
case 'c':
case 'C':
- return hasSchemeAndNoAuthority(url, content_string, strlen(content_string));
+ return hasScheme(url, content_string, strlen(content_string))
+ && hasLocalContentAuthority(url, strlen(content_string));
#endif
default:
break;
@@ -584,10 +623,12 @@ QString QQmlFile::urlToLocalFileOrQrc(const QUrl& url)
#if defined(Q_OS_ANDROID)
if (url.scheme().compare(QLatin1String("assets"), Qt::CaseInsensitive) == 0)
return url.authority().isEmpty() ? url.toString() : QString();
- if (url.scheme().compare(QLatin1String("content"), Qt::CaseInsensitive) == 0)
- return url.authority().isEmpty() ? url.toString() : QString();
+ if (url.scheme().compare(QLatin1String("content"), Qt::CaseInsensitive) == 0) {
+ if (hasLocalContentAuthority(url))
+ return url.toString();
+ return QString();
+ }
#endif
-
return url.toLocalFile();
}
@@ -605,7 +646,7 @@ static QString toLocalFile(const QString &url)
static bool isDoubleSlashed(const QString &url, qsizetype offset)
{
- const qsizetype urlLength = url.length();
+ const qsizetype urlLength = url.size();
if (urlLength < offset + 2)
return false;
@@ -628,7 +669,7 @@ QString QQmlFile::urlToLocalFileOrQrc(const QString& url)
if (url.startsWith(QLatin1String("qrc://"), Qt::CaseInsensitive)) {
// Exactly two slashes are bad because that's a URL authority.
// One slash is fine and >= 3 slashes are file.
- if (url.length() == 6 || url[6] != QLatin1Char('/')) {
+ if (url.size() == 6 || url[6] != QLatin1Char('/')) {
Q_ASSERT(isDoubleSlashed(url, strlen("qrc:")));
return QString();
}
@@ -638,7 +679,7 @@ QString QQmlFile::urlToLocalFileOrQrc(const QString& url)
if (url.startsWith(QLatin1String("qrc:"), Qt::CaseInsensitive)) {
Q_ASSERT(!isDoubleSlashed(url, strlen("qrc:")));
- if (url.length() > 4)
+ if (url.size() > 4)
return QLatin1Char(':') + QStringView{url}.mid(4);
return QStringLiteral(":");
}
@@ -646,8 +687,8 @@ QString QQmlFile::urlToLocalFileOrQrc(const QString& url)
#if defined(Q_OS_ANDROID)
if (url.startsWith(QLatin1String("assets:"), Qt::CaseInsensitive))
return isDoubleSlashed(url, strlen("assets:")) ? QString() : url;
- if (url.startsWith(QLatin1String("content:"), Qt::CaseInsensitive))
- return isDoubleSlashed(url, strlen("content:")) ? QString() : url;
+ if (hasScheme(url, content_string, strlen(content_string)))
+ return hasLocalContentAuthority(url, strlen(content_string)) ? url : QString();
#endif
return toLocalFile(url);
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index a7af7cedd6..e09b254f46 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -32,6 +32,8 @@
#include <algorithm>
#include <functional>
+using namespace Qt::Literals::StringLiterals;
+
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE)
@@ -123,7 +125,7 @@ QString resolveLocalUrl(const QString &url, const QString &relative)
QString base = baseRef + relative;
// Remove any relative directory elements in the path
- int length = base.length();
+ int length = base.size();
int index = 0;
while ((index = base.indexOf(QLatin1String("/."), index)) != -1) {
if ((length > (index + 2)) && (base.at(index + 2) == Dot) &&
@@ -235,7 +237,7 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const
{
const QQmlImportNamespace &set = m_unqualifiedset;
- for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ for (int ii = set.imports.size() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version);
if (module) {
@@ -251,7 +253,7 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const
QQmlImportRef &typeimport = cache->m_namedImports[set.prefix];
typeimport.m_qualifier = set.prefix;
- for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ for (int ii = set.imports.size() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version);
if (module) {
@@ -283,7 +285,7 @@ void findCompositeSingletons(const QQmlImportNamespace &set, QList<QQmlImports::
{
typedef QQmlDirComponents::const_iterator ConstIterator;
- for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ for (int ii = set.imports.size() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
const QQmlDirComponents &components = import->qmlDirComponents;
@@ -373,7 +375,7 @@ QList<QQmlImports::ScriptReference> QQmlImports::resolvedScripts() const
const QQmlImportNamespace &set = m_unqualifiedset;
- for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ for (int ii = set.imports.size() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
for (const QQmlDirParser::Script &script : import->qmlDirScripts) {
@@ -387,7 +389,7 @@ QList<QQmlImports::ScriptReference> QQmlImports::resolvedScripts() const
for (QQmlImportNamespace *ns = m_qualifiedSets.first(); ns; ns = m_qualifiedSets.next(ns)) {
const QQmlImportNamespace &set = *ns;
- for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ for (int ii = set.imports.size() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
for (const QQmlDirParser::Script &script : import->qmlDirScripts) {
@@ -736,7 +738,7 @@ bool QQmlImports::resolveType(
m_typeLoader, unqualifiedtype, version_return, type_return, &m_base, errors,
registrationType, typeRecursionDetected))
return true;
- if (nameSpace->imports.count() == 1
+ if (nameSpace->imports.size() == 1
&& !nameSpace->imports.at(0)->isLibrary
&& type_return
&& nameSpace != &m_unqualifiedset) {
@@ -868,13 +870,13 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS
});
setNeedsSorting(false);
}
- for (int i=0; i<imports.count(); ++i) {
+ for (int i=0; i<imports.size(); ++i) {
const QQmlImportInstance *import = imports.at(i);
if (import->resolveType(typeLoader, type, version_return, type_return, base,
typeRecursionDetected, registrationType, recursionRestriction, errors)) {
if (qmlCheckTypes()) {
// check for type clashes
- for (int j = i+1; j<imports.count(); ++j) {
+ for (int j = i+1; j<imports.size(); ++j) {
const QQmlImportInstance *import2 = imports.at(j);
if (import2->resolveType(typeLoader, type, version_return, nullptr, base,
nullptr, registrationType)) {
@@ -1010,9 +1012,9 @@ QString QQmlImports::resolvedUri(const QString &dir_arg, QQmlImportDatabase *dat
std::sort(paths.begin(), paths.end(), std::greater<QString>()); // Ensure subdirs preceed their parents.
QString stableRelativePath = dir;
- for (const QString &path : qAsConst(paths)) {
+ for (const QString &path : std::as_const(paths)) {
if (dir.startsWith(path)) {
- stableRelativePath = dir.mid(path.length()+1);
+ stableRelativePath = dir.mid(path.size()+1);
break;
}
}
@@ -1034,6 +1036,26 @@ QString QQmlImports::resolvedUri(const QString &dir_arg, QQmlImportDatabase *dat
return stableRelativePath;
}
+/* removes all file selector occurrences in path
+ firstPlus is the position of the initial '+' in the path
+ which we always have as we check for '+' to decide whether
+ we need to do some work at all
+*/
+static QString pathWithoutFileSelectors(QString path, // we want a copy of path
+ qsizetype firstPlus)
+{
+ do {
+ Q_ASSERT(path.at(firstPlus) == u'+');
+ const auto eos = path.size();
+ qsizetype terminatingSlashPos = firstPlus + 1;
+ while (terminatingSlashPos != eos && path.at(terminatingSlashPos) != u'/')
+ ++terminatingSlashPos;
+ path.remove(firstPlus, terminatingSlashPos - firstPlus + 1);
+ firstPlus = path.indexOf(u'+', firstPlus);
+ } while (firstPlus != -1);
+ return path;
+}
+
/*!
\internal
@@ -1080,10 +1102,42 @@ QTypeRevision QQmlImports::matchingQmldirVersion(
typedef QQmlDirComponents::const_iterator ConstIterator;
const QQmlDirComponents &components = qmldir.components();
+ QMultiHash<QString, ConstIterator> baseFileName2ConflictingComponents;
+
ConstIterator cend = components.constEnd();
for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) {
for (ConstIterator cit2 = components.constBegin(); cit2 != cit; ++cit2) {
if (cit2->typeName == cit->typeName && cit2->version == cit->version) {
+ // ugly heuristic to deal with file selectors
+ const auto comp2PotentialFileSelectorPos = cit2->fileName.indexOf(u'+');
+ const bool comp2MightHaveFileSelector = comp2PotentialFileSelectorPos != -1;
+ /* If we detect conflicting paths, we check if they agree when we remove anything looking like a
+ file selector.
+ We need to create copies of the filenames, otherwise QString::replace would modify the
+ existing file-names
+ */
+ QString compFileName1 = cit->fileName;
+ QString compFileName2 = cit2->fileName;
+ if (auto fileSelectorPos1 = compFileName1.indexOf(u'+'); fileSelectorPos1 != -1) {
+ // existing entry was file selector entry, fix it up
+ // it could also be the case that _both_ are using file selectors
+ QString baseName = comp2MightHaveFileSelector ? pathWithoutFileSelectors(compFileName2,
+ comp2PotentialFileSelectorPos)
+ : compFileName2;
+ if (pathWithoutFileSelectors(compFileName1, fileSelectorPos1) == baseName) {
+ baseFileName2ConflictingComponents.insert(baseName, cit);
+ baseFileName2ConflictingComponents.insert(baseName, cit2);
+ continue;
+ }
+ // fall through to error case
+ } else if (comp2MightHaveFileSelector) {
+ // new entry contains file selector (and we now that cit did not)
+ if (pathWithoutFileSelectors(compFileName2, comp2PotentialFileSelectorPos) == compFileName1) {
+ baseFileName2ConflictingComponents.insert(compFileName1, cit2);
+ continue;
+ }
+ // fall through to error case
+ }
// This entry clashes with a predecessor
QQmlError error;
error.setDescription(QQmlImportDatabase::tr("\"%1\" version %2.%3 is defined more than once in module \"%4\"")
@@ -1097,6 +1151,14 @@ QTypeRevision QQmlImports::matchingQmldirVersion(
addVersion(cit->version);
}
+ // ensure that all components point to the actual base URL, and let the file selectors resolve them correctly during URL resolution
+ for (auto keyIt = baseFileName2ConflictingComponents.keyBegin(); keyIt != baseFileName2ConflictingComponents.keyEnd(); ++keyIt) {
+ const QString& baseFileName = *keyIt;
+ const auto conflictingComponents = baseFileName2ConflictingComponents.values(baseFileName);
+ for (ConstIterator component: conflictingComponents)
+ component->fileName = baseFileName;
+ }
+
typedef QList<QQmlDirParser::Script>::const_iterator SConstIterator;
const QQmlDirScripts &scripts = qmldir.scripts();
@@ -1496,7 +1558,7 @@ QUrl QQmlImports::urlFromLocalFileOrQrcOrUrl(const QString &file)
QUrl url(QLatin1String(file.at(0) == Colon ? "qrc" : "") + file);
// We don't support single character schemes as those conflict with windows drive letters.
- if (url.scheme().length() < 2)
+ if (url.scheme().size() < 2)
return QUrl::fromLocalFile(file);
return url;
}
@@ -1547,7 +1609,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
auto addEnvImportPath = [this](const char *var) {
if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty(var))) {
const QStringList paths = parseEnvPath(qEnvironmentVariable(var));
- for (int ii = paths.count() - 1; ii >= 0; --ii)
+ for (int ii = paths.size() - 1; ii >= 0; --ii)
addImportPath(paths.at(ii));
}
};
@@ -1562,7 +1624,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
auto addEnvPluginPath = [this](const char *var) {
if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty(var))) {
const QStringList paths = parseEnvPath(qEnvironmentVariable(var));
- for (int ii = paths.count() - 1; ii >= 0; --ii)
+ for (int ii = paths.size() - 1; ii >= 0; --ii)
addPluginPath(paths.at(ii));
}
};
@@ -1609,7 +1671,7 @@ void QQmlImportDatabase::addPluginPath(const QString& path)
QUrl url = QUrl(path);
if (url.isRelative() || url.scheme() == QLatin1String("file")
- || (url.scheme().length() == 1 && QFile::exists(path)) ) { // windows path
+ || (url.scheme().size() == 1 && QFile::exists(path)) ) { // windows path
QDir dir = QDir(path);
filePluginPath.prepend(dir.canonicalPath());
} else {
@@ -1643,7 +1705,7 @@ void QQmlImportDatabase::addImportPath(const QString& path)
cPath = QLatin1String("qrc") + path;
cPath.replace(Backslash, Slash);
} else if (url.isRelative() ||
- (url.scheme().length() == 1 && QFile::exists(path)) ) { // windows path
+ (url.scheme().size() == 1 && QFile::exists(path)) ) { // windows path
QDir dir = QDir(path);
cPath = dir.canonicalPath();
} else {
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 31dc1b449f..5e6afe25c6 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -233,6 +233,7 @@ void QQmlIncubatorPrivate::forceCompletion(QQmlInstantiationInterrupt &i)
}
}
+
void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
{
if (!compilationUnit)
@@ -244,6 +245,20 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
// get a copy of the engine pointer as it might get reset;
QQmlEnginePrivate *enginePriv = this->enginePriv;
+ // Incubating objects takes quite a bit more stack space than our usual V4 function
+ enum { EstimatedSizeInV4Frames = 2 };
+ QV4::ExecutionEngineCallDepthRecorder<EstimatedSizeInV4Frames> callDepthRecorder(
+ compilationUnit->engine);
+ if (callDepthRecorder.hasOverflow()) {
+ QQmlError error;
+ error.setMessageType(QtCriticalMsg);
+ error.setUrl(compilationUnit->url());
+ error.setDescription(QQmlComponent::tr("Maximum call stack size exceeded."));
+ errors << error;
+ progress = QQmlIncubatorPrivate::Completed;
+ goto finishIncubate;
+ }
+
if (!vmeGuard.isOK()) {
QQmlError error;
error.setMessageType(QtInfoMsg);
diff --git a/src/qml/qml/qqmlirloader.cpp b/src/qml/qml/qqmlirloader.cpp
index 4ead4d05cb..5c322ab021 100644
--- a/src/qml/qml/qqmlirloader.cpp
+++ b/src/qml/qml/qqmlirloader.cpp
@@ -98,7 +98,7 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
object->bindings->append(b);
if (b->type() == QV4::CompiledData::Binding::Type_Script) {
functionIndices.append(b->value.compiledScriptIndex);
- b->value.compiledScriptIndex = functionIndices.count() - 1;
+ b->value.compiledScriptIndex = functionIndices.size() - 1;
QmlIR::CompiledFunctionOrExpression *foe = pool->New<QmlIR::CompiledFunctionOrExpression>();
foe->nameIndex = 0;
@@ -106,9 +106,9 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
QQmlJS::AST::ExpressionNode *expr;
if (b->stringIndex != quint32(0)) {
- const int start = output->code.length();
+ const int start = output->code.size();
const QString script = output->stringAt(b->stringIndex);
- const int length = script.length();
+ const int length = script.size();
output->code.append(script);
expr = new (pool) FakeExpression(start, length);
} else
@@ -118,7 +118,7 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
}
}
- Q_ASSERT(object->functionsAndExpressions->count == functionIndices.count());
+ Q_ASSERT(object->functionsAndExpressions->count == functionIndices.size());
for (uint i = 0; i < serializedObject->nSignals; ++i) {
const QV4::CompiledData::Signal *serializedSignal = serializedObject->signalAt(i);
@@ -174,7 +174,7 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
const QV4::CompiledData::Function *compiledFunction = unit->functionAt(*functionIdx);
functionIndices.append(*functionIdx);
- f->index = functionIndices.count() - 1;
+ f->index = functionIndices.size() - 1;
f->location = compiledFunction->location;
f->nameIndex = compiledFunction->nameIndex;
f->returnType = compiledFunction->returnType;
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 3fb1bd45cd..304c5da29a 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -176,7 +176,7 @@ public:
~QQmlJavaScriptExpressionCapture()
{
if (capture.errorString) {
- for (int ii = 0; ii < capture.errorString->count(); ++ii)
+ for (int ii = 0; ii < capture.errorString->size(); ++ii)
qWarning("%s", qPrintable(capture.errorString->at(ii)));
delete capture.errorString;
capture.errorString = nullptr;
diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h
index 051f3d67ff..4c1455b2e2 100644
--- a/src/qml/qml/qqmllist.h
+++ b/src/qml/qml/qqmllist.h
@@ -91,7 +91,7 @@ private:
reinterpret_cast<QList<T *> *>(p->data)->append(v);
}
static qsizetype qlist_count(QQmlListProperty *p) {
- return reinterpret_cast<QList<T *> *>(p->data)->count();
+ return reinterpret_cast<QList<T *> *>(p->data)->size();
}
static T *qlist_at(QQmlListProperty *p, qsizetype idx) {
return reinterpret_cast<QList<T *> *>(p->data)->at(idx);
@@ -118,7 +118,7 @@ private:
for (qsizetype i = 0; i < length; ++i)
stash.append(i == idx ? v : list->at(list, i));
list->clear(list);
- for (T *item : qAsConst(stash))
+ for (T *item : std::as_const(stash))
list->append(list, item);
} else {
stash.reserve(length - idx - 1);
@@ -149,7 +149,7 @@ private:
for (qsizetype i = 0; i < length; ++i)
stash.append(list->at(list, i));
list->clear(list);
- for (T *item : qAsConst(stash))
+ for (T *item : std::as_const(stash))
list->append(list, item);
}
};
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index cd356271a9..3ee8fee5c3 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -353,7 +353,7 @@ QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(const QV4::Functio
if (!argv[1].isString())
THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
QString fs = argv[1].toQString();
- if (fs.length())
+ if (fs.size())
format = fs.at(0).unicode();
}
int prec = 2;
@@ -415,7 +415,7 @@ ReturnedValue QQmlNumberExtension::method_fromLocaleString(const QV4::FunctionOb
}
QString ns = argv[numberIdx].toQString();
- if (!ns.length())
+ if (!ns.size())
RETURN_RESULT(QV4::Encode(Q_QNAN));
bool ok = false;
@@ -667,7 +667,9 @@ ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (const QV4::FunctionObject
LOCALE_STRING_PROPERTY(name)
LOCALE_STRING_PROPERTY(nativeLanguageName)
+#if QT_DEPRECATED_SINCE(6, 6)
QT_IGNORE_DEPRECATIONS(LOCALE_STRING_PROPERTY(nativeCountryName))
+#endif
LOCALE_STRING_PROPERTY(nativeTerritoryName)
LOCALE_STRING_PROPERTY(decimalPoint)
LOCALE_STRING_PROPERTY(groupSeparator)
@@ -714,7 +716,9 @@ QV4LocaleDataDeletable::QV4LocaleDataDeletable(QV4::ExecutionEngine *engine)
o->defineAccessorProperty(QStringLiteral("groupSeparator"), QQmlLocaleData::method_get_groupSeparator, nullptr);
o->defineAccessorProperty(QStringLiteral("decimalPoint"), QQmlLocaleData::method_get_decimalPoint, nullptr);
o->defineAccessorProperty(QStringLiteral("nativeLanguageName"), QQmlLocaleData::method_get_nativeLanguageName, nullptr);
+#if QT_DEPRECATED_SINCE(6, 6)
o->defineAccessorProperty(QStringLiteral("nativeCountryName"), QQmlLocaleData::method_get_nativeCountryName, nullptr);
+#endif
o->defineAccessorProperty(QStringLiteral("nativeTerritoryName"), QQmlLocaleData::method_get_nativeTerritoryName, nullptr);
o->defineAccessorProperty(QStringLiteral("zeroDigit"), QQmlLocaleData::method_get_zeroDigit, nullptr);
o->defineAccessorProperty(QStringLiteral("amText"), QQmlLocaleData::method_get_amText, nullptr);
@@ -866,10 +870,10 @@ ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, con
/*!
\qmlproperty string QtQml::Locale::name
- Holds the language and country of this locale as a
- string of the form "language_country", where
+ Holds the language and territory of this locale as a
+ string of the form "language_territory", where
language is a lowercase, two-letter ISO 639 language code,
- and country is an uppercase, two- or three-letter ISO 3166 country code.
+ and territory is an uppercase, two- or three-letter ISO 3166 territory code.
*/
/*!
@@ -1096,7 +1100,7 @@ ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, con
Holds a native name of the language for the locale. For example
"Schwiizertüütsch" for Swiss-German locale.
- \sa nativeCountryName
+ \sa nativeTerritoryName
*/
/*!
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 598b8c0bd1..8d9718ffb8 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -165,7 +165,9 @@ struct QQmlLocaleData : public QV4::Object
static QV4::ReturnedValue method_get_name(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue method_get_nativeLanguageName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+#if QT_DEPRECATED_SINCE(6, 6)
static QV4::ReturnedValue method_get_nativeCountryName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+#endif
static QV4::ReturnedValue method_get_nativeTerritoryName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue method_get_decimalPoint(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue method_get_groupSeparator(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index e87eed27bc..10f0a6f438 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -311,6 +311,7 @@ void QQmlMetaType::clearTypeRegistrations()
data->urlToNonFileImportType.clear();
data->metaObjectToType.clear();
data->undeletableTypes.clear();
+ data->propertyCaches.clear();
}
int QQmlMetaType::registerAutoParentFunction(const QQmlPrivate::RegisterAutoParent &function)
@@ -322,7 +323,7 @@ int QQmlMetaType::registerAutoParentFunction(const QQmlPrivate::RegisterAutoPare
data->parentFunctions.append(function.function);
- return data->parentFunctions.count() - 1;
+ return data->parentFunctions.size() - 1;
}
void QQmlMetaType::unregisterAutoParentFunction(const QQmlPrivate::AutoParentFunction &function)
@@ -390,7 +391,7 @@ static bool checkRegistration(
// There can also be types that aren't even gadgets, and there can be types for namespaces.
// We cannot check those, but namespaces should be uppercase.
- int typeNameLen = typeName.length();
+ int typeNameLen = typeName.size();
for (int ii = 0; ii < typeNameLen; ++ii) {
if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == u'_')) {
QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\""));
@@ -834,7 +835,7 @@ QQmlMetaType::RegistrationResult QQmlMetaType::registerPluginTypes(
if (!failures.isEmpty()) {
if (errors) {
- for (const QString &failure : qAsConst(failures)) {
+ for (const QString &failure : std::as_const(failures)) {
QQmlError error;
error.setDescription(failure);
errors->prepend(error);
@@ -1148,7 +1149,7 @@ QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, QTypeRevision versi
return QQmlType();
QHashedStringRef module(qualifiedName.constData(), slash);
- QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.length() - slash - 1);
+ QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.size() - slash - 1);
return qmlType(name, module, version);
}
@@ -1406,7 +1407,7 @@ void QQmlMetaType::registerMetaObjectForType(const QMetaObject *metaobject, QQml
static bool hasActiveInlineComponents(const QQmlTypePrivate *d)
{
- for (const QQmlType &ic : qAsConst(d->objectIdToICType)) {
+ for (const QQmlType &ic : std::as_const(d->objectIdToICType)) {
const QQmlTypePrivate *icPriv = ic.priv();
if (icPriv && icPriv->count() > 1)
return true;
@@ -1471,7 +1472,7 @@ QList<QString> QQmlMetaType::qmlTypeNames()
const QQmlMetaTypeDataPtr data;
QList<QString> names;
- names.reserve(data->nameToType.count());
+ names.reserve(data->nameToType.size());
QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.cbegin();
while (it != data->nameToType.cend()) {
QQmlType t(*it);
@@ -1513,7 +1514,7 @@ QList<QQmlType> QQmlMetaType::qmlSingletonTypes()
const QQmlMetaTypeDataPtr data;
QList<QQmlType> retn;
- for (const auto t : qAsConst(data->nameToType)) {
+ for (const auto t : std::as_const(data->nameToType)) {
QQmlType type(t);
if (type.isSingleton())
retn.append(type);
@@ -1525,7 +1526,7 @@ const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(const
{
const QQmlMetaTypeDataPtr data;
- for (const auto lookup : qAsConst(data->lookupCachedQmlUnit)) {
+ for (const auto lookup : std::as_const(data->lookupCachedQmlUnit)) {
if (const QQmlPrivate::CachedQmlUnit *unit = lookup(uri)) {
QString error;
if (!QV4::ExecutableCompilationUnit::verifyHeader(unit->qmlData, QDateTime(), &error)) {
diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp
index 2dd86c1c2a..ab6054349a 100644
--- a/src/qml/qml/qqmlmetatypedata.cpp
+++ b/src/qml/qml/qqmlmetatypedata.cpp
@@ -28,7 +28,7 @@ QQmlMetaTypeData::~QQmlMetaTypeData()
// This expects a "fresh" QQmlTypePrivate and adopts its reference.
void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
{
- for (int i = 0; i < types.count(); ++i) {
+ for (int i = 0; i < types.size(); ++i) {
if (!types.at(i).isValid()) {
types[i] = QQmlType(priv);
priv->index = i;
@@ -37,7 +37,7 @@ void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
}
}
types.append(QQmlType(priv));
- priv->index = types.count() - 1;
+ priv->index = types.size() - 1;
priv->release();
}
@@ -86,7 +86,7 @@ bool QQmlMetaTypeData::registerModuleTypes(const QString &uri)
QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCacheForVersion(
int index, QTypeRevision version) const
{
- return (index < typePropertyCaches.length())
+ return (index < typePropertyCaches.size())
? typePropertyCaches.at(index).value(version)
: QQmlPropertyCache::ConstPtr();
}
@@ -94,14 +94,14 @@ QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCacheForVersion(
void QQmlMetaTypeData::setPropertyCacheForVersion(int index, QTypeRevision version,
const QQmlPropertyCache::ConstPtr &cache)
{
- if (index >= typePropertyCaches.length())
+ if (index >= typePropertyCaches.size())
typePropertyCaches.resize(index + 1);
typePropertyCaches[index][version] = cache;
}
void QQmlMetaTypeData::clearPropertyCachesForVersion(int index)
{
- if (index < typePropertyCaches.length())
+ if (index < typePropertyCaches.size())
typePropertyCaches[index].clear();
}
@@ -167,13 +167,13 @@ QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCache(
QQmlPropertyCache::ConstPtr raw = propertyCache(type.metaObject(), combinedVersion);
QQmlPropertyCache::Ptr copied;
- for (int ii = 0; ii < types.count(); ++ii) {
+ for (int ii = 0; ii < types.size(); ++ii) {
const QQmlType &currentType = types.at(ii);
if (!currentType.isValid())
continue;
QTypeRevision rev = currentType.metaObjectRevision();
- int moIndex = types.count() - 1 - ii;
+ int moIndex = types.size() - 1 - ii;
if (raw->allowedRevision(moIndex) != rev) {
if (copied.isNull()) {
diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp
index e36be3840e..e7b8799f82 100644
--- a/src/qml/qml/qqmlnotifier.cpp
+++ b/src/qml/qml/qqmlnotifier.cpp
@@ -89,10 +89,10 @@ void QQmlNotifierEndpoint::connect(QObject *source, int sourceSignal, QQmlEngine
QString sourceName;
QDebug(&sourceName) << source;
- sourceName = sourceName.left(sourceName.length() - 1);
+ sourceName = sourceName.left(sourceName.size() - 1);
QString engineName;
QDebug(&engineName).nospace() << engine;
- engineName = engineName.left(engineName.length() - 1);
+ engineName = engineName.left(engineName.size() - 1);
qFatal("QQmlEngine: Illegal attempt to connect to %s that is in"
" a different thread than the QML engine %s.", qPrintable(sourceName),
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 05951edfbc..64d1f79044 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1408,16 +1408,24 @@ bool QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
void *argv[] = { &bindable };
// allow interception
target->metaObject()->metacall(target, QMetaObject::BindableProperty, index, argv);
- bindable.setBinding(qmlBinding);
+ const bool success = bindable.setBinding(qmlBinding);
+
+ // Only pop_front after setting the binding as the bindings are refcounted.
sharedState->allQPropertyBindings.pop_front();
- if (auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) {
- auto qmlBindingPriv = static_cast<QQmlPropertyBinding *>(priv);
- auto jsExpression = qmlBindingPriv->jsExpression();
- const bool canRemove = !qmlBinding.error().hasError() && !qmlBindingPriv->hasDependencies()
- && !jsExpression->hasUnresolvedNames();
- if (canRemove)
- bindable.takeBinding();
+
+ // If the binding was actually not set, it's deleted now.
+ if (success) {
+ if (auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) {
+ auto qmlBindingPriv = static_cast<QQmlPropertyBinding *>(priv);
+ auto jsExpression = qmlBindingPriv->jsExpression();
+ const bool canRemove = !qmlBinding.error().hasError()
+ && !qmlBindingPriv->hasDependencies()
+ && !jsExpression->hasUnresolvedNames();
+ if (canRemove)
+ bindable.takeBinding();
+ }
}
+
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
return false;
}
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp
index b6ea0ee2e6..cf51286677 100644
--- a/src/qml/qml/qqmlopenmetaobject.cpp
+++ b/src/qml/qml/qqmlopenmetaobject.cpp
@@ -59,19 +59,19 @@ int QQmlOpenMetaObjectType::signalOffset() const
int QQmlOpenMetaObjectType::propertyCount() const
{
- return d->names.count();
+ return d->names.size();
}
QByteArray QQmlOpenMetaObjectType::propertyName(int idx) const
{
- Q_ASSERT(idx >= 0 && idx < d->names.count());
+ Q_ASSERT(idx >= 0 && idx < d->names.size());
return d->mob.property(idx).name();
}
void QQmlOpenMetaObjectType::createProperties(const QVector<QByteArray> &names)
{
- for (int i = 0; i < names.count(); ++i) {
+ for (int i = 0; i < names.size(); ++i) {
const QByteArray &name = names.at(i);
const int id = d->mob.propertyCount();
d->mob.addSignal("__" + QByteArray::number(id) + "()");
@@ -114,7 +114,7 @@ int QQmlOpenMetaObjectType::createProperty(const QByteArray &name)
void QQmlOpenMetaObjectType::propertyCreated(int id, QMetaPropertyBuilder &builder)
{
- if (d->referers.count())
+ if (d->referers.size())
(*d->referers.begin())->propertyCreated(id, builder);
}
@@ -163,13 +163,13 @@ public:
};
inline void setPropertyValue(int idx, const QVariant &value) {
- if (data.count() <= idx)
+ if (data.size() <= idx)
data.resize(idx + 1);
data[idx].setValue(value);
}
inline Property &propertyRef(int idx) {
- if (data.count() <= idx)
+ if (data.size() <= idx)
data.resize(idx + 1);
Property &prop = data[idx];
if (!prop.valueSet)
@@ -188,7 +188,7 @@ public:
}
inline bool hasProperty(int idx) const {
- if (idx >= data.count())
+ if (idx >= data.size())
return false;
return data[idx].valueSet;
}
@@ -270,7 +270,7 @@ int QQmlOpenMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void *
propertyRead(propId);
*reinterpret_cast<QVariant *>(a[0]) = d->propertyValue(propId);
} else if (c == QMetaObject::WriteProperty) {
- if (propId >= d->data.count() || d->data.at(propId).value() != *reinterpret_cast<QVariant *>(a[0])) {
+ if (propId >= d->data.size() || d->data.at(propId).value() != *reinterpret_cast<QVariant *>(a[0])) {
propertyWrite(propId);
d->setPropertyValue(propId, propertyWriteValue(propId, *reinterpret_cast<QVariant *>(a[0])));
propertyWritten(propId);
@@ -375,7 +375,7 @@ void QQmlOpenMetaObject::setValues(const QHash<QByteArray, QVariant> &values, bo
d->type->createProperties(missingProperties);
d->dropPropertyCache();
- for (const QByteArray &name : qAsConst(missingProperties))
+ for (const QByteArray &name : std::as_const(missingProperties))
checkedSetValue(names[name], values[name], force);
}
@@ -461,12 +461,12 @@ QVariant QQmlOpenMetaObject::initialValue(int)
int QQmlOpenMetaObject::count() const
{
- return d->type->d->names.count();
+ return d->type->d->names.size();
}
QByteArray QQmlOpenMetaObject::name(int idx) const
{
- Q_ASSERT(idx >= 0 && idx < d->type->d->names.count());
+ Q_ASSERT(idx >= 0 && idx < d->type->d->names.size());
return d->type->d->mob.property(idx).name();
}
diff --git a/src/qml/qml/qqmlpluginimporter.cpp b/src/qml/qml/qqmlpluginimporter.cpp
index 62b3a4b4a4..0b14d1f561 100644
--- a/src/qml/qml/qqmlpluginimporter.cpp
+++ b/src/qml/qml/qqmlpluginimporter.cpp
@@ -91,7 +91,7 @@ static QStringList versionUriList(const QString &uri, QTypeRevision version)
{
QStringList result;
for (int mode = QQmlImports::FullyVersioned; mode <= QQmlImports::Unversioned; ++mode) {
- int index = uri.length();
+ int index = uri.size();
do {
QString versionUri = uri;
versionUri.insert(index, QQmlImports::versionString(
@@ -129,7 +129,7 @@ static bool unloadPlugin(const std::pair<const QString, QmlPlugin> &plugin)
void qmlClearEnginePlugins()
{
PluginMapPtr plugins(qmlPluginsById());
- for (const auto &plugin : qAsConst(*plugins))
+ for (const auto &plugin : std::as_const(*plugins))
unloadPlugin(plugin);
plugins->clear();
}
@@ -395,7 +395,7 @@ QString QQmlPluginImporter::resolvePlugin(const QString &qmldirPluginPath, const
if (!qmldirPluginPathIsRelative)
searchPaths.prepend(qmldirPluginPath);
- for (const QString &pluginPath : qAsConst(searchPaths)) {
+ for (const QString &pluginPath : std::as_const(searchPaths)) {
QString resolvedBasePath;
if (pluginPath == QLatin1String(".")) {
if (qmldirPluginPathIsRelative && !qmldirPluginPath.isEmpty()
@@ -501,7 +501,7 @@ bool QQmlPluginImporter::populatePluginDataVector(QVector<StaticPluginData> &res
QTypeRevision QQmlPluginImporter::importPlugins() {
const auto qmldirPlugins = qmldir->plugins();
- const int qmldirPluginCount = qmldirPlugins.count();
+ const int qmldirPluginCount = qmldirPlugins.size();
QTypeRevision importVersion = version;
// If the path contains a version marker or if we have more than one plugin,
@@ -550,7 +550,7 @@ QTypeRevision QQmlPluginImporter::importPlugins() {
return QTypeRevision();
for (const QString &versionUri : versionUris) {
- for (const StaticPluginData &pair : qAsConst(pluginPairs)) {
+ for (const StaticPluginData &pair : std::as_const(pluginPairs)) {
for (const QJsonValueConstRef metaTagUri : pair.uriList) {
if (versionUri == metaTagUri.toString()) {
staticPluginsFound++;
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index f2b4cc85ed..4cf57a9ae9 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -32,6 +32,7 @@
#include <cmath>
#include <QtQml/QQmlPropertyMap>
#include <QtCore/private/qproperty_p.h>
+#include <QtCore/qsequentialiterable.h>
Q_DECLARE_METATYPE(QList<int>)
Q_DECLARE_METATYPE(QList<qreal>)
@@ -248,7 +249,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
if (path.isEmpty()) return;
// Everything up to the last property must be an "object type" property
- for (int ii = 0; ii < path.count() - 1; ++ii) {
+ for (int ii = 0; ii < path.size() - 1; ++ii) {
const QStringView &pathName = path.at(ii);
// Types must begin with an uppercase letter (see checkRegistration()
@@ -264,7 +265,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
currentObject = qmlAttachedPropertiesObject(currentObject, func);
if (!currentObject) return; // Something is broken with the attachable type
} else if (r.importNamespace) {
- if (++ii == path.count())
+ if (++ii == path.size())
return; // No type following the namespace
// TODO: Do we really _not_ want to query the namespaced types here?
@@ -320,7 +321,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
return; // Not an object property
}
- if (ii == (path.count() - 2) && QQmlMetaType::isValueType(property->propType())) {
+ if (ii == (path.size() - 2) && QQmlMetaType::isValueType(property->propType())) {
// We're now at a value type property
const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForValueType(property->propType());
if (!valueTypeMetaObject) return; // Not a value type
@@ -374,7 +375,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
auto findChangeSignal = [&](QStringView signalName) {
const QString changed = QStringLiteral("Changed");
if (signalName.endsWith(changed)) {
- const QStringView propName = signalName.first(signalName.length() - changed.length());
+ const QStringView propName = signalName.first(signalName.size() - changed.size());
const QQmlPropertyData *d = ddata->propertyCache->property(propName, currentObject, context);
while (d && d->isFunction())
d = ddata->propertyCache->overrideData(d);
@@ -392,7 +393,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
if (QmlIR::IRBuilder::isSignalPropertyName(terminalString)) {
QString signalName = terminalString.mid(2);
int firstNon_;
- int length = signalName.length();
+ int length = signalName.size();
for (firstNon_ = 0; firstNon_ < length; ++firstNon_)
if (signalName.at(firstNon_) != u'_')
break;
@@ -753,7 +754,7 @@ QString QQmlProperty::name() const
} else if (type() & SignalProperty) {
// ### Qt7: Return the original signal name here. Do not prepend "on"
QString name = QStringLiteral("on") + d->core.name(d->object);
- for (int i = 2, end = name.length(); i != end; ++i) {
+ for (int i = 2, end = name.size(); i != end; ++i) {
const QChar c = name.at(i);
if (c != u'_') {
name[i] = c.toUpper();
@@ -1451,7 +1452,7 @@ bool QQmlPropertyPrivate::write(
} else if (variantMetaType == QMetaType::fromType<QList<QObject *>>()) {
const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value);
- for (qsizetype ii = 0; ii < list.count(); ++ii) {
+ for (qsizetype ii = 0; ii < list.size(); ++ii) {
QObject *o = list.at(ii);
if (o && !QQmlMetaObject::canConvert(o, valueMetaObject))
o = nullptr;
@@ -1505,40 +1506,46 @@ bool QQmlPropertyPrivate::write(
}
if (!ok) {
// the only other options are that they are assigning a single value
- // to a sequence type property (eg, an int to a QList<int> property).
- // or that we encountered an interface type
+ // or a QVariantList 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 (variantMetaType == QMetaType::fromType<int>()
- && propertyMetaType == QMetaType::fromType<QList<int>>()) {
- QList<int> list;
- list << value.toInt();
- v = QVariant::fromValue<QList<int> >(list);
- ok = true;
- } else if ((variantMetaType == QMetaType::fromType<double>()
- || variantMetaType == QMetaType::fromType<int>())
- && (propertyMetaType == QMetaType::fromType<QList<qreal>>())) {
- QList<qreal> list;
- list << value.toReal();
- v = QVariant::fromValue<QList<qreal> >(list);
- ok = true;
- } else if (variantMetaType == QMetaType::fromType<bool>()
- && propertyMetaType == QMetaType::fromType<QList<bool>>()) {
- QList<bool> list;
- list << value.toBool();
- v = QVariant::fromValue<QList<bool> >(list);
- ok = true;
- } else if (variantMetaType == QMetaType::fromType<QString>()
- && propertyMetaType == QMetaType::fromType<QList<QString>>()) {
- QList<QString> list;
- list << value.toString();
- v = QVariant::fromValue<QList<QString> >(list);
- ok = true;
- } else if (variantMetaType == QMetaType::fromType<QString>()
- && propertyMetaType == QMetaType::fromType<QStringList>()) {
- QStringList list;
- list << value.toString();
- v = QVariant::fromValue<QStringList>(list);
- ok = true;
+ QSequentialIterable iterable;
+ v = QVariant(propertyMetaType);
+ if (QMetaType::view(
+ propertyMetaType, v.data(),
+ QMetaType::fromType<QSequentialIterable>(),
+ &iterable)) {
+ const QMetaSequence metaContainer = iterable.metaContainer();
+ if (metaContainer.canAddValueAtEnd()) {
+ const QMetaType elementMetaType = iterable.valueMetaType();
+ void *container = iterable.mutableIterable();
+ if (variantMetaType == elementMetaType) {
+ metaContainer.addValueAtEnd(container, value.constData());
+ ok = true;
+ } else if (variantMetaType == QMetaType::fromType<QVariantList>()) {
+ const QVariantList list = value.value<QVariantList>();
+ for (const QVariant &valueElement : list) {
+ if (valueElement.metaType() == elementMetaType) {
+ metaContainer.addValueAtEnd(
+ container, valueElement.constData());
+ } else {
+ QVariant converted(elementMetaType);
+ QMetaType::convert(
+ valueElement.metaType(), valueElement.constData(),
+ elementMetaType, converted.data());
+ metaContainer.addValueAtEnd(
+ container, converted.constData());
+ }
+ }
+ ok = true;
+ } else {
+ QVariant converted = value;
+ if (converted.convert(elementMetaType)) {
+ metaContainer.addValueAtEnd(container, converted.constData());
+ ok = true;
+ }
+ }
+ }
}
}
@@ -1788,7 +1795,7 @@ QMetaMethod QQmlPropertyPrivate::findSignalByName(const QMetaObject *mo, const Q
// If no signal is found, but the signal is of the form "onBlahChanged",
// return the notify signal for the property "Blah"
if (name.endsWith("Changed")) {
- QByteArray propName = name.mid(0, name.length() - 7);
+ QByteArray propName = name.mid(0, name.size() - 7);
int propIdx = mo->indexOfProperty(propName.constData());
if (propIdx >= 0) {
QMetaProperty prop = mo->property(propIdx);
diff --git a/src/qml/qml/qqmlproperty.h b/src/qml/qml/qqmlproperty.h
index 4d4e1d0ebf..0878034bab 100644
--- a/src/qml/qml/qqmlproperty.h
+++ b/src/qml/qml/qqmlproperty.h
@@ -56,7 +56,7 @@ public:
QQmlProperty &operator=(const QQmlProperty &);
QQmlProperty(QQmlProperty &&other) noexcept : d(std::exchange(other.d, nullptr)) {}
- QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QQmlProperty);
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QQmlProperty)
void swap(QQmlProperty &other) noexcept { qt_ptr_swap(d, other.d); }
bool operator==(const QQmlProperty &) const;
diff --git a/src/qml/qml/qqmlpropertybinding.cpp b/src/qml/qml/qqmlpropertybinding.cpp
index d55f1021f2..24fd48ffae 100644
--- a/src/qml/qml/qqmlpropertybinding.cpp
+++ b/src/qml/qml/qqmlpropertybinding.cpp
@@ -131,7 +131,8 @@ QUntypedPropertyBinding QQmlPropertyBinding::createFromBoundFunction(const QQmlP
void QQmlPropertyBindingJS::expressionChanged()
{
- if (!asBinding()->propertyDataPtr)
+ auto binding = asBinding();
+ if (!binding->propertyDataPtr)
return;
const auto currentTag = m_error.tag();
if (currentTag == InEvaluationLoop) {
@@ -151,8 +152,9 @@ void QQmlPropertyBindingJS::expressionChanged()
return;
}
m_error.setTag(InEvaluationLoop);
- asBinding()->evaluateRecursive();
- asBinding()->notifyRecursive();
+ PendingBindingObserverList bindingObservers;
+ binding->evaluateRecursive(bindingObservers);
+ binding->notifyNonRecursive(bindingObservers);
m_error.setTag(NoTag);
}
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index c61254ae56..cd6ca93356 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -15,8 +15,8 @@
#include <QtCore/qdebug.h>
#include <QtCore/QCryptographicHash>
+#include <QtCore/private/qtools_p.h>
-#include <ctype.h> // for toupper
#include <limits.h>
#include <algorithm>
@@ -166,9 +166,9 @@ QQmlPropertyCache::Ptr QQmlPropertyCache::copy(const QQmlMetaObjectPointer &mo,
QQmlPropertyCache::Ptr cache = QQmlPropertyCache::Ptr(
new QQmlPropertyCache(mo), QQmlPropertyCache::Ptr::Adopt);
cache->_parent.reset(this);
- cache->propertyIndexCacheStart = propertyIndexCache.count() + propertyIndexCacheStart;
- cache->methodIndexCacheStart = methodIndexCache.count() + methodIndexCacheStart;
- cache->signalHandlerIndexCacheStart = signalHandlerIndexCache.count() + signalHandlerIndexCacheStart;
+ cache->propertyIndexCacheStart = propertyIndexCache.size() + propertyIndexCacheStart;
+ cache->methodIndexCacheStart = methodIndexCache.size() + methodIndexCacheStart;
+ cache->signalHandlerIndexCacheStart = signalHandlerIndexCache.size() + signalHandlerIndexCacheStart;
cache->stringCache.linkAndReserve(stringCache, reserve);
cache->allowedRevisionCache = allowedRevisionCache;
cache->_defaultPropertyName = _defaultPropertyName;
@@ -214,7 +214,7 @@ void QQmlPropertyCache::appendProperty(const QString &name, QQmlPropertyData::Fl
if (overrideResult == InvalidOverride)
return;
- int index = propertyIndexCache.count();
+ int index = propertyIndexCache.size();
propertyIndexCache.append(data);
setNamedProperty(name, index + propertyOffset(), propertyIndexCache.data() + index,
@@ -235,7 +235,7 @@ void QQmlPropertyCache::appendSignal(const QString &name, QQmlPropertyData::Flag
handler.m_flags.setIsSignalHandler(true);
if (types) {
- const auto argumentCount = names.length();
+ const auto argumentCount = names.size();
QQmlPropertyCacheMethodArguments *args = createArgumentsObject(argumentCount, names);
new (args->types) QMetaType; // Invalid return type
::memcpy(args->types + 1, types, argumentCount * sizeof(QMetaType));
@@ -246,10 +246,10 @@ void QQmlPropertyCache::appendSignal(const QString &name, QQmlPropertyData::Flag
if (overrideResult == InvalidOverride)
return;
- int methodIndex = methodIndexCache.count();
+ int methodIndex = methodIndexCache.size();
methodIndexCache.append(data);
- int signalHandlerIndex = signalHandlerIndexCache.count();
+ int signalHandlerIndex = signalHandlerIndexCache.size();
signalHandlerIndexCache.append(handler);
QString handlerName = QLatin1String("on") + name;
@@ -267,7 +267,7 @@ void QQmlPropertyCache::appendMethod(const QString &name, QQmlPropertyData::Flag
const QList<QByteArray> &names,
const QVector<QMetaType> &parameterTypes)
{
- int argumentCount = names.count();
+ int argumentCount = names.size();
QQmlPropertyData data;
data.setPropType(returnType);
@@ -283,7 +283,7 @@ void QQmlPropertyCache::appendMethod(const QString &name, QQmlPropertyData::Flag
new (args->types + ii + 1) QMetaType(parameterTypes.at(ii));
data.setArguments(args);
- int methodIndex = methodIndexCache.count();
+ int methodIndex = methodIndexCache.size();
methodIndexCache.append(data);
setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex,
@@ -435,8 +435,8 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
data->load(m);
- Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
- data->setMetaObjectOffset(allowedRevisionCache.count() - 1);
+ Q_ASSERT((allowedRevisionCache.size() - 1) < Q_INT16_MAX);
+ data->setMetaObjectOffset(allowedRevisionCache.size() - 1);
if (data->isSignal()) {
sigdata = &signalHandlerIndexCache[signalHandlerIndex - signalHandlerIndexCacheStart];
@@ -473,7 +473,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
QVarLengthArray<char, 128> str(length+3);
str[0] = 'o';
str[1] = 'n';
- str[2] = toupper(rawName[0]);
+ str[2] = QtMiscUtils::toAsciiUpper(rawName[0]);
if (length > 1)
memcpy(&str[3], &rawName[1], length - 1);
str[length + 2] = '\0';
@@ -516,8 +516,8 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
data->load(p);
data->setTypeVersion(typeVersion);
- Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
- data->setMetaObjectOffset(allowedRevisionCache.count() - 1);
+ Q_ASSERT((allowedRevisionCache.size() - 1) < Q_INT16_MAX);
+ data->setMetaObjectOffset(allowedRevisionCache.size() - 1);
QQmlPropertyData *old = nullptr;
@@ -591,9 +591,9 @@ void QQmlPropertyCache::invalidate(const QMetaObject *metaObject)
int reserve = pc + mc + sc;
if (parent()) {
- propertyIndexCacheStart = parent()->propertyIndexCache.count() + parent()->propertyIndexCacheStart;
- methodIndexCacheStart = parent()->methodIndexCache.count() + parent()->methodIndexCacheStart;
- signalHandlerIndexCacheStart = parent()->signalHandlerIndexCache.count() + parent()->signalHandlerIndexCacheStart;
+ propertyIndexCacheStart = parent()->propertyIndexCache.size() + parent()->propertyIndexCacheStart;
+ methodIndexCacheStart = parent()->methodIndexCache.size() + parent()->methodIndexCacheStart;
+ signalHandlerIndexCacheStart = parent()->signalHandlerIndexCache.size() + parent()->signalHandlerIndexCacheStart;
stringCache.linkAndReserve(parent()->stringCache, reserve);
append(metaObject, QTypeRevision());
} else {
@@ -743,7 +743,7 @@ QString QQmlPropertyCache::signalParameterStringForJS(QV4::ExecutionEngine *engi
const QSet<QString> &illegalNames = engine->illegalNames();
QString parameters;
- for (int i = 0; i < parameterNameList.count(); ++i) {
+ for (int i = 0; i < parameterNameList.size(); ++i) {
if (i > 0)
parameters += QLatin1Char(',');
const QByteArray &param = parameterNameList.at(i);
@@ -976,13 +976,13 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) const
for (StringCache::ConstIterator iter = stringCache.begin(), cend = stringCache.end(); iter != cend; ++iter)
Insert::in(this, properties, methods, iter, iter.value().second);
- Q_ASSERT(properties.count() == propertyIndexCache.count());
- Q_ASSERT(methods.count() == methodIndexCache.count());
+ Q_ASSERT(properties.size() == propertyIndexCache.size());
+ Q_ASSERT(methods.size() == methodIndexCache.size());
std::sort(properties.begin(), properties.end(), Sort::lt);
std::sort(methods.begin(), methods.end(), Sort::lt);
- for (int ii = 0; ii < properties.count(); ++ii) {
+ for (int ii = 0; ii < properties.size(); ++ii) {
const QQmlPropertyData *data = properties.at(ii).second;
int notifierId = -1;
@@ -998,9 +998,10 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) const
property.setWritable(data->isWritable());
property.setResettable(data->isResettable());
property.setBindable(data->isBindable());
+ property.setAlias(data->isAlias());
}
- for (int ii = 0; ii < methods.count(); ++ii) {
+ for (int ii = 0; ii < methods.size(); ++ii) {
const QQmlPropertyData *data = methods.at(ii).second;
QByteArray returnType;
@@ -1014,7 +1015,7 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) const
QQmlPropertyCacheMethodArguments *arguments = nullptr;
if (data->hasArguments()) {
arguments = data->arguments();
- for (int ii = 0, end = arguments->names ? arguments->names->length() : 0;
+ for (int ii = 0, end = arguments->names ? arguments->names->size() : 0;
ii < end; ++ii) {
if (ii != 0)
signature.append(',');
@@ -1039,11 +1040,11 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) const
method.setReturnType(returnType);
}
- for (int ii = 0; ii < enumCache.count(); ++ii) {
+ for (int ii = 0; ii < enumCache.size(); ++ii) {
const QQmlEnumData &enumData = enumCache.at(ii);
QMetaEnumBuilder enumeration = builder.addEnumerator(enumData.name.toUtf8());
enumeration.setIsScoped(true);
- for (int jj = 0; jj < enumData.values.count(); ++jj) {
+ for (int jj = 0; jj < enumData.values.size(); ++jj) {
const QQmlEnumValue &value = enumData.values.at(jj);
enumeration.addKey(value.namedValue.toUtf8(), value.value);
}
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 681945d5f8..1ba23a15e3 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -343,7 +343,7 @@ inline const QQmlPropertyData *QQmlPropertyCache::property(int index) const
inline const QQmlPropertyData *QQmlPropertyCache::method(int index) const
{
- if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.count()))
+ if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.size()))
return nullptr;
if (index < methodIndexCacheStart)
@@ -358,7 +358,7 @@ inline const QQmlPropertyData *QQmlPropertyCache::method(int index) const
*/
inline const QQmlPropertyData *QQmlPropertyCache::signal(int index) const
{
- if (index < 0 || index >= (signalHandlerIndexCacheStart + signalHandlerIndexCache.count()))
+ if (index < 0 || index >= (signalHandlerIndexCacheStart + signalHandlerIndexCache.size()))
return nullptr;
if (index < signalHandlerIndexCacheStart)
@@ -371,7 +371,7 @@ inline const QQmlPropertyData *QQmlPropertyCache::signal(int index) const
inline QQmlEnumData *QQmlPropertyCache::qmlEnum(int index) const
{
- if (index < 0 || index >= enumCache.count())
+ if (index < 0 || index >= enumCache.size())
return nullptr;
return const_cast<QQmlEnumData *>(&enumCache.at(index));
@@ -379,7 +379,7 @@ inline QQmlEnumData *QQmlPropertyCache::qmlEnum(int index) const
inline int QQmlPropertyCache::methodIndexToSignalIndex(int index) const
{
- if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.count()))
+ if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.size()))
return index;
if (index < methodIndexCacheStart)
@@ -419,7 +419,7 @@ bool QQmlPropertyCache::isAllowedInRevision(const QQmlPropertyData *data) const
return true;
Q_ASSERT(offset >= 0);
- Q_ASSERT(offset < allowedRevisionCache.length());
+ Q_ASSERT(offset < allowedRevisionCache.size());
const QTypeRevision allowed = allowedRevisionCache[offset];
if (requested.hasMajorVersion()) {
@@ -434,7 +434,7 @@ bool QQmlPropertyCache::isAllowedInRevision(const QQmlPropertyData *data) const
int QQmlPropertyCache::propertyCount() const
{
- return propertyIndexCacheStart + propertyIndexCache.count();
+ return propertyIndexCacheStart + propertyIndexCache.size();
}
int QQmlPropertyCache::propertyOffset() const
@@ -444,7 +444,7 @@ int QQmlPropertyCache::propertyOffset() const
int QQmlPropertyCache::methodCount() const
{
- return methodIndexCacheStart + methodIndexCache.count();
+ return methodIndexCacheStart + methodIndexCache.size();
}
int QQmlPropertyCache::methodOffset() const
@@ -454,7 +454,7 @@ int QQmlPropertyCache::methodOffset() const
int QQmlPropertyCache::signalCount() const
{
- return signalHandlerIndexCacheStart + signalHandlerIndexCache.count();
+ return signalHandlerIndexCacheStart + signalHandlerIndexCache.size();
}
int QQmlPropertyCache::signalOffset() const
@@ -464,7 +464,7 @@ int QQmlPropertyCache::signalOffset() const
int QQmlPropertyCache::qmlEnumCount() const
{
- return enumCache.count();
+ return enumCache.size();
}
bool QQmlPropertyCache::callJSFactoryMethod(QObject *object, void **args) const
diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp
index c6e628e02f..4bc903c22e 100644
--- a/src/qml/qml/qqmlpropertycachecreator.cpp
+++ b/src/qml/qml/qqmlpropertycachecreator.cpp
@@ -58,7 +58,7 @@ QByteArray QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(const QUrl &ur
if (lastSlash <= -1)
return QByteArray();
// ### this might not be correct for .ui.qml files
- const QStringView nameBase = QStringView{path}.mid(lastSlash + 1, path.length() - lastSlash - 5);
+ const QStringView nameBase = QStringView{path}.mid(lastSlash + 1, path.size() - 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();
@@ -94,8 +94,10 @@ bool QQmlBindingInstantiationContext::resolveInstantiatingProperty()
return true;
}
+ if (!referencingObjectPropertyCache)
+ return false;
+
Q_ASSERT(referencingObjectIndex >= 0);
- Q_ASSERT(referencingObjectPropertyCache);
Q_ASSERT(instantiatingBinding->propertyNameIndex != 0);
bool notInRevision = false;
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index 6d0e5925a8..1901688174 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -720,8 +720,15 @@ inline QMetaType QQmlPropertyCacheCreator<ObjectContainer>::metaTypeForParameter
QQmlType::AnyRegistrationType, &selfReference))
return QMetaType();
- if (!qmltype.isComposite())
- return qmltype.typeId();
+ if (!qmltype.isComposite()) {
+ const QMetaType typeId = qmltype.typeId();
+ if (!typeId.isValid() && qmltype.isInlineComponentType()) {
+ const int objectId = qmltype.inlineComponentId();
+ return objectContainer->typeIdsForComponent(objectId).id;
+ } else {
+ return typeId;
+ }
+ }
if (selfReference)
return objectContainer->typeIdsForComponent().id;
@@ -823,7 +830,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertie
do {
QVector<int> pendingObjects;
- for (int objectIndex: qAsConst(objectsWithAliases)) {
+ for (int objectIndex: std::as_const(objectsWithAliases)) {
const CompiledObject &object = *objectContainer->objectAt(objectIndex);
if (allAliasTargetsExist(object)) {
@@ -919,10 +926,16 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor
}
const auto referencedType = typeRef->type();
- if (referencedType.isValid())
+ if (referencedType.isValid()) {
*type = referencedType.typeId();
- else
+ if (!type->isValid() && referencedType.isInlineComponentType()) {
+ int objectId = referencedType.inlineComponentId();
+ *type = objectContainer->typeIdsForComponent(objectId).id;
+ Q_ASSERT(type->isValid());
+ }
+ } else {
*type = typeRef->compilationUnit()->typeIds.id;
+ }
*version = typeRef->version();
@@ -1000,8 +1013,8 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesTo
QQmlPropertyCache::Ptr propertyCache = propertyCaches->ownAt(objectIndex);
Q_ASSERT(propertyCache);
- int effectiveSignalIndex = propertyCache->signalHandlerIndexCacheStart + propertyCache->propertyIndexCache.count();
- int effectivePropertyIndex = propertyCache->propertyIndexCacheStart + propertyCache->propertyIndexCache.count();
+ int effectiveSignalIndex = propertyCache->signalHandlerIndexCacheStart + propertyCache->propertyIndexCache.size();
+ int effectivePropertyIndex = propertyCache->propertyIndexCacheStart + propertyCache->propertyIndexCache.size();
int aliasIndex = 0;
auto alias = object.aliasesBegin();
diff --git a/src/qml/qml/qqmlpropertycachevector_p.h b/src/qml/qml/qqmlpropertycachevector_p.h
index 71a4896315..6386795086 100644
--- a/src/qml/qml/qqmlpropertycachevector_p.h
+++ b/src/qml/qml/qqmlpropertycachevector_p.h
@@ -36,10 +36,10 @@ public:
return data.resize(size);
}
- int count() const { return data.count(); }
+ int count() const { return data.size(); }
void clear()
{
- for (int i = 0; i < data.count(); ++i) {
+ for (int i = 0; i < data.size(); ++i) {
const auto &cache = data.at(i);
if (cache.isT2()) {
if (QQmlPropertyCache *data = cache.asT2())
diff --git a/src/qml/qml/qqmlpropertydata_p.h b/src/qml/qml/qqmlpropertydata_p.h
index 83ae5ff9a8..dd9aa21c7b 100644
--- a/src/qml/qml/qqmlpropertydata_p.h
+++ b/src/qml/qml/qqmlpropertydata_p.h
@@ -240,7 +240,6 @@ public:
{
Q_ASSERT(idx >= std::numeric_limits<qint16>::min());
Q_ASSERT(idx <= std::numeric_limits<qint16>::max());
- Q_ASSERT(idx != m_coreIndex);
m_overrideIndex = qint16(idx);
}
diff --git a/src/qml/qml/qqmlpropertyresolver.cpp b/src/qml/qml/qqmlpropertyresolver.cpp
index 6be2c205ed..ff29c38997 100644
--- a/src/qml/qml/qqmlpropertyresolver.cpp
+++ b/src/qml/qml/qqmlpropertyresolver.cpp
@@ -44,7 +44,7 @@ const QQmlPropertyData *QQmlPropertyResolver::signal(const QString &name, bool *
}
if (name.endsWith(QLatin1String("Changed"))) {
- QString propName = name.mid(0, name.length() - static_cast<int>(strlen("Changed")));
+ QString propName = name.mid(0, name.size() - static_cast<int>(strlen("Changed")));
d = property(propName, notInRevision);
if (d)
diff --git a/src/qml/qml/qqmlpropertyvalidator_p.h b/src/qml/qml/qqmlpropertyvalidator_p.h
index bd81b75e78..e1154347ec 100644
--- a/src/qml/qml/qqmlpropertyvalidator_p.h
+++ b/src/qml/qml/qqmlpropertyvalidator_p.h
@@ -32,6 +32,9 @@ public:
QVector<QQmlError> validate();
+ QQmlPropertyCache::ConstPtr rootPropertyCache() const { return propertyCaches.at(0); }
+ QUrl documentSourceUrl() const { return compilationUnit->url(); }
+
private:
QVector<QQmlError> validateObject(
int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding,
diff --git a/src/qml/qml/qqmlproxymetaobject.cpp b/src/qml/qml/qqmlproxymetaobject.cpp
index 9a5347bd74..ad67856c02 100644
--- a/src/qml/qml/qqmlproxymetaobject.cpp
+++ b/src/qml/qml/qqmlproxymetaobject.cpp
@@ -32,8 +32,8 @@ QQmlProxyMetaObject::~QQmlProxyMetaObject()
QObject *QQmlProxyMetaObject::getProxy(int index)
{
if (!proxies) {
- proxies = new QObject *[metaObjects->count()];
- ::memset(proxies, 0, sizeof(QObject *) * metaObjects->count());
+ proxies = new QObject *[metaObjects->size()];
+ ::memset(proxies, 0, sizeof(QObject *) * metaObjects->size());
}
if (!proxies[index]) {
@@ -71,7 +71,7 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void
if (id < metaObjects->constLast().propertyOffset)
break;
- for (int ii = 0; ii < metaObjects->count(); ++ii) {
+ for (int ii = 0; ii < metaObjects->size(); ++ii) {
const int globalPropertyOffset = metaObjects->at(ii).propertyOffset;
if (id < globalPropertyOffset)
continue;
@@ -94,7 +94,7 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void
return -1;
}
- for (int ii = 0; ii < metaObjects->count(); ++ii) {
+ for (int ii = 0; ii < metaObjects->size(); ++ii) {
const int globalMethodOffset = metaObjects->at(ii).methodOffset;
if (id < globalMethodOffset)
continue;
diff --git a/src/qml/qml/qqmlscriptblob.cpp b/src/qml/qml/qqmlscriptblob.cpp
index 5bfa6d3470..505a57636f 100644
--- a/src/qml/qml/qqmlscriptblob.cpp
+++ b/src/qml/qml/qqmlscriptblob.cpp
@@ -126,7 +126,7 @@ void QQmlScriptBlob::done()
return;
// Check all script dependencies for errors
- for (int ii = 0; ii < m_scripts.count(); ++ii) {
+ for (int ii = 0; ii < m_scripts.size(); ++ii) {
const ScriptReference &script = m_scripts.at(ii);
Q_ASSERT(script.script->isCompleteOrError());
if (script.script->isError()) {
@@ -147,7 +147,7 @@ void QQmlScriptBlob::done()
QSet<QString> ns;
- for (int scriptIndex = 0; scriptIndex < m_scripts.count(); ++scriptIndex) {
+ for (int scriptIndex = 0; scriptIndex < m_scripts.size(); ++scriptIndex) {
const ScriptReference &script = m_scripts.at(scriptIndex);
m_scriptData->scripts.append(script.script);
diff --git a/src/qml/qml/qqmlscriptdata.cpp b/src/qml/qml/qqmlscriptdata.cpp
index 994a76c96e..b5ba04c93e 100644
--- a/src/qml/qml/qqmlscriptdata.cpp
+++ b/src/qml/qml/qqmlscriptdata.cpp
@@ -55,14 +55,14 @@ QQmlRefPointer<QQmlContextData> QQmlScriptData::qmlContextDataForContext(
QV4::Scope scope(v4);
QV4::ScopedObject scriptsArray(scope);
if (qmlContextData->importedScripts().isNullOrUndefined()) {
- scriptsArray = v4->newArrayObject(scripts.count());
+ scriptsArray = v4->newArrayObject(scripts.size());
qmlContextData->setImportedScripts(
QV4::PersistentValue(v4, scriptsArray.asReturnedValue()));
} else {
scriptsArray = qmlContextData->importedScripts().valueRef();
}
QV4::ScopedValue v(scope);
- for (int ii = 0; ii < scripts.count(); ++ii) {
+ for (int ii = 0; ii < scripts.size(); ++ii) {
v = scripts.at(ii)->scriptData()->scriptValueForContext(qmlContextData);
scriptsArray->put(ii, v);
}
diff --git a/src/qml/qml/qqmlscriptstring.cpp b/src/qml/qml/qqmlscriptstring.cpp
index d872d4b55c..370573b199 100644
--- a/src/qml/qml/qqmlscriptstring.cpp
+++ b/src/qml/qml/qqmlscriptstring.cpp
@@ -154,7 +154,7 @@ Otherwise returns a null QString.
QString QQmlScriptString::stringLiteral() const
{
if (d->isStringLiteral)
- return d->script.mid(1, d->script.length()-2);
+ return d->script.mid(1, d->script.size()-2);
return QString();
}
diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp
index 5c3cfa94a5..52437348d9 100644
--- a/src/qml/qml/qqmltype.cpp
+++ b/src/qml/qml/qqmltype.cpp
@@ -208,7 +208,7 @@ void QQmlTypePrivate::init() const
mo, baseMetaObject, metaObjects.isEmpty() ? nullptr
: metaObjects.constLast().metaObject));
- for (int ii = 0; ii < metaObjects.count(); ++ii) {
+ for (int ii = 0; ii < metaObjects.size(); ++ii) {
metaObjects[ii].propertyOffset =
metaObjects.at(ii).metaObject->propertyOffset();
metaObjects[ii].methodOffset =
@@ -320,7 +320,7 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
if (isScoped) {
scopedEnums << scoped;
- scopedEnumIndex.insert(QString::fromUtf8(e.name()), scopedEnums.count()-1);
+ scopedEnumIndex.insert(QString::fromUtf8(e.name()), scopedEnums.size()-1);
}
}
}
@@ -371,7 +371,7 @@ void QQmlTypePrivate::createEnumConflictReport(const QMetaObject *metaObject, co
qWarning().noquote() << QLatin1String("Possible conflicting items:");
// find items with conflicting key
- for (const auto &i : qAsConst(enumInfoList)) {
+ for (const auto &i : std::as_const(enumInfoList)) {
if (i.enumKey == conflictingKey)
qWarning().noquote().nospace() << " " << i.metaObjectName << "." << i.enumName << "." << i.enumKey << " from scope "
<< i.metaEnumScope << " injected by " << i.path.join(QLatin1String("->"));
@@ -392,13 +392,13 @@ void QQmlTypePrivate::insertEnumsFromPropertyCache(
QStringHash<int> *scoped = new QStringHash<int>();
QQmlEnumData *enumData = currentCache->qmlEnum(ii);
- for (int jj = 0; jj < enumData->values.count(); ++jj) {
+ for (int jj = 0; jj < enumData->values.size(); ++jj) {
const QQmlEnumValue &value = enumData->values.at(jj);
enums.insert(value.namedValue, value.value);
scoped->insert(value.namedValue, value.value);
}
scopedEnums << scoped;
- scopedEnumIndex.insert(enumData->name, scopedEnums.count()-1);
+ scopedEnumIndex.insert(enumData->name, scopedEnums.size()-1);
}
}
insertEnums(cppMetaObject);
@@ -822,7 +822,7 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QV4::S
*ok = true;
if (d) {
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ Q_ASSERT(index > -1 && index < d->scopedEnums.size());
int *rv = d->scopedEnums.at(index)->value(name);
if (rv)
return *rv;
@@ -839,7 +839,7 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QStrin
*ok = true;
if (d) {
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ Q_ASSERT(index > -1 && index < d->scopedEnums.size());
int *rv = d->scopedEnums.at(index)->value(name);
if (rv)
return *rv;
@@ -857,11 +857,11 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &scope
d->initEnums(engine);
- int *rv = d->scopedEnumIndex.value(QHashedCStringRef(scopedEnumName.constData(), scopedEnumName.length()));
+ int *rv = d->scopedEnumIndex.value(QHashedCStringRef(scopedEnumName.constData(), scopedEnumName.size()));
if (rv) {
int index = *rv;
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
- rv = d->scopedEnums.at(index)->value(QHashedCStringRef(name.constData(), name.length()));
+ Q_ASSERT(index > -1 && index < d->scopedEnums.size());
+ rv = d->scopedEnums.at(index)->value(QHashedCStringRef(name.constData(), name.size()));
if (rv)
return *rv;
}
@@ -882,7 +882,7 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, QStringView scopedEnumN
int *rv = d->scopedEnumIndex.value(QHashedStringRef(scopedEnumName));
if (rv) {
int index = *rv;
- Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ Q_ASSERT(index > -1 && index < d->scopedEnums.size());
rv = d->scopedEnums.at(index)->value(QHashedStringRef(name));
if (rv)
return *rv;
diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp
index 64a9238739..c2aff473fd 100644
--- a/src/qml/qml/qqmltypecompiler.cpp
+++ b/src/qml/qml/qqmltypecompiler.cpp
@@ -117,7 +117,7 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile()
document->jsModule.fileName = typeData->urlString();
document->jsModule.finalUrl = typeData->finalUrlString();
QmlIR::JSCodeGen v4CodeGenerator(document, engine->v4engine()->illegalNames());
- for (QmlIR::Object *object : qAsConst(document->objects)) {
+ for (QmlIR::Object *object : std::as_const(document->objects)) {
if (!v4CodeGenerator.generateRuntimeFunctions(object)) {
Q_ASSERT(v4CodeGenerator.hasError());
recordError(v4CodeGenerator.error());
@@ -243,7 +243,7 @@ void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier
const quint32 moduleIdx = registerString(module);
const quint32 qualifierIdx = registerString(qualifier);
- for (int i = 0, count = document->imports.count(); i < count; ++i) {
+ for (int i = 0, count = document->imports.size(); i < count; ++i) {
const QV4::CompiledData::Import *existingImport = document->imports.at(i);
if (existingImport->type == QV4::CompiledData::Import::ImportLibrary
&& existingImport->uriIndex == moduleIdx
@@ -282,7 +282,7 @@ SignalHandlerResolver::SignalHandlerResolver(QQmlTypeCompiler *typeCompiler)
bool SignalHandlerResolver::resolveSignalHandlerExpressions()
{
- for (int objectIndex = 0; objectIndex < qmlObjects.count(); ++objectIndex) {
+ for (int objectIndex = 0; objectIndex < qmlObjects.size(); ++objectIndex) {
const QmlIR::Object * const obj = qmlObjects.at(objectIndex);
QQmlPropertyCache::ConstPtr cache = propertyCaches->at(objectIndex);
if (!cache)
@@ -335,7 +335,7 @@ bool SignalHandlerResolver::resolveSignalHandlerExpressions(
QString qPropertyName;
if (signalName.endsWith(QLatin1String("Changed")))
- qPropertyName = signalName.mid(0, signalName.length() - static_cast<int>(strlen("Changed")));
+ qPropertyName = signalName.mid(0, signalName.size() - static_cast<int>(strlen("Changed")));
bool notInRevision = false;
const QQmlPropertyData * const signal = resolver.signal(signalName, &notInRevision);
@@ -353,7 +353,7 @@ bool SignalHandlerResolver::resolveSignalHandlerExpressions(
bool unnamedParameter = false;
QList<QByteArray> parameterNames = propertyCache->signalParameterNames(sigIndex);
- for (int i = 0; i < parameterNames.count(); ++i) {
+ for (int i = 0; i < parameterNames.size(); ++i) {
const QString param = QString::fromUtf8(parameterNames.at(i));
if (param.isEmpty())
unnamedParameter = true;
@@ -442,7 +442,7 @@ QQmlEnumTypeResolver::QQmlEnumTypeResolver(QQmlTypeCompiler *typeCompiler)
bool QQmlEnumTypeResolver::resolveEnumBindings()
{
- for (int i = 0; i < qmlObjects.count(); ++i) {
+ for (int i = 0; i < qmlObjects.size(); ++i) {
QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(i);
if (!propertyCache)
continue;
@@ -517,11 +517,11 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(
// * <TypeName>.<ScopedEnumName>.<EnumValue>
int dot = string.indexOf(QLatin1Char('.'));
- if (dot == -1 || dot == string.length()-1)
+ if (dot == -1 || dot == string.size()-1)
return true;
int dot2 = string.indexOf(QLatin1Char('.'), dot+1);
- if (dot2 != -1 && dot2 != string.length()-1) {
+ if (dot2 != -1 && dot2 != string.size()-1) {
if (!string.at(dot+1).isUpper())
return true;
if (string.indexOf(QLatin1Char('.'), dot2+1) != -1)
@@ -612,7 +612,7 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, QStringView enumNam
return -1;
if (!enumName.isEmpty())
return type.scopedEnumValue(compiler->enginePrivate(), enumName, enumValue, ok);
- return type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.length()), ok);
+ return type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.size()), ok);
}
const QMetaObject *mo = &Qt::staticMetaObject;
@@ -674,7 +674,7 @@ QQmlAliasAnnotator::QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler)
void QQmlAliasAnnotator::annotateBindingsToAliases()
{
- for (int i = 0; i < qmlObjects.count(); ++i) {
+ for (int i = 0; i < qmlObjects.size(); ++i) {
QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(i);
if (!propertyCache)
continue;
@@ -706,7 +706,7 @@ QQmlScriptStringScanner::QQmlScriptStringScanner(QQmlTypeCompiler *typeCompiler)
void QQmlScriptStringScanner::scan()
{
const QMetaType scriptStringMetaType = QMetaType::fromType<QQmlScriptString>();
- for (int i = 0; i < qmlObjects.count(); ++i) {
+ for (int i = 0; i < qmlObjects.size(); ++i) {
QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(i);
if (!propertyCache)
continue;
@@ -833,7 +833,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(
}
qmlObjects->append(syntheticComponent);
- const int componentIndex = qmlObjects->count() - 1;
+ const int componentIndex = qmlObjects->size() - 1;
// Keep property caches symmetric
QQmlPropertyCache::ConstPtr componentCache
= QQmlMetaType::propertyCache(&QQmlComponent::staticMetaObject);
@@ -863,7 +863,7 @@ bool QQmlComponentAndAliasResolver::resolve(int root)
// someItemDelegate: Item {}
// In the implicit case Item is surrounded by a synthetic Component {} because the property
// on the left hand side is of QQmlComponent type.
- const int objCountWithoutSynthesizedComponents = qmlObjects->count();
+ const int objCountWithoutSynthesizedComponents = qmlObjects->size();
const int startObjectIndex = root == 0 ? root : root+1; // root+1, as ic root is handled at the end
for (int i = startObjectIndex; i < objCountWithoutSynthesizedComponents; ++i) {
QmlIR::Object *obj = qmlObjects->at(i);
@@ -931,7 +931,7 @@ bool QQmlComponentAndAliasResolver::resolve(int root)
}
- for (int i = 0; i < componentRoots.count(); ++i) {
+ for (int i = 0; i < componentRoots.size(); ++i) {
QmlIR::Object *component = qmlObjects->at(componentRoots.at(i));
const QmlIR::Binding *rootBinding = component->firstBinding();
@@ -977,7 +977,7 @@ bool QQmlComponentAndAliasResolver::collectIdsAndAliases(int objectIndex)
recordError(obj->locationOfIdProperty, tr("id is not unique"));
return false;
}
- obj->id = _idToObjectIndex.count();
+ obj->id = _idToObjectIndex.size();
_idToObjectIndex.insert(obj->idNameIndex, objectIndex);
}
@@ -1016,7 +1016,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex)
atLeastOneAliasResolved = false;
QVector<int> pendingObjects;
- for (int objectIndex: qAsConst(_objectsWithAliases)) {
+ for (int objectIndex: std::as_const(_objectsWithAliases)) {
QQmlError error;
const auto result = resolveAliasesInObject(objectIndex, &error);
@@ -1396,7 +1396,7 @@ QQmlDefaultPropertyMerger::QQmlDefaultPropertyMerger(QQmlTypeCompiler *typeCompi
void QQmlDefaultPropertyMerger::mergeDefaultProperties()
{
- for (int i = 0; i < qmlObjects.count(); ++i)
+ for (int i = 0; i < qmlObjects.size(); ++i)
mergeDefaultProperties(i);
}
diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h
index 188eda471f..02edbb0c08 100644
--- a/src/qml/qml/qqmltypecompiler_p.h
+++ b/src/qml/qml/qqmltypecompiler_p.h
@@ -55,7 +55,7 @@ public:
using ListPropertyAssignBehavior = QmlIR::Pragma::ListPropertyAssignBehaviorValue;
const QmlIR::Object *objectAt(int index) const { return document->objects.at(index); }
- int objectCount() const { return document->objects.count(); }
+ int objectCount() const { return document->objects.size(); }
QString stringAt(int idx) const;
QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsBegin(const QmlIR::Object *object) const { return object->functionsBegin(); }
QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsEnd(const QmlIR::Object *object) const { return object->functionsEnd(); }
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index 972723326a..c56acaef0d 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -292,7 +292,7 @@ void QQmlTypeData::done()
return;
// Check all script dependencies for errors
- for (int ii = 0; ii < m_scripts.count(); ++ii) {
+ for (int ii = 0; ii < m_scripts.size(); ++ii) {
const ScriptReference &script = m_scripts.at(ii);
Q_ASSERT(script.script->isCompleteOrError());
if (script.script->isError()) {
@@ -309,7 +309,7 @@ void QQmlTypeData::done()
}
// Check all type dependencies for errors
- for (auto it = qAsConst(m_resolvedTypes).begin(), end = qAsConst(m_resolvedTypes).end(); it != end;
+ for (auto it = std::as_const(m_resolvedTypes).begin(), end = std::as_const(m_resolvedTypes).end(); it != end;
++it) {
const TypeReference &type = *it;
Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError() || type.type.isInlineComponentType());
@@ -349,7 +349,7 @@ void QQmlTypeData::done()
}
// Check all composite singleton type dependencies for errors
- for (int ii = 0; ii < m_compositeSingletons.count(); ++ii) {
+ for (int ii = 0; ii < m_compositeSingletons.size(); ++ii) {
const TypeReference &type = m_compositeSingletons.at(ii);
Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError());
if (type.typeData && type.typeData->isError()) {
@@ -470,7 +470,7 @@ void QQmlTypeData::done()
auto type = QQmlMetaType::typeForUrl(finalUrlString(), hashedStringRef, false, &errors);
Q_ASSERT(errors.empty());
if (type.isValid()) {
- for (auto const &icDatum : qAsConst(m_inlineComponentData)) {
+ for (auto const &icDatum : std::as_const(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),
@@ -482,8 +482,8 @@ void QQmlTypeData::done()
{
// Collect imported scripts
- m_compiledData->dependentScripts.reserve(m_scripts.count());
- for (int scriptIndex = 0; scriptIndex < m_scripts.count(); ++scriptIndex) {
+ m_compiledData->dependentScripts.reserve(m_scripts.size());
+ for (int scriptIndex = 0; scriptIndex < m_scripts.size(); ++scriptIndex) {
const QQmlTypeData::ScriptReference &script = m_scripts.at(scriptIndex);
QStringView qualifier(script.qualifier);
@@ -599,8 +599,8 @@ bool QQmlTypeData::loadFromSource()
if (!compiler.generateFromQml(source, finalUrlString(), m_document.data())) {
QList<QQmlError> errors;
- errors.reserve(compiler.errors.count());
- for (const QQmlJS::DiagnosticMessage &msg : qAsConst(compiler.errors)) {
+ errors.reserve(compiler.errors.size());
+ for (const QQmlJS::DiagnosticMessage &msg : std::as_const(compiler.errors)) {
QQmlError e;
e.setUrl(url());
e.setLine(qmlConvertSourceCoordinate<quint32, int>(msg.loc.startLine));
@@ -668,7 +668,7 @@ void QQmlTypeData::continueLoadFromIR()
QList<QQmlError> errors;
- for (const QV4::CompiledData::Import *import : qAsConst(m_document->imports)) {
+ for (const QV4::CompiledData::Import *import : std::as_const(m_document->imports)) {
if (!addImport(import, {}, &errors)) {
Q_ASSERT(errors.size());
@@ -723,7 +723,7 @@ void QQmlTypeData::allDependenciesDone()
void QQmlTypeData::downloadProgressChanged(qreal p)
{
- for (int ii = 0; ii < m_callbacks.count(); ++ii) {
+ for (int ii = 0; ii < m_callbacks.size(); ++ii) {
TypeDataCallback *callback = m_callbacks.at(ii);
callback->typeDataProgress(this, p);
}
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 046ee0ef51..ab3ea80d35 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -614,7 +614,7 @@ bool QQmlTypeLoader::Blob::addLibraryImport(PendingImportPtr import, QList<QQmlE
scriptImported(blob, import->location, script.nameSpace, import->qualifier);
}
}
- if (!qmldir.plugins().count()) {
+ if (!qmldir.plugins().size()) {
// If the qmldir does not register a plugin, we might still have declaratively
// registered types (if we are dealing with an application instead of a library)
auto module = QQmlMetaType::typeModule(import->uri, import->version);
@@ -1035,7 +1035,7 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
return QString();
QString absoluteFilePath;
- QString fileName(path.mid(lastSlash+1, path.length()-lastSlash-1));
+ QString fileName(path.mid(lastSlash+1, path.size()-lastSlash-1));
bool *value = fileSet->object(fileName);
if (value) {
@@ -1048,7 +1048,7 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
absoluteFilePath = path;
}
- if (absoluteFilePath.length() > 2 && absoluteFilePath.at(0) != QLatin1Char('/') && absoluteFilePath.at(1) != QLatin1Char(':'))
+ if (absoluteFilePath.size() > 2 && absoluteFilePath.at(0) != QLatin1Char('/') && absoluteFilePath.at(1) != QLatin1Char(':'))
absoluteFilePath = QFileInfo(absoluteFilePath).absoluteFilePath();
return absoluteFilePath;
@@ -1134,7 +1134,7 @@ bool QQmlTypeLoader::directoryExists(const QString &path)
return fileInfo.exists() && fileInfo.isDir();
}
- int length = path.length();
+ int length = path.size();
if (path.endsWith(QLatin1Char('/')))
--length;
QString dirPath(path.left(length));
@@ -1171,7 +1171,7 @@ const QQmlTypeLoaderQmldirContent QQmlTypeLoader::qmldirContent(const QString &f
// Yet, this heuristic is the best we can do until we pass more structured information here,
// for example a QUrl also for local files.
QUrl url(filePathIn);
- if (url.scheme().length() < 2) {
+ if (url.scheme().size() < 2) {
filePath = filePathIn;
} else {
filePath = QQmlFile::urlToLocalFileOrQrc(url);
diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp
index 4360bf8fb9..b188b7fb90 100644
--- a/src/qml/qml/qqmltypemodule.cpp
+++ b/src/qml/qml/qqmltypemodule.cpp
@@ -30,7 +30,7 @@ void QQmlTypeModule::add(QQmlTypePrivate *type)
addMinorVersion(type->version.minorVersion());
QList<QQmlTypePrivate *> &list = m_typeHash[type->elementName];
- for (int ii = 0; ii < list.count(); ++ii) {
+ for (int ii = 0; ii < list.size(); ++ii) {
QQmlTypePrivate *in_list = list.at(ii);
Q_ASSERT(in_list);
if (in_list->version.minorVersion() < type->version.minorVersion()) {
@@ -54,7 +54,7 @@ void QQmlTypeModule::remove(const QQmlTypePrivate *type)
QQmlType QQmlTypeModule::findType(const QList<QQmlTypePrivate *> *types, QTypeRevision version)
{
if (types) {
- for (int ii = 0; ii < types->count(); ++ii)
+ for (int ii = 0; ii < types->size(); ++ii)
if (types->at(ii)->version.minorVersion() <= version.minorVersion())
return QQmlType(types->at(ii));
}
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index bf270cef7d..d3088a6c7c 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -9,7 +9,7 @@ QT_BEGIN_NAMESPACE
void QQmlTypeNameCache::add(const QHashedString &name, const QUrl &url, const QHashedString &nameSpace)
{
- if (nameSpace.length() != 0) {
+ if (nameSpace.size() != 0) {
QQmlImportRef *i = m_namedImports.value(nameSpace);
Q_ASSERT(i != nullptr);
i->compositeSingletons.insert(name, url);
@@ -28,7 +28,7 @@ void QQmlTypeNameCache::add(const QHashedString &name, int importedScriptIndex,
import.scriptIndex = importedScriptIndex;
import.m_qualifier = name;
- if (nameSpace.length() != 0) {
+ if (nameSpace.size() != 0) {
QQmlImportRef *i = m_namedImports.value(nameSpace);
Q_ASSERT(i != nullptr);
m_namespacedImports[i].insert(name, import);
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index 7365255935..8cb18104b6 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -11,20 +11,9 @@
QT_BEGIN_NAMESPACE
-QQmlValueType::QQmlValueType(QMetaType type, const QMetaObject *gadgetMetaObject)
- : metaType(type)
-{
- QMetaObjectBuilder builder(gadgetMetaObject);
-
- // This is required for calling readOnGadget() on properties from this metaObject.
- builder.setFlags(PropertyAccessInStaticMetaCall);
-
- dynamicMetaObject = builder.toMetaObject();
-}
-
QQmlValueType::~QQmlValueType()
{
- ::free(dynamicMetaObject);
+ ::free(m_dynamicMetaObject);
}
QQmlGadgetPtrWrapper *QQmlGadgetPtrWrapper::instance(QQmlEngine *engine, QMetaType type)
@@ -54,7 +43,7 @@ void QQmlGadgetPtrWrapper::read(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QQmlGadgetPtrWrapper::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags)
+void QQmlGadgetPtrWrapper::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags) const
{
Q_ASSERT(m_gadgetPtr);
int status = -1;
@@ -62,16 +51,16 @@ void QQmlGadgetPtrWrapper::write(QObject *obj, int idx, QQmlPropertyData::WriteF
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
-QVariant QQmlGadgetPtrWrapper::value()
+QVariant QQmlGadgetPtrWrapper::value() const
{
Q_ASSERT(m_gadgetPtr);
- return QVariant(QMetaType(metaTypeId()), m_gadgetPtr);
+ return QVariant(metaType(), m_gadgetPtr);
}
void QQmlGadgetPtrWrapper::setValue(const QVariant &value)
{
Q_ASSERT(m_gadgetPtr);
- Q_ASSERT(metaTypeId() == value.userType());
+ Q_ASSERT(metaType() == value.metaType());
const QQmlValueType *type = valueType();
type->destruct(m_gadgetPtr);
type->construct(m_gadgetPtr, value.constData());
@@ -80,7 +69,7 @@ void QQmlGadgetPtrWrapper::setValue(const QVariant &value)
int QQmlGadgetPtrWrapper::metaCall(QMetaObject::Call type, int id, void **argv)
{
Q_ASSERT(m_gadgetPtr);
- const QMetaObject *metaObject = valueType()->metaObject();
+ const QMetaObject *metaObject = valueType()->staticMetaObject();
QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(type, &metaObject, &id);
metaObject->d.static_metacall(static_cast<QObject *>(m_gadgetPtr), type, id, argv);
return id;
@@ -94,7 +83,16 @@ const QQmlValueType *QQmlGadgetPtrWrapper::valueType() const
QMetaObject *QQmlValueType::toDynamicMetaObject(QObject *)
{
- return dynamicMetaObject;
+ if (!m_dynamicMetaObject) {
+ QMetaObjectBuilder builder(m_staticMetaObject);
+
+ // Do not set PropertyAccessInStaticMetaCall here. QQmlGadgetPtrWrapper likes to
+ // to intercept the metacalls since it needs to use its gadgetPtr.
+ // For QQmlValueType::metaObject() we use the base type that has the flag.
+
+ m_dynamicMetaObject = builder.toMetaObject();
+ }
+ return m_dynamicMetaObject;
}
void QQmlValueType::objectDestroyed(QObject *)
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index 6b7df3f1b9..5376130b0f 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -34,18 +34,20 @@ QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QQmlValueType : public QDynamicMetaObjectData
{
public:
- QQmlValueType() : metaType(QMetaType::UnknownType) {}
- QQmlValueType(QMetaType type, const QMetaObject *metaObject);
+ QQmlValueType() = default;
+ QQmlValueType(QMetaType type, const QMetaObject *staticMetaObject)
+ : m_metaType(type), m_staticMetaObject(staticMetaObject)
+ {}
~QQmlValueType();
- void *create() const { return metaType.create(); }
- void destroy(void *gadgetPtr) const { metaType.destroy(gadgetPtr); }
+ void *create() const { return m_metaType.create(); }
+ void destroy(void *gadgetPtr) const { m_metaType.destroy(gadgetPtr); }
- void construct(void *gadgetPtr, const void *copy) const { metaType.construct(gadgetPtr, copy); }
- void destruct(void *gadgetPtr) const { metaType.destruct(gadgetPtr); }
+ void construct(void *gadgetPtr, const void *copy) const { m_metaType.construct(gadgetPtr, copy); }
+ void destruct(void *gadgetPtr) const { m_metaType.destruct(gadgetPtr); }
- int metaTypeId() const { return metaType.id(); }
- const QMetaObject *metaObject() const { return dynamicMetaObject; }
+ QMetaType metaType() const { return m_metaType; }
+ const QMetaObject *staticMetaObject() const { return m_staticMetaObject; }
// ---- dynamic meta object data interface
QMetaObject *toDynamicMetaObject(QObject *) override;
@@ -53,9 +55,10 @@ public:
int metaCall(QObject *obj, QMetaObject::Call type, int _id, void **argv) override;
// ----
-public:
- QMetaType metaType;
- QMetaObject *dynamicMetaObject = nullptr;
+private:
+ QMetaType m_metaType;
+ const QMetaObject *m_staticMetaObject = nullptr;
+ QMetaObject *m_dynamicMetaObject = nullptr;
};
class Q_QML_PRIVATE_EXPORT QQmlGadgetPtrWrapper : public QObject
@@ -68,14 +71,18 @@ public:
~QQmlGadgetPtrWrapper();
void read(QObject *obj, int idx);
- void write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags);
- QVariant value();
+ void write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags) const;
+ QVariant value() const;
void setValue(const QVariant &value);
- int metaTypeId() const { return valueType()->metaTypeId(); }
+ QMetaType metaType() const { return valueType()->metaType(); }
int metaCall(QMetaObject::Call type, int id, void **argv);
- QMetaProperty property(int index) { return valueType()->metaObject()->property(index); }
+ QMetaProperty property(int index) const
+ {
+ return valueType()->staticMetaObject()->property(index);
+ }
+
QVariant readOnGadget(const QMetaProperty &property) const
{
return property.readOnGadget(m_gadgetPtr);
@@ -88,7 +95,6 @@ public:
private:
const QQmlValueType *valueType() const;
-
void *m_gadgetPtr = nullptr;
};
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 34de9faef9..d088d5e411 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -35,7 +35,7 @@ using namespace QV4;
void Heap::QQmlValueTypeWrapper::destroy()
{
if (m_gadgetPtr) {
- m_valueType->metaType.destruct(m_gadgetPtr);
+ m_valueType->metaType().destruct(m_gadgetPtr);
::operator delete(m_gadgetPtr);
}
Object::destroy();
@@ -44,22 +44,22 @@ void Heap::QQmlValueTypeWrapper::destroy()
void Heap::QQmlValueTypeWrapper::setData(const void *data) const
{
if (auto *gadget = gadgetPtr())
- valueType()->metaType.destruct(gadget);
+ valueType()->metaType().destruct(gadget);
if (!gadgetPtr())
- setGadgetPtr(::operator new(valueType()->metaType.sizeOf()));
- valueType()->metaType.construct(gadgetPtr(), data);
+ setGadgetPtr(::operator new(valueType()->metaType().sizeOf()));
+ valueType()->metaType().construct(gadgetPtr(), data);
}
void Heap::QQmlValueTypeWrapper::setValue(const QVariant &value) const
{
- Q_ASSERT(valueType()->metaType.id() == value.userType());
+ Q_ASSERT(valueType()->metaType().id() == value.userType());
setData(value.constData());
}
QVariant Heap::QQmlValueTypeWrapper::toVariant() const
{
Q_ASSERT(gadgetPtr());
- return QVariant(valueType()->metaType, gadgetPtr());
+ return QVariant(valueType()->metaType(), gadgetPtr());
}
@@ -86,7 +86,7 @@ bool QQmlValueTypeReference::readReferenceValue() const
if (QQmlMetaType::isValueType(variantReferenceType)) {
const QMetaObject *mo = QQmlMetaType::metaObjectForValueType(variantReferenceType);
if (d()->gadgetPtr()) {
- d()->valueType()->metaType.destruct(d()->gadgetPtr());
+ d()->valueType()->metaType().destruct(d()->gadgetPtr());
::operator delete(d()->gadgetPtr());
}
d()->setGadgetPtr(nullptr);
@@ -101,8 +101,8 @@ bool QQmlValueTypeReference::readReferenceValue() const
d()->setValue(variantReferenceValue);
} else {
if (!d()->gadgetPtr()) {
- d()->setGadgetPtr(::operator new(d()->valueType()->metaType.sizeOf()));
- d()->valueType()->metaType.construct(d()->gadgetPtr(), nullptr);
+ d()->setGadgetPtr(::operator new(d()->valueType()->metaType().sizeOf()));
+ d()->valueType()->metaType().construct(d()->gadgetPtr(), nullptr);
}
// value-type reference
void *args[] = { d()->gadgetPtr(), nullptr };
@@ -145,7 +145,7 @@ ReturnedValue QQmlValueTypeWrapper::create(
ExecutionEngine *engine, const QVariant &value, const QMetaObject *metaObject,
QMetaType type)
{
- Q_ASSERT(value.metaType() == QQmlMetaType::valueType(type)->metaType);
+ Q_ASSERT(value.metaType() == QQmlMetaType::valueType(type)->metaType());
return create(engine, value.constData(), metaObject, type);
}
@@ -181,7 +181,7 @@ bool QQmlValueTypeWrapper::toGadget(void *data) const
if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>())
if (!ref->readReferenceValue())
return false;
- const QMetaType type = d()->valueType()->metaType;
+ const QMetaType type = d()->valueType()->metaType();
type.destruct(data);
type.construct(data, d()->gadgetPtr());
return true;
@@ -367,12 +367,12 @@ bool QQmlValueTypeWrapper::isEqual(const QVariant& value) const
int QQmlValueTypeWrapper::typeId() const
{
- return d()->valueType()->metaType.id();
+ return d()->valueType()->metaType().id();
}
QMetaType QQmlValueTypeWrapper::type() const
{
- return d()->valueType()->metaType;
+ return d()->valueType()->metaType();
}
bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
@@ -381,9 +381,9 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
Q_ALLOCA_DECLARE(void, gadget);
if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>()) {
if (!d()->gadgetPtr()) {
- Q_ALLOCA_ASSIGN(void, gadget, d()->valueType()->metaType.sizeOf());
+ Q_ALLOCA_ASSIGN(void, gadget, d()->valueType()->metaType().sizeOf());
d()->setGadgetPtr(gadget);
- d()->valueType()->metaType.construct(d()->gadgetPtr(), nullptr);
+ d()->valueType()->metaType().construct(d()->gadgetPtr(), nullptr);
destructGadgetOnExit = true;
}
if (!ref->readReferenceValue())
@@ -396,7 +396,7 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
QMetaObject::metacall(target, QMetaObject::WriteProperty, propertyIndex, a);
if (destructGadgetOnExit) {
- d()->valueType()->metaType.destruct(d()->gadgetPtr());
+ d()->valueType()->metaType().destruct(d()->gadgetPtr());
d()->setGadgetPtr(nullptr);
}
return true;
@@ -434,9 +434,9 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(const FunctionObject *b, con
RETURN_UNDEFINED();
QString result;
- if (!QMetaType::convert(w->d()->valueType()->metaType, w->d()->gadgetPtr(),
+ if (!QMetaType::convert(w->d()->valueType()->metaType(), w->d()->gadgetPtr(),
QMetaType(QMetaType::QString), &result)) {
- result = QString::fromUtf8(w->d()->valueType()->metaType.name()) + QLatin1Char('(');
+ result = QString::fromUtf8(w->d()->valueType()->metaType().name()) + QLatin1Char('(');
const QMetaObject *mo = w->d()->metaObject();
const int propCount = mo->propertyCount();
for (int i = 0; i < propCount; ++i) {
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 8a0bc1a08e..710aadda45 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -99,7 +99,7 @@ static void list_append(QQmlListProperty<QObject> *prop, QObject *o)
static qsizetype list_count(QQmlListProperty<QObject> *prop)
{
- return ResolvedList(prop).list()->count();
+ return ResolvedList(prop).list()->size();
}
static QObject *list_at(QQmlListProperty<QObject> *prop, qsizetype index)
@@ -203,13 +203,10 @@ void QQmlVMEMetaObjectEndpoint::tryConnect()
if (!target)
return;
- QQmlData *targetDData = QQmlData::get(target, /*create*/false);
- if (!targetDData)
- return;
QQmlPropertyIndex encodedIndex = QQmlPropertyIndex::fromEncoded(aliasData->encodedMetaPropertyIndex);
int coreIndex = encodedIndex.coreIndex();
int valueTypeIndex = encodedIndex.valueTypeIndex();
- const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
+ const QQmlPropertyData *pd = QQmlData::ensurePropertyCache(target)->property(coreIndex);
if (pd && valueTypeIndex != -1 && !QQmlMetaType::valueType(pd->propType())) {
// deep alias
const QQmlPropertyCache::ConstPtr newPropertyCache
@@ -899,7 +896,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
QObject *arg = *reinterpret_cast<QObject **>(a[0]);
if (const auto *wrap = sv->as<QV4::QObjectWrapper>())
needActivate = wrap->object() != arg;
- else
+ else if (arg != nullptr || !sv->isNull())
needActivate = true;
if (needActivate)
writeProperty(id, arg);
@@ -1053,7 +1050,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
auto arguments = methodData->hasArguments() ? methodData->arguments() : nullptr;
if (arguments && arguments->names) {
- const quint32 parameterCount = arguments->names->count();
+ const quint32 parameterCount = arguments->names->size();
Q_ASSERT(parameterCount == function->formalParameterCount());
if (void *result = a[0])
arguments->types[0].destruct(result);
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 4d3ba7df24..daaeb16c13 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -504,7 +504,7 @@ ReturnedValue NodePrototype::method_get_previousSibling(const FunctionObject *b,
if (!r->d()->d->parent)
RETURN_RESULT(Encode::null());
- for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) {
+ for (int ii = 0; ii < r->d()->d->parent->children.size(); ++ii) {
if (r->d()->d->parent->children.at(ii) == r->d()->d) {
if (ii == 0)
return Encode::null();
@@ -526,9 +526,9 @@ ReturnedValue NodePrototype::method_get_nextSibling(const FunctionObject *b, con
if (!r->d()->d->parent)
RETURN_RESULT(Encode::null());
- for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) {
+ for (int ii = 0; ii < r->d()->d->parent->children.size(); ++ii) {
if (r->d()->d->parent->children.at(ii) == r->d()->d) {
- if ((ii + 1) == r->d()->d->parent->children.count())
+ if ((ii + 1) == r->d()->d->parent->children.size())
return Encode::null();
else
return Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1));
@@ -666,7 +666,7 @@ ReturnedValue CharacterData::method_length(const FunctionObject *b, const Value
if (!r)
RETURN_UNDEFINED();
- return Encode(int(r->d()->d->data.length()));
+ return Encode(int(r->d()->d->data.size()));
}
ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
@@ -859,7 +859,7 @@ ReturnedValue NamedNodeMap::virtualGet(const Managed *m, PropertyKey id, const V
if (id.isArrayIndex()) {
uint index = id.asArrayIndex();
- if ((int)index < r->d()->list().count()) {
+ if ((int)index < r->d()->list().size()) {
if (hasProperty)
*hasProperty = true;
return Node::create(v4, r->d()->list().at(index));
@@ -873,10 +873,10 @@ ReturnedValue NamedNodeMap::virtualGet(const Managed *m, PropertyKey id, const V
return Object::virtualGet(m, id, receiver, hasProperty);
if (id == v4->id_length()->propertyKey())
- return Value::fromInt32(r->d()->list().count()).asReturnedValue();
+ return Value::fromInt32(r->d()->list().size()).asReturnedValue();
QString str = id.toQString();
- for (int ii = 0; ii < r->d()->list().count(); ++ii) {
+ for (int ii = 0; ii < r->d()->list().size(); ++ii) {
if (r->d()->list().at(ii)->name == str) {
if (hasProperty)
*hasProperty = true;
@@ -902,7 +902,7 @@ ReturnedValue NodeList::virtualGet(const Managed *m, PropertyKey id, const Value
if (id.isArrayIndex()) {
uint index = id.asArrayIndex();
- if ((int)index < r->d()->d->children.count()) {
+ if ((int)index < r->d()->d->children.size()) {
if (hasProperty)
*hasProperty = true;
return Node::create(v4, r->d()->d->children.at(index));
@@ -913,7 +913,7 @@ ReturnedValue NodeList::virtualGet(const Managed *m, PropertyKey id, const Value
}
if (id == v4->id_length()->propertyKey())
- return Value::fromInt32(r->d()->d->children.count()).asReturnedValue();
+ return Value::fromInt32(r->d()->d->children.size()).asReturnedValue();
return Object::virtualGet(m, id, receiver, hasProperty);
}
@@ -1138,7 +1138,7 @@ QString QQmlXMLHttpRequest::headers() const
QString ret;
for (const HeaderPair &header : m_headersList) {
- if (ret.length())
+ if (ret.size())
ret.append(QLatin1String("\r\n"));
ret += QString::fromUtf8(header.first) + QLatin1String(": ")
+ QString::fromUtf8(header.second);
@@ -1202,7 +1202,7 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
int n = 0;
int semiColon = str.indexOf(QLatin1Char(';'), charsetIdx);
if (semiColon == -1) {
- n = str.length() - charsetIdx;
+ n = str.size() - charsetIdx;
} else {
n = semiColon - charsetIdx;
}
@@ -1436,7 +1436,7 @@ void QQmlXMLHttpRequest::finished()
void QQmlXMLHttpRequest::readEncoding()
{
- for (const HeaderPair &header : qAsConst(m_headersList)) {
+ for (const HeaderPair &header : std::as_const(m_headersList)) {
if (header.first == "content-type") {
int separatorIdx = header.second.indexOf(';');
if (separatorIdx == -1) {
@@ -1447,7 +1447,7 @@ void QQmlXMLHttpRequest::readEncoding()
if (charsetIdx != -1) {
charsetIdx += 8;
separatorIdx = header.second.indexOf(';', charsetIdx);
- m_charset = header.second.mid(charsetIdx, separatorIdx >= 0 ? separatorIdx : header.second.length());
+ m_charset = header.second.mid(charsetIdx, separatorIdx >= 0 ? separatorIdx : header.second.size());
}
}
break;
@@ -1480,7 +1480,7 @@ QV4::ReturnedValue QQmlXMLHttpRequest::jsonResponseBody(QV4::ExecutionEngine* en
QJsonParseError error;
const QString& jtext = responseBody();
- JsonParser parser(scope.engine, jtext.constData(), jtext.length());
+ JsonParser parser(scope.engine, jtext.constData(), jtext.size());
ScopedValue jsonObject(scope, parser.parse(&error));
if (error.error != QJsonParseError::NoError)
return engine->throwSyntaxError(QStringLiteral("JSON.parse: Parse error"));
@@ -1513,11 +1513,8 @@ QStringDecoder QQmlXMLHttpRequest::findTextDecoder() const
decoder = QStringDecoder(reader.documentEncoding().toString().toUtf8());
}
- if (!decoder.isValid() && m_mime == "text/html") {
- auto encoding = QStringConverter::encodingForHtml(m_responseEntityBody);
- if (encoding)
- decoder = QStringDecoder(*encoding);
- }
+ if (!decoder.isValid() && m_mime == "text/html")
+ decoder = QStringDecoder::decoderForHtml(m_responseEntityBody);
if (!decoder.isValid()) {
auto encoding = QStringConverter::encodingForData(m_responseEntityBody);
@@ -1621,7 +1618,7 @@ struct QQmlXMLHttpRequestWrapper : Object {
Member(class, Pointer, Object *, proto)
DECLARE_HEAP_OBJECT(QQmlXMLHttpRequestCtor, FunctionObject) {
- DECLARE_MARKOBJECTS(QQmlXMLHttpRequestCtor);
+ DECLARE_MARKOBJECTS(QQmlXMLHttpRequestCtor)
void init(ExecutionEngine *engine);
};
diff --git a/src/qml/qmldirparser/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp
index 6415e6cee2..112c7d12d0 100644
--- a/src/qml/qmldirparser/qqmldirparser.cpp
+++ b/src/qml/qmldirparser/qqmldirparser.cpp
@@ -11,13 +11,13 @@ static int parseInt(QStringView str, bool *ok)
{
int pos = 0;
int number = 0;
- while (pos < str.length() && str.at(pos).isDigit()) {
+ while (pos < str.size() && str.at(pos).isDigit()) {
if (pos != 0)
number *= 10;
number += str.at(pos).unicode() - '0';
++pos;
}
- if (pos != str.length())
+ if (pos != str.size())
*ok = false;
else
*ok = true;
@@ -31,7 +31,7 @@ static QTypeRevision parseVersion(const QString &str)
bool ok = false;
const int major = parseInt(QStringView(str).left(dotIndex), &ok);
if (!ok) return QTypeRevision();
- const int minor = parseInt(QStringView(str).mid(dotIndex + 1, str.length() - dotIndex - 1), &ok);
+ const int minor = parseInt(QStringView(str).mid(dotIndex + 1, str.size() - dotIndex - 1), &ok);
return ok ? QTypeRevision::fromVersion(major, minor) : QTypeRevision();
}
return QTypeRevision();
diff --git a/src/qml/qmldirparser/qqmlimportresolver.cpp b/src/qml/qmldirparser/qqmlimportresolver.cpp
index b4f4dbf7a1..15ec7765b0 100644
--- a/src/qml/qmldirparser/qqmlimportresolver.cpp
+++ b/src/qml/qmldirparser/qqmlimportresolver.cpp
@@ -28,7 +28,7 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
QStringList importPaths;
// fully & partially versioned parts + 1 unversioned for each base path
- importPaths.reserve(2 * parts.count() + 1);
+ importPaths.reserve(2 * parts.size() + 1);
auto versionString = [](QTypeRevision version, ImportVersion mode)
{
@@ -71,7 +71,7 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
if (mode != Unversioned) {
// insert in the middle
- for (int index = parts.count() - 2; index >= 0; --index) {
+ for (int index = parts.size() - 2; index >= 0; --index) {
importPaths += dir + joinStringRefs(parts.mid(0, index + 1), Slash)
+ ver + Slash
+ joinStringRefs(parts.mid(index + 1), Slash);
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index fb2664da73..34f288b9d5 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -307,7 +307,7 @@ void QQmlBindPrivate::validate(QQmlBind *q) const
if (!when)
return;
- qsizetype iterationEnd = entries.length();
+ qsizetype iterationEnd = entries.size();
if (lastIsTarget) {
if (obj) {
Q_ASSERT(!entries.isEmpty());
@@ -604,7 +604,7 @@ void QQmlBind::setDelayed(bool delayed)
oldEntries.pop_back();
}
- for (qsizetype i = 0, end = oldEntries.length(); i < end; ++i) {
+ for (qsizetype i = 0, end = oldEntries.size(); i < end; ++i) {
QQmlBindEntry &newEntry = d->entries[i];
QQmlBindEntry &oldEntry = oldEntries[i];
newEntry.previousKind = newEntry.previous.set(
@@ -757,7 +757,8 @@ void QQmlBindPrivate::decodeBinding(
if (!immediateState)
return;
- QQmlProperty property(q, propertyName);
+ QQmlProperty property = QQmlPropertyPrivate::create(
+ q, propertyName, contextData, QQmlPropertyPrivate::InitFlag::AllowSignal);
if (property.isValid()) {
if (!immediateState->creator) {
immediateState->completePending = true;
@@ -794,7 +795,7 @@ void QQmlBindPrivate::decodeBinding(
if (delayed) {
if (!delayedValues)
createDelayedValues();
- const QString delayedName = QString::number(entries.length());
+ const QString delayedName = QString::number(entries.size());
delayedValues->insert(delayedName, QVariant());
QQmlProperty bindingTarget = QQmlProperty(delayedValues.get(), delayedName);
Q_ASSERT(bindingTarget.isValid());
@@ -863,7 +864,7 @@ void QQmlBindPrivate::evalDelayed()
bool ok;
const int delayedIndex = delayedName.toInt(&ok);
Q_ASSERT(ok);
- Q_ASSERT(delayedIndex >= 0 && delayedIndex < entries.length());
+ Q_ASSERT(delayedIndex >= 0 && delayedIndex < entries.size());
entries[delayedIndex].prop.write((*delayedValues)[delayedName]);
}
(*delayedValues)[pendingName].setValue(QStringList());
@@ -1010,7 +1011,7 @@ void QQmlBind::eval()
return;
d->writingProperty = true;
- for (qsizetype i = 0, end = d->entries.length(); i != end; ++i) {
+ for (qsizetype i = 0, end = d->entries.size(); i != end; ++i) {
QQmlBindEntry &entry = d->entries[i];
if (!entry.prop.isValid())
continue;
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 60d0e7a085..1527a2ea34 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -24,15 +24,13 @@ Q_LOGGING_CATEGORY(lcQmlConnections, "qt.qml.connections")
class QQmlConnectionsPrivate : public QObjectPrivate
{
public:
- QQmlConnectionsPrivate() : target(nullptr), enabled(true), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {}
-
QList<QQmlBoundSignal*> boundsignals;
- QObject *target;
+ QQmlGuard<QObject> target;
- bool enabled;
- bool targetSet;
- bool ignoreUnknownSignals;
- bool componentcomplete;
+ bool enabled = true;
+ bool targetSet = false;
+ bool ignoreUnknownSignals = false;
+ bool componentcomplete = true;
QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
QList<const QV4::CompiledData::Binding *> bindings;
@@ -94,6 +92,12 @@ public:
}
\endqml
+ \note For backwards compatibility you can also specify the signal handlers
+ without \c{function}, like you would specify them directly in the target
+ object. This is not recommended. If you specify one signal handler this way,
+ then all signal handlers specified as \c{function} in the same Connections
+ object are ignored.
+
\sa {Qt QML}
*/
QQmlConnections::QQmlConnections(QObject *parent) :
@@ -113,7 +117,7 @@ QQmlConnections::QQmlConnections(QObject *parent) :
QObject *QQmlConnections::target() const
{
Q_D(const QQmlConnections);
- return d->targetSet ? d->target : parent();
+ return d->targetSet ? d->target.data() : parent();
}
class QQmlBoundSignalDeleter : public QObject
@@ -132,7 +136,7 @@ void QQmlConnections::setTarget(QObject *obj)
if (d->targetSet && d->target == obj)
return;
d->targetSet = true; // even if setting to 0, it is *set*
- for (QQmlBoundSignal *s : qAsConst(d->boundsignals)) {
+ for (QQmlBoundSignal *s : std::as_const(d->boundsignals)) {
// It is possible that target is being changed due to one of our signal
// handlers -> use deleteLater().
if (s->isNotifying())
@@ -168,7 +172,7 @@ void QQmlConnections::setEnabled(bool enabled)
d->enabled = enabled;
- for (QQmlBoundSignal *s : qAsConst(d->boundsignals))
+ for (QQmlBoundSignal *s : std::as_const(d->boundsignals))
s->setEnabled(d->enabled);
emit enabledChanged();
@@ -197,11 +201,11 @@ void QQmlConnections::setIgnoreUnknownSignals(bool ignore)
void QQmlConnectionsParser::verifyBindings(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &props)
{
- for (int ii = 0; ii < props.count(); ++ii) {
+ for (int ii = 0; ii < props.size(); ++ii) {
const QV4::CompiledData::Binding *binding = props.at(ii);
const QString &propName = compilationUnit->stringAt(binding->propertyNameIndex);
- const bool thirdCharacterIsValid = (propName.length() >= 2)
+ const bool thirdCharacterIsValid = (propName.size() >= 2)
&& (propName.at(2).isUpper() || propName.at(2) == u'_');
if (!propName.startsWith(QLatin1String("on")) || !thirdCharacterIsValid) {
error(props.at(ii), QQmlConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
@@ -298,7 +302,7 @@ void QQmlConnections::connectSignalsToMethods()
signal->takeExpression(expression);
d->boundsignals += signal;
} else if (!d->ignoreUnknownSignals
- && propName.startsWith(QLatin1String("on")) && propName.length() > 2
+ && propName.startsWith(QLatin1String("on")) && propName.size() > 2
&& propName.at(2).isUpper()) {
qmlWarning(this) << tr("Detected function \"%1\" in Connections element. "
"This is probably intended to be a signal handler but no "
@@ -315,7 +319,7 @@ void QQmlConnections::connectSignalsToBindings()
QQmlData *ddata = QQmlData::get(this);
QQmlRefPointer<QQmlContextData> ctxtdata = ddata ? ddata->outerContext : nullptr;
- for (const QV4::CompiledData::Binding *binding : qAsConst(d->bindings)) {
+ for (const QV4::CompiledData::Binding *binding : std::as_const(d->bindings)) {
Q_ASSERT(binding->type() == QV4::CompiledData::Binding::Type_Script);
QString propName = d->compilationUnit->stringAt(binding->propertyNameIndex);
diff --git a/src/qml/util/qqmlpropertymap.cpp b/src/qml/util/qqmlpropertymap.cpp
index 663d4974a7..494bf4e744 100644
--- a/src/qml/util/qqmlpropertymap.cpp
+++ b/src/qml/util/qqmlpropertymap.cpp
@@ -263,7 +263,7 @@ QStringList QQmlPropertyMap::keys() const
int QQmlPropertyMap::count() const
{
Q_D(const QQmlPropertyMap);
- return d->keys.count();
+ return d->keys.size();
}
/*!
diff --git a/src/qmlcompiler/qdeferredpointer_p.h b/src/qmlcompiler/qdeferredpointer_p.h
index 481c0e27ae..f4d8696f69 100644
--- a/src/qmlcompiler/qdeferredpointer_p.h
+++ b/src/qmlcompiler/qdeferredpointer_p.h
@@ -50,15 +50,15 @@ public:
QDeferredSharedPointer() = default;
QDeferredSharedPointer(QSharedPointer<T> data)
- : m_data(data)
+ : m_data(std::move(data))
{}
QDeferredSharedPointer(QWeakPointer<T> data)
- : m_data(data)
+ : m_data(std::move(data))
{}
QDeferredSharedPointer(QSharedPointer<T> data, QSharedPointer<Factory> factory)
- : m_data(data), m_factory(factory)
+ : m_data(std::move(data)), m_factory(std::move(factory))
{
// You have to provide a valid pointer if you provide a factory. We cannot allocate the
// pointer for you because then two copies of the same QDeferredSharedPointer will diverge
diff --git a/src/qmlcompiler/qqmljsbasicblocks.cpp b/src/qmlcompiler/qqmljsbasicblocks.cpp
index a7bbd5326c..093b11684c 100644
--- a/src/qmlcompiler/qqmljsbasicblocks.cpp
+++ b/src/qmlcompiler/qqmljsbasicblocks.cpp
@@ -45,14 +45,14 @@ QQmlJSCompilePass::InstructionAnnotations QQmlJSBasicBlocks::run(
m_function = function;
m_annotations = annotations;
- for (int i = 0, end = function->argumentTypes.length(); i != end; ++i) {
+ for (int i = 0, end = function->argumentTypes.size(); i != end; ++i) {
InstructionAnnotation annotation;
annotation.changedRegisterIndex = FirstArgument + i;
annotation.changedRegister = function->argumentTypes[i];
m_annotations[-annotation.changedRegisterIndex] = annotation;
}
- for (int i = 0, end = function->registerTypes.length(); i != end; ++i) {
+ for (int i = 0, end = function->registerTypes.size(); i != end; ++i) {
InstructionAnnotation annotation;
annotation.changedRegisterIndex = firstRegisterIndex() + i;
annotation.changedRegister = function->registerTypes[i];
@@ -62,7 +62,7 @@ QQmlJSCompilePass::InstructionAnnotations QQmlJSBasicBlocks::run(
m_basicBlocks.insert_or_assign(m_annotations.begin().key(), BasicBlock());
const QByteArray byteCode = function->code;
- decode(byteCode.constData(), static_cast<uint>(byteCode.length()));
+ decode(byteCode.constData(), static_cast<uint>(byteCode.size()));
if (m_hadBackJumps) {
// We may have missed some connections between basic blocks if there were back jumps.
// Fill them in via a second pass.
@@ -75,7 +75,7 @@ QQmlJSCompilePass::InstructionAnnotations QQmlJSBasicBlocks::run(
}
reset();
- decode(byteCode.constData(), static_cast<uint>(byteCode.length()));
+ decode(byteCode.constData(), static_cast<uint>(byteCode.size()));
for (auto it = m_basicBlocks.begin(), end = m_basicBlocks.end(); it != end; ++it)
deduplicate(it->second.jumpOrigins);
}
@@ -415,7 +415,7 @@ void QQmlJSBasicBlocks::adjustTypes()
const InstructionAnnotation &annotation = m_annotations[instructionOffset];
- Q_ASSERT(it->trackedTypes.length() == 1);
+ Q_ASSERT(it->trackedTypes.size() == 1);
Q_ASSERT(it->trackedTypes[0] == m_typeResolver->containedType(annotation.changedRegister));
Q_ASSERT(!annotation.readRegisters.isEmpty());
@@ -430,7 +430,7 @@ void QQmlJSBasicBlocks::adjustTypes()
valueType);
}
- for (const QList<int> &conversions : qAsConst(it->registerReadersAndConversions)) {
+ for (const QList<int> &conversions : std::as_const(it->registerReadersAndConversions)) {
for (int conversion : conversions)
liveConversions[conversion].append(it->trackedRegister);
}
@@ -439,14 +439,14 @@ void QQmlJSBasicBlocks::adjustTypes()
}
for (auto it = m_readerLocations.begin(), end = m_readerLocations.end(); it != end; ++it) {
- for (const QList<int> &conversions : qAsConst(it->registerReadersAndConversions)) {
+ for (const QList<int> &conversions : std::as_const(it->registerReadersAndConversions)) {
for (int conversion : conversions)
liveConversions[conversion].append(it->trackedRegister);
}
// There is always one first occurrence of any tracked type. Conversions don't change
// the type.
- if (it->trackedTypes.length() != 1)
+ if (it->trackedTypes.size() != 1)
continue;
m_typeResolver->adjustTrackedType(it->trackedTypes[0], it->typeReaders.values());
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index f9455e7815..a14ea33e14 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -35,6 +35,15 @@ using namespace Qt::StringLiterals;
m_body += u"// "_s + QStringLiteral(#function) + u'\n'; \
}
+
+static bool isTypeStorable(const QQmlJSTypeResolver *resolver, const QQmlJSScope::ConstPtr &type)
+{
+ return !type.isNull()
+ && !resolver->equals(type, resolver->nullType())
+ && !resolver->equals(type, resolver->emptyListType())
+ && !resolver->equals(type, resolver->voidType());
+}
+
QString QQmlJSCodeGenerator::castTargetName(const QQmlJSScope::ConstPtr &type) const
{
return type->augmentedInternalName();
@@ -43,9 +52,8 @@ QString QQmlJSCodeGenerator::castTargetName(const QQmlJSScope::ConstPtr &type) c
QQmlJSCodeGenerator::QQmlJSCodeGenerator(const QV4::Compiler::Context *compilerContext,
const QV4::Compiler::JSUnitGenerator *unitGenerator,
const QQmlJSTypeResolver *typeResolver,
- QQmlJSLogger *logger, const QStringList &sourceCodeLines)
+ QQmlJSLogger *logger)
: QQmlJSCompilePass(unitGenerator, typeResolver, logger)
- , m_sourceCodeLines(sourceCodeLines)
, m_context(compilerContext)
{}
@@ -75,14 +83,6 @@ QString QQmlJSCodeGenerator::metaObject(const QQmlJSScope::ConstPtr &objectType)
return QString();
}
-static bool isTypeStorable(const QQmlJSTypeResolver *resolver, const QQmlJSScope::ConstPtr &type)
-{
- return !type.isNull()
- && !resolver->equals(type, resolver->nullType())
- && !resolver->equals(type, resolver->emptyListType())
- && !resolver->equals(type, resolver->voidType());
-}
-
QQmlJSAotFunction QQmlJSCodeGenerator::run(
const Function *function, const InstructionAnnotations *annotations,
QQmlJS::DiagnosticMessage *error)
@@ -103,7 +103,7 @@ QQmlJSAotFunction QQmlJSCodeGenerator::run(
auto &currentRegisterNames = registerNames[registerIndex];
QString &name = currentRegisterNames[m_typeResolver->comparableType(seenType)];
if (name.isEmpty())
- name = u"r%1_%2"_s.arg(registerIndex).arg(currentRegisterNames.count());
+ name = u"r%1_%2"_s.arg(registerIndex).arg(currentRegisterNames.size());
typesForRegisters[seenType] = name;
}
};
@@ -123,7 +123,7 @@ QT_WARNING_POP
// ensure we have m_labels for loops
for (const auto loopLabel : m_context->labelInfo)
- m_labels.insert(loopLabel, u"label_%1"_s.arg(m_labels.count()));
+ m_labels.insert(loopLabel, u"label_%1"_s.arg(m_labels.size()));
// Initialize the first instruction's state to hold the arguments.
// After this, the arguments (or whatever becomes of them) are carried
@@ -131,11 +131,14 @@ QT_WARNING_POP
m_state.State::operator=(initialState(m_function));
const QByteArray byteCode = function->code;
- decode(byteCode.constData(), static_cast<uint>(byteCode.length()));
+ decode(byteCode.constData(), static_cast<uint>(byteCode.size()));
QQmlJSAotFunction result;
result.includes.swap(m_includes);
+ result.code += u"// %1 at line %2, column %3\n"_s
+ .arg(m_context->name).arg(m_context->line).arg(m_context->column);
+
QDuplicateTracker<QString> generatedVariables;
for (auto registerIt = m_registerVariables.cbegin(), registerEnd = m_registerVariables.cend();
registerIt != registerEnd; ++registerIt) {
@@ -204,7 +207,7 @@ QT_WARNING_POP
result.code += m_body;
- for (const QQmlJSRegisterContent &argType : qAsConst(function->argumentTypes)) {
+ for (const QQmlJSRegisterContent &argType : std::as_const(function->argumentTypes)) {
if (argType.isValid()) {
result.argumentTypes.append(
m_typeResolver->originalType(argType.storedType())
@@ -309,17 +312,41 @@ void QQmlJSCodeGenerator::generate_LoadConst(int index)
{
INJECT_TRACE_INFO(generate_LoadConst);
- auto encodedConst = m_jsUnitGenerator->constant(index);
- double value = QV4::StaticValue::fromReturnedValue(encodedConst).doubleValue();
- m_body += m_state.accumulatorVariableOut;
+ // You cannot actually get it to generate LoadConst for anything but double. We have
+ // a numer of specialized instructions for the other types, after all. However, let's
+ // play it safe.
- // ### handle other types?
- m_body += u" = "_s + conversion(
- m_typeResolver->intType(), m_state.accumulatorOut().storedType(),
- toNumericString(value));
+ const QV4::ReturnedValue encodedConst = m_jsUnitGenerator->constant(index);
+ const QV4::StaticValue value = QV4::StaticValue::fromReturnedValue(encodedConst);
+ const QQmlJSScope::ConstPtr type = m_typeResolver->typeForConst(encodedConst);
+
+ m_body += m_state.accumulatorVariableOut + u" = "_s;
+ if (type == m_typeResolver->realType()) {
+ m_body += conversion(
+ type, m_state.accumulatorOut().storedType(),
+ toNumericString(value.doubleValue()));
+ } else if (type == m_typeResolver->intType()) {
+ m_body += conversion(
+ type, m_state.accumulatorOut().storedType(),
+ QString::number(value.integerValue()));
+ } else if (type == m_typeResolver->boolType()) {
+ m_body += conversion(
+ type, m_state.accumulatorOut().storedType(),
+ value.booleanValue() ? u"true"_s : u"false"_s);
+ } else if (type == m_typeResolver->voidType()) {
+ m_body += conversion(
+ type, m_state.accumulatorOut().storedType(),
+ QString());
+ } else if (type == m_typeResolver->nullType()) {
+ m_body += conversion(
+ type, m_state.accumulatorOut().storedType(),
+ u"nullptr"_s);
+ } else {
+ reject(u"unsupported constant type"_s);
+ }
m_body += u";\n"_s;
- generateOutputVariantConversion(m_typeResolver->intType());
+ generateOutputVariantConversion(type);
}
void QQmlJSCodeGenerator::generate_LoadZero()
@@ -2227,17 +2254,6 @@ QV4::Moth::ByteCodeHandler::Verdict QQmlJSCodeGenerator::startInstruction(
|| !m_state.accumulatorVariableOut.isEmpty()
|| !isTypeStorable(m_typeResolver, m_state.changedRegister().storedType()));
- const int currentLine = currentSourceLocation().startLine;
- if (currentLine != m_lastLineNumberUsed) {
- const int nextLine = nextJSLine(currentLine);
- for (auto line = currentLine - 1; line < nextLine - 1; ++line) {
- m_body += u"// "_s;
- m_body += m_sourceCodeLines.value(line).trimmed();
- m_body += u'\n';
- }
- m_lastLineNumberUsed = currentLine;
- }
-
// If the instruction has no side effects and doesn't write any register, it's dead.
// We might still need the label, though, and the source code comment.
if (!m_state.hasSideEffects() && changedRegisterVariable().isEmpty())
@@ -2291,9 +2307,18 @@ void QQmlJSCodeGenerator::generateEqualityOperation(int lhs, const QString &func
const auto primitive = m_typeResolver->jsPrimitiveType();
if (m_typeResolver->equals(lhsType, rhsType) && !m_typeResolver->equals(lhsType, primitive)) {
- m_body += conversion(m_typeResolver->boolType(), m_state.accumulatorOut().storedType(),
- registerVariable(lhs) + (invert ? u" != "_s : u" == "_s)
- + m_state.accumulatorVariableIn);
+ if (isTypeStorable(m_typeResolver, lhsType)) {
+ m_body += conversion(m_typeResolver->boolType(), m_state.accumulatorOut().storedType(),
+ registerVariable(lhs) + (invert ? u" != "_s : u" == "_s)
+ + m_state.accumulatorVariableIn);
+ } else if (m_typeResolver->equals(lhsType, m_typeResolver->emptyListType())) {
+ // We cannot compare two empty lists, because we don't know whether it's
+ // the same instance or not. "[] === []" is false, but "var a = []; a === a" is true;
+ reject(u"comparison of two empty lists"_s);
+ } else {
+ // null === null and undefined === undefined
+ m_body += invert ? u"false"_s : u"true"_s;
+ }
} else {
m_body += conversion(
m_typeResolver->boolType(), m_state.accumulatorOut().storedType(),
@@ -2462,7 +2487,7 @@ void QQmlJSCodeGenerator::generateJumpCodeWithTypeConversions(int relativeOffset
if (relativeOffset) {
auto labelIt = m_labels.find(absoluteOffset);
if (labelIt == m_labels.end())
- labelIt = m_labels.insert(absoluteOffset, u"label_%1"_s.arg(m_labels.count()));
+ labelIt = m_labels.insert(absoluteOffset, u"label_%1"_s.arg(m_labels.size()));
conversionCode += u" goto "_s + *labelIt + u";\n"_s;
}
@@ -2510,24 +2535,24 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
const auto jsPrimitiveType = m_typeResolver->jsPrimitiveType();
const auto boolType = m_typeResolver->boolType();
- auto zeroBoolOrNumeric = [&](const QQmlJSScope::ConstPtr &to) {
+ auto zeroBoolOrInt = [&](const QQmlJSScope::ConstPtr &to) {
if (m_typeResolver->equals(to, boolType))
return u"false"_s;
if (m_typeResolver->equals(to, m_typeResolver->intType()))
return u"0"_s;
- if (m_typeResolver->equals(to, m_typeResolver->floatType()))
- return u"0.0f"_s;
- if (m_typeResolver->equals(to, m_typeResolver->realType()))
- return u"0.0"_s;
return QString();
};
if (m_typeResolver->equals(from, m_typeResolver->voidType())) {
if (to->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
return u"static_cast<"_s + to->internalName() + u" *>(nullptr)"_s;
- const QString zero = zeroBoolOrNumeric(to);
+ const QString zero = zeroBoolOrInt(to);
if (!zero.isEmpty())
return zero;
+ if (m_typeResolver->equals(to, m_typeResolver->floatType()))
+ return u"std::numeric_limits<float>::quiet_NaN()"_s;
+ if (m_typeResolver->equals(to, m_typeResolver->realType()))
+ return u"std::numeric_limits<double>::quiet_NaN()"_s;
if (m_typeResolver->equals(to, m_typeResolver->stringType()))
return QQmlJSUtils::toLiteral(u"undefined"_s);
if (m_typeResolver->equals(from, to))
@@ -2545,9 +2570,13 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
return u"QJSPrimitiveValue(QJSPrimitiveNull())"_s;
if (m_typeResolver->equals(to, varType))
return u"QVariant::fromValue<std::nullptr_t>(nullptr)"_s;
- const QString zero = zeroBoolOrNumeric(to);
+ const QString zero = zeroBoolOrInt(to);
if (!zero.isEmpty())
return zero;
+ if (m_typeResolver->equals(to, m_typeResolver->floatType()))
+ return u"0.0f"_s;
+ if (m_typeResolver->equals(to, m_typeResolver->realType()))
+ return u"0.0"_s;
if (m_typeResolver->equals(to, m_typeResolver->stringType()))
return QQmlJSUtils::toLiteral(u"null"_s);
if (m_typeResolver->equals(from, to))
@@ -2702,21 +2731,6 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
return QString();
}
-int QQmlJSCodeGenerator::nextJSLine(uint line) const
-{
- auto findLine = [](uint line, const QV4::CompiledData::CodeOffsetToLine &entry) {
- return entry.line > line;
- };
- const auto codeToLine
- = std::upper_bound(m_context->lineNumberMapping.constBegin(),
- m_context->lineNumberMapping.constEnd(),
- line,
- findLine);
- bool bNoNextLine = m_context->lineNumberMapping.constEnd() == codeToLine;
-
- return static_cast<int>(bNoNextLine ? -1 : codeToLine->line);
-}
-
void QQmlJSCodeGenerator::reject(const QString &thing)
{
setError(u"Cannot generate efficient code for %1"_s.arg(thing));
diff --git a/src/qmlcompiler/qqmljscodegenerator_p.h b/src/qmlcompiler/qqmljscodegenerator_p.h
index fb54ac0ad2..6fdad57831 100644
--- a/src/qmlcompiler/qqmljscodegenerator_p.h
+++ b/src/qmlcompiler/qqmljscodegenerator_p.h
@@ -33,7 +33,7 @@ public:
QQmlJSCodeGenerator(const QV4::Compiler::Context *compilerContext,
const QV4::Compiler::JSUnitGenerator *unitGenerator,
const QQmlJSTypeResolver *typeResolver,
- QQmlJSLogger *logger, const QStringList &sourceCodeLines);
+ QQmlJSLogger *logger);
~QQmlJSCodeGenerator() = default;
QQmlJSAotFunction run(const Function *function, const InstructionAnnotations *annotations,
@@ -270,17 +270,12 @@ private:
return m_typeResolver->jsGlobalObject()->property(u"Math"_s).type();
}
- int nextJSLine(uint line) const;
-
- QStringList m_sourceCodeLines;
-
// map from instruction offset to sequential label number
QHash<int, QString> m_labels;
const QV4::Compiler::Context *m_context = nullptr;
const InstructionAnnotations *m_annotations = nullptr;
- int m_lastLineNumberUsed = -1;
bool m_skipUntilNextLabel = false;
QStringList m_includes;
diff --git a/src/qmlcompiler/qqmljscompilepass_p.h b/src/qmlcompiler/qqmljscompilepass_p.h
index 40e61464f5..5c4f1c4637 100644
--- a/src/qmlcompiler/qqmljscompilepass_p.h
+++ b/src/qmlcompiler/qqmljscompilepass_p.h
@@ -166,7 +166,7 @@ protected:
int firstRegisterIndex() const
{
- return FirstArgument + m_function->argumentTypes.count();
+ return FirstArgument + m_function->argumentTypes.size();
}
bool isArgument(int registerIndex) const
@@ -184,11 +184,11 @@ protected:
State initialState(const Function *function)
{
State state;
- for (int i = 0, end = function->argumentTypes.length(); i < end; ++i) {
+ for (int i = 0, end = function->argumentTypes.size(); i < end; ++i) {
state.registers[FirstArgument + i] = function->argumentTypes.at(i);
Q_ASSERT(state.registers[FirstArgument + i].isValid());
}
- for (int i = 0, end = function->registerTypes.length(); i != end; ++i)
+ for (int i = 0, end = function->registerTypes.size(); i != end; ++i)
state.registers[firstRegisterIndex() + i] = function->registerTypes[i];
return state;
}
diff --git a/src/qmlcompiler/qqmljscompiler.cpp b/src/qmlcompiler/qqmljscompiler.cpp
index 76a7ed80e2..d2e43b6f0b 100644
--- a/src/qmlcompiler/qqmljscompiler.cpp
+++ b/src/qmlcompiler/qqmljscompiler.cpp
@@ -87,7 +87,7 @@ static void annotateListElements(QmlIR::Document *document)
{
QStringList listElementNames;
- for (const QV4::CompiledData::Import *import : qAsConst(document->imports)) {
+ for (const QV4::CompiledData::Import *import : std::as_const(document->imports)) {
const QString uri = document->stringAt(import->uriIndex);
if (uri != QStringLiteral("QtQml.Models") && uri != QStringLiteral("QtQuick"))
continue;
@@ -104,7 +104,7 @@ static void annotateListElements(QmlIR::Document *document)
if (listElementNames.isEmpty())
return;
- for (QmlIR::Object *object : qAsConst(document->objects)) {
+ for (QmlIR::Object *object : std::as_const(document->objects)) {
if (!listElementNames.contains(document->stringAt(object->inheritedTypeNameIndex)))
continue;
for (QmlIR::Binding *binding = object->firstBinding(); binding; binding = binding->next) {
@@ -118,7 +118,7 @@ static void annotateListElements(QmlIR::Document *document)
static bool checkArgumentsObjectUseInSignalHandlers(const QmlIR::Document &doc,
QQmlJSCompileError *error)
{
- for (QmlIR::Object *object: qAsConst(doc.objects)) {
+ for (QmlIR::Object *object: std::as_const(doc.objects)) {
for (auto binding = object->bindingsBegin(); binding != object->bindingsEnd(); ++binding) {
if (binding->type() != QV4::CompiledData::Binding::Type_Script)
continue;
@@ -227,7 +227,7 @@ bool qCompileQmlFile(QmlIR::Document &irDocument, const QString &inputFileName,
aotCompiler->setDocument(&v4CodeGen, &irDocument);
QHash<QmlIR::Object *, QmlIR::Object *> effectiveScopes;
- for (QmlIR::Object *object: qAsConst(irDocument.objects)) {
+ for (QmlIR::Object *object: std::as_const(irDocument.objects)) {
if (object->functionsAndExpressions->count == 0 && object->bindingCount() == 0)
continue;
@@ -438,7 +438,7 @@ void wrapCall(const QQmlPrivate::AOTCompiledContext *aotContext, void *dataPtr,
{
using return_type = std::invoke_result_t<Binding, const QQmlPrivate::AOTCompiledContext *, void **>;
if constexpr (std::is_same_v<return_type, void>) {
- Q_UNUSED(dataPtr);
+ Q_UNUSED(dataPtr)
binding(aotContext, argumentsPtr);
} else {
if (dataPtr) {
@@ -453,8 +453,8 @@ void wrapCall(const QQmlPrivate::AOTCompiledContext *aotContext, void *dataPtr,
static const char *funcHeaderCode = R"(
[](const QQmlPrivate::AOTCompiledContext *aotContext, void *dataPtr, void **argumentsPtr) {
wrapCall(aotContext, dataPtr, argumentsPtr, [](const QQmlPrivate::AOTCompiledContext *aotContext, void **argumentsPtr) {
-Q_UNUSED(aotContext);
-Q_UNUSED(argumentsPtr);
+Q_UNUSED(aotContext)
+Q_UNUSED(argumentsPtr)
)";
bool qSaveQmlJSUnitAsCpp(const QString &inputFileName, const QString &outputFileName, const QV4::CompiledData::SaveableUnitPointer &unit, const QQmlJSAotFunctionMap &aotFunctions, QString *errorString)
@@ -509,7 +509,8 @@ bool qSaveQmlJSUnitAsCpp(const QString &inputFileName, const QString &outputFile
if (!writeStr(qQmlJSSymbolNamespaceForPath(inputFileName).toUtf8()))
return false;
- if (!writeStr(QByteArrayLiteral(" {\nextern const unsigned char qmlData alignas(16) [] = {\n")))
+ if (!writeStr(QByteArrayLiteral(" {\nextern const unsigned char qmlData alignas(16) [];\n"
+ "extern const unsigned char qmlData alignas(16) [] = {\n")))
return false;
unit.saveToDisk<uchar>([&writeStr](const uchar *begin, quint32 size) {
@@ -549,10 +550,12 @@ bool qSaveQmlJSUnitAsCpp(const QString &inputFileName, const QString &outputFile
writeStr(aotFunctions[FileScopeCodeIndex].code.toUtf8().constData());
if (aotFunctions.size() <= 1) {
// FileScopeCodeIndex is always there, but it may be the only one.
- writeStr("extern const QQmlPrivate::AOTCompiledFunction aotBuiltFunctions[] = { { 0, QMetaType::fromType<void>(), {}, nullptr } };");
+ writeStr("extern const QQmlPrivate::AOTCompiledFunction aotBuiltFunctions[];\n"
+ "extern const QQmlPrivate::AOTCompiledFunction aotBuiltFunctions[] = { { 0, QMetaType::fromType<void>(), {}, nullptr } };");
} else {
writeStr(wrapCallCode);
- writeStr("extern const QQmlPrivate::AOTCompiledFunction aotBuiltFunctions[] = {\n");
+ writeStr("extern const QQmlPrivate::AOTCompiledFunction aotBuiltFunctions[];\n"
+ "extern const QQmlPrivate::AOTCompiledFunction aotBuiltFunctions[] = {\n");
QString footer = QStringLiteral("});}\n");
@@ -621,7 +624,6 @@ void QQmlJSAotCompiler::setDocument(
m_logger->setFileName(resourcePathInfo.fileName());
m_logger->setCode(irDocument->code);
m_unitGenerator = &irDocument->jsGenerator;
- m_entireSourceCodeLines = irDocument->code.split(u'\n');
QQmlJSScope::Ptr target = QQmlJSScope::create();
QQmlJSImportVisitor visitor(target, m_importer, m_logger,
resourcePathInfo.canonicalPath() + u'/',
@@ -648,9 +650,8 @@ QQmlJS::DiagnosticMessage QQmlJSAotCompiler::diagnose(
const QString &message, QtMsgType type, const QQmlJS::SourceLocation &location) const
{
if (isStrict(m_document)
- && (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
- && !m_logger->isCategoryIgnored(Log_Compiler)
- && m_logger->categoryLevel(Log_Compiler) == QtCriticalMsg) {
+ && (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
+ && m_logger->isCategoryFatal(Log_Compiler)) {
qFatal("%s:%d: (strict mode) %s",
qPrintable(QFileInfo(m_resourcePath).fileName()),
location.startLine, qPrintable(message));
@@ -763,8 +764,7 @@ QQmlJSAotFunction QQmlJSAotCompiler::doCompile(
return compileError();
QQmlJSCodeGenerator codegen(
- context, m_unitGenerator, &m_typeResolver, m_logger,
- m_entireSourceCodeLines);
+ context, m_unitGenerator, &m_typeResolver, m_logger);
QQmlJSAotFunction result = codegen.run(function, &typePropagationResult, error);
return error->isValid() ? compileError() : result;
}
diff --git a/src/qmlcompiler/qqmljscompiler_p.h b/src/qmlcompiler/qqmljscompiler_p.h
index c6a60f5a94..45de4abaf1 100644
--- a/src/qmlcompiler/qqmljscompiler_p.h
+++ b/src/qmlcompiler/qqmljscompiler_p.h
@@ -75,7 +75,6 @@ protected:
const QString &message, QtMsgType type, const QQmlJS::SourceLocation &location) const;
QQmlJSTypeResolver m_typeResolver;
- QStringList m_entireSourceCodeLines;
const QString m_resourcePath;
const QStringList m_qmldirFiles;
diff --git a/src/qmlcompiler/qqmljsfunctioninitializer.cpp b/src/qmlcompiler/qqmljsfunctioninitializer.cpp
index 56d1d25124..528b4c0602 100644
--- a/src/qmlcompiler/qqmljsfunctioninitializer.cpp
+++ b/src/qmlcompiler/qqmljsfunctioninitializer.cpp
@@ -66,7 +66,7 @@ void QQmlJSFunctionInitializer::populateSignature(
arguments = ast->formals->formals();
if (function->argumentTypes.isEmpty()) {
- for (const QQmlJS::AST::BoundName &argument : qAsConst(arguments)) {
+ for (const QQmlJS::AST::BoundName &argument : std::as_const(arguments)) {
if (argument.typeAnnotation) {
if (const auto type = m_typeResolver->typeFromAST(argument.typeAnnotation->type)) {
function->argumentTypes.append(
@@ -97,7 +97,7 @@ void QQmlJSFunctionInitializer::populateSignature(
}
}
- for (int i = QQmlJSCompilePass::FirstArgument + function->argumentTypes.length();
+ for (int i = QQmlJSCompilePass::FirstArgument + function->argumentTypes.size();
i < context->registerCountInFunction; ++i) {
function->registerTypes.append(m_typeResolver->tracked(
m_typeResolver->globalType(m_typeResolver->voidType())));
diff --git a/src/qmlcompiler/qqmljsimporter.cpp b/src/qmlcompiler/qqmljsimporter.cpp
index f0897de99f..739ad70b7e 100644
--- a/src/qmlcompiler/qqmljsimporter.cpp
+++ b/src/qmlcompiler/qqmljsimporter.cpp
@@ -81,7 +81,7 @@ void QQmlJSImporter::readQmltypes(
QQmlJS::SourceLocation()
});
- for (const QString &dependency : qAsConst(dependencyStrings)) {
+ for (const QString &dependency : std::as_const(dependencyStrings)) {
const auto blank = dependency.indexOf(u' ');
if (blank < 0) {
dependencies->append(QQmlDirParser::Import(dependency, {},
@@ -265,11 +265,11 @@ void QQmlJSImporter::importDependencies(const QQmlJSImporter::Import &import,
{
// Import the dependencies with an invalid prefix. The prefix will never be matched by actual
// QML code but the C++ types will be visible.
- for (auto const &dependency : qAsConst(import.dependencies))
+ for (auto const &dependency : std::as_const(import.dependencies))
importHelper(dependency.module, types, QString(), dependency.version, true);
bool hasOptionalImports = false;
- for (auto const &import : qAsConst(import.imports)) {
+ for (auto const &import : std::as_const(import.imports)) {
if (import.flags & QQmlDirParser::Import::Optional) {
hasOptionalImports = true;
if (!m_useOptionalImports) {
@@ -576,7 +576,7 @@ void QQmlJSImporter::importQmldirs(const QStringList &qmldirFiles)
m_seenQmldirFiles.insert(qmldirName, result);
- for (const auto &object : qAsConst(result.objects)) {
+ for (const auto &object : std::as_const(result.objects)) {
for (const auto &ex : object.exports) {
m_seenImports.insert({ex.package(), ex.version()}, qmldirName);
// We also have to handle the case that no version is provided
@@ -696,7 +696,7 @@ bool QQmlJSImporter::importHelper(const QString &module, AvailableTypes *types,
if (modulePath.startsWith(u':')) {
if (m_mapper) {
const QString resourcePath = modulePath.mid(
- 1, modulePath.endsWith(u'/') ? modulePath.length() - 2 : -1)
+ 1, modulePath.endsWith(u'/') ? modulePath.size() - 2 : -1)
+ SlashQmldir;
const auto entry = m_mapper->entry(
QQmlJSResourceFileMapper::resourceFileFilter(resourcePath));
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp
index 5128b0f69c..6f2a8ee265 100644
--- a/src/qmlcompiler/qqmljsimportvisitor.cpp
+++ b/src/qmlcompiler/qqmljsimportvisitor.cpp
@@ -283,8 +283,8 @@ void QQmlJSImportVisitor::resolveAliasesAndIds()
if (doRequeue)
requeue.enqueue(object);
- if (objects.isEmpty() && requeue.length() < lastRequeueLength) {
- lastRequeueLength = requeue.length();
+ if (objects.isEmpty() && requeue.size() < lastRequeueLength) {
+ lastRequeueLength = requeue.size();
objects.swap(requeue);
}
}
@@ -547,7 +547,7 @@ void QQmlJSImportVisitor::processDefaultProperties()
const QQmlJSMetaProperty defaultProp = parentScope->property(defaultPropertyName);
- if (it.value().length() > 1 && !defaultProp.isList()) {
+ if (it.value().size() > 1 && !defaultProp.isList()) {
m_logger->log(
QStringLiteral("Cannot assign multiple objects to a default non-list property"),
Log_Property, it.value().constFirst()->sourceLocation());
@@ -618,7 +618,7 @@ void QQmlJSImportVisitor::processPropertyBindingObjects()
// literal bindings must already be added at this point.
QSet<QPair<QQmlJSScope::Ptr, QString>> visited;
for (const PendingPropertyObjectBinding &objectBinding :
- qAsConst(m_pendingPropertyObjectBindings)) {
+ std::as_const(m_pendingPropertyObjectBindings)) {
// unique because it's per-scope and per-property
const auto uniqueBindingId = qMakePair(objectBinding.scope, objectBinding.name);
if (visited.contains(uniqueBindingId))
@@ -640,7 +640,7 @@ void QQmlJSImportVisitor::processPropertyBindingObjects()
QSet<QPair<QQmlJSScope::Ptr, QString>> foundValueSources;
for (const PendingPropertyObjectBinding &objectBinding :
- qAsConst(m_pendingPropertyObjectBindings)) {
+ std::as_const(m_pendingPropertyObjectBindings)) {
const QString propertyName = objectBinding.name;
QQmlJSScope::ConstPtr childScope = objectBinding.childScope;
@@ -780,7 +780,7 @@ void QQmlJSImportVisitor::checkRequiredProperties()
QStringList aliasExpression =
property.aliasExpression().split(u'.');
- if (aliasExpression.length() != 2)
+ if (aliasExpression.size() != 2)
continue;
if (aliasExpression[0] == scopeId
&& aliasExpression[1] == propName) {
@@ -793,8 +793,8 @@ void QQmlJSImportVisitor::checkRequiredProperties()
if (propertyUsedInRootAlias)
continue;
- const QQmlJSScope::ConstPtr propertyScope = scopesToSearch.length() > 1
- ? scopesToSearch.at(scopesToSearch.length() - 2)
+ const QQmlJSScope::ConstPtr propertyScope = scopesToSearch.size() > 1
+ ? scopesToSearch.at(scopesToSearch.size() - 2)
: QQmlJSScope::ConstPtr();
const QString propertyScopeName = !propertyScope.isNull()
@@ -971,7 +971,7 @@ void QQmlJSImportVisitor::checkSignals()
const QStringList signalParameters = signalMethod->parameterNames();
- if (pair.second.length() > signalParameters.length()) {
+ if (pair.second.size() > signalParameters.size()) {
m_logger->log(QStringLiteral("Signal handler for \"%2\" has more formal"
" parameters than the signal it handles.")
.arg(pair.first),
@@ -979,7 +979,7 @@ void QQmlJSImportVisitor::checkSignals()
continue;
}
- for (qsizetype i = 0; i < pair.second.length(); i++) {
+ for (qsizetype i = 0; i < pair.second.size(); i++) {
const QStringView handlerParameter = pair.second.at(i);
const qsizetype j = signalParameters.indexOf(handlerParameter);
if (j == i || j < 0)
@@ -1043,7 +1043,7 @@ void QQmlJSImportVisitor::breakInheritanceCycles(const QQmlJSScope::Ptr &origina
for (QQmlJSScope::ConstPtr scope = originalScope; scope;) {
if (scopes.contains(scope)) {
QString inheritenceCycle;
- for (const auto &seen : qAsConst(scopes)) {
+ for (const auto &seen : std::as_const(scopes)) {
inheritenceCycle.append(seen->baseTypeName());
inheritenceCycle.append(QLatin1String(" -> "));
}
@@ -1273,7 +1273,7 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::StringLiteral *sl)
bool escaped = false;
const QChar stringQuote = s[0];
- for (qsizetype i = 1; i < s.length() - 1; i++) {
+ for (qsizetype i = 1; i < s.size() - 1; i++) {
const QChar c = s[i];
if (c == u'\\') {
@@ -1287,7 +1287,7 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::StringLiteral *sl)
} else {
if (c == u'`')
templateString += u'\\';
- if (c == u'$' && i + 1 < s.length() - 1 && s[i + 1] == u'{')
+ if (c == u'$' && i + 1 < s.size() - 1 && s[i + 1] == u'{')
templateString += u'\\';
}
@@ -1369,10 +1369,14 @@ bool QQmlJSImportVisitor::visit(UiInlineComponent *component)
return true;
}
-void QQmlJSImportVisitor::endVisit(UiInlineComponent *)
+void QQmlJSImportVisitor::endVisit(UiInlineComponent *component)
{
m_inlineComponentName = QStringView();
- Q_ASSERT(!m_nextIsInlineComponent);
+ if (m_nextIsInlineComponent) {
+ m_logger->log(u"Inline component declaration must be followed by a typename"_s,
+ Log_Syntax, component->firstSourceLocation());
+ }
+ m_nextIsInlineComponent = false; // might have missed an inline component if file contains invalid QML
}
bool QQmlJSImportVisitor::visit(UiPublicMember *publicMember)
@@ -1395,9 +1399,15 @@ bool QQmlJSImportVisitor::visit(UiPublicMember *publicMember)
QString aliasExpr;
const bool isAlias = (typeName == u"alias"_s);
if (isAlias) {
+ auto tryParseAlias = [&]() {
typeName.clear(); // type name is useless for alias here, so keep it empty
+ if (!publicMember->statement) {
+ m_logger->log(QStringLiteral("Invalid alias expression – an initalizer is needed."),
+ Log_Alias, publicMember->memberType->firstSourceLocation()); // TODO: extend warning to cover until endSourceLocation
+ return;
+ }
const auto expression = cast<ExpressionStatement *>(publicMember->statement);
- auto node = expression->expression;
+ auto node = expression ? expression->expression : nullptr;
auto fex = cast<FieldMemberExpression *>(node);
while (fex) {
node = fex->base;
@@ -1412,6 +1422,8 @@ bool QQmlJSImportVisitor::visit(UiPublicMember *publicMember)
"member expressions can be aliased."),
Log_Alias, expression->firstSourceLocation());
}
+ };
+ tryParseAlias();
} else {
const QString name = buildName(publicMember->memberType);
if (m_rootScopeImports.contains(name) && !m_rootScopeImports[name].scope.isNull()) {
diff --git a/src/qmlcompiler/qqmljslinter.cpp b/src/qmlcompiler/qqmljslinter.cpp
index 03eb481f5a..5c947cd321 100644
--- a/src/qmlcompiler/qqmljslinter.cpp
+++ b/src/qmlcompiler/qqmljslinter.cpp
@@ -223,9 +223,9 @@ void QQmlJSLinter::parseComments(QQmlJSLogger *logger,
if (!comment.startsWith(u" qmllint ") && !comment.startsWith(u"qmllint "))
continue;
- QStringList words = comment.split(u' ');
- if (words.constFirst().isEmpty())
- words.removeFirst();
+ QStringList words = comment.split(u' ', Qt::SkipEmptyParts);
+ if (words.size() < 2)
+ continue;
const QString command = words.at(1);
@@ -246,21 +246,23 @@ void QQmlJSLinter::parseComments(QQmlJSLogger *logger,
}
if (command == u"disable"_s) {
- const QString line = lines[loc.startLine - 1];
- const QString preComment = line.left(line.indexOf(comment) - 2);
-
- bool lineHasContent = false;
- for (qsizetype i = 0; i < preComment.size(); i++) {
- if (!preComment[i].isSpace()) {
- lineHasContent = true;
- break;
+ if (const qsizetype lineIndex = loc.startLine - 1; lineIndex < lines.size()) {
+ const QString line = lines[loc.startLine - 1];
+ const QString preComment = line.left(line.indexOf(comment) - 2);
+
+ bool lineHasContent = false;
+ for (qsizetype i = 0; i < preComment.size(); i++) {
+ if (!preComment[i].isSpace()) {
+ lineHasContent = true;
+ break;
+ }
}
- }
- if (lineHasContent)
- oneLineDisablesPerLine[loc.startLine] |= categories;
- else
- disablesPerLine[loc.startLine] |= categories;
+ if (lineHasContent)
+ oneLineDisablesPerLine[loc.startLine] |= categories;
+ else
+ disablesPerLine[loc.startLine] |= categories;
+ }
} else if (command == u"enable"_s) {
enablesPerLine[loc.startLine + 1] |= categories;
} else {
diff --git a/src/qmlcompiler/qqmljslintercodegen.cpp b/src/qmlcompiler/qqmljslintercodegen.cpp
index dfa474fc46..e362044779 100644
--- a/src/qmlcompiler/qqmljslintercodegen.cpp
+++ b/src/qmlcompiler/qqmljslintercodegen.cpp
@@ -28,7 +28,6 @@ void QQmlJSLinterCodegen::setDocument(const QmlIR::JSCodeGen *codegen,
Q_UNUSED(codegen);
m_document = document;
m_unitGenerator = &document->jsGenerator;
- m_entireSourceCodeLines = document->code.split(u'\n');
}
std::variant<QQmlJSAotFunction, QQmlJS::DiagnosticMessage>
diff --git a/src/qmlcompiler/qqmljsloadergenerator.cpp b/src/qmlcompiler/qqmljsloadergenerator.cpp
index 21be215bba..494ecdadd0 100644
--- a/src/qmlcompiler/qqmljsloadergenerator.cpp
+++ b/src/qmlcompiler/qqmljsloadergenerator.cpp
@@ -49,7 +49,7 @@ QString mangledIdentifier(const QString &str)
}
}
- for (int ei = str.length(); i != ei; ++i) {
+ for (int ei = str.size(); i != ei; ++i) {
auto c = str.at(i).unicode();
if ((c >= QLatin1Char('0') && c <= QLatin1Char('9'))
|| (c >= QLatin1Char('a') && c <= QLatin1Char('z'))
@@ -68,7 +68,7 @@ QString qQmlJSSymbolNamespaceForPath(const QString &relativePath)
{
QFileInfo fi(relativePath);
QString symbol = fi.path();
- if (symbol.length() == 1 && symbol.startsWith(QLatin1Char('.'))) {
+ if (symbol.size() == 1 && symbol.startsWith(QLatin1Char('.'))) {
symbol.clear();
} else {
symbol.replace(QLatin1Char('/'), QLatin1Char('_'));
@@ -105,7 +105,7 @@ bool qQmlJSGenerateLoader(const QStringList &compiledFiles, const QString &outpu
stream << "\n";
stream << "namespace QmlCacheGeneratedCode {\n";
- for (int i = 0; i < compiledFiles.count(); ++i) {
+ for (int i = 0; i < compiledFiles.size(); ++i) {
const QString compiledFile = compiledFiles.at(i);
const QString ns = qQmlJSSymbolNamespaceForPath(compiledFile);
stream << "namespace " << ns << " { \n";
@@ -131,7 +131,7 @@ bool qQmlJSGenerateLoader(const QStringList &compiledFiles, const QString &outpu
stream << "Registry::Registry() {\n";
- for (int i = 0; i < compiledFiles.count(); ++i) {
+ for (int i = 0; i < compiledFiles.size(); ++i) {
const QString qrcFile = compiledFiles.at(i);
const QString ns = qQmlJSSymbolNamespaceForPath(qrcFile);
stream << " resourcePathToCachedUnit.insert(QStringLiteral(\"" << qrcFile << "\"), &QmlCacheGeneratedCode::" << ns << "::unit);\n";
diff --git a/src/qmlcompiler/qqmljslogger.cpp b/src/qmlcompiler/qqmljslogger.cpp
index d8b1fe096f..9c22f55287 100644
--- a/src/qmlcompiler/qqmljslogger.cpp
+++ b/src/qmlcompiler/qqmljslogger.cpp
@@ -223,7 +223,7 @@ void QQmlJSLogger::printContext(const QString &overrideFileName,
int tabCount = issueLocationWithContext.beforeText().count(QLatin1Char('\t'));
int locationLength = location.length == 0 ? 1 : location.length;
- m_output.write(QString::fromLatin1(" ").repeated(issueLocationWithContext.beforeText().length()
+ m_output.write(QString::fromLatin1(" ").repeated(issueLocationWithContext.beforeText().size()
- tabCount)
+ QString::fromLatin1("\t").repeated(tabCount)
+ QString::fromLatin1("^").repeated(locationLength) + QLatin1Char('\n'));
@@ -278,9 +278,9 @@ void QQmlJSLogger::printFix(const FixSuggestion &fix)
continue;
m_output.write(u" "_s.repeated(
- issueLocationWithContext.beforeText().length() - tabCount)
+ issueLocationWithContext.beforeText().size() - tabCount)
+ u"\t"_s.repeated(tabCount)
- + u"^"_s.repeated(fixItem.replacementString.length()) + u'\n');
+ + u"^"_s.repeated(fixItem.replacementString.size()) + u'\n');
}
}
diff --git a/src/qmlcompiler/qqmljslogger_p.h b/src/qmlcompiler/qqmljslogger_p.h
index 0302201eaf..9c89fd754a 100644
--- a/src/qmlcompiler/qqmljslogger_p.h
+++ b/src/qmlcompiler/qqmljslogger_p.h
@@ -201,6 +201,16 @@ public:
m_categoryChanged[category] = true;
}
+ bool isCategoryFatal(QQmlJSLoggerCategory category) const
+ {
+ return m_categoryFatal[category];
+ }
+ void setCategoryFatal(QQmlJSLoggerCategory category, bool error)
+ {
+ m_categoryFatal[category] = error;
+ m_categoryChanged[category] = true;
+ }
+
bool wasCategoryChanged(QQmlJSLoggerCategory category) const
{
return m_categoryChanged[category];
@@ -257,6 +267,10 @@ private:
bool m_categoryIgnored[QQmlJSLoggerCategory_Last + 1] = {};
bool m_categoryChanged[QQmlJSLoggerCategory_Last + 1] = {};
+ // If true, triggers qFatal on documents with "pragma Strict"
+ // TODO: Works only for qmlCompiler category so far.
+ bool m_categoryFatal[QQmlJSLoggerCategory_Last + 1] = {};
+
QList<Message> m_infos;
QList<Message> m_warnings;
QList<Message> m_errors;
diff --git a/src/qmlcompiler/qqmljsmetatypes_p.h b/src/qmlcompiler/qqmljsmetatypes_p.h
index 75f635d5d0..e2987984fb 100644
--- a/src/qmlcompiler/qqmljsmetatypes_p.h
+++ b/src/qmlcompiler/qqmljsmetatypes_p.h
@@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE
class QQmlJSTypeResolver;
class QQmlJSScope;
-class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSMetaEnum
+class QQmlJSMetaEnum
{
QStringList m_keys;
QList<int> m_values; // empty if values unknown.
@@ -98,7 +98,7 @@ public:
}
};
-class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSMetaMethod
+class QQmlJSMetaMethod
{
public:
enum Type {
@@ -158,7 +158,7 @@ public:
}
void setParameterTypes(const QList<QSharedPointer<const QQmlJSScope>> &types)
{
- Q_ASSERT(types.length() == m_paramNames.length());
+ Q_ASSERT(types.size() == m_paramNames.size());
m_paramTypes.clear();
for (const auto &type : types)
m_paramTypes.append(type);
@@ -262,7 +262,7 @@ private:
bool m_isImplicitQmlPropertyChangeSignal = false;
};
-class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSMetaProperty
+class QQmlJSMetaProperty
{
QString m_propertyName;
QString m_typeName;
diff --git a/src/qmlcompiler/qqmljsresourcefilemapper.cpp b/src/qmlcompiler/qqmljsresourcefilemapper.cpp
index b9ae292018..4213902fb3 100644
--- a/src/qmlcompiler/qqmljsresourcefilemapper.cpp
+++ b/src/qmlcompiler/qqmljsresourcefilemapper.cpp
@@ -101,7 +101,7 @@ void doFilter(const QList<QQmlJSResourceFileMapper::Entry> &qrcPathToFileSystemP
if ((filter.flags & QQmlJSResourceFileMapper::Recurse)
// Crude. But shall we really allow slashes in QRC file names?
- || !candidate.mid(terminatedDirectory.length()).contains(u'/')) {
+ || !candidate.mid(terminatedDirectory.size()).contains(u'/')) {
if (handler(*it))
return;
}
diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp
index 3e0cff0e52..03d47203ce 100644
--- a/src/qmlcompiler/qqmljsscope.cpp
+++ b/src/qmlcompiler/qqmljsscope.cpp
@@ -267,6 +267,9 @@ bool QQmlJSScope::causesImplicitComponentWrapping(const QQmlJSMetaProperty &prop
Either because it has been implicitly wrapped, e.g. due to an assignment to
a Component property, or because it is the first (and only) child of a
Component.
+ For visitors: This method should only be called after implicit components
+ are detected, that is, after QQmlJSImportVisitor::endVisit(UiProgram *)
+ was called.
*/
bool QQmlJSScope::isComponentRootElement() const {
if (m_flags.testFlag(WrappedInImplicitComponent))
@@ -339,7 +342,7 @@ QQmlJSScope::ImportedScope<QQmlJSScope::ConstPtr> QQmlJSScope::findType(
const QString outerTypeName = name.left(colonColon);
const auto outerType = contextualTypes.constFind(outerTypeName);
if (outerType != contextualTypes.constEnd()) {
- for (const auto &innerType : qAsConst(outerType->scope->m_childScopes)) {
+ for (const auto &innerType : std::as_const(outerType->scope->m_childScopes)) {
if (innerType->m_internalName == name) {
if (usedTypes != nullptr)
usedTypes->insert(name);
@@ -394,10 +397,10 @@ QTypeRevision QQmlJSScope::resolveType(
const auto paramTypeNames = it->parameterTypeNames();
QList<QSharedPointer<const QQmlJSScope>> paramTypes = it->parameterTypes();
- if (paramTypes.length() < paramTypeNames.length())
- paramTypes.resize(paramTypeNames.length());
+ if (paramTypes.size() < paramTypeNames.size())
+ paramTypes.resize(paramTypeNames.size());
- for (int i = 0, length = paramTypes.length(); i < length; ++i) {
+ for (int i = 0, length = paramTypes.size(); i < length; ++i) {
auto &paramType = paramTypes[i];
const auto paramTypeName = paramTypeNames[i];
if (!paramType && !paramTypeName.isEmpty()) {
diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h
index 46aee20d90..6047d0c1d9 100644
--- a/src/qmlcompiler/qqmljsscope_p.h
+++ b/src/qmlcompiler/qqmljsscope_p.h
@@ -278,10 +278,30 @@ public:
{
using namespace Qt::StringLiterals;
- QString suffix;
- if (m_semantics == AccessSemantics::Reference)
- suffix = u" *"_s;
- return m_internalName + suffix;
+ switch (m_semantics) {
+ case AccessSemantics::Reference:
+ return m_internalName + " *"_L1;
+ case AccessSemantics::Value:
+ case AccessSemantics::Sequence:
+ break;
+ case AccessSemantics::None:
+ // If we got a namespace, it might still be a regular type, exposed as namespace.
+ // We may need to travel the inheritance chain all the way up to QObject to
+ // figure this out, since all other types may be exposed the same way.
+ for (QQmlJSScope::ConstPtr base = baseType(); base; base = base->baseType()) {
+ switch (base->accessSemantics()) {
+ case AccessSemantics::Reference:
+ return m_internalName + " *"_L1;
+ case AccessSemantics::Value:
+ case AccessSemantics::Sequence:
+ return m_internalName;
+ case AccessSemantics::None:
+ break;
+ }
+ }
+ break;
+ }
+ return m_internalName;
}
// This returns a more user readable version of internalName / baseTypeName
diff --git a/src/qmlcompiler/qqmljsshadowcheck.cpp b/src/qmlcompiler/qqmljsshadowcheck.cpp
index 719eeaef31..086b778263 100644
--- a/src/qmlcompiler/qqmljsshadowcheck.cpp
+++ b/src/qmlcompiler/qqmljsshadowcheck.cpp
@@ -36,11 +36,14 @@ void QQmlJSShadowCheck::run(
m_function = function;
m_error = error;
m_state = initialState(function);
- decode(m_function->code.constData(), static_cast<uint>(m_function->code.length()));
+ decode(m_function->code.constData(), static_cast<uint>(m_function->code.size()));
}
void QQmlJSShadowCheck::generate_LoadProperty(int nameIndex)
{
+ if (!m_state.readsRegister(Accumulator))
+ return; // enum lookup cannot be shadowed.
+
auto accumulatorIn = m_state.registers.find(Accumulator);
if (accumulatorIn != m_state.registers.end())
checkShadowing(accumulatorIn.value(), m_jsUnitGenerator->stringForIndex(nameIndex));
@@ -48,6 +51,9 @@ void QQmlJSShadowCheck::generate_LoadProperty(int nameIndex)
void QQmlJSShadowCheck::generate_GetLookup(int index)
{
+ if (!m_state.readsRegister(Accumulator))
+ return; // enum lookup cannot be shadowed.
+
auto accumulatorIn = m_state.registers.find(Accumulator);
if (accumulatorIn != m_state.registers.end())
checkShadowing(accumulatorIn.value(), m_jsUnitGenerator->lookupName(index));
diff --git a/src/qmlcompiler/qqmljsstreamwriter.cpp b/src/qmlcompiler/qqmljsstreamwriter.cpp
index 093d15dbd4..e435b8df92 100644
--- a/src/qmlcompiler/qqmljsstreamwriter.cpp
+++ b/src/qmlcompiler/qqmljsstreamwriter.cpp
@@ -161,7 +161,7 @@ void QQmlJSStreamWriter::flushPotentialLinesWithNewlines()
{
if (m_maybeOneline)
m_stream->write("\n");
- for (const QByteArray &line : qAsConst(m_pendingLines)) {
+ for (const QByteArray &line : std::as_const(m_pendingLines)) {
writeIndent();
m_stream->write(line);
m_stream->write("\n");
diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp
index bab06d1035..9469380bba 100644
--- a/src/qmlcompiler/qqmljstypepropagator.cpp
+++ b/src/qmlcompiler/qqmljstypepropagator.cpp
@@ -50,7 +50,7 @@ QQmlJSCompilePass::InstructionAnnotations QQmlJSTypePropagator::run(
m_state.State::operator=(initialState(m_function));
reset();
- decode(m_function->code.constData(), static_cast<uint>(m_function->code.length()));
+ decode(m_function->code.constData(), static_cast<uint>(m_function->code.size()));
// If we have found unresolved backwards jumps, we need to start over with a fresh state.
// Mind that m_jumpOriginRegisterStateByTargetInstructionOffset is retained in that case.
@@ -287,20 +287,20 @@ void QQmlJSTypePropagator::handleUnqualifiedAccess(const QString &name, bool isM
if (isMethod) {
if (isCallingProperty(m_function->qmlScope, name))
return;
- } else if (isMissingPropertyType(m_function->qmlScope, name)) {
+ } else if (propertyResolution(m_function->qmlScope, name) != PropertyMissing) {
return;
}
std::optional<FixSuggestion> suggestion;
auto childScopes = m_function->qmlScope->childScopes();
- for (qsizetype i = 0; i < m_function->qmlScope->childScopes().length(); i++) {
+ for (qsizetype i = 0; i < m_function->qmlScope->childScopes().size(); i++) {
auto &scope = childScopes[i];
if (location.offset > scope->sourceLocation().offset) {
- if (i + 1 < childScopes.length()
+ if (i + 1 < childScopes.size()
&& childScopes.at(i + 1)->sourceLocation().offset < location.offset)
continue;
- if (scope->childScopes().length() == 0)
+ if (scope->childScopes().size() == 0)
continue;
const auto jsId = scope->childScopes().first()->findJSIdentifier(name);
@@ -481,18 +481,20 @@ bool QQmlJSTypePropagator::isRestricted(const QString &propertyName) const
}
// Only to be called once a lookup has already failed
-bool QQmlJSTypePropagator::isMissingPropertyType(QQmlJSScope::ConstPtr scope,
- const QString &propertyName) const
+QQmlJSTypePropagator::PropertyResolution QQmlJSTypePropagator::propertyResolution(
+ QQmlJSScope::ConstPtr scope, const QString &propertyName) const
{
auto property = scope->property(propertyName);
if (!property.isValid())
- return false;
+ return PropertyMissing;
QString errorType;
if (property.type().isNull())
errorType = u"found"_s;
else if (!property.type()->isFullyResolved())
errorType = u"fully resolved"_s;
+ else
+ return PropertyFullyResolved;
Q_ASSERT(!errorType.isEmpty());
@@ -501,7 +503,7 @@ bool QQmlJSTypePropagator::isMissingPropertyType(QQmlJSScope::ConstPtr scope,
.arg(property.typeName(), propertyName, errorType),
Log_Type, getCurrentSourceLocation());
- return true;
+ return PropertyTypeUnresolved;
}
bool QQmlJSTypePropagator::isCallingProperty(QQmlJSScope::ConstPtr scope, const QString &name) const
@@ -664,6 +666,10 @@ void QQmlJSTypePropagator::generate_StoreElement(int base, int index)
addReadAccumulator(jsValue);
addReadRegister(base, jsValue);
addReadRegister(index, jsValue);
+
+ // Writing to a JS array can have side effects all over the place since it's
+ // passed by reference.
+ m_state.setHasSideEffects(true);
return;
}
@@ -777,7 +783,7 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName)
auto baseType = m_typeResolver->containedType(m_state.accumulatorIn());
// Warn separately when a property is only not found because of a missing type
- if (isMissingPropertyType(baseType, propertyName))
+ if (propertyResolution(baseType, propertyName) != PropertyMissing)
return;
std::optional<FixSuggestion> fixSuggestion;
@@ -808,7 +814,7 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName)
return;
}
- if (m_state.accumulatorOut().isMethod() && m_state.accumulatorOut().method().length() != 1) {
+ if (m_state.accumulatorOut().isMethod() && m_state.accumulatorOut().method().size() != 1) {
setError(u"Cannot determine overloaded method on loadProperty"_s);
return;
}
@@ -1026,8 +1032,9 @@ void QQmlJSTypePropagator::generate_CallProperty(int nameIndex, int base, int ar
if (m_passManager != nullptr) {
// TODO: Should there be an analyzeCall() in the future? (w. corresponding onCall in Pass)
- m_passManager->analyzeRead(m_typeResolver->containedType(m_state.accumulatorIn()),
- propertyName, m_function->qmlScope, getCurrentSourceLocation());
+ m_passManager->analyzeRead(
+ m_typeResolver->containedType(callBase),
+ propertyName, m_function->qmlScope, getCurrentSourceLocation());
}
addReadRegister(base, callBase);
@@ -1159,8 +1166,8 @@ void QQmlJSTypePropagator::propagateCall(const QList<QQmlJSMetaMethod> &methods,
const QQmlJSMetaMethod match = bestMatchForCall(methods, argc, argv, &errors);
if (!match.isValid()) {
- Q_ASSERT(errors.length() == methods.length());
- if (methods.length() == 1)
+ Q_ASSERT(errors.size() == methods.size());
+ if (methods.size() == 1)
setError(errors.first());
else
setError(u"No matching override found. Candidates:\n"_s + errors.join(u'\n'));
@@ -1180,7 +1187,7 @@ void QQmlJSTypePropagator::propagateCall(const QList<QQmlJSMetaMethod> &methods,
m_state.setHasSideEffects(true);
const auto types = match.parameterTypes();
for (int i = 0; i < argc; ++i) {
- if (i < types.length()) {
+ if (i < types.size()) {
const QQmlJSScope::ConstPtr type = match.isJavaScriptFunction()
? m_typeResolver->jsValueType()
: QQmlJSScope::ConstPtr(types.at(i));
@@ -2156,12 +2163,12 @@ QString QQmlJSTypePropagator::registerName(int registerIndex) const
if (registerIndex == Accumulator)
return u"accumulator"_s;
if (registerIndex >= FirstArgument
- && registerIndex < FirstArgument + m_function->argumentTypes.count()) {
+ && registerIndex < FirstArgument + m_function->argumentTypes.size()) {
return u"argument %1"_s.arg(registerIndex - FirstArgument);
}
return u"temporary register %1"_s.arg(
- registerIndex - FirstArgument - m_function->argumentTypes.count());
+ registerIndex - FirstArgument - m_function->argumentTypes.size());
}
QQmlJSRegisterContent QQmlJSTypePropagator::checkedInputRegister(int reg)
diff --git a/src/qmlcompiler/qqmljstypepropagator_p.h b/src/qmlcompiler/qqmljstypepropagator_p.h
index 30967413b9..06fc2c9793 100644
--- a/src/qmlcompiler/qqmljstypepropagator_p.h
+++ b/src/qmlcompiler/qqmljstypepropagator_p.h
@@ -191,7 +191,14 @@ private:
void checkDeprecated(QQmlJSScope::ConstPtr scope, const QString &name, bool isMethod) const;
bool isRestricted(const QString &propertyName) const;
bool isCallingProperty(QQmlJSScope::ConstPtr scope, const QString &name) const;
- bool isMissingPropertyType(QQmlJSScope::ConstPtr scope, const QString &type) const;
+
+ enum PropertyResolution {
+ PropertyMissing,
+ PropertyTypeUnresolved,
+ PropertyFullyResolved
+ };
+
+ PropertyResolution propertyResolution(QQmlJSScope::ConstPtr scope, const QString &type) const;
QQmlJS::SourceLocation getCurrentSourceLocation() const;
QQmlJS::SourceLocation getCurrentBindingSourceLocation() const;
diff --git a/src/qmlcompiler/qqmljstyperesolver.cpp b/src/qmlcompiler/qqmljstyperesolver.cpp
index 046a79ce01..eeb5f605f0 100644
--- a/src/qmlcompiler/qqmljstyperesolver.cpp
+++ b/src/qmlcompiler/qqmljstyperesolver.cpp
@@ -38,6 +38,10 @@ QQmlJSTypeResolver::QQmlJSTypeResolver(QQmlJSImporter *importer)
m_varType = builtinTypes[u"QVariant"_s].scope;
m_jsValueType = builtinTypes[u"QJSValue"_s].scope;
+ QQmlJSScope::Ptr emptyType = QQmlJSScope::create();
+ emptyType->setAccessSemantics(QQmlJSScope::AccessSemantics::None);
+ m_emptyType = emptyType;
+
QQmlJSScope::Ptr emptyListType = QQmlJSScope::create();
emptyListType->setInternalName(u"void*"_s);
emptyListType->setAccessSemantics(QQmlJSScope::AccessSemantics::Sequence);
@@ -70,7 +74,7 @@ QQmlJSTypeResolver::QQmlJSTypeResolver(QQmlJSImporter *importer)
m_jsGlobalObject = importer->jsGlobalObject();
auto numberMethods = m_jsGlobalObject->methods(u"Number"_s);
- Q_ASSERT(numberMethods.length() == 1);
+ Q_ASSERT(numberMethods.size() == 1);
m_numberPrototype = numberMethods[0].returnType()->baseType();
Q_ASSERT(m_numberPrototype);
Q_ASSERT(m_numberPrototype->internalName() == u"NumberPrototype"_s);
@@ -169,7 +173,10 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::typeForConst(QV4::ReturnedValue rv) co
return realType();
if (value.isNull())
- return jsPrimitiveType();
+ return nullType();
+
+ if (value.isEmpty())
+ return emptyType();
return {};
}
@@ -396,6 +403,64 @@ QQmlJSRegisterContent QQmlJSTypeResolver::transformed(
return {};
}
+QQmlJSRegisterContent QQmlJSTypeResolver::referenceTypeForName(
+ const QString &name, const QQmlJSScope::ConstPtr &scopeType,
+ bool hasObjectModulePrefix) const
+{
+ QQmlJSScope::ConstPtr type = typeForName(name);
+ if (!type)
+ return QQmlJSRegisterContent();
+
+ if (type->isSingleton())
+ return QQmlJSRegisterContent::create(storedType(type), type,
+ QQmlJSRegisterContent::Singleton, scopeType);
+
+ if (type->isScript())
+ return QQmlJSRegisterContent::create(storedType(type), type,
+ QQmlJSRegisterContent::Script, scopeType);
+
+ if (const auto attached = type->attachedType()) {
+ if (!genericType(attached)) {
+ m_logger->log(u"Cannot resolve generic base of attached %1"_s.arg(
+ attached->internalName()),
+ Log_Compiler, attached->sourceLocation());
+ return {};
+ } else if (type->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
+ m_logger->log(u"Cannot retrieve attached object for non-reference type %1"_s.arg(
+ type->internalName()),
+ Log_Compiler, type->sourceLocation());
+ return {};
+ } else {
+ // We don't know yet whether we need the attached or the plain object. In direct
+ // mode, we will figure this out using the scope type and access any enums of the
+ // plain type directly. In indirect mode, we can use enum lookups.
+ return QQmlJSRegisterContent::create(
+ storedType(attached), attached,
+ hasObjectModulePrefix
+ ? QQmlJSRegisterContent::ObjectAttached
+ : QQmlJSRegisterContent::ScopeAttached, type);
+ }
+ }
+
+ switch (type->accessSemantics()) {
+ case QQmlJSScope::AccessSemantics::None:
+ case QQmlJSScope::AccessSemantics::Reference:
+ // A plain reference to a non-singleton, non-attached type.
+ // We may still need the plain type reference for enum lookups,
+ // Store it as QMetaObject.
+ // This only works with namespaces and object types.
+ return QQmlJSRegisterContent::create(metaObjectType(), metaObjectType(),
+ QQmlJSRegisterContent::MetaType, type);
+ case QQmlJSScope::AccessSemantics::Sequence:
+ case QQmlJSScope::AccessSemantics::Value:
+ // This is not actually a type reference. You cannot get the metaobject
+ // of a value type in QML and sequences don't even have metaobjects.
+ break;
+ }
+
+ return QQmlJSRegisterContent();
+}
+
QQmlJSRegisterContent QQmlJSTypeResolver::original(const QQmlJSRegisterContent &type) const
{
return transformed(type, &QQmlJSTypeResolver::originalType);
@@ -643,7 +708,8 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::genericType(const QQmlJSScope::ConstPt
return m_metaObjectType;
if (type->accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
- for (auto base = type; base; base = base->baseType()) {
+ QString unresolvedBaseTypeName;
+ for (auto base = type; base;) {
// QObject and QQmlComponent are the two required base types.
// Any QML type system has to define those, or use the ones from builtins.
// As QQmlComponent is derived from QObject, we can restrict ourselves to the latter.
@@ -655,10 +721,19 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::genericType(const QQmlJSScope::ConstPt
&& base->internalName() == u"QQmlComponent"_s) {
return base;
}
+
+ if (auto baseBase = base->baseType()) {
+ base = baseBase;
+ } else {
+ unresolvedBaseTypeName = base->baseTypeName();
+ break;
+ }
}
- m_logger->log(u"Object type %1 is not derived from QObject or QQmlComponent"_s.arg(
- type->internalName()),
+ m_logger->log(u"Object type %1 is not derived from QObject or QQmlComponent. "
+ "You may need to fully qualify all names in C++ so that moc can see them. "
+ "You may also need to add qt_extract_metatypes(<target containing %2>)."_s
+ .arg(type->internalName(), unresolvedBaseTypeName),
Log_Compiler, type->sourceLocation());
// Reference types that are not QObject or QQmlComponent are likely JavaScript objects.
@@ -685,6 +760,7 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::genericType(const QQmlJSScope::ConstPt
return type;
if (const QQmlJSScope::ConstPtr valueType = type->valueType())
return listType(genericType(valueType), UseQObjectList);
+ return m_variantListType;
}
return m_varType;
@@ -802,51 +878,9 @@ QQmlJSRegisterContent QQmlJSTypeResolver::scopedType(const QQmlJSScope::ConstPtr
}
}
- if (QQmlJSScope::ConstPtr type = typeForName(name)) {
- if (type->isSingleton())
- return QQmlJSRegisterContent::create(storedType(type), type,
- QQmlJSRegisterContent::Singleton);
-
- if (type->isScript())
- return QQmlJSRegisterContent::create(storedType(type), type,
- QQmlJSRegisterContent::Script);
-
- if (const auto attached = type->attachedType()) {
- if (!genericType(attached)) {
- m_logger->log(u"Cannot resolve generic base of attached %1"_s.arg(
- attached->internalName()),
- Log_Compiler, attached->sourceLocation());
- return {};
- } else if (type->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
- m_logger->log(u"Cannot retrieve attached object for non-reference type %1"_s.arg(
- type->internalName()),
- Log_Compiler, type->sourceLocation());
- return {};
- } else {
- // We don't know yet whether we need the attached or the plain object. In direct
- // mode, we will figure this out using the scope type and access any enums of the
- // plain type directly. In indirect mode, we can use enum lookups.
- return QQmlJSRegisterContent::create(storedType(attached), attached,
- QQmlJSRegisterContent::ScopeAttached, type);
- }
- }
-
- switch (type->accessSemantics()) {
- case QQmlJSScope::AccessSemantics::None:
- case QQmlJSScope::AccessSemantics::Reference:
- // A plain reference to a non-singleton, non-attached type.
- // We may still need the plain type reference for enum lookups,
- // Store it as QMetaObject.
- // This only works with namespaces and object types.
- return QQmlJSRegisterContent::create(metaObjectType(), metaObjectType(),
- QQmlJSRegisterContent::MetaType, type);
- case QQmlJSScope::AccessSemantics::Sequence:
- case QQmlJSScope::AccessSemantics::Value:
- // This is not actually a type reference. You cannot get the metaobject
- // of a value type in QML and sequences don't even have metaobjects.
- break;
- }
- }
+ QQmlJSRegisterContent result = referenceTypeForName(name);
+ if (result.isValid())
+ return result;
if (m_jsGlobalObject->hasProperty(name)) {
return QQmlJSRegisterContent::create(jsValueType(), m_jsGlobalObject->property(name),
@@ -987,6 +1021,10 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(const QQmlJSScope::ConstPtr
{
QQmlJSRegisterContent result;
+ // If we got a plain type reference we have to check the enums of the _scope_.
+ if (equals(type, metaObjectType()))
+ return {};
+
if (equals(type, jsValueType())) {
QQmlJSMetaProperty prop;
prop.setPropertyName(name);
@@ -1134,34 +1172,9 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(const QQmlJSRegisterContent
return {};
}
- if (QQmlJSScope::ConstPtr result = typeForName(name)) {
- QQmlJSScope::ConstPtr attached = result->attachedType();
- if (attached && genericType(attached)) {
- return QQmlJSRegisterContent::create(
- storedType(attached), attached,
- type.variant() == QQmlJSRegisterContent::ObjectModulePrefix
- ? QQmlJSRegisterContent::ObjectAttached
- : QQmlJSRegisterContent::ScopeAttached,
- result);
- }
-
- if (result->isSingleton()) {
- return QQmlJSRegisterContent::create(
- storedType(result), result,
- QQmlJSRegisterContent::Singleton, type.scopeType());
- }
-
- if (result->isScript()) {
- return QQmlJSRegisterContent::create(
- storedType(result), result,
- QQmlJSRegisterContent::Script, type.scopeType());
- }
-
- return QQmlJSRegisterContent::create(metaObjectType(), metaObjectType(),
- QQmlJSRegisterContent::MetaType, result);
- }
-
- return {};
+ return referenceTypeForName(
+ name, type.scopeType(),
+ type.variant() == QQmlJSRegisterContent::ObjectModulePrefix);
}
if (type.isConversion()) {
const auto result = memberType(type.conversionResult(), name);
@@ -1243,7 +1256,7 @@ bool QQmlJSTypeResolver::registerContains(const QQmlJSRegisterContent &reg,
: equals(type, prop.type());
}
if (reg.isEnumeration())
- return equals(type, intType());
+ return equals(type, reg.enumeration().type());
if (reg.isMethod())
return equals(type, jsValueType());
return false;
diff --git a/src/qmlcompiler/qqmljstyperesolver_p.h b/src/qmlcompiler/qqmljstyperesolver_p.h
index e05f5b3757..a56a85bbc6 100644
--- a/src/qmlcompiler/qqmljstyperesolver_p.h
+++ b/src/qmlcompiler/qqmljstyperesolver_p.h
@@ -39,6 +39,7 @@ public:
void init(QQmlJSImportVisitor *visitor, QQmlJS::AST::Node *program);
QQmlJSScope::ConstPtr voidType() const { return m_voidType; }
+ QQmlJSScope::ConstPtr emptyType() const { return m_emptyType; }
QQmlJSScope::ConstPtr emptyListType() const { return m_emptyListType; }
QQmlJSScope::ConstPtr nullType() const { return m_nullType; }
QQmlJSScope::ConstPtr realType() const { return m_realType; }
@@ -167,8 +168,14 @@ protected:
const QQmlJSRegisterContent &origin,
QQmlJSScope::ConstPtr (QQmlJSTypeResolver::*op)(const QQmlJSScope::ConstPtr &) const) const;
+ QQmlJSRegisterContent referenceTypeForName(
+ const QString &name,
+ const QQmlJSScope::ConstPtr &scopeType = QQmlJSScope::ConstPtr(),
+ bool hasObjectModuelPrefix = false) const;
+
QQmlJSScope::ConstPtr m_voidType;
QQmlJSScope::ConstPtr m_emptyListType;
+ QQmlJSScope::ConstPtr m_emptyType;
QQmlJSScope::ConstPtr m_nullType;
QQmlJSScope::ConstPtr m_numberPrototype;
QQmlJSScope::ConstPtr m_realType;
diff --git a/src/qmlcompiler/qqmljsutils.cpp b/src/qmlcompiler/qqmljsutils.cpp
index c07c0b6845..8ef11444d7 100644
--- a/src/qmlcompiler/qqmljsutils.cpp
+++ b/src/qmlcompiler/qqmljsutils.cpp
@@ -25,17 +25,23 @@ resolveAlias(ScopeForId scopeForId, const QQmlJSMetaProperty &property,
QQmlJSUtils::ResolvedAlias result {};
result.owner = owner;
- for (QQmlJSMetaProperty nextProperty = property; nextProperty.isAlias();) {
-
- // this is a special (seemingly useless) section which is necessary when
- // we have an alias pointing to an alias. this way we avoid a check
- // whether a property is an alias at the very end of the loop body
+ // TODO: one could optimize the generated alias code for aliases pointing to aliases
+ // e.g., if idA.myAlias -> idB.myAlias2 -> idC.myProp, then one could directly generate
+ // idA.myProp as pointing to idC.myProp.
+ // This gets complicated when idB.myAlias is in a different Component than where the
+ // idA.myAlias is defined: scopeForId currently only contains the ids of the current
+ // component and alias resolution on the ids of a different component fails then.
+ if (QQmlJSMetaProperty nextProperty = property; nextProperty.isAlias()) {
QQmlJSScope::ConstPtr resultOwner = result.owner;
result = QQmlJSUtils::ResolvedAlias {};
visitor.reset();
auto aliasExprBits = nextProperty.aliasExpression().split(u'.');
+ // do not crash on invalid aliasexprbits when accessing aliasExprBits[0]
+ if (aliasExprBits.size() < 1)
+ return {};
+
// resolve id first:
resultOwner = scopeForId(aliasExprBits[0], resultOwner);
if (!resultOwner)
@@ -46,10 +52,8 @@ resolveAlias(ScopeForId scopeForId, const QQmlJSMetaProperty &property,
aliasExprBits.removeFirst(); // Note: for simplicity, remove the <id>
result.owner = resultOwner;
result.kind = QQmlJSUtils::AliasTarget_Object;
- // reset the property to avoid endless loop when aliasExprBits is empty
- nextProperty = QQmlJSMetaProperty {};
- for (const QString &bit : qAsConst(aliasExprBits)) {
+ for (const QString &bit : std::as_const(aliasExprBits)) {
nextProperty = resultOwner->property(bit);
if (!nextProperty.isValid())
return {};
@@ -96,7 +100,7 @@ std::optional<FixSuggestion> QQmlJSUtils::didYouMean(const QString &userInput,
QQmlJS::SourceLocation location)
{
QString shortestDistanceWord;
- int shortestDistance = userInput.length();
+ int shortestDistance = userInput.size();
// Most of the time the candidates are keys() from QHash, which means that
// running this function in the seemingly same setup might yield different
@@ -114,14 +118,14 @@ std::optional<FixSuggestion> QQmlJSUtils::didYouMean(const QString &userInput,
* Roughly based on
* https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows.
*/
- QList<int> v0(candidate.length() + 1);
- QList<int> v1(candidate.length() + 1);
+ QList<int> v0(candidate.size() + 1);
+ QList<int> v1(candidate.size() + 1);
std::iota(v0.begin(), v0.end(), 0);
- for (qsizetype i = 0; i < userInput.length(); i++) {
+ for (qsizetype i = 0; i < userInput.size(); i++) {
v1[0] = i + 1;
- for (qsizetype j = 0; j < candidate.length(); j++) {
+ for (qsizetype j = 0; j < candidate.size(); j++) {
int deletionCost = v0[j + 1] + 1;
int insertionCost = v1[j] + 1;
int substitutionCost = userInput[i] == candidate[j] ? v0[j] : v0[j] + 1;
@@ -130,7 +134,7 @@ std::optional<FixSuggestion> QQmlJSUtils::didYouMean(const QString &userInput,
std::swap(v0, v1);
}
- int distance = v0[candidate.length()];
+ int distance = v0[candidate.size()];
if (distance < shortestDistance) {
shortestDistanceWord = candidate;
shortestDistance = distance;
@@ -138,7 +142,7 @@ std::optional<FixSuggestion> QQmlJSUtils::didYouMean(const QString &userInput,
}
if (shortestDistance
- < std::min(std::max(userInput.length() / 2, qsizetype(3)), userInput.length())) {
+ < std::min(std::max(userInput.size() / 2, qsizetype(3)), userInput.size())) {
return FixSuggestion { { FixSuggestion::Fix {
u"Did you mean \"%1\"?"_s.arg(shortestDistanceWord), location,
shortestDistanceWord } } };
diff --git a/src/qmlcompiler/qqmljsutils_p.h b/src/qmlcompiler/qqmljsutils_p.h
index 8a1ee9c287..040e996cd4 100644
--- a/src/qmlcompiler/qqmljsutils_p.h
+++ b/src/qmlcompiler/qqmljsutils_p.h
@@ -104,7 +104,7 @@ struct Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSUtils
{
if (handlerName.startsWith(u"on") && handlerName.size() > 2) {
QString signal = handlerName.mid(2).toString();
- for (int i = 0; i < signal.length(); ++i) {
+ for (int i = 0; i < signal.size(); ++i) {
QChar &ch = signal[i];
if (ch.isLower())
return {};
diff --git a/src/qmldebug/qqmlprofilerclient_p_p.h b/src/qmldebug/qqmlprofilerclient_p_p.h
index 39e606ab61..e6cf1054ee 100644
--- a/src/qmldebug/qqmlprofilerclient_p_p.h
+++ b/src/qmldebug/qqmlprofilerclient_p_p.h
@@ -43,7 +43,7 @@ public:
{
}
- virtual ~QQmlProfilerClientPrivate() override;
+ ~QQmlProfilerClientPrivate() override;
void sendRecordingStatus(int engineId);
bool updateFeatures(ProfileFeature feature);
diff --git a/src/qmldebug/qv4debugclient.cpp b/src/qmldebug/qv4debugclient.cpp
index bb108fc5ef..83c6660a94 100644
--- a/src/qmldebug/qv4debugclient.cpp
+++ b/src/qmldebug/qv4debugclient.cpp
@@ -293,7 +293,7 @@ void QV4DebugClient::scripts(int types, const QList<int> &ids, bool includeSourc
QJsonObject args;
args.insert(QLatin1String(TYPES), types);
- if (ids.count()) {
+ if (ids.size()) {
QJsonArray array;
for (int id : ids)
array.append(id);
diff --git a/src/qmldom/qqmldomastcreator.cpp b/src/qmldom/qqmldomastcreator.cpp
index 81d2d5d750..78c896619e 100644
--- a/src/qmldom/qqmldomastcreator.cpp
+++ b/src/qmldom/qqmldomastcreator.cpp
@@ -67,6 +67,26 @@ static QString toString(const UiQualifiedId *qualifiedId, QChar delimiter = QLat
return result;
}
+static QString typeToString(AST::Type *t)
+{
+ Q_ASSERT(t);
+ QString res = toString(t->typeId);
+ if (!t->typeArguments)
+ return res;
+ res += u"<";
+ bool first = true;
+ for (TypeArgumentList *tt = static_cast<TypeArgumentList *>(t->typeArguments);
+ tt; tt = tt->next) {
+ if (first)
+ first = false;
+ else
+ res += u",";
+ res += typeToString(tt->typeId);
+ }
+ res += u">";
+ return res;
+}
+
SourceLocation combineLocations(SourceLocation s1, SourceLocation s2)
{
return combine(s1, s2);
@@ -113,9 +133,9 @@ class QmlDomAstCreator final : public AST::Visitor
template<typename T>
StackEl &currentEl(int idx = 0)
{
- Q_ASSERT_X(idx < nodeStack.length() && idx >= 0, "currentQmlObjectOrComponentEl",
+ Q_ASSERT_X(idx < nodeStack.size() && idx >= 0, "currentQmlObjectOrComponentEl",
"Stack does not contain enough elements!");
- int i = nodeStack.length() - idx;
+ int i = nodeStack.size() - idx;
while (i-- > 0) {
DomType k = nodeStack.at(i).item.kind;
if (k == T::kindValue)
@@ -135,9 +155,9 @@ class QmlDomAstCreator final : public AST::Visitor
StackEl &currentQmlObjectOrComponentEl(int idx = 0)
{
- Q_ASSERT_X(idx < nodeStack.length() && idx >= 0, "currentQmlObjectOrComponentEl",
+ Q_ASSERT_X(idx < nodeStack.size() && idx >= 0, "currentQmlObjectOrComponentEl",
"Stack does not contain enough elements!");
- int i = nodeStack.length() - idx;
+ int i = nodeStack.size() - idx;
while (i-- > 0) {
DomType k = nodeStack.at(i).item.kind;
if (k == DomType::QmlObject || k == DomType::QmlComponent)
@@ -149,16 +169,16 @@ class QmlDomAstCreator final : public AST::Visitor
StackEl &currentNodeEl(int i = 0)
{
- Q_ASSERT_X(i < nodeStack.length() && i >= 0, "currentNode",
+ Q_ASSERT_X(i < nodeStack.size() && i >= 0, "currentNode",
"Stack does not contain element!");
- return nodeStack[nodeStack.length() - i - 1];
+ return nodeStack[nodeStack.size() - i - 1];
}
DomValue &currentNode(int i = 0)
{
- Q_ASSERT_X(i < nodeStack.length() && i >= 0, "currentNode",
+ Q_ASSERT_X(i < nodeStack.size() && i >= 0, "currentNode",
"Stack does not contain element!");
- return nodeStack[nodeStack.length() - i - 1].item;
+ return nodeStack[nodeStack.size() - i - 1].item;
}
void removeCurrentNode(std::optional<DomType> expectedType)
@@ -451,7 +471,7 @@ public:
currentEl<QmlObject>()
.path.field(Fields::bindings)
.key(pDef.name)
- .index(obj.m_bindings.values(pDef.name).length() - 1),
+ .index(obj.m_bindings.values(pDef.name).size() - 1),
ann);
}
}
@@ -487,13 +507,8 @@ public:
MethodInfo m;
m.name = fDef->name.toString();
if (AST::TypeAnnotation *tAnn = fDef->typeAnnotation) {
- if (AST::Type *t = tAnn->type) {
- m.typeName = toString(t->typeId);
- if (t->typeArguments) {
- Q_ASSERT_X(false, className,
- "todo: type argument should be added to the typeName");
- }
- }
+ if (AST::Type *t = tAnn->type)
+ m.typeName = typeToString(t);
}
m.access = MethodInfo::Public;
m.methodType = MethodInfo::Method;
@@ -528,13 +543,8 @@ public:
MethodParameter param;
param.name = args->element->bindingIdentifier.toString();
if (AST::TypeAnnotation *tAnn = args->element->typeAnnotation) {
- if (AST::Type *t = tAnn->type) {
- param.typeName = toString(t->typeId);
- if (t->typeArguments) {
- Q_ASSERT_X(false, className,
- "todo: type argument should be added to the typeName");
- }
- }
+ if (AST::Type *t = tAnn->type)
+ param.typeName = typeToString(t);
}
if (args->element->initializer) {
SourceLocation loc = combineLocations(args->element->initializer);
@@ -581,11 +591,11 @@ public:
scope.addPrototypePath(Paths::lookupTypePath(scope.name()));
QmlObject *sPtr = nullptr;
Path sPathFromOwner;
- if (!arrayBindingLevels.isEmpty() && nodeStack.length() == arrayBindingLevels.last()) {
+ if (!arrayBindingLevels.isEmpty() && nodeStack.size() == arrayBindingLevels.last()) {
if (currentNode().kind == DomType::Binding) {
QList<QmlObject> *vals = std::get<Binding>(currentNode().value).arrayValue();
if (vals) {
- int idx = vals->length();
+ int idx = vals->size();
vals->append(scope);
sPathFromOwner = currentNodeEl().path.field(Fields::value).index(idx);
sPtr = &((*vals)[idx]);
@@ -621,7 +631,7 @@ public:
{
QmlObject &obj = current<QmlObject>();
int idx = currentIndex();
- if (!arrayBindingLevels.isEmpty() && nodeStack.length() == arrayBindingLevels.last() + 1) {
+ if (!arrayBindingLevels.isEmpty() && nodeStack.size() == arrayBindingLevels.last() + 1) {
if (currentNode(1).kind == DomType::Binding) {
Binding &b = std::get<Binding>(currentNode(1).value);
QList<QmlObject> *vals = b.arrayValue();
@@ -804,7 +814,7 @@ public:
createMap(currentNodeEl().fileLocations, Path::Field(Fields::value), nullptr);
FileLocations::addRegion(arrayList, u"leftSquareBrace", el->lbracketToken);
FileLocations::addRegion(arrayList, u"rightSquareBrace", el->lbracketToken);
- arrayBindingLevels.append(nodeStack.length());
+ arrayBindingLevels.append(nodeStack.size());
return true;
}
diff --git a/src/qmldom/qqmldomcomments.cpp b/src/qmldom/qqmldomcomments.cpp
index 19e1328d6e..257916cffa 100644
--- a/src/qmldom/qqmldomcomments.cpp
+++ b/src/qmldom/qqmldomcomments.cpp
@@ -68,12 +68,12 @@ CommentInfo gets such a raw comment string and makes the various pieces availabl
CommentInfo::CommentInfo(QStringView rawComment) : rawComment(rawComment)
{
commentBegin = 0;
- while (commentBegin < quint32(rawComment.length()) && rawComment.at(commentBegin).isSpace()) {
+ while (commentBegin < quint32(rawComment.size()) && rawComment.at(commentBegin).isSpace()) {
if (rawComment.at(commentBegin) == QLatin1Char('\n'))
hasStartNewline = true;
++commentBegin;
}
- if (commentBegin < quint32(rawComment.length())) {
+ if (commentBegin < quint32(rawComment.size())) {
QString expectedEnd;
switch (rawComment.at(commentBegin).unicode()) {
case '/':
@@ -98,7 +98,7 @@ CommentInfo::CommentInfo(QStringView rawComment) : rawComment(rawComment)
break;
}
commentEnd = commentBegin + commentStartStr.size();
- quint32 rawEnd = quint32(rawComment.length());
+ quint32 rawEnd = quint32(rawComment.size());
while (commentEnd < rawEnd && rawComment.at(commentEnd).isSpace())
++commentEnd;
commentContentEnd = commentContentBegin = commentEnd;
@@ -106,9 +106,9 @@ CommentInfo::CommentInfo(QStringView rawComment) : rawComment(rawComment)
while (commentEnd < rawEnd) {
QChar c = rawComment.at(commentEnd);
if (c == e1) {
- if (expectedEnd.length() > 1) {
+ if (expectedEnd.size() > 1) {
if (++commentEnd < rawEnd && rawComment.at(commentEnd) == expectedEnd.at(1)) {
- Q_ASSERT(expectedEnd.length() == 2);
+ Q_ASSERT(expectedEnd.size() == 2);
commentEndStr = rawComment.mid(++commentEnd - 2, 2);
break;
} else {
diff --git a/src/qmldom/qqmldomcomments_p.h b/src/qmldom/qqmldomcomments_p.h
index fe7638913a..5dd541684e 100644
--- a/src/qmldom/qqmldomcomments_p.h
+++ b/src/qmldom/qqmldomcomments_p.h
@@ -145,7 +145,7 @@ public:
Path addPreComment(const Comment &comment, QString regionName)
{
auto &preList = regionComments[regionName].preComments;
- index_type idx = preList.length();
+ index_type idx = preList.size();
preList.append(comment);
return Path::Field(Fields::regionComments)
.key(regionName)
@@ -156,7 +156,7 @@ public:
Path addPostComment(const Comment &comment, QString regionName)
{
auto &postList = regionComments[regionName].postComments;
- index_type idx = postList.length();
+ index_type idx = postList.size();
postList.append(comment);
return Path::Field(Fields::regionComments)
.key(regionName)
diff --git a/src/qmldom/qqmldomelements_p.h b/src/qmldom/qqmldomelements_p.h
index 0f5159e535..341ca1e68f 100644
--- a/src/qmldom/qqmldomelements_p.h
+++ b/src/qmldom/qqmldomelements_p.h
@@ -541,7 +541,7 @@ public:
bool isSignalHandler() const
{
QString baseName = m_name.split(QLatin1Char('.')).last();
- if (baseName.startsWith(u"on") && baseName.length() > 2 && baseName.at(2).isUpper())
+ if (baseName.startsWith(u"on") && baseName.size() > 2 && baseName.at(2).isUpper())
return true;
return false;
}
diff --git a/src/qmldom/qqmldomerrormessage.cpp b/src/qmldom/qqmldomerrormessage.cpp
index 6eb9ce98ea..d4b95850e2 100644
--- a/src/qmldom/qqmldomerrormessage.cpp
+++ b/src/qmldom/qqmldomerrormessage.cpp
@@ -72,20 +72,20 @@ and use it to create new ErrorMessages using its debug, warning, error,... metho
void ErrorGroups::dump(Sink sink) const
{
- for (int i = 0; i < groups.length(); ++i)
+ for (int i = 0; i < groups.size(); ++i)
groups.at(i).dump(sink);
}
void ErrorGroups::dumpId(Sink sink) const
{
- for (int i = 0; i < groups.length(); ++i)
+ for (int i = 0; i < groups.size(); ++i)
groups.at(i).dumpId(sink);
}
QCborArray ErrorGroups::toCbor() const
{
QCborArray res;
- for (int i = 0; i < groups.length(); ++i)
+ for (int i = 0; i < groups.size(); ++i)
res.append(QCborValue(groups.at(i).groupId()));
return res;
}
@@ -163,7 +163,7 @@ void ErrorGroups::fatal(Dumper msg, Path element, QStringView canonicalFilePath,
int ibuf = 0;
auto sink = [&ibuf, &buf](QStringView s) {
int is = 0;
- while (ibuf < FatalMsgMaxLen && is < s.length()) {
+ while (ibuf < FatalMsgMaxLen && is < s.size()) {
QChar c = s.at(is);
if (c == QChar::fromLatin1('\n') || c == QChar::fromLatin1('\r') || (c >= QChar::fromLatin1(' ') && c <= QChar::fromLatin1('~')))
buf[ibuf++] = c.toLatin1();
@@ -236,11 +236,11 @@ int ErrorGroups::cmp(const ErrorGroups &o1, const ErrorGroups &o2)
{
auto &g1 = o1.groups;
auto &g2 = o2.groups;
- if (g1.length() < g2.length())
+ if (g1.size() < g2.size())
return -1;
- if (g1.length() < g2.length())
+ if (g1.size() < g2.size())
return 1;
- for (int i = 0; i < g1.length(); ++i) {
+ for (int i = 0; i < g1.size(); ++i) {
int c = std::strcmp(g1.at(i).groupId().data(), g2.at(i).groupId().data());
if (c != 0)
return c;
diff --git a/src/qmldom/qqmldomexternalitems_p.h b/src/qmldom/qqmldomexternalitems_p.h
index 4f6648f9e4..7bd51a30d1 100644
--- a/src/qmldom/qqmldomexternalitems_p.h
+++ b/src/qmldom/qqmldomexternalitems_p.h
@@ -286,7 +286,7 @@ public:
void setImports(const QList<Import> &imports) { m_imports = imports; }
Path addImport(const Import &i)
{
- index_type idx = index_type(m_imports.length());
+ index_type idx = index_type(m_imports.size());
m_imports.append(i);
if (i.uri.isModule()) {
m_importScope.addImport((i.importId.isEmpty()
@@ -313,7 +313,7 @@ public:
void setPragmas(QList<Pragma> pragmas) { m_pragmas = pragmas; }
Path addPragma(const Pragma &pragma)
{
- int idx = m_pragmas.length();
+ int idx = m_pragmas.size();
m_pragmas.append(pragma);
return Path::Field(Fields::pragmas).index(idx);
}
@@ -383,7 +383,7 @@ public:
void setExports(QMultiMap<QString, Export> e) { m_exports = e; }
Path addExport(const Export &e)
{
- index_type i = m_exports.values(e.typeName).length();
+ index_type i = m_exports.values(e.typeName).size();
m_exports.insert(e.typeName, e);
addUri(e.uri, e.version.majorVersion);
return canonicalPath().field(Fields::exports).index(i);
diff --git a/src/qmldom/qqmldomitem.cpp b/src/qmldom/qqmldomitem.cpp
index f7ef17771b..040218cf84 100644
--- a/src/qmldom/qqmldomitem.cpp
+++ b/src/qmldom/qqmldomitem.cpp
@@ -1653,6 +1653,11 @@ bool DomItem::visitLookup1(QString symbolName, function_ref<bool(DomItem &)> vis
// the prototype chain)
DomItem importScope = fileObject().field(Fields::importScope);
if (const ImportScope *importScopePtr = importScope.as<ImportScope>()) {
+ if (importScopePtr->subImports().contains(symbolName)) {
+ DomItem subItem = importScope.field(Fields::qualifiedImports).key(symbolName);
+ if (!visitor(subItem))
+ return false;
+ }
QList<DomItem> types = importScopePtr->importedItemsWithName(importScope, symbolName);
for (DomItem &t : types) {
if (!visitor(t))
@@ -1740,18 +1745,18 @@ bool DomItem::visitLookup(QString target, function_ref<bool(DomItem &)> visitor,
while (!lookupToDos.isEmpty()) {
ResolveToDo tNow = lookupToDos.takeFirst();
auto vNow = qMakePair(tNow.item.id(), tNow.pathIndex);
- if (vNow.first != 0) {
- if (lookupVisited[vNow.second].contains(vNow.first))
- continue;
- else
- lookupVisited[vNow.second].insert(vNow.first);
- }
DomItem subNow = tNow.item;
int iSubPath = tNow.pathIndex;
Q_ASSERT(iSubPath < subpath.length());
QString subPathNow = subpath[iSubPath++];
DomItem scope = subNow.proceedToScope();
if (iSubPath < subpath.length()) {
+ if (vNow.first != 0) {
+ if (lookupVisited[vNow.second].contains(vNow.first))
+ continue;
+ else
+ lookupVisited[vNow.second].insert(vNow.first);
+ }
if (scope.internalKind() == DomType::QmlObject)
scope.visitDirectAccessibleScopes(
[&lookupToDos, subPathNow, iSubPath](DomItem &el) {
@@ -2106,7 +2111,7 @@ bool DomItem::visitLocalSymbolsNamed(QString name, function_ref<bool(DomItem &)>
return false;
f = field(Fields::qualifiedImports);
v = f.key(name);
- if (!v.visitIndexes(visitor))
+ if (v && !visitor(v))
return false;
break;
default:
diff --git a/src/qmldom/qqmldomitem_p.h b/src/qmldom/qqmldomitem_p.h
index f5fca3bc41..10945734da 100644
--- a/src/qmldom/qqmldomitem_p.h
+++ b/src/qmldom/qqmldomitem_p.h
@@ -407,7 +407,7 @@ public:
for (void *p : pList)
m_pList.append(p);
} else if (options == ListOptions::Reverse) {
- for (qsizetype i = pList.length(); i-- != 0;)
+ for (qsizetype i = pList.size(); i-- != 0;)
// probably writing in reverse and reading sequentially would be better
m_pList.append(pList.at(i));
} else {
@@ -1204,21 +1204,21 @@ List List::fromQList(
std::function<DomItem(DomItem &, const PathEls::PathComponent &, T &)> elWrapper,
ListOptions options)
{
- index_type len = list.length();
+ index_type len = list.size();
if (options == ListOptions::Reverse) {
return List(
pathFromOwner,
[list, elWrapper](DomItem &self, index_type i) mutable {
- if (i < 0 || i >= list.length())
+ if (i < 0 || i >= list.size())
return DomItem();
- return elWrapper(self, PathEls::Index(i), list[list.length() - i - 1]);
+ return elWrapper(self, PathEls::Index(i), list[list.size() - i - 1]);
},
[len](DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
} else {
return List(
pathFromOwner,
[list, elWrapper](DomItem &self, index_type i) mutable {
- if (i < 0 || i >= list.length())
+ if (i < 0 || i >= list.size())
return DomItem();
return elWrapper(self, PathEls::Index(i), list[i]);
},
@@ -1236,21 +1236,21 @@ List List::fromQListRef(
return List(
pathFromOwner,
[&list, elWrapper](DomItem &self, index_type i) {
- if (i < 0 || i >= list.length())
+ if (i < 0 || i >= list.size())
return DomItem();
- return elWrapper(self, PathEls::Index(i), list[list.length() - i - 1]);
+ return elWrapper(self, PathEls::Index(i), list[list.size() - i - 1]);
},
- [&list](DomItem &) { return list.length(); }, nullptr,
+ [&list](DomItem &) { return list.size(); }, nullptr,
QLatin1String(typeid(T).name()));
} else {
return List(
pathFromOwner,
[&list, elWrapper](DomItem &self, index_type i) {
- if (i < 0 || i >= list.length())
+ if (i < 0 || i >= list.size())
return DomItem();
return elWrapper(self, PathEls::Index(i), list[i]);
},
- [&list](DomItem &) { return list.length(); }, nullptr,
+ [&list](DomItem &) { return list.size(); }, nullptr,
QLatin1String(typeid(T).name()));
}
}
@@ -1635,7 +1635,7 @@ template<typename T>
Path appendUpdatableElementInQList(Path listPathFromOwner, QList<T> &list, const T &value,
T **vPtr = nullptr)
{
- int idx = list.length();
+ int idx = list.size();
list.append(value);
Path newPath = listPathFromOwner.index(idx);
T &targetV = list[idx];
@@ -1946,7 +1946,7 @@ bool ListPT<T>::iterateDirectSubpaths(DomItem &self, DirectVisitor v)
template<typename T>
DomItem ListPT<T>::index(DomItem &self, index_type index) const
{
- if (index >= 0 && index < m_pList.length())
+ if (index >= 0 && index < m_pList.size())
return self.wrap(PathEls::Index(index), *reinterpret_cast<T *>(m_pList.value(index)));
return DomItem();
}
diff --git a/src/qmldom/qqmldomlinewriter.cpp b/src/qmldom/qqmldomlinewriter.cpp
index cb312b4fa7..c0110e8bf9 100644
--- a/src/qmldom/qqmldomlinewriter.cpp
+++ b/src/qmldom/qqmldomlinewriter.cpp
@@ -94,10 +94,10 @@ LineWriter &LineWriter::ensureSpace(QStringView space, TextAddType t)
if (ind.nNewlines > 0)
ensureNewline(ind.nNewlines, t);
if (cc != counter() || m_currentLine.isEmpty()
- || !m_currentLine.at(m_currentLine.length() - 1).isSpace())
+ || !m_currentLine.at(m_currentLine.size() - 1).isSpace())
write(ind.trailingString, t);
else {
- int len = m_currentLine.length();
+ int len = m_currentLine.size();
int i = len;
while (i != 0 && m_currentLine.at(i - 1).isSpace())
--i;
@@ -109,8 +109,8 @@ LineWriter &LineWriter::ensureSpace(QStringView space, TextAddType t)
ind = IndentInfo(space, tabSize, trailingSpaceStartColumn);
if (i == 0) {
if (indExisting.column < ind.column) {
- qint32 utf16Change = ind.trailingString.length() - trailingSpace.length();
- m_currentColumnNr += ind.trailingString.length() - trailingSpace.length();
+ qint32 utf16Change = ind.trailingString.size() - trailingSpace.size();
+ m_currentColumnNr += ind.trailingString.size() - trailingSpace.size();
m_currentLine.replace(
i, len - i, ind.trailingString.toString()); // invalidates most QStringViews
changeAtOffset(i, utf16Change, utf16Change, 0);
@@ -341,8 +341,8 @@ void LineWriter::changeAtOffset(quint32 offset, qint32 change, qint32 colChange,
int LineWriter::column(int index)
{
- if (index > m_currentLine.length())
- index = m_currentLine.length();
+ if (index > m_currentLine.size())
+ index = m_currentLine.size();
IndentInfo iInfo(QStringView(m_currentLine).mid(0, index), m_options.formatOptions.tabSize,
m_columnNr);
return iInfo.column;
diff --git a/src/qmldom/qqmldomlinewriter_p.h b/src/qmldom/qqmldomlinewriter_p.h
index b3efadd958..ff7c075899 100644
--- a/src/qmldom/qqmldomlinewriter_p.h
+++ b/src/qmldom/qqmldomlinewriter_p.h
@@ -45,7 +45,7 @@ public:
column = initialColumn + fixup;
const QChar tab = QLatin1Char('\t');
int iStart = 0;
- int len = line.length();
+ int len = line.size();
for (int i = 0; i < len; i++) {
if (line[i] == tab)
column = ((column / tabSize) + 1) * tabSize;
diff --git a/src/qmldom/qqmldommoduleindex.cpp b/src/qmldom/qqmldommoduleindex.cpp
index 5dfb4d7917..37a33c328a 100644
--- a/src/qmldom/qqmldommoduleindex.cpp
+++ b/src/qmldom/qqmldommoduleindex.cpp
@@ -154,7 +154,7 @@ QSet<QString> ModuleIndex::exportNames(DomItem &self) const
{
QSet<QString> res;
QList<Path> mySources = sources();
- for (int i = 0; i < mySources.length(); ++i) {
+ for (int i = 0; i < mySources.size(); ++i) {
DomItem source = self.path(mySources.at(i));
res += source.field(Fields::exports).keys();
}
@@ -230,7 +230,7 @@ QList<DomItem> ModuleIndex::exportsWithNameAndMinorVersion(DomItem &self, QStrin
if (minorVersion < 0)
minorVersion = std::numeric_limits<int>::max();
int vNow = Version::Undefined;
- for (int i = 0; i < mySources.length(); ++i) {
+ for (int i = 0; i < mySources.size(); ++i) {
DomItem source = self.path(mySources.at(i));
DomItem exports = source.field(Fields::exports).key(name);
int nExports = exports.indexes();
diff --git a/src/qmldom/qqmldompath.cpp b/src/qmldom/qqmldompath.cpp
index 447e0479c4..2af5f3739b 100644
--- a/src/qmldom/qqmldompath.cpp
+++ b/src/qmldom/qqmldompath.cpp
@@ -90,7 +90,7 @@ QString Filter::name() const {
bool Filter::checkName(QStringView s) const
{
return s.startsWith(u"?(")
- && s.mid(2, s.length()-3) == filterDescription
+ && s.mid(2, s.size()-3) == filterDescription
&& s.endsWith(u")");
}
@@ -181,9 +181,9 @@ const PathEls::PathComponent &Path::component(int i) const
i = i - m_length - m_endOffset;
auto data = m_data.get();
while (data) {
- i += data->components.length();
+ i += data->components.size();
if (i >= 0)
- return qAsConst(data)->components[i];
+ return std::as_const(data)->components[i];
data = data->parent.get();
}
Q_ASSERT(false && "Invalid data reached while resolving a seemengly valid index in Path (inconsisten Path object)");
@@ -311,7 +311,7 @@ Path Path::fromString(QStringView s, ErrorHandler errorHandler)
const QChar backslash = QChar::fromLatin1('\\');
const QChar underscore = QChar::fromLatin1('_');
const QChar tilda = QChar::fromLatin1('~');
- for (int i=0; i < s.length(); ++i)
+ for (int i=0; i < s.size(); ++i)
if (s.at(i) == lsBrace || s.at(i) == dot)
++len;
QVector<Component> components;
@@ -320,25 +320,25 @@ Path Path::fromString(QStringView s, ErrorHandler errorHandler)
int i0 = 0;
PathEls::ParserState state = PathEls::ParserState::Start;
QStringList strVals;
- while (i < s.length()) {
+ while (i < s.size()) {
// skip space
- while (i < s.length() && s.at(i).isSpace())
+ while (i < s.size() && s.at(i).isSpace())
++i;
- if (i >= s.length())
+ if (i >= s.size())
break;
QChar c = s.at(i++);
switch (state) {
case PathEls::ParserState::Start:
if (c == dollar) {
i0 = i;
- while (i < s.length() && s.at(i).isLetterOrNumber()){
+ while (i < s.size() && s.at(i).isLetterOrNumber()){
++i;
}
components.append(Component(PathEls::Root(s.mid(i0,i-i0))));
state = PathEls::ParserState::End;
} else if (c == at) {
i0 = i;
- while (i < s.length() && s.at(i).isLetterOrNumber()){
+ while (i < s.size() && s.at(i).isLetterOrNumber()){
++i;
}
components.append(Component(PathEls::Current(s.mid(i0,i-i0))));
@@ -355,7 +355,7 @@ Path Path::fromString(QStringView s, ErrorHandler errorHandler)
case PathEls::ParserState::IndexOrKey:
if (c.isDigit()) {
i0 = i-1;
- while (i < s.length() && s.at(i).isDigit())
+ while (i < s.size() && s.at(i).isDigit())
++i;
bool ok;
components.append(Component(static_cast<index_type>(s.mid(i0,i-i0).toString()
@@ -367,14 +367,14 @@ Path Path::fromString(QStringView s, ErrorHandler errorHandler)
}
} else if (c.isLetter() || c == tilda || c == underscore) {
i0 = i-1;
- while (i < s.length() && (s.at(i).isLetterOrNumber() || s.at(i) == underscore || s.at(i) == tilda))
+ while (i < s.size() && (s.at(i).isLetterOrNumber() || s.at(i) == underscore || s.at(i) == tilda))
++i;
components.append(Component(PathEls::Key(s.mid(i0, i - i0).toString())));
} else if (c == quote) {
i0 = i;
QString strVal;
bool properEnd = false;
- while (i < s.length()) {
+ while (i < s.size()) {
c = s.at(i);
if (c == quote) {
properEnd = true;
@@ -406,16 +406,16 @@ Path Path::fromString(QStringView s, ErrorHandler errorHandler)
} else if (c == QChar::fromLatin1('*')) {
components.append(Component(PathEls::Any()));
} else if (c == QChar::fromLatin1('?')) {
- while (i < s.length() && s.at(i).isSpace())
+ while (i < s.size() && s.at(i).isSpace())
++i;
- if (i >= s.length() || s.at(i) != QChar::fromLatin1('(')) {
+ if (i >= s.size() || s.at(i) != QChar::fromLatin1('(')) {
myErrors().error(tr("Expected a brace in filter after the question mark (at char %1).")
.arg(QString::number(i))).handle(errorHandler);
return Path();
}
i0 = ++i;
- while (i < s.length() && s.at(i) != QChar::fromLatin1(')')) ++i; // check matching braces when skipping??
- if (i >= s.length() || s.at(i) != QChar::fromLatin1(')')) {
+ while (i < s.size() && s.at(i) != QChar::fromLatin1(')')) ++i; // check matching braces when skipping??
+ if (i >= s.size() || s.at(i) != QChar::fromLatin1(')')) {
myErrors().error(tr("Expected a closing brace in filter after the question mark (at char %1).")
.arg(QString::number(i))).handle(errorHandler);
return Path();
@@ -429,8 +429,8 @@ Path Path::fromString(QStringView s, ErrorHandler errorHandler)
.arg(c).arg(i-1)).handle(errorHandler);
return Path();
}
- while (i < s.length() && s.at(i).isSpace()) ++i;
- if (i >= s.length() || s.at(i) != rsBrace) {
+ while (i < s.size() && s.at(i).isSpace()) ++i;
+ if (i >= s.size() || s.at(i) != rsBrace) {
myErrors().error(tr("square braces misses closing brace at char %1.")
.arg(QString::number(i))).handle(errorHandler);
return Path();
@@ -441,20 +441,20 @@ Path Path::fromString(QStringView s, ErrorHandler errorHandler)
break;
case PathEls::ParserState::End:
if (c == dot) {
- while (i < s.length() && s.at(i).isSpace()) ++i;
- if (i == s.length()) {
+ while (i < s.size() && s.at(i).isSpace()) ++i;
+ if (i == s.size()) {
components.append(Component());
state = PathEls::ParserState::End;
} else if (s.at(i).isLetter() || s.at(i) == underscore || s.at(i) == tilda) {
i0 = i;
- while (i < s.length() && (s.at(i).isLetterOrNumber() || s.at(i) == underscore || s.at(i) == tilda)) {
+ while (i < s.size() && (s.at(i).isLetterOrNumber() || s.at(i) == underscore || s.at(i) == tilda)) {
++i;
}
components.append(Component(PathEls::Field(s.mid(i0,i-i0))));
state = PathEls::ParserState::End;
} else if (s.at(i).isDigit()) {
i0 = i;
- while (i < s.length() && s.at(i).isDigit()){
+ while (i < s.size() && s.at(i).isDigit()){
++i;
}
bool ok;
@@ -474,14 +474,14 @@ Path Path::fromString(QStringView s, ErrorHandler errorHandler)
state = PathEls::ParserState::End;
} else if (s.at(i) == at) {
i0 = ++i;
- while (i < s.length() && s.at(i).isLetterOrNumber()){
+ while (i < s.size() && s.at(i).isLetterOrNumber()){
++i;
}
components.append(Component(PathEls::Current(s.mid(i0,i-i0))));
state = PathEls::ParserState::End;
} else if (s.at(i) == dollar) {
i0 = ++i;
- while (i < s.length() && s.at(i).isLetterOrNumber()){
+ while (i < s.size() && s.at(i).isLetterOrNumber()){
++i;
}
components.append(Component(PathEls::Root(s.mid(i0,i-i0))));
@@ -512,7 +512,7 @@ Path Path::fromString(QStringView s, ErrorHandler errorHandler)
return Path();
case PathEls::ParserState::End:
- return Path(0, components.length(), std::shared_ptr<PathEls::PathData>(
+ return Path(0, components.size(), std::shared_ptr<PathEls::PathData>(
new PathEls::PathData(strVals, components)));
}
Q_ASSERT(false && "Unexpected state in Path::fromString");
@@ -728,9 +728,9 @@ Path Path::path(Path toAdd, bool avoidToAddAsBase) const
}
data = toAdd.m_data.get();
while (data) {
- for (int ij = 0; ij < data->strData.length(); ++ij) {
+ for (int ij = 0; ij < data->strData.size(); ++ij) {
bool hasAlready = false;
- for (int ii = 0; ii < myStrs.length() && !hasAlready; ++ii)
+ for (int ii = 0; ii < myStrs.size() && !hasAlready; ++ii)
hasAlready = inQString(data->strData[ij], myStrs[ii]);
if (!hasAlready)
addedStrs.append(data->strData[ij]);
@@ -743,7 +743,7 @@ Path Path::path(Path toAdd, bool avoidToAddAsBase) const
components.append(toAdd.component(i));
QStringView compStrView = toAdd.component(i).stringView();
if (!compStrView.isEmpty()) {
- for (int j = 0; j < addedStrs.length(); ++j) {
+ for (int j = 0; j < addedStrs.size(); ++j) {
if (inQString(compStrView, addedStrs[j])) {
toAddStrs.append(addedStrs[j]);
addedStrs.removeAt(j);
@@ -761,7 +761,7 @@ Path Path::expandFront() const
int newLen = 0;
auto data = m_data.get();
while (data) {
- newLen += data->components.length();
+ newLen += data->components.size();
data = data->parent.get();
}
newLen -= m_endOffset;
@@ -822,14 +822,14 @@ Path Path::noEndOffset() const
// peel back
qint16 endOffset = m_endOffset;
std::shared_ptr<PathEls::PathData> lastData = m_data;
- while (lastData && endOffset >= lastData->components.length()) {
- endOffset -= lastData->components.length();
+ while (lastData && endOffset >= lastData->components.size()) {
+ endOffset -= lastData->components.size();
lastData = lastData->parent;
}
if (endOffset > 0) {
Q_ASSERT(lastData && "Internal problem, reference to non existing PathData");
return Path(0, m_length, std::shared_ptr<PathEls::PathData>(
- new PathEls::PathData(lastData->strData, lastData->components.mid(0, lastData->components.length() - endOffset), lastData->parent)));
+ new PathEls::PathData(lastData->strData, lastData->components.mid(0, lastData->components.size() - endOffset), lastData->parent)));
}
return Path(0, m_length, lastData);
}
diff --git a/src/qmldom/qqmldomreformatter.cpp b/src/qmldom/qqmldomreformatter.cpp
index bb76f8f772..3dfacfc84e 100644
--- a/src/qmldom/qqmldomreformatter.cpp
+++ b/src/qmldom/qqmldomreformatter.cpp
@@ -301,6 +301,7 @@ protected:
for (PatternPropertyList *it = ast; it; it = it->next) {
PatternProperty *assignment = AST::cast<PatternProperty *>(it->property);
if (assignment) {
+ preVisit(assignment);
bool isStringLike = AST::cast<StringLiteralPropertyName *>(assignment->name)
|| cast<IdentifierPropertyName *>(assignment->name);
if (isStringLike)
@@ -316,6 +317,7 @@ protected:
accept(assignment->initializer);
if (it->next)
newLine();
+ postVisit(assignment);
continue;
}
PatternPropertyList *getterSetter = AST::cast<PatternPropertyList *>(it->next);
diff --git a/src/qmldom/qqmldomstringdumper.cpp b/src/qmldom/qqmldomstringdumper.cpp
index a964a542e0..081a6abf81 100644
--- a/src/qmldom/qqmldomstringdumper.cpp
+++ b/src/qmldom/qqmldomstringdumper.cpp
@@ -63,7 +63,7 @@ void sinkEscaped(Sink sink, QStringView s, EscapeOptions options) {
if (options == EscapeOptions::OuterQuotes)
sink(u"\"");
int it0=0;
- for (int it = 0; it < s.length();++it) {
+ for (int it = 0; it < s.size();++it) {
QChar c=s[it];
bool noslash = c != QLatin1Char('\\');
bool noquote = c != QLatin1Char('"');
@@ -84,7 +84,7 @@ void sinkEscaped(Sink sink, QStringView s, EscapeOptions options) {
else
Q_ASSERT(0);
}
- sink(s.mid(it0, s.length() - it0));
+ sink(s.mid(it0, s.size() - it0));
if (options == EscapeOptions::OuterQuotes)
sink(u"\"");
}
@@ -161,9 +161,9 @@ void sinkIndent(Sink s, int indent)
{
if (indent > 0) {
QStringView spaces = u" ";
- while (indent > spaces.length()) {
+ while (indent > spaces.size()) {
s(spaces);
- indent -= spaces.length();
+ indent -= spaces.size();
}
s(spaces.left(indent));
}
diff --git a/src/qmldom/qqmldomtop.cpp b/src/qmldom/qqmldomtop.cpp
index 61ecbb4957..0e263a0859 100644
--- a/src/qmldom/qqmldomtop.cpp
+++ b/src/qmldom/qqmldomtop.cpp
@@ -2158,7 +2158,7 @@ void DomEnvironment::loadPendingDependencies(DomItem &self)
m_allLoadedCallback.clear();
}
}
- for (const Callback &cb : qAsConst(endCallbacks))
+ for (const Callback &cb : std::as_const(endCallbacks))
cb(self.canonicalPath(), self, self);
});
DomItem loadInfoObj = self.copy(loadInfo);
diff --git a/src/qmldom/qqmldomtop_p.h b/src/qmldom/qqmldomtop_p.h
index f1b0a3b76a..1e020600fc 100644
--- a/src/qmldom/qqmldomtop_p.h
+++ b/src/qmldom/qqmldomtop_p.h
@@ -567,7 +567,7 @@ public:
int nNotDone() const
{
QMutexLocker l(mutex());
- return m_toDo.length() + m_inProgress.length();
+ return m_toDo.size() + m_inProgress.size();
}
QList<Dependency> inProgress() const
@@ -585,7 +585,7 @@ public:
int nCallbacks() const
{
QMutexLocker l(mutex());
- return m_endCallbacks.length();
+ return m_endCallbacks.size();
}
private:
diff --git a/src/qmldom/qqmldomtypesreader.cpp b/src/qmldom/qqmldomtypesreader.cpp
index f6c8eecdc4..5dd486a41d 100644
--- a/src/qmldom/qqmldomtypesreader.cpp
+++ b/src/qmldom/qqmldomtypesreader.cpp
@@ -248,7 +248,7 @@ bool QmltypesReader::parse()
QStringList dependencies;
QHash<QString, QQmlJSExportedScope> objects;
m_isValid = reader(&objects, &dependencies);
- for (const auto &obj : qAsConst(objects))
+ for (const auto &obj : std::as_const(objects))
insertComponent(obj.scope, obj.exports);
qmltypesFilePtr()->setIsValid(m_isValid);
return m_isValid;
diff --git a/src/qmldom/standalone/private/qtqmlcompilerexports_p.h b/src/qmldom/standalone/private/qtqmlcompilerexports_p.h
index 6906e69371..28864cd96f 100644
--- a/src/qmldom/standalone/private/qtqmlcompilerexports_p.h
+++ b/src/qmldom/standalone/private/qtqmlcompilerexports_p.h
@@ -4,6 +4,18 @@
#include "../qqmldom_global.h"
#ifndef QTQMLCOMPILEREXPORTS_P_H
#define QTQMLCOMPILEREXPORTS_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.
+//
+
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
#include <QtCore/qstring.h>
namespace Qt {
diff --git a/src/qmllocalstorage/qqmllocalstorage.cpp b/src/qmllocalstorage/qqmllocalstorage.cpp
index 59e503f59d..073b3c790f 100644
--- a/src/qmllocalstorage/qqmllocalstorage.cpp
+++ b/src/qmllocalstorage/qqmllocalstorage.cpp
@@ -491,7 +491,7 @@ through the data.
*/
/*!
- \qmlmodule QtQuick.LocalStorage 2.\QtMinorVersion
+ \qmlmodule QtQuick.LocalStorage
\title Qt Quick Local Storage QML Types
\ingroup qmlmodules
\brief Provides a JavaScript object singleton type for accessing a local
@@ -549,10 +549,10 @@ db = Sql.openDatabaseSync(identifier, version, description, estimated_size, call
\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.
+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 relative 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.
diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp
index 080cd90aa6..1f275ded5a 100644
--- a/src/qmlmodels/qqmladaptormodel.cpp
+++ b/src/qmlmodels/qqmladaptormodel.cpp
@@ -109,7 +109,7 @@ public:
}
QVector<int> signalIndexes;
- for (int i = 0; i < roles.count(); ++i) {
+ for (int i = 0; i < roles.size(); ++i) {
const int role = roles.at(i);
if (!changed && watchedRoleIds.contains(role))
changed = true;
@@ -119,7 +119,7 @@ public:
signalIndexes.append(propertyId + signalOffset);
}
if (roles.isEmpty()) {
- const int propertyRolesCount = propertyRoles.count();
+ const int propertyRolesCount = propertyRoles.size();
signalIndexes.reserve(propertyRolesCount);
for (int propertyId = 0; propertyId < propertyRolesCount; ++propertyId)
signalIndexes.append(propertyId + signalOffset);
@@ -129,13 +129,13 @@ public:
for (const auto item : items)
guardedItems.append(item);
- for (const auto &item : qAsConst(guardedItems)) {
+ for (const auto &item : std::as_const(guardedItems)) {
if (item.isNull())
continue;
const int idx = item->modelIndex();
if (idx >= index && idx < index + count) {
- for (int i = 0; i < signalIndexes.count(); ++i)
+ for (int i = 0; i < signalIndexes.size(); ++i)
QMetaObject::activate(item, signalIndexes.at(i), nullptr);
}
}
@@ -226,7 +226,7 @@ QQmlDMCachedModelData::QQmlDMCachedModelData(
, type(dataType)
{
if (index == -1)
- cachedData.resize(type->hasModelData ? 1 : type->propertyRoles.count());
+ cachedData.resize(type->hasModelData ? 1 : type->propertyRoles.size());
QObjectPrivate::get(this)->metaObject = type;
@@ -250,10 +250,10 @@ int QQmlDMCachedModelData::metaCall(QMetaObject::Call call, int id, void **argum
const int propertyIndex = id - type->propertyOffset;
if (index == -1) {
const QMetaObject *meta = metaObject();
- if (cachedData.count() > 1) {
+ if (cachedData.size() > 1) {
cachedData[propertyIndex] = *static_cast<QVariant *>(arguments[0]);
QMetaObject::activate(this, meta, propertyIndex, nullptr);
- } else if (cachedData.count() == 1) {
+ } else if (cachedData.size() == 1) {
cachedData[0] = *static_cast<QVariant *>(arguments[0]);
QMetaObject::activate(this, meta, 0, nullptr);
QMetaObject::activate(this, meta, 1, nullptr);
@@ -271,7 +271,7 @@ void QQmlDMCachedModelData::setValue(const QString &role, const QVariant &value)
{
QHash<QByteArray, int>::iterator it = type->roleNames.find(role.toUtf8());
if (it != type->roleNames.end()) {
- for (int i = 0; i < type->propertyRoles.count(); ++i) {
+ for (int i = 0; i < type->propertyRoles.size(); ++i) {
if (type->propertyRoles.at(i) == *it) {
cachedData[i] = value;
return;
@@ -287,7 +287,7 @@ bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &adaptorModel, i
cachedData.clear();
setModelIndex(idx, adaptorModel.rowAt(idx), adaptorModel.columnAt(idx));
const QMetaObject *meta = metaObject();
- const int propertyCount = type->propertyRoles.count();
+ const int propertyCount = type->propertyRoles.size();
for (int i = 0; i < propertyCount; ++i)
QMetaObject::activate(this, meta, i, nullptr);
return true;
@@ -332,10 +332,10 @@ QV4::ReturnedValue QQmlDMCachedModelData::set_property(const QV4::FunctionObject
if (o->d()->item->index == -1) {
QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
if (!modelData->cachedData.isEmpty()) {
- if (modelData->cachedData.count() > 1) {
+ if (modelData->cachedData.size() > 1) {
modelData->cachedData[propertyId] = scope.engine->toVariant(argv[0], QMetaType {});
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), propertyId, nullptr);
- } else if (modelData->cachedData.count() == 1) {
+ } else if (modelData->cachedData.size() == 1) {
modelData->cachedData[0] = scope.engine->toVariant(argv[0], QMetaType {});
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 0, nullptr);
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 1, nullptr);
@@ -496,12 +496,12 @@ public:
const QAbstractItemModel *aim = model.aim();
const QHash<int, QByteArray> names = aim ? aim->roleNames() : QHash<int, QByteArray>();
for (QHash<int, QByteArray>::const_iterator it = names.begin(), cend = names.end(); it != cend; ++it) {
- const int propertyId = propertyRoles.count();
+ const int propertyId = propertyRoles.size();
propertyRoles.append(it.key());
roleNames.insert(it.value(), it.key());
addProperty(&builder, propertyId, it.value(), propertyType);
}
- if (propertyRoles.count() == 1) {
+ if (propertyRoles.size() == 1) {
hasModelData = true;
const int role = names.begin().key();
const QByteArray propertyName = QByteArrayLiteral("modelData");
@@ -656,7 +656,7 @@ public:
// NB: This acquires the lock on QQmlMetaTypeData. If we had a QQmlEngine here,
// we could use QQmlGadgetPtrWrapper::instance() to avoid this.
if (const QQmlValueType *valueType = QQmlMetaType::valueType(type))
- metaObject = valueType->metaObject();
+ metaObject = valueType->staticMetaObject();
else
return QVariant();
}
diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index 7222b6cb93..46d8dbe14c 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -144,6 +144,9 @@ QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent)
provide delegates to multiple views, and with DelegateModelGroup to sort and filter
delegate items.
+ DelegateModel only supports one-dimensional models -- assigning a table model to
+ DelegateModel and that to TableView will thus only show one column.
+
The example below illustrates using a DelegateModel with a ListView.
\snippet delegatemodel/delegatemodel.qml 0
@@ -227,7 +230,7 @@ QQmlDelegateModel::~QQmlDelegateModel()
d->disconnectFromAbstractItemModel();
d->m_adaptorModel.setObject(nullptr);
- for (QQmlDelegateModelItem *cacheItem : qAsConst(d->m_cache)) {
+ for (QQmlDelegateModelItem *cacheItem : std::as_const(d->m_cache)) {
if (cacheItem->object) {
delete cacheItem->object;
@@ -412,7 +415,7 @@ void QQmlDelegateModel::setModel(const QVariant &model)
d->connectToAbstractItemModel();
d->m_adaptorModel.replaceWatchedRoles(QList<QByteArray>(), d->m_watchedRoles);
- for (int i = 0; d->m_parts && i < d->m_parts->models.count(); ++i) {
+ for (int i = 0; d->m_parts && i < d->m_parts->models.size(); ++i) {
d->m_adaptorModel.replaceWatchedRoles(
QList<QByteArray>(), d->m_parts->models.at(i)->watchedRoles());
}
@@ -656,7 +659,7 @@ void QQmlDelegateModel::cancel(int index)
Compositor::Cache, it.cacheIndex(), 1, Compositor::CacheFlag);
d->m_cache.removeAt(it.cacheIndex());
delete cacheItem;
- Q_ASSERT(d->m_cache.count() == d->m_compositor.count(Compositor::Cache));
+ Q_ASSERT(d->m_cache.size() == d->m_compositor.count(Compositor::Cache));
}
}
}
@@ -833,7 +836,7 @@ void QQmlDelegateModelPrivate::updateFilterGroup()
if (m_parts) {
auto partsCopy = m_parts->models; // deliberate; this may alter m_parts
- for (QQmlPartsModel *model : qAsConst(partsCopy))
+ for (QQmlPartsModel *model : std::as_const(partsCopy))
model->updateFilterGroup(m_compositorGroup, changeSet);
}
}
@@ -1083,7 +1086,7 @@ void QQmlDelegateModelPrivate::addCacheItem(QQmlDelegateModelItem *item, Composi
{
m_cache.insert(it.cacheIndex(), item);
m_compositor.setFlags(it, 1, Compositor::CacheFlag);
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ Q_ASSERT(m_cache.size() == m_compositor.count(Compositor::Cache));
}
void QQmlDelegateModelPrivate::removeCacheItem(QQmlDelegateModelItem *cacheItem)
@@ -1093,7 +1096,7 @@ void QQmlDelegateModelPrivate::removeCacheItem(QQmlDelegateModelItem *cacheItem)
m_compositor.clearFlags(Compositor::Cache, cidx, 1, Compositor::CacheFlag);
m_cache.removeAt(cidx);
}
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ Q_ASSERT(m_cache.size() == m_compositor.count(Compositor::Cache));
}
void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status)
@@ -1489,7 +1492,7 @@ void QQmlDelegateModelPrivate::itemsInserted(
if (movedItems && insert.isMove()) {
QList<QQmlDelegateModelItem *> items = movedItems->take(insert.moveId);
- Q_ASSERT(items.count() == insert.count);
+ Q_ASSERT(items.size() == insert.count);
m_cache = m_cache.mid(0, insert.cacheIndex())
+ items + m_cache.mid(insert.cacheIndex());
}
@@ -1516,7 +1519,7 @@ void QQmlDelegateModelPrivate::itemsInserted(
cacheIndex = insert.cacheIndex() + insert.count;
}
}
- for (const QList<QQmlDelegateModelItem *> cache = m_cache; cacheIndex < cache.count(); ++cacheIndex)
+ for (const QList<QQmlDelegateModelItem *> cache = m_cache; cacheIndex < cache.size(); ++cacheIndex)
incrementIndexes(cache.at(cacheIndex), m_groupCount, inserted);
}
@@ -1524,7 +1527,7 @@ void QQmlDelegateModelPrivate::itemsInserted(const QVector<Compositor::Insert> &
{
QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> translatedInserts(m_groupCount);
itemsInserted(inserts, &translatedInserts);
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ Q_ASSERT(m_cache.size() == m_compositor.count(Compositor::Cache));
if (!m_delegate)
return;
@@ -1542,7 +1545,7 @@ void QQmlDelegateModel::_q_itemsInserted(int index, int count)
d->m_count += count;
const QList<QQmlDelegateModelItem *> cache = d->m_cache;
- for (int i = 0, c = cache.count(); i < c; ++i) {
+ for (int i = 0, c = cache.size(); i < c; ++i) {
QQmlDelegateModelItem *item = cache.at(i);
// layout change triggered by changing the modelIndex might have
// already invalidated this item in d->m_cache and deleted it.
@@ -1620,7 +1623,7 @@ void QQmlDelegateModelPrivate::itemsRemoved(
delete cacheItem;
--cacheIndex;
++removedCache;
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ Q_ASSERT(m_cache.size() == m_compositor.count(Compositor::Cache));
} else if (remove.groups() == cacheItem->groups) {
cacheItem->groups = 0;
if (QQDMIncubationTask *incubationTask = cacheItem->incubationTask) {
@@ -1664,7 +1667,7 @@ void QQmlDelegateModelPrivate::itemsRemoved(
}
}
- for (const QList<QQmlDelegateModelItem *> cache = m_cache; cacheIndex < cache.count(); ++cacheIndex)
+ for (const QList<QQmlDelegateModelItem *> cache = m_cache; cacheIndex < cache.size(); ++cacheIndex)
incrementIndexes(cache.at(cacheIndex), m_groupCount, removed);
}
@@ -1672,7 +1675,7 @@ void QQmlDelegateModelPrivate::itemsRemoved(const QVector<Compositor::Remove> &r
{
QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> translatedRemoves(m_groupCount);
itemsRemoved(removes, &translatedRemoves);
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ Q_ASSERT(m_cache.size() == m_compositor.count(Compositor::Cache));
if (!m_delegate)
return;
@@ -1693,7 +1696,7 @@ void QQmlDelegateModel::_q_itemsRemoved(int index, int count)
for (QQmlDelegateModelItem *item : cache)
item->referenceObject();
- for (int i = 0, c = cache.count(); i < c; ++i) {
+ for (int i = 0, c = cache.size(); i < c; ++i) {
QQmlDelegateModelItem *item = cache.at(i);
// layout change triggered by removal of a previous item might have
// already invalidated this item in d->m_cache and deleted it
@@ -1730,7 +1733,7 @@ void QQmlDelegateModelPrivate::itemsMoved(
QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> translatedInserts(m_groupCount);
itemsInserted(inserts, &translatedInserts, &movedItems);
- Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ Q_ASSERT(m_cache.size() == m_compositor.count(Compositor::Cache));
Q_ASSERT(movedItems.isEmpty());
if (!m_delegate)
return;
@@ -1753,7 +1756,7 @@ void QQmlDelegateModel::_q_itemsMoved(int from, int to, int count)
const int difference = from > to ? count : -count;
const QList<QQmlDelegateModelItem *> cache = d->m_cache;
- for (int i = 0, c = cache.count(); i < c; ++i) {
+ for (int i = 0, c = cache.size(); i < c; ++i) {
QQmlDelegateModelItem *item = cache.at(i);
// layout change triggered by changing the modelIndex might have
// already invalidated this item in d->m_cache and deleted it.
@@ -1831,7 +1834,7 @@ void QQmlDelegateModelPrivate::emitChanges()
QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitModelUpdated(reset);
auto cacheCopy = m_cache; // deliberate; emitChanges may alter m_cache
- for (QQmlDelegateModelItem *cacheItem : qAsConst(cacheCopy)) {
+ for (QQmlDelegateModelItem *cacheItem : std::as_const(cacheCopy)) {
if (cacheItem->attached)
cacheItem->attached->emitChanges();
}
@@ -1853,7 +1856,7 @@ void QQmlDelegateModel::_q_modelReset()
for (QQmlDelegateModelItem *item : cache)
item->referenceObject();
- for (int i = 0, c = cache.count(); i < c; ++i) {
+ for (int i = 0, c = cache.size(); i < c; ++i) {
QQmlDelegateModelItem *item = cache.at(i);
// layout change triggered by changing the modelIndex might have
// already invalidated this item in d->m_cache and deleted it.
@@ -1974,7 +1977,7 @@ void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelInd
bool QQmlDelegateModel::isDescendantOf(const QPersistentModelIndex& desc, const QList< QPersistentModelIndex >& parents) const
{
- for (int i = 0, c = parents.count(); i < c; ++i) {
+ for (int i = 0, c = parents.size(); i < c; ++i) {
for (QPersistentModelIndex parent = desc; parent.isValid(); parent = parent.parent()) {
if (parent == parents[i])
return true;
@@ -2058,7 +2061,7 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
QQmlDelegateModelItemMetaType::QQmlDelegateModelItemMetaType(
QV4::ExecutionEngine *engine, QQmlDelegateModel *model, const QStringList &groupNames)
: model(model)
- , groupCount(groupNames.count() + 1)
+ , groupCount(groupNames.size() + 1)
, v4Engine(engine)
, metaObject(nullptr)
, groupNames(groupNames)
@@ -2079,7 +2082,7 @@ void QQmlDelegateModelItemMetaType::initializeMetaObject()
builder.setSuperClass(&QQmlDelegateModelAttached::staticMetaObject);
int notifierId = 0;
- for (int i = 0; i < groupNames.count(); ++i, ++notifierId) {
+ for (int i = 0; i < groupNames.size(); ++i, ++notifierId) {
QString propertyName = QLatin1String("in") + groupNames.at(i);
propertyName.replace(2, 1, propertyName.at(2).toUpper());
builder.addSignal("__" + propertyName.toUtf8() + "Changed()");
@@ -2087,7 +2090,7 @@ void QQmlDelegateModelItemMetaType::initializeMetaObject()
propertyName.toUtf8(), "bool", notifierId);
propertyBuilder.setWritable(true);
}
- for (int i = 0; i < groupNames.count(); ++i, ++notifierId) {
+ for (int i = 0; i < groupNames.size(); ++i, ++notifierId) {
const QString propertyName = groupNames.at(i) + QLatin1String("Index");
builder.addSignal("__" + propertyName.toUtf8() + "Changed()");
QMetaPropertyBuilder propertyBuilder = builder.addProperty(
@@ -2134,7 +2137,7 @@ void QQmlDelegateModelItemMetaType::initializePrototype()
p->setSetter(nullptr);
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- for (int i = 2; i < groupNames.count(); ++i) {
+ for (int i = 2; i < groupNames.size(); ++i) {
QString propertyName = QLatin1String("in") + groupNames.at(i);
propertyName.replace(2, 1, propertyName.at(2).toUpper());
s = v4Engine->newString(propertyName);
@@ -2142,7 +2145,7 @@ void QQmlDelegateModelItemMetaType::initializePrototype()
p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::set_member)));
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
- for (int i = 2; i < groupNames.count(); ++i) {
+ for (int i = 2; i < groupNames.size(); ++i) {
const QString propertyName = groupNames.at(i) + QLatin1String("Index");
s = v4Engine->newString(propertyName);
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::get_index)));
@@ -2447,7 +2450,7 @@ QQmlDelegateModelAttachedMetaObject::QQmlDelegateModelAttachedMetaObject(
: metaType(metaType)
, metaObject(metaObject)
, memberPropertyOffset(QQmlDelegateModelAttached::staticMetaObject.propertyCount())
- , indexPropertyOffset(QQmlDelegateModelAttached::staticMetaObject.propertyCount() + metaType->groupNames.count())
+ , indexPropertyOffset(QQmlDelegateModelAttached::staticMetaObject.propertyCount() + metaType->groupNames.size())
{
// Don't reference count the meta-type here as that would create a circular reference.
// Instead we rely the fact that the meta-type's reference count can't reach 0 without first
@@ -3237,7 +3240,7 @@ void QQmlDelegateModelGroup::resolve(QQmlV4Function *args)
Compositor::Cache, toIt.cacheIndex(), resolvedList,
resolvedIndex, 1, Compositor::CacheFlag);
- Q_ASSERT(model->m_cache.count() == model->m_compositor.count(Compositor::Cache));
+ Q_ASSERT(model->m_cache.size() == model->m_compositor.count(Compositor::Cache));
if (!cacheItem->isReferenced()) {
Q_ASSERT(toIt.cacheIndex() == model->m_cache.indexOf(cacheItem));
@@ -3245,7 +3248,7 @@ void QQmlDelegateModelGroup::resolve(QQmlV4Function *args)
model->m_compositor.clearFlags(
Compositor::Cache, toIt.cacheIndex(), 1, Compositor::CacheFlag);
delete cacheItem;
- Q_ASSERT(model->m_cache.count() == model->m_compositor.count(Compositor::Cache));
+ Q_ASSERT(model->m_cache.size() == model->m_compositor.count(Compositor::Cache));
} else {
cacheItem->resolveIndex(model->m_adaptorModel, resolvedIndex);
if (cacheItem->attached)
@@ -3901,7 +3904,7 @@ public:
return engine->memoryManager->allocate<QQmlDelegateModelGroupChangeArray>(changes);
}
- quint32 count() const { return d()->changes->count(); }
+ quint32 count() const { return d()->changes->size(); }
const QQmlChangeSet::Change &at(int index) const { return d()->changes->at(index); }
static QV4::ReturnedValue virtualGet(const QV4::Managed *m, QV4::PropertyKey id, const QV4::Value *receiver, bool *hasProperty)
diff --git a/src/qmlmodels/qqmlinstantiator.cpp b/src/qmlmodels/qqmlinstantiator.cpp
index 5b5ac7766e..fca56dd45a 100644
--- a/src/qmlmodels/qqmlinstantiator.cpp
+++ b/src/qmlmodels/qqmlinstantiator.cpp
@@ -39,10 +39,10 @@ void QQmlInstantiatorPrivate::clear()
Q_Q(QQmlInstantiator);
if (!instanceModel)
return;
- if (!objects.count())
+ if (!objects.size())
return;
- for (int i=0; i < objects.count(); i++) {
+ for (int i=0; i < objects.size(); i++) {
q->objectRemoved(i, objects[i]);
instanceModel->release(objects[i]);
}
@@ -103,7 +103,7 @@ void QQmlInstantiatorPrivate::_q_createdItem(int idx, QObject* item)
if (QObject *o = objects.at(idx))
instanceModel->release(o);
objects.replace(idx, item);
- if (objects.count() == 1)
+ if (objects.size() == 1)
q->objectChanged();
q->objectAdded(idx, item);
}
@@ -126,8 +126,8 @@ void QQmlInstantiatorPrivate::_q_modelUpdated(const QQmlChangeSet &changeSet, bo
QHash<int, QVector<QPointer<QObject> > > moved;
const QVector<QQmlChangeSet::Change> &removes = changeSet.removes();
for (const QQmlChangeSet::Change &remove : removes) {
- int index = qMin(remove.index, objects.count());
- int count = qMin(remove.index + remove.count, objects.count()) - index;
+ int index = qMin(remove.index, objects.size());
+ int count = qMin(remove.index + remove.count, objects.size()) - index;
if (remove.isMove()) {
moved.insert(remove.moveId, objects.mid(index, count));
objects.erase(
@@ -146,7 +146,7 @@ void QQmlInstantiatorPrivate::_q_modelUpdated(const QQmlChangeSet &changeSet, bo
const QVector<QQmlChangeSet::Change> &inserts = changeSet.inserts();
for (const QQmlChangeSet::Change &insert : inserts) {
- int index = qMin(insert.index, objects.count());
+ int index = qMin(insert.index, objects.size());
if (insert.isMove()) {
QVector<QPointer<QObject> > movedObjects = moved.value(insert.moveId);
objects = objects.mid(0, index) + movedObjects + objects.mid(index);
@@ -288,7 +288,7 @@ void QQmlInstantiator::setAsync(bool newVal)
int QQmlInstantiator::count() const
{
Q_D(const QQmlInstantiator);
- return d->objects.count();
+ return d->objects.size();
}
/*!
@@ -420,7 +420,7 @@ void QQmlInstantiator::setModel(const QVariant &v)
QObject *QQmlInstantiator::object() const
{
Q_D(const QQmlInstantiator);
- if (d->objects.count())
+ if (d->objects.size())
return d->objects[0];
return nullptr;
}
@@ -433,7 +433,7 @@ QObject *QQmlInstantiator::object() const
QObject *QQmlInstantiator::objectAt(int index) const
{
Q_D(const QQmlInstantiator);
- if (index >= 0 && index < d->objects.count())
+ if (index >= 0 && index < d->objects.size())
return d->objects[index];
return nullptr;
}
diff --git a/src/qmlmodels/qqmllistaccessor.cpp b/src/qmlmodels/qqmllistaccessor.cpp
index d68d0a2b90..0e57c3c4e9 100644
--- a/src/qmlmodels/qqmllistaccessor.cpp
+++ b/src/qmlmodels/qqmllistaccessor.cpp
@@ -94,16 +94,16 @@ qsizetype QQmlListAccessor::count() const
switch(m_type) {
case StringList:
Q_ASSERT(d.metaType() == QMetaType::fromType<QStringList>());
- return reinterpret_cast<const QStringList *>(d.constData())->count();
+ return reinterpret_cast<const QStringList *>(d.constData())->size();
case UrlList:
Q_ASSERT(d.metaType() == QMetaType::fromType<QList<QUrl>>());
- return reinterpret_cast<const QList<QUrl> *>(d.constData())->count();
+ return reinterpret_cast<const QList<QUrl> *>(d.constData())->size();
case VariantList:
Q_ASSERT(d.metaType() == QMetaType::fromType<QVariantList>());
- return reinterpret_cast<const QVariantList *>(d.constData())->count();
+ return reinterpret_cast<const QVariantList *>(d.constData())->size();
case ObjectList:
Q_ASSERT(d.metaType() == QMetaType::fromType<QList<QObject *>>());
- return reinterpret_cast<const QList<QObject *> *>(d.constData())->count();
+ return reinterpret_cast<const QList<QObject *> *>(d.constData())->size();
case ListProperty:
Q_ASSERT(d.metaType() == QMetaType::fromType<QQmlListReference>());
return reinterpret_cast<const QQmlListReference *>(d.constData())->count();
diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp
index f02449e6c6..78a513fb02 100644
--- a/src/qmlmodels/qqmllistmodel.cpp
+++ b/src/qmlmodels/qqmllistmodel.cpp
@@ -98,7 +98,7 @@ const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::R
sizeof(double),
sizeof(bool),
sizeof(ListModel *),
- sizeof(ListElement::GuardedQObjectPointer),
+ sizeof(QV4::PersistentValue),
sizeof(QVariantMap),
sizeof(QDateTime),
sizeof(QUrl),
@@ -109,7 +109,7 @@ const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::R
alignof(double),
alignof(bool),
alignof(ListModel *),
- alignof(QObject *),
+ alignof(QV4::PersistentValue),
alignof(QVariantMap),
alignof(QDateTime),
alignof(QUrl),
@@ -140,7 +140,7 @@ const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::R
currentBlockOffset = dataOffset + dataSize;
}
- int roleIndex = roles.count();
+ int roleIndex = roles.size();
r->index = roleIndex;
roles.append(r);
@@ -151,7 +151,7 @@ const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::R
ListLayout::ListLayout(const ListLayout *other) : currentBlock(0), currentBlockOffset(0)
{
- const int otherRolesCount = other->roles.count();
+ const int otherRolesCount = other->roles.size();
roles.reserve(otherRolesCount);
for (int i=0 ; i < otherRolesCount; ++i) {
Role *role = new Role(other->roles[i]);
@@ -169,8 +169,8 @@ ListLayout::~ListLayout()
void ListLayout::sync(ListLayout *src, ListLayout *target)
{
- int roleOffset = target->roles.count();
- int newRoleCount = src->roles.count() - roleOffset;
+ int roleOffset = target->roles.size();
+ int newRoleCount = src->roles.size() - roleOffset;
for (int i=0 ; i < newRoleCount ; ++i) {
Role *role = new Role(src->roles[roleOffset + i]);
@@ -271,7 +271,7 @@ void StringOrTranslation::setString(const QString &s)
QString::DataPointer dataPointer = mutableString.data_ptr();
arrayData = dataPointer->d_ptr();
stringData = dataPointer->data();
- stringSize = mutableString.length();
+ stringSize = mutableString.size();
if (arrayData)
arrayData->ref();
}
@@ -618,10 +618,9 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles)
roleIndex = e->setFunctionProperty(r, jsv);
} else if (QV4::Object *o = propertyValue->as<QV4::Object>()) {
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
- QObject *o = wrapper->object();
const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject);
if (role.type == ListLayout::Role::QObject)
- roleIndex = e->setQObjectProperty(role, o);
+ roleIndex = e->setQObjectProperty(role, wrapper);
} else if (QVariant maybeUrl = o->engine()->toVariant(o->asReturnedValue(), QMetaType::fromType<QUrl>(), true);
maybeUrl.metaType() == QMetaType::fromType<QUrl>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Url);
@@ -709,10 +708,9 @@ void ListModel::set(int elementIndex, QV4::Object *object, ListModel::SetElement
}
} else if (QV4::Object *o = propertyValue->as<QV4::Object>()) {
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
- QObject *o = wrapper->object();
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject);
if (r.type == ListLayout::Role::QObject)
- e->setQObjectPropertyFast(r, o);
+ e->setQObjectPropertyFast(r, wrapper);
} else {
QVariant maybeUrl = o->engine()->toVariant(o->asReturnedValue(), QMetaType::fromType<QUrl>(), true);
if (maybeUrl.metaType() == QMetaType::fromType<QUrl>()) {
@@ -836,12 +834,11 @@ StringOrTranslation *ListElement::getStringProperty(const ListLayout::Role &role
return s;
}
-QObject *ListElement::getQObjectProperty(const ListLayout::Role &role)
+QV4::QObjectWrapper *ListElement::getQObjectProperty(const ListLayout::Role &role)
{
char *mem = getPropertyMemory(role);
- GuardedQObjectPointer *o
- = reinterpret_cast<GuardedQObjectPointer *>(mem);
- return o->data();
+ QV4::PersistentValue *g = reinterpret_cast<QV4::PersistentValue *>(mem);
+ return g->as<QV4::QObjectWrapper>();
}
QVariantMap *ListElement::getVariantMapProperty(const ListLayout::Role &role)
@@ -888,13 +885,13 @@ QJSValue *ListElement::getFunctionProperty(const ListLayout::Role &role)
return f;
}
-ListElement::GuardedQObjectPointer *
+QV4::PersistentValue *
ListElement::getGuardProperty(const ListLayout::Role &role)
{
char *mem = getPropertyMemory(role);
bool existingGuard = false;
- for (size_t i = 0; i < sizeof(GuardedQObjectPointer);
+ for (size_t i = 0; i < sizeof(QV4::PersistentValue);
++i) {
if (mem[i] != 0) {
existingGuard = true;
@@ -902,12 +899,12 @@ ListElement::getGuardProperty(const ListLayout::Role &role)
}
}
- GuardedQObjectPointer *o = nullptr;
+ QV4::PersistentValue *g = nullptr;
if (existingGuard)
- o = reinterpret_cast<GuardedQObjectPointer *>(mem);
+ g = reinterpret_cast<QV4::PersistentValue *>(mem);
- return o;
+ return g;
}
ListModel *ListElement::getListProperty(const ListLayout::Role &role)
@@ -963,12 +960,8 @@ QVariant ListElement::getProperty(const ListLayout::Role &role, const QQmlListMo
break;
case ListLayout::Role::QObject:
{
- GuardedQObjectPointer *guard =
- reinterpret_cast<GuardedQObjectPointer *>(
- mem);
- QObject *object = guard->data();
- if (object)
- data = QVariant::fromValue(object);
+ QV4::PersistentValue *guard = reinterpret_cast<QV4::PersistentValue *>(mem);
+ data = QVariant::fromValue(guard->as<QV4::QObjectWrapper>()->object());
}
break;
case ListLayout::Role::VariantMap:
@@ -1080,67 +1073,17 @@ int ListElement::setListProperty(const ListLayout::Role &role, ListModel *m)
return roleIndex;
}
-static void
-restoreQObjectOwnership(ListElement::GuardedQObjectPointer *pointer)
-{
- if (QObject *o = pointer->data()) {
- QQmlData *data = QQmlData::get(o, false);
- Q_ASSERT(data);
-
- // Only restore the previous state if the object hasn't become explicitly
- // owned
- if (!data->explicitIndestructibleSet)
- data->indestructible = (pointer->tag() & ListElement::Indestructible);
- }
-}
-
-static void setQObjectOwnership(char *mem, QObject *o)
-{
- QQmlData *ddata = QQmlData::get(o, false);
- const int ownership = (!ddata || ddata->indestructible ? ListElement::Indestructible : 0)
- | (ddata && ddata->explicitIndestructibleSet ? ListElement::ExplicitlySet : 0);
-
- // If ddata didn't exist above, force its creation now
- if (!ddata)
- ddata = QQmlData::get(o, true);
-
- if (!ddata->explicitIndestructibleSet)
- ddata->indestructible = ownership != 0;
-
- new (mem) ListElement::GuardedQObjectPointer(
- o, static_cast<ListElement::ObjectIndestructible>(ownership));
-}
-
-int ListElement::setQObjectProperty(const ListLayout::Role &role, QObject *o)
+int ListElement::setQObjectProperty(const ListLayout::Role &role, QV4::QObjectWrapper *o)
{
int roleIndex = -1;
if (role.type == ListLayout::Role::QObject) {
char *mem = getPropertyMemory(role);
- GuardedQObjectPointer *g =
- reinterpret_cast<GuardedQObjectPointer *>(mem);
- bool existingGuard = false;
- for (size_t i = 0; i < sizeof(GuardedQObjectPointer);
- ++i) {
- if (mem[i] != 0) {
- existingGuard = true;
- break;
- }
- }
- bool changed;
- if (existingGuard) {
- changed = g->data() != o;
- if (changed)
- restoreQObjectOwnership(g);
- g->~GuardedQObjectPointer();
- } else {
- changed = true;
- }
-
- setQObjectOwnership(mem, o);
-
- if (changed)
- roleIndex = role.index;
+ if (isMemoryUsed<QVariantMap>(mem))
+ reinterpret_cast<QV4::PersistentValue *>(mem)->set(o->engine(), *o);
+ else
+ new (mem) QV4::PersistentValue(o->engine(), o);
+ roleIndex = role.index;
}
return roleIndex;
@@ -1273,11 +1216,10 @@ void ListElement::setBoolPropertyFast(const ListLayout::Role &role, bool b)
*value = b;
}
-void ListElement::setQObjectPropertyFast(const ListLayout::Role &role, QObject *o)
+void ListElement::setQObjectPropertyFast(const ListLayout::Role &role, QV4::QObjectWrapper *o)
{
char *mem = getPropertyMemory(role);
-
- setQObjectOwnership(mem, o);
+ new (mem) QV4::PersistentValue(o->engine(), o);
}
void ListElement::setListPropertyFast(const ListLayout::Role &role, ListModel *m)
@@ -1394,7 +1336,7 @@ QVector<int> ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElem
break;
case ListLayout::Role::QObject:
{
- QObject *object = src->getQObjectProperty(srcRole);
+ QV4::QObjectWrapper *object = src->getQObjectProperty(srcRole);
roleIndex = target->setQObjectProperty(targetRole, object);
}
break;
@@ -1449,14 +1391,8 @@ void ListElement::destroy(ListLayout *layout)
break;
case ListLayout::Role::QObject:
{
- GuardedQObjectPointer *guard =
- getGuardProperty(r);
-
- if (guard) {
- restoreQObjectOwnership(guard);
-
- guard->~GuardedQObjectPointer();
- }
+ if (QV4::PersistentValue *guard = getGuardProperty(r))
+ guard->~PersistentValue();
}
break;
case ListLayout::Role::VariantMap:
@@ -1593,8 +1529,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
QV4::ScopedObject o(scope, d);
QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>();
if (role.type == ListLayout::Role::QObject && wrapper) {
- QObject *o = wrapper->object();
- roleIndex = setQObjectProperty(role, o);
+ roleIndex = setQObjectProperty(role, wrapper);
} else if (role.type == ListLayout::Role::VariantMap) {
roleIndex = setVariantMapProperty(role, o);
} else if (role.type == ListLayout::Role::Url) {
@@ -1671,10 +1606,10 @@ void ModelNodeMetaObject::updateValues()
void ModelNodeMetaObject::updateValues(const QVector<int> &roles)
{
if (!m_initialized) {
- emitDirectNotifies(roles.constData(), roles.count());
+ emitDirectNotifies(roles.constData(), roles.size());
return;
}
- int roleCount = roles.count();
+ int roleCount = roles.size();
for (int i=0 ; i < roleCount ; ++i) {
int roleIndex = roles.at(i);
const ListLayout::Role &role = m_model->m_listModel->getExistingRole(roleIndex);
@@ -1872,7 +1807,7 @@ void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector<int>
int roleIndex = m_owner->m_roles.indexOf(key);
if (roleIndex == -1) {
- roleIndex = m_owner->m_roles.count();
+ roleIndex = m_owner->m_roles.size();
m_owner->m_roles.append(key);
}
@@ -2172,7 +2107,7 @@ bool QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target)
// Build hash of elements <-> uid for each of the lists
QHash<int, ElementSync> elementHash;
- for (int i = 0 ; i < target->m_modelObjects.count(); ++i) {
+ for (int i = 0 ; i < target->m_modelObjects.size(); ++i) {
DynamicRoleModelNode *e = target->m_modelObjects.at(i);
int uid = e->getUid();
ElementSync sync;
@@ -2180,7 +2115,7 @@ bool QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target)
sync.targetIndex = i;
elementHash.insert(uid, sync);
}
- for (int i = 0 ; i < src->m_modelObjects.count(); ++i) {
+ for (int i = 0 ; i < src->m_modelObjects.size(); ++i) {
DynamicRoleModelNode *e = src->m_modelObjects.at(i);
int uid = e->getUid();
@@ -2199,7 +2134,7 @@ bool QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target)
// Get list of elements that are in the target but no longer in the source. These get deleted first.
int rowsRemoved = 0;
- for (int i = 0 ; i < target->m_modelObjects.count() ; ++i) {
+ for (int i = 0 ; i < target->m_modelObjects.size() ; ++i) {
DynamicRoleModelNode *element = target->m_modelObjects.at(i);
ElementSync &s = elementHash.find(element->getUid()).value();
Q_ASSERT(s.targetIndex >= 0);
@@ -2220,7 +2155,7 @@ bool QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target)
// Clear the target list, and append in correct order from the source
target->m_modelObjects.clear();
- for (int i = 0 ; i < src->m_modelObjects.count() ; ++i) {
+ for (int i = 0 ; i < src->m_modelObjects.size() ; ++i) {
DynamicRoleModelNode *element = src->m_modelObjects.at(i);
ElementSync &s = elementHash.find(element->getUid()).value();
Q_ASSERT(s.srcIndex >= 0);
@@ -2238,7 +2173,7 @@ bool QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target)
// to ensure things are kept in the correct order, emit inserts and moves first. This shouls ensure all persistent
// model indices are updated correctly
int rowsInserted = 0;
- for (int i = 0 ; i < target->m_modelObjects.count() ; ++i) {
+ for (int i = 0 ; i < target->m_modelObjects.size() ; ++i) {
DynamicRoleModelNode *element = target->m_modelObjects.at(i);
ElementSync &s = elementHash.find(element->getUid()).value();
Q_ASSERT(s.srcIndex >= 0);
@@ -2357,7 +2292,7 @@ QHash<int, QByteArray> QQmlListModel::roleNames() const
QHash<int, QByteArray> roleNames;
if (m_dynamicRoles) {
- for (int i = 0 ; i < m_roles.count() ; ++i)
+ for (int i = 0 ; i < m_roles.size() ; ++i)
roleNames.insert(i, m_roles.at(i).toUtf8());
} else {
for (int i = 0 ; i < m_listModel->roleCount() ; ++i) {
@@ -2404,7 +2339,7 @@ void QQmlListModel::setDynamicRoles(bool enableDynamicRoles)
else
m_dynamicRoles = true;
} else {
- if (m_roles.count()) {
+ if (m_roles.size()) {
qmlWarning(this) << tr("unable to enable static roles as this model is not empty");
} else {
m_dynamicRoles = false;
@@ -2421,7 +2356,7 @@ void QQmlListModel::setDynamicRoles(bool enableDynamicRoles)
*/
int QQmlListModel::count() const
{
- return m_dynamicRoles ? m_modelObjects.count() : m_listModel->elementCount();
+ return m_dynamicRoles ? m_modelObjects.size() : m_listModel->elementCount();
}
/*!
@@ -2502,6 +2437,16 @@ void QQmlListModel::updateTranslations()
if (m_dynamicRoles)
return;
Q_ASSERT(m_listModel);
+
+ QList<int> roles;
+ for (int i = 0, end = m_listModel->roleCount(); i != end; ++i) {
+ if (m_listModel->getExistingRole(i).type == ListLayout::Role::String)
+ roles.append(i);
+ }
+
+ if (!roles.isEmpty())
+ emitItemsChanged(0, rowCount(QModelIndex()), roles);
+
m_listModel->updateTranslations();
}
@@ -2668,7 +2613,7 @@ void QQmlListModel::append(QQmlV4Function *args)
int index;
if (m_dynamicRoles) {
- index = m_modelObjects.count();
+ index = m_modelObjects.size();
emitItemsAboutToBeInserted(index, 1);
m_modelObjects.append(DynamicRoleModelNode::create(scope.engine->variantMapFromJS(argObject), this));
} else {
@@ -2794,7 +2739,7 @@ void QQmlListModel::set(int index, const QJSValue &value)
m_listModel->set(index, object, &roles);
}
- if (roles.count())
+ if (roles.size())
emitItemsChanged(index, 1, roles);
}
}
@@ -2822,7 +2767,7 @@ void QQmlListModel::setProperty(int index, const QString& property, const QVaria
if (m_dynamicRoles) {
int roleIndex = m_roles.indexOf(property);
if (roleIndex == -1) {
- roleIndex = m_roles.count();
+ roleIndex = m_roles.size();
m_roles.append(property);
}
if (m_modelObjects[index]->setValue(property.toUtf8(), value))
@@ -2881,9 +2826,8 @@ bool QQmlListModelParser::verifyProperty(const QQmlRefPointer<QV4::ExecutableCom
} else if (binding->type() == QV4::CompiledData::Binding::Type_Script) {
QString scriptStr = compilationUnit->bindingValueAsScriptString(binding);
if (!binding->isFunctionExpression() && !definesEmptyList(scriptStr)) {
- QByteArray script = scriptStr.toUtf8();
bool ok;
- evaluateEnum(script, &ok);
+ evaluateEnum(scriptStr, &ok);
if (!ok) {
error(binding, QQmlListModel::tr("ListElement: cannot use script for property value"));
return false;
@@ -2966,9 +2910,8 @@ bool QQmlListModelParser::applyProperty(
QJSValuePrivate::setValue(&v, result->asReturnedValue());
value.setValue(v);
} else {
- QByteArray script = scriptStr.toUtf8();
bool ok;
- value = evaluateEnum(script, &ok);
+ value = evaluateEnum(scriptStr, &ok);
}
} else {
Q_UNREACHABLE();
@@ -3027,7 +2970,7 @@ void QQmlListModelParser::applyBindings(QObject *obj, const QQmlRefPointer<QV4::
bool QQmlListModelParser::definesEmptyList(const QString &s)
{
if (s.startsWith(QLatin1Char('[')) && s.endsWith(QLatin1Char(']'))) {
- for (int i=1; i<s.length()-1; i++) {
+ for (int i=1; i<s.size()-1; i++) {
if (!s[i].isSpace())
return false;
}
diff --git a/src/qmlmodels/qqmllistmodel_p_p.h b/src/qmlmodels/qqmllistmodel_p_p.h
index 0499c6a1a0..662a12f9e7 100644
--- a/src/qmlmodels/qqmllistmodel_p_p.h
+++ b/src/qmlmodels/qqmllistmodel_p_p.h
@@ -202,7 +202,7 @@ public:
const Role *getExistingRole(const QString &key) const;
const Role *getExistingRole(QV4::String *key) const;
- int roleCount() const { return roles.count(); }
+ int roleCount() const { return roles.size(); }
static void sync(ListLayout *src, ListLayout *target);
@@ -245,43 +245,6 @@ public:
enum ObjectIndestructible { Indestructible = 1, ExplicitlySet = 2 };
enum { BLOCK_SIZE = 64 - sizeof(int) - sizeof(ListElement *) - sizeof(ModelNodeMetaObject *) };
- // This is a basic guarded QObject pointer, with tag. It cannot be copied or moved.
- class GuardedQObjectPointer
- {
- Q_DISABLE_COPY_MOVE(GuardedQObjectPointer)
-
- using RefCountData = QtSharedPointer::ExternalRefCountData;
- using Storage = QTaggedPointer<QObject, ObjectIndestructible>;
-
- public:
- GuardedQObjectPointer(QObject *o, ObjectIndestructible ownership)
- : storage(o, ownership)
- , refCount(o ? RefCountData::getAndRef(o) : nullptr)
- {}
-
- ~GuardedQObjectPointer()
- {
- if (refCount && !refCount->weakref.deref())
- delete refCount;
- }
-
- QObject *data() const
- {
- return (refCount == nullptr || refCount->strongref.loadRelaxed() == 0)
- ? nullptr
- : storage.data();
- }
-
- ObjectIndestructible tag() const
- {
- return storage.tag();
- }
-
- private:
- Storage storage;
- RefCountData *refCount = nullptr;
- };
-
ListElement();
ListElement(int existingUid);
~ListElement();
@@ -300,7 +263,7 @@ private:
int setDoubleProperty(const ListLayout::Role &role, double n);
int setBoolProperty(const ListLayout::Role &role, bool b);
int setListProperty(const ListLayout::Role &role, ListModel *m);
- int setQObjectProperty(const ListLayout::Role &role, QObject *o);
+ int setQObjectProperty(const ListLayout::Role &role, QV4::QObjectWrapper *o);
int setVariantMapProperty(const ListLayout::Role &role, QV4::Object *o);
int setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m);
int setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt);
@@ -311,7 +274,7 @@ private:
void setStringPropertyFast(const ListLayout::Role &role, const QString &s);
void setDoublePropertyFast(const ListLayout::Role &role, double n);
void setBoolPropertyFast(const ListLayout::Role &role, bool b);
- void setQObjectPropertyFast(const ListLayout::Role &role, QObject *o);
+ void setQObjectPropertyFast(const ListLayout::Role &role, QV4::QObjectWrapper *o);
void setListPropertyFast(const ListLayout::Role &role, ListModel *m);
void setVariantMapFast(const ListLayout::Role &role, QV4::Object *o);
void setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt);
@@ -323,8 +286,8 @@ private:
QVariant getProperty(const ListLayout::Role &role, const QQmlListModel *owner, QV4::ExecutionEngine *eng);
ListModel *getListProperty(const ListLayout::Role &role);
StringOrTranslation *getStringProperty(const ListLayout::Role &role);
- QObject *getQObjectProperty(const ListLayout::Role &role);
- GuardedQObjectPointer *getGuardProperty(const ListLayout::Role &role);
+ QV4::QObjectWrapper *getQObjectProperty(const ListLayout::Role &role);
+ QV4::PersistentValue *getGuardProperty(const ListLayout::Role &role);
QVariantMap *getVariantMapProperty(const ListLayout::Role &role);
QDateTime *getDateTimeProperty(const ListLayout::Role &role);
QUrl *getUrlProperty(const ListLayout::Role &role);
diff --git a/src/qmlmodels/qqmlobjectmodel.cpp b/src/qmlmodels/qqmlobjectmodel.cpp
index 118b2fab78..970a1e541f 100644
--- a/src/qmlmodels/qqmlobjectmodel.cpp
+++ b/src/qmlmodels/qqmlobjectmodel.cpp
@@ -39,12 +39,12 @@ public:
QQmlObjectModelPrivate() : QObjectPrivate(), moveId(0) {}
static void children_append(QQmlListProperty<QObject> *prop, QObject *item) {
- qsizetype index = static_cast<QQmlObjectModelPrivate *>(prop->data)->children.count();
+ qsizetype index = static_cast<QQmlObjectModelPrivate *>(prop->data)->children.size();
static_cast<QQmlObjectModelPrivate *>(prop->data)->insert(index, item);
}
static qsizetype children_count(QQmlListProperty<QObject> *prop) {
- return static_cast<QQmlObjectModelPrivate *>(prop->data)->children.count();
+ return static_cast<QQmlObjectModelPrivate *>(prop->data)->children.size();
}
static QObject *children_at(QQmlListProperty<QObject> *prop, qsizetype index) {
@@ -61,13 +61,13 @@ public:
static void children_removeLast(QQmlListProperty<QObject> *prop) {
auto data = static_cast<QQmlObjectModelPrivate *>(prop->data);
- data->remove(data->children.count() - 1, 1);
+ data->remove(data->children.size() - 1, 1);
}
void insert(int index, QObject *item) {
Q_Q(QQmlObjectModel);
children.insert(index, Item(item));
- for (int i = index; i < children.count(); ++i) {
+ for (int i = index; i < children.size(); ++i) {
QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.at(i).item);
attached->setIndex(i);
}
@@ -126,7 +126,7 @@ public:
attached->setIndex(-1);
}
children.erase(children.begin() + index, children.begin() + index + n);
- for (int i = index; i < children.count(); ++i) {
+ for (int i = index; i < children.size(); ++i) {
QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.at(i).item);
attached->setIndex(i);
}
@@ -142,11 +142,11 @@ public:
const auto copy = children;
for (const Item &child : copy)
emit q->destroyingItem(child.item);
- remove(0, children.count());
+ remove(0, children.size());
}
int indexOf(QObject *item) const {
- for (int i = 0; i < children.count(); ++i)
+ for (int i = 0; i < children.size(); ++i)
if (children.at(i).item == item)
return i;
return -1;
@@ -231,7 +231,7 @@ QQmlListProperty<QObject> QQmlObjectModel::children()
int QQmlObjectModel::count() const
{
Q_D(const QQmlObjectModel);
- return d->children.count();
+ return d->children.size();
}
bool QQmlObjectModel::isValid() const
@@ -265,7 +265,7 @@ QQmlInstanceModel::ReleaseFlags QQmlObjectModel::release(QObject *item, Reusable
QVariant QQmlObjectModel::variantValue(int index, const QString &role)
{
Q_D(QQmlObjectModel);
- if (index < 0 || index >= d->children.count())
+ if (index < 0 || index >= d->children.size())
return QString();
return d->children.at(index).item->property(role.toUtf8().constData());
}
@@ -308,7 +308,7 @@ QQmlObjectModelAttached *QQmlObjectModel::qmlAttachedProperties(QObject *obj)
QObject *QQmlObjectModel::get(int index) const
{
Q_D(const QQmlObjectModel);
- if (index < 0 || index >= d->children.count())
+ if (index < 0 || index >= d->children.size())
return nullptr;
return d->children.at(index).item;
}
diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp
index 39102c27c9..b6836be349 100644
--- a/src/qmlmodels/qqmltableinstancemodel.cpp
+++ b/src/qmlmodels/qqmltableinstancemodel.cpp
@@ -409,7 +409,7 @@ void QQmlTableInstanceModel::deleteIncubationTaskLater(QQmlIncubator *incubation
// delete them while we're in the middle of an incubation change callback.
Q_ASSERT(!m_finishedIncubationTasks.contains(incubationTask));
m_finishedIncubationTasks.append(incubationTask);
- if (m_finishedIncubationTasks.count() == 1)
+ if (m_finishedIncubationTasks.size() == 1)
QTimer::singleShot(1, this, &QQmlTableInstanceModel::deleteAllFinishedIncubationTasks);
}
diff --git a/src/qmlmodels/qqmltreemodeltotablemodel.cpp b/src/qmlmodels/qqmltreemodeltotablemodel.cpp
index 810ea2cde8..1fdcc1f95b 100644
--- a/src/qmlmodels/qqmltreemodeltotablemodel.cpp
+++ b/src/qmlmodels/qqmltreemodeltotablemodel.cpp
@@ -133,7 +133,7 @@ int QQmlTreeModelToTableModel::rowCount(const QModelIndex &) const
{
if (!m_model)
return 0;
- return m_items.count();
+ return m_items.size();
}
int QQmlTreeModelToTableModel::columnCount(const QModelIndex &parent) const
@@ -166,7 +166,7 @@ QVariant QQmlTreeModelToTableModel::headerData(int section, Qt::Orientation orie
int QQmlTreeModelToTableModel::depthAtRow(int row) const
{
- if (row < 0 || row >= m_items.count())
+ if (row < 0 || row >= m_items.size())
return 0;
return m_items.at(row).depth;
}
@@ -177,7 +177,7 @@ int QQmlTreeModelToTableModel::itemIndex(const QModelIndex &index) const
if (!index.isValid() || index == m_rootIndex || m_items.isEmpty())
return -1;
- const int totalCount = m_items.count();
+ const int totalCount = m_items.size();
// We start nearest to the lastViewedItem
int localCount = qMin(m_lastItemIndex - 1, totalCount - m_lastItemIndex);
@@ -232,7 +232,7 @@ QModelIndex QQmlTreeModelToTableModel::mapToModel(const QModelIndex &index) cons
return QModelIndex();
const int row = index.row();
- if (row < 0 || row > m_items.count() - 1)
+ if (row < 0 || row > m_items.size() - 1)
return QModelIndex();
const QModelIndex sourceIndex = m_items.at(row).index;
@@ -245,7 +245,7 @@ QModelIndex QQmlTreeModelToTableModel::mapFromModel(const QModelIndex &index) co
return QModelIndex();
int row = -1;
- for (int i = 0; i < m_items.count(); ++i) {
+ for (int i = 0; i < m_items.size(); ++i) {
const QModelIndex proxyIndex = m_items[i].index;
if (proxyIndex.row() == index.row() && proxyIndex.parent() == index.parent()) {
row = i;
@@ -261,7 +261,7 @@ QModelIndex QQmlTreeModelToTableModel::mapFromModel(const QModelIndex &index) co
QModelIndex QQmlTreeModelToTableModel::mapToModel(int row) const
{
- if (row < 0 || row >= m_items.count())
+ if (row < 0 || row >= m_items.size())
return QModelIndex();
return m_items.at(row).index;
}
@@ -314,8 +314,8 @@ QItemSelection QQmlTreeModelToTableModel::selectionForRowRange(const QModelInde
}
QItemSelection sel;
- sel.reserve(ranges.count());
- for (const MIPair &pair : qAsConst(ranges))
+ sel.reserve(ranges.size());
+ for (const MIPair &pair : std::as_const(ranges))
sel.append(QItemSelectionRange(pair.first, pair.second));
return sel;
@@ -368,7 +368,7 @@ void QQmlTreeModelToTableModel::showModelChildItems(const TreeItem &parentItem,
int rowDepth = rowIdx == 0 ? 0 : parentItem.depth + 1;
if (doInsertRows)
beginInsertRows(QModelIndex(), startIdx, startIdx + insertCount - 1);
- m_items.reserve(m_items.count() + insertCount);
+ m_items.reserve(m_items.size() + insertCount);
for (int i = 0; i < insertCount; i++) {
const QModelIndex &cmi = m_model->index(start + i, 0, parentIndex);
@@ -446,14 +446,14 @@ bool QQmlTreeModelToTableModel::isExpanded(const QModelIndex &index) const
bool QQmlTreeModelToTableModel::isExpanded(int row) const
{
- if (row < 0 || row >= m_items.count())
+ if (row < 0 || row >= m_items.size())
return false;
return m_items.at(row).expanded;
}
bool QQmlTreeModelToTableModel::hasChildren(int row) const
{
- if (row < 0 || row >= m_items.count())
+ if (row < 0 || row >= m_items.size())
return false;
return m_model->hasChildren(m_items[row].index);
}
@@ -591,7 +591,7 @@ int QQmlTreeModelToTableModel::lastChildIndex(const QModelIndex &index) const
parent = parent.parent();
}
- int firstIndex = nextSiblingIndex.isValid() ? itemIndex(nextSiblingIndex) : m_items.count();
+ int firstIndex = nextSiblingIndex.isValid() ? itemIndex(nextSiblingIndex) : m_items.size();
return firstIndex - 1;
}
@@ -607,7 +607,7 @@ void QQmlTreeModelToTableModel::removeVisibleRows(int startIndex, int endIndex,
endRemoveRows();
/* We need to update the model index for all the items below the removed ones */
- int lastIndex = m_items.count() - 1;
+ int lastIndex = m_items.size() - 1;
if (startIndex <= lastIndex) {
const QModelIndex &topLeft = index(startIndex, 0, QModelIndex());
const QModelIndex &bottomRight = index(lastIndex, 0, QModelIndex());
@@ -647,7 +647,7 @@ void QQmlTreeModelToTableModel::modelDataChanged(const QModelIndex &topLeft, con
for (int i = topLeft.row(); i <= bottomRight.row(); i++) {
// Group items with same parent to minize the number of 'dataChanged()' emits
int bottomIndex = topIndex;
- while (bottomIndex < m_items.count()) {
+ while (bottomIndex < m_items.size()) {
const QModelIndex &idx = m_items.at(bottomIndex).index;
if (idx.parent() != parent) {
--bottomIndex;
@@ -663,7 +663,7 @@ void QQmlTreeModelToTableModel::modelDataChanged(const QModelIndex &topLeft, con
if (i == bottomRight.row())
break;
topIndex = bottomIndex + 1;
- while (topIndex < m_items.count()
+ while (topIndex < m_items.size()
&& m_items.at(topIndex).index.parent() != parent)
topIndex++;
}
@@ -672,50 +672,87 @@ void QQmlTreeModelToTableModel::modelDataChanged(const QModelIndex &topLeft, con
void QQmlTreeModelToTableModel::modelLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint)
{
- ASSERT_CONSISTENCY();
- Q_UNUSED(parents)
Q_UNUSED(hint)
+
+ // Since the m_items is a list of TreeItems that contains QPersistentModelIndexes, we
+ // cannot wait until we get a modelLayoutChanged() before we remove the affected rows
+ // from that list. After the layout has changed, the list (or, the persistent indexes
+ // that it contains) is no longer in sync with the model (after all, that is what we're
+ // supposed to correct in modelLayoutChanged()).
+ // This means that vital functions, like itemIndex(index), cannot be trusted at that point.
+ // Therefore we need to do the update in two steps; First remove all the affected rows
+ // from here (while we're still in sync with the model), and then add back the
+ // affected rows, and notify about it, from modelLayoutChanged().
+ m_modelLayoutChanged = false;
+
+ if (parents.isEmpty() || !parents[0].isValid()) {
+ // Update entire model
+ emit layoutAboutToBeChanged();
+ m_modelLayoutChanged = true;
+ m_items.clear();
+ return;
+ }
+
+ for (const QPersistentModelIndex &pmi : parents) {
+ if (!m_expandedItems.contains(pmi))
+ continue;
+ const int row = itemIndex(pmi);
+ if (row == -1)
+ continue;
+ const int rowCount = m_model->rowCount(pmi);
+ if (rowCount == 0)
+ continue;
+
+ if (!m_modelLayoutChanged) {
+ emit layoutAboutToBeChanged();
+ m_modelLayoutChanged = true;
+ }
+
+ const QModelIndex &lmi = m_model->index(rowCount - 1, 0, pmi);
+ const int lastRow = lastChildIndex(lmi);
+ removeVisibleRows(row + 1, lastRow, false /*doRemoveRows*/);
+ }
+
+ ASSERT_CONSISTENCY();
}
void QQmlTreeModelToTableModel::modelLayoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint)
{
Q_UNUSED(hint)
- if (parents.isEmpty()) {
- emit layoutAboutToBeChanged();
- m_items.clear();
+ if (!m_modelLayoutChanged) {
+ // No relevant changes done from modelLayoutAboutToBeChanged()
+ return;
+ }
+
+ if (m_items.isEmpty()) {
+ // Entire model has changed. Add back all rows.
showModelTopLevelItems(false /*doInsertRows*/);
const QModelIndex &mi = m_model->index(0, 0);
const int columnCount = m_model->columnCount(mi);
- emit dataChanged(index(0, 0), index(m_items.count() - 1, columnCount - 1));
+ emit dataChanged(index(0, 0), index(m_items.size() - 1, columnCount - 1));
emit layoutChanged();
return;
}
- bool shouldEmitLayoutChanged = false;
for (const QPersistentModelIndex &pmi : parents) {
- if (m_expandedItems.contains(pmi)) {
- int row = itemIndex(pmi);
- if (row != -1) {
- if (!shouldEmitLayoutChanged) {
- shouldEmitLayoutChanged = true;
- emit layoutAboutToBeChanged();
- }
- int rowCount = m_model->rowCount(pmi);
- if (rowCount > 0) {
- const QModelIndex &lmi = m_model->index(rowCount - 1, 0, pmi);
- const int lastRow = lastChildIndex(lmi);
- const int columnCount = m_model->columnCount(lmi);
- removeVisibleRows(row + 1, lastRow, false /*doRemoveRows*/);
- showModelChildItems(m_items.at(row), 0, rowCount - 1, false /*doInsertRows*/);
- emit dataChanged(index(row + 1, 0), index(lastRow, columnCount - 1));
- }
- }
- }
+ if (!m_expandedItems.contains(pmi))
+ continue;
+ const int row = itemIndex(pmi);
+ if (row == -1)
+ continue;
+ const int rowCount = m_model->rowCount(pmi);
+ if (rowCount == 0)
+ continue;
+
+ const QModelIndex &lmi = m_model->index(rowCount - 1, 0, pmi);
+ const int columnCount = m_model->columnCount(lmi);
+ showModelChildItems(m_items.at(row), 0, rowCount - 1, false /*doInsertRows*/);
+ const int lastRow = lastChildIndex(lmi);
+ emit dataChanged(index(row + 1, 0), index(lastRow, columnCount - 1));
}
- if (shouldEmitLayoutChanged)
- emit layoutChanged();
+ emit layoutChanged();
ASSERT_CONSISTENCY();
}
@@ -864,7 +901,7 @@ void QQmlTreeModelToTableModel::modelRowsAboutToBeMoved(const QModelIndex & sour
}
bufferCopyOffset = destIndex;
}
- for (int i = 0; i < buffer.length(); i++) {
+ for (int i = 0; i < buffer.size(); i++) {
TreeItem item = buffer.at(i);
item.depth += depthDifference;
m_items.replace(bufferCopyOffset + i, item);
@@ -933,7 +970,7 @@ void QQmlTreeModelToTableModel::dump() const
{
if (!m_model)
return;
- int count = m_items.count();
+ int count = m_items.size();
if (count == 0)
return;
int countWidth = floor(log10(double(count))) + 1;
@@ -965,7 +1002,7 @@ bool QQmlTreeModelToTableModel::testConsistency(bool dumpOnFail) const
QModelIndex parent = m_rootIndex;
QStack<QModelIndex> ancestors;
QModelIndex idx = m_model->index(0, 0, parent);
- for (int i = 0; i < m_items.count(); i++) {
+ for (int i = 0; i < m_items.size(); i++) {
bool isConsistent = true;
const TreeItem &item = m_items.at(i);
if (item.index != idx) {
@@ -978,9 +1015,9 @@ bool QQmlTreeModelToTableModel::testConsistency(bool dumpOnFail) const
qWarning() << " stored index parent" << item.index.parent() << "model parent" << parent;
isConsistent = false;
}
- if (item.depth != ancestors.count()) {
+ if (item.depth != ancestors.size()) {
qWarning() << "Depth inconsistency" << i << item.index;
- qWarning() << " item depth" << item.depth << "ancestors stack" << ancestors.count();
+ qWarning() << " item depth" << item.depth << "ancestors stack" << ancestors.size();
isConsistent = false;
}
if (item.expanded && !m_expandedItems.contains(item.index)) {
@@ -1045,7 +1082,7 @@ void QQmlTreeModelToTableModel::emitQueuedSignals()
* We don't merge adjacent updates, because they are typically filed with a
* different role (a parent row is next to its children).
*/
- for (const DataChangedParams &dataChange : qAsConst(m_queuedDataChanged)) {
+ for (const DataChangedParams &dataChange : std::as_const(m_queuedDataChanged)) {
int startRow = dataChange.topLeft.row();
int endRow = dataChange.bottomRight.row();
bool merged = false;
diff --git a/src/qmlmodels/qqmltreemodeltotablemodel_p_p.h b/src/qmlmodels/qqmltreemodeltotablemodel_p_p.h
index dd5857e3a6..55ef45912a 100644
--- a/src/qmlmodels/qqmltreemodeltotablemodel_p_p.h
+++ b/src/qmlmodels/qqmltreemodeltotablemodel_p_p.h
@@ -165,6 +165,7 @@ private:
QList<TreeItem> m_itemsToExpand;
mutable int m_lastItemIndex = 0;
bool m_visibleRowsMoved = false;
+ bool m_modelLayoutChanged = false;
int m_signalAggregatorStack = 0;
QVector<DataChangedParams> m_queuedDataChanged;
int m_column = 0;
diff --git a/src/qmlmodels/qquickpackage.cpp b/src/qmlmodels/qquickpackage.cpp
index a7532a49df..70a3a6c19b 100644
--- a/src/qmlmodels/qquickpackage.cpp
+++ b/src/qmlmodels/qquickpackage.cpp
@@ -80,7 +80,7 @@ public:
}
static qsizetype data_count(QQmlListProperty<QObject> *prop) {
QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
- return list->count();
+ return list->size();
}
static void data_replace(QQmlListProperty<QObject> *prop, qsizetype index, QObject *o) {
QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
@@ -135,7 +135,7 @@ QQmlListProperty<QObject> QQuickPackage::data()
bool QQuickPackage::hasPart(const QString &name)
{
Q_D(QQuickPackage);
- for (int ii = 0; ii < d->dataList.count(); ++ii) {
+ for (int ii = 0; ii < d->dataList.size(); ++ii) {
QObject *obj = d->dataList.at(ii);
QQuickPackageAttached *a = QQuickPackageAttached::attached.value(obj);
if (a && a->name() == name)
@@ -150,7 +150,7 @@ QObject *QQuickPackage::part(const QString &name)
if (name.isEmpty() && !d->dataList.isEmpty())
return d->dataList.at(0);
- for (int ii = 0; ii < d->dataList.count(); ++ii) {
+ for (int ii = 0; ii < d->dataList.size(); ++ii) {
QObject *obj = d->dataList.at(ii);
QQuickPackageAttached *a = QQuickPackageAttached::attached.value(obj);
if (a && a->name() == name)
diff --git a/src/qmltest/TestCase.qml b/src/qmltest/TestCase.qml
index b8937fc2e7..a69c2fe6f6 100644
--- a/src/qmltest/TestCase.qml
+++ b/src/qmltest/TestCase.qml
@@ -631,6 +631,9 @@ Item {
throw new Error("QtQuickTest::fail");
}
+ if (parent === undefined)
+ parent = null
+
var object = component.createObject(parent, properties ? properties : ({}));
qtest_temporaryObjects.push(object);
return object;
@@ -1146,23 +1149,36 @@ Item {
\qmlmethod TestCase::failOnWarning(message)
\since 6.3
- Fails the test if a warning \a message appears during the test run.
- Similar to \c{QTest::failOnWarning(message)} in C++.
+ Appends a test failure to the test log for each warning that matches
+ \a message. The test function will continue execution when a failure
+ is added.
\a message can be either a string, or a regular expression providing a
- pattern of messages. In the latter case, the first encountered message
- would fail the test.
+ pattern of messages. In the latter case, for each warning encountered,
+ the first pattern that matches will cause a failure, and the remaining
+ patterns will be ignored.
+
+ All patterns are cleared at the end of each test function.
- For example, the following snippet will fail a test if a warning is
- produced:
+ For example, the following snippet will fail a test if a warning with
+ the text "Something bad happened" is produced:
\qml
failOnWarning("Something bad happened")
\endqml
- And the following snippet will fail a test if any warning matching a
- pattern is encountered:
+ The following snippet will fail a test if any warning matching the
+ given pattern is encountered:
+ \qml
+ failOnWarning(/[0-9]+ bad things happened/)
+ \endqml
+
+ To fail every test that triggers a given warning, pass a suitable regular
+ expression to this function in \l init():
+
\qml
- failOnWarning(new RegExp("[0-9]+ bad things happened"))
+ function init() {
+ failOnWarning(/.?/)
+ }
\endqml
\note Despite being a JavaScript RegExp object, it will not be
@@ -1173,7 +1189,7 @@ Item {
warnings that match a pattern given to both \c ignoreMessage() and \c
failOnWarning() will be ignored.
- \sa warn()
+ \sa QTest::failOnWarning(), warn()
*/
function failOnWarning(msg) {
if (msg === undefined)
diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp
index a048c43e76..9ecaa42f14 100644
--- a/src/qmltest/quicktest.cpp
+++ b/src/qmltest/quicktest.cpp
@@ -161,8 +161,8 @@ bool QQuickTest::qWaitForPolish(const QQuickWindow *window, int timeout)
static inline QString stripQuotes(const QString &s)
{
- if (s.length() >= 2 && s.startsWith(QLatin1Char('"')) && s.endsWith(QLatin1Char('"')))
- return s.mid(1, s.length() - 2);
+ if (s.size() >= 2 && s.startsWith(QLatin1Char('"')) && s.endsWith(QLatin1Char('"')))
+ return s.mid(1, s.size() - 2);
else
return s;
}
@@ -541,15 +541,15 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch
// Scan through all of the "tst_*.qml" files and run each of them
// in turn with a separate QQuickView (for test isolation).
- for (const QString &file : qAsConst(files)) {
+ for (const QString &file : std::as_const(files)) {
const QFileInfo fi(file);
if (!fi.exists())
continue;
QQmlEngine engine;
- for (const QString &path : qAsConst(imports))
+ for (const QString &path : std::as_const(imports))
engine.addImportPath(path);
- for (const QString &path : qAsConst(pluginPaths))
+ for (const QString &path : std::as_const(pluginPaths))
engine.addPluginPath(path);
if (!fileSelectors.isEmpty()) {
@@ -654,9 +654,9 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch
// Check that all test functions passed on the command line were found
if (!commandLineTestFunctions.isEmpty()) {
qWarning() << "Could not find the following test functions:";
- for (const QString &functionName : qAsConst(commandLineTestFunctions))
+ for (const QString &functionName : std::as_const(commandLineTestFunctions))
qWarning(" %s()", qUtf8Printable(functionName));
- return commandLineTestFunctions.count();
+ return commandLineTestFunctions.size();
}
// Return the number of failures as the exit code.
diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp
index 28d6c073fd..b1b8e60eab 100644
--- a/src/qmltest/quicktestevent.cpp
+++ b/src/qmltest/quicktestevent.cpp
@@ -57,7 +57,7 @@ bool QuickTestEvent::keyClick(int key, int modifiers, int delay)
bool QuickTestEvent::keyPressChar(const QString &character, int modifiers, int delay)
{
- QTEST_ASSERT(character.length() == 1);
+ QTEST_ASSERT(character.size() == 1);
QWindow *window = activeWindow();
if (!window)
return false;
@@ -67,7 +67,7 @@ bool QuickTestEvent::keyPressChar(const QString &character, int modifiers, int d
bool QuickTestEvent::keyReleaseChar(const QString &character, int modifiers, int delay)
{
- QTEST_ASSERT(character.length() == 1);
+ QTEST_ASSERT(character.size() == 1);
QWindow *window = activeWindow();
if (!window)
return false;
@@ -77,7 +77,7 @@ bool QuickTestEvent::keyReleaseChar(const QString &character, int modifiers, int
bool QuickTestEvent::keyClickChar(const QString &character, int modifiers, int delay)
{
- QTEST_ASSERT(character.length() == 1);
+ QTEST_ASSERT(character.size() == 1);
QWindow *window = activeWindow();
if (!window)
return false;
diff --git a/src/qmltyperegistrar/metatypesjsonprocessor.cpp b/src/qmltyperegistrar/metatypesjsonprocessor.cpp
index 49088400b4..d167b75afd 100644
--- a/src/qmltyperegistrar/metatypesjsonprocessor.cpp
+++ b/src/qmltyperegistrar/metatypesjsonprocessor.cpp
@@ -326,6 +326,7 @@ void MetaTypesJsonProcessor::processTypes(const QJsonObject &types)
if (!include.endsWith(QLatin1String(".h"))
&& !include.endsWith(QLatin1String(".hpp"))
&& !include.endsWith(QLatin1String(".hxx"))
+ && !include.endsWith(QLatin1String(".hh"))
&& !include.endsWith(u".py")
&& include.contains(QLatin1Char('.'))) {
fprintf(stderr,
diff --git a/src/qmlworkerscript/qv4serialize.cpp b/src/qmlworkerscript/qv4serialize.cpp
index 1906d164f6..d445299828 100644
--- a/src/qmlworkerscript/qv4serialize.cpp
+++ b/src/qmlworkerscript/qv4serialize.cpp
@@ -106,7 +106,7 @@ static inline void *popPtr(const char *&data)
#define ALIGN(size) (((size) + 3) & ~3)
static inline void serializeString(QByteArray &data, const QString &str, Type type)
{
- int length = str.length();
+ int length = str.size();
if (length > 0xFFFFFF) {
push(data, valueheader(WorkerUndefined));
return;
@@ -174,7 +174,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
} else if (const RegExpObject *re = v.as<RegExpObject>()) {
quint32 flags = re->flags();
QString pattern = re->source();
- int length = pattern.length() + 1;
+ int length = pattern.size() + 1;
if (length > 0xFFFFFF) {
push(data, valueheader(WorkerUndefined));
return;
diff --git a/src/qmlxmllistmodel/qqmlxmllistmodel.cpp b/src/qmlxmllistmodel/qqmlxmllistmodel.cpp
index 72c3b21e87..2f40bd525b 100644
--- a/src/qmlxmllistmodel/qqmlxmllistmodel.cpp
+++ b/src/qmlxmllistmodel/qqmlxmllistmodel.cpp
@@ -363,7 +363,7 @@ QVariant QQmlXmlListModel::data(const QModelIndex &index, int role) const
QHash<int, QByteArray> QQmlXmlListModel::roleNames() const
{
QHash<int, QByteArray> roleNames;
- for (int i = 0; i < m_roles.count(); ++i)
+ for (int i = 0; i < m_roles.size(); ++i)
roleNames.insert(m_roles.at(i), m_roleNames.at(i).toUtf8());
return roleNames;
}
@@ -437,7 +437,7 @@ QQmlListProperty<QQmlXmlListModelRole> QQmlXmlListModel::roleObjects()
void QQmlXmlListModel::appendRole(QQmlXmlListModelRole *role)
{
if (role) {
- int i = m_roleObjects.count();
+ int i = m_roleObjects.size();
m_roleObjects.append(role);
if (m_roleNames.contains(role->name())) {
qmlWarning(role)
@@ -519,7 +519,7 @@ QQmlXmlListModelQueryJob QQmlXmlListModel::createJob(const QByteArray &data)
job.data = data;
job.query = m_query;
- for (int i = 0; i < m_roleObjects.count(); i++) {
+ for (int i = 0; i < m_roleObjects.size(); i++) {
if (!m_roleObjects.at(i)->isValid()) {
job.roleNames << QString();
job.elementNames << QString();
@@ -744,7 +744,7 @@ void QQmlXmlListModel::dataCleared()
void QQmlXmlListModel::queryError(void *object, const QString &error)
{
- for (int i = 0; i < m_roleObjects.count(); i++) {
+ for (int i = 0; i < m_roleObjects.size(); i++) {
if (m_roleObjects.at(i) == static_cast<QQmlXmlListModelRole *>(object)) {
qmlWarning(m_roleObjects.at(i))
<< QQmlXmlListModel::tr("Query error: \"%1\"").arg(error);
@@ -760,7 +760,7 @@ void QQmlXmlListModel::queryCompleted(const QQmlXmlListModelQueryResult &result)
return;
int origCount = m_size;
- bool sizeChanged = result.data.count() != m_size;
+ bool sizeChanged = result.data.size() != m_size;
if (m_source.isEmpty())
m_status = Null;
@@ -773,7 +773,7 @@ void QQmlXmlListModel::queryCompleted(const QQmlXmlListModelQueryResult &result)
beginRemoveRows(QModelIndex(), 0, origCount - 1);
endRemoveRows();
}
- m_size = result.data.count();
+ m_size = result.data.size();
m_data = result.data;
if (m_size > 0) {
@@ -841,10 +841,10 @@ void QQmlXmlListModelQueryRunnable::doQueryJob(QQmlXmlListModelQueryResult *curr
while (!reader.atEnd() && !m_promise.isCanceled()) {
int i = 0;
- while (i < items.count()) {
+ while (i < items.size()) {
if (reader.readNextStartElement()) {
if (reader.name() == items.at(i)) {
- if (i != items.count() - 1) {
+ if (i != items.size() - 1) {
i++;
continue;
} else {
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index e891b5c132..c47a94e3aa 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -46,7 +46,7 @@ public:
QString anchor() const override
{
const QVector<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks();
- if (linkIndex < links.count())
+ if (linkIndex < links.size())
return links.at(linkIndex).m_anchor;
return QString();
}
@@ -54,7 +54,7 @@ public:
QString anchorTarget() const override
{
const QVector<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks();
- if (linkIndex < links.count())
+ if (linkIndex < links.size())
return links.at(linkIndex).m_anchorTarget;
return QString();
}
@@ -62,7 +62,7 @@ public:
int startIndex() const override
{
const QVector<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks();
- if (linkIndex < links.count())
+ if (linkIndex < links.size())
return links.at(linkIndex).m_startIndex;
return -1;
}
@@ -70,7 +70,7 @@ public:
int endIndex() const override
{
const QVector<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks();
- if (linkIndex < links.count())
+ if (linkIndex < links.size())
return links.at(linkIndex).m_endIndex;
return -1;
}
@@ -113,7 +113,7 @@ QWindow *QAccessibleHyperlink::window() const
QRect QAccessibleHyperlink::rect() const
{
const QVector<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks();
- if (linkIndex < links.count()) {
+ if (linkIndex < links.size()) {
const QPoint tl = itemScreenRect(textItem()).topLeft();
return links.at(linkIndex).rect.translated(tl);
}
@@ -232,9 +232,9 @@ int QAccessibleQuickItem::childCount() const
// see comment in QAccessibleQuickItem::child() as to why we do this
int cc = 0;
if (QQuickText *textItem = qobject_cast<QQuickText*>(item())) {
- cc = QQuickTextPrivate::get(textItem)->getLinks().count();
+ cc = QQuickTextPrivate::get(textItem)->getLinks().size();
}
- cc += childItems().count();
+ cc += childItems().size();
return cc;
}
@@ -271,7 +271,7 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
// special case for text interfaces
if (QQuickText *textItem = qobject_cast<QQuickText*>(item())) {
- const auto hyperLinkChildCount = QQuickTextPrivate::get(textItem)->getLinks().count();
+ const auto hyperLinkChildCount = QQuickTextPrivate::get(textItem)->getLinks().size();
for (auto i = 0; i < hyperLinkChildCount; i++) {
QAccessibleInterface *iface = child(i);
if (iface->rect().contains(x,y)) {
@@ -282,7 +282,7 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
// general item hit test
const QList<QQuickItem*> kids = accessibleUnignoredChildren(item(), true);
- for (int i = kids.count() - 1; i >= 0; --i) {
+ for (int i = kids.size() - 1; i >= 0; --i) {
QAccessibleInterface *childIface = QAccessible::queryAccessibleInterface(kids.at(i));
if (QAccessibleInterface *childChild = childIface->childAt(x, y))
return childChild;
@@ -344,7 +344,7 @@ QAccessibleInterface *QAccessibleQuickItem::child(int index) const
if (QQuickText *textItem = qobject_cast<QQuickText*>(item())) {
- const int hyperLinkChildCount = QQuickTextPrivate::get(textItem)->getLinks().count();
+ const int hyperLinkChildCount = QQuickTextPrivate::get(textItem)->getLinks().size();
if (index < hyperLinkChildCount) {
auto it = m_childToId.constFind(index);
if (it != m_childToId.constEnd())
@@ -359,7 +359,7 @@ QAccessibleInterface *QAccessibleQuickItem::child(int index) const
}
QList<QQuickItem *> children = childItems();
- if (index < children.count()) {
+ if (index < children.size()) {
QQuickItem *child = children.at(index);
return QAccessible::queryAccessibleInterface(child);
}
@@ -370,7 +370,7 @@ int QAccessibleQuickItem::indexOfChild(const QAccessibleInterface *iface) const
{
int hyperLinkChildCount = 0;
if (QQuickText *textItem = qobject_cast<QQuickText*>(item())) {
- hyperLinkChildCount = QQuickTextPrivate::get(textItem)->getLinks().count();
+ hyperLinkChildCount = QQuickTextPrivate::get(textItem)->getLinks().size();
if (QAccessibleHyperlinkInterface *hyperLinkIface = const_cast<QAccessibleInterface *>(iface)->hyperlinkInterface()) {
// ### assumes that there is only one subclass implementing QAccessibleHyperlinkInterface
// Alternatively, we could simply iterate with child() and do a linear search for it
diff --git a/src/quick/accessible/qaccessiblequickview.cpp b/src/quick/accessible/qaccessiblequickview.cpp
index 3f327619c8..5cd93b9613 100644
--- a/src/quick/accessible/qaccessiblequickview.cpp
+++ b/src/quick/accessible/qaccessiblequickview.cpp
@@ -28,7 +28,7 @@ QList<QQuickItem *> QAccessibleQuickWindow::rootItems() const
int QAccessibleQuickWindow::childCount() const
{
- return rootItems().count();
+ return rootItems().size();
}
QAccessibleInterface *QAccessibleQuickWindow::parent() const
@@ -40,7 +40,7 @@ QAccessibleInterface *QAccessibleQuickWindow::parent() const
QAccessibleInterface *QAccessibleQuickWindow::child(int index) const
{
const QList<QQuickItem*> &kids = rootItems();
- if (index >= 0 && index < kids.count())
+ if (index >= 0 && index < kids.size())
return QAccessible::queryAccessibleInterface(kids.at(index));
return nullptr;
}
@@ -109,7 +109,7 @@ int QAccessibleQuickWindow::indexOfChild(const QAccessibleInterface *iface) cons
int i = -1;
if (iface) {
const QList<QQuickItem *> &roots = rootItems();
- i = roots.count() - 1;
+ i = roots.size() - 1;
while (i >= 0) {
if (iface->object() == roots.at(i))
break;
diff --git a/src/quick/designer/qqmldesignermetaobject.cpp b/src/quick/designer/qqmldesignermetaobject.cpp
index 4bd221481b..e368f5f443 100644
--- a/src/quick/designer/qqmldesignermetaobject.cpp
+++ b/src/quick/designer/qqmldesignermetaobject.cpp
@@ -17,7 +17,7 @@ static void (*notifyPropertyChangeCallBack)(QObject*, const QQuickDesignerSuppor
struct MetaPropertyData {
inline QPair<QVariant, bool> &getDataRef(int idx) {
- while (m_data.count() <= idx)
+ while (m_data.size() <= idx)
m_data << QPair<QVariant, bool>(QVariant(), false);
return m_data[idx];
}
@@ -32,12 +32,12 @@ struct MetaPropertyData {
}
inline bool hasData(int idx) const {
- if (idx >= m_data.count())
+ if (idx >= m_data.size())
return false;
return m_data[idx].second;
}
- inline int count() { return m_data.count(); }
+ inline int count() { return m_data.size(); }
QVector<QPair<QVariant, bool> > m_data;
};
diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp
index 2ee8984ea1..5887ff951f 100644
--- a/src/quick/designer/qquickdesignersupportitems.cpp
+++ b/src/quick/designer/qquickdesignersupportitems.cpp
@@ -118,7 +118,7 @@ void QQuickDesignerSupportItems::tweakObjects(QObject *object)
{
QObjectList objectList;
allSubObjects(object, objectList);
- for (QObject* childObject : qAsConst(objectList)) {
+ for (QObject* childObject : std::as_const(objectList)) {
stopAnimation(childObject);
makeLoaderSynchronous(childObject);
if (fixResourcePathsForObjectCallBack)
diff --git a/src/quick/doc/images/pointerHandlers/dragReleaseMenu.webp b/src/quick/doc/images/pointerHandlers/dragReleaseMenu.webp
new file mode 100644
index 0000000000..16aaca4d86
--- /dev/null
+++ b/src/quick/doc/images/pointerHandlers/dragReleaseMenu.webp
Binary files differ
diff --git a/src/quick/doc/images/pointerHandlers/tapHandlerButtonReleaseWithinBounds.webp b/src/quick/doc/images/pointerHandlers/tapHandlerButtonReleaseWithinBounds.webp
new file mode 100644
index 0000000000..3edab7d7a1
--- /dev/null
+++ b/src/quick/doc/images/pointerHandlers/tapHandlerButtonReleaseWithinBounds.webp
Binary files differ
diff --git a/src/quick/doc/images/pointerHandlers/tapHandlerButtonWithinBounds.webp b/src/quick/doc/images/pointerHandlers/tapHandlerButtonWithinBounds.webp
new file mode 100644
index 0000000000..05cb2f2276
--- /dev/null
+++ b/src/quick/doc/images/pointerHandlers/tapHandlerButtonWithinBounds.webp
Binary files differ
diff --git a/src/quick/doc/images/pointerHandlers/tapHandlerOverlappingButtons.webp b/src/quick/doc/images/pointerHandlers/tapHandlerOverlappingButtons.webp
new file mode 100644
index 0000000000..0455097159
--- /dev/null
+++ b/src/quick/doc/images/pointerHandlers/tapHandlerOverlappingButtons.webp
Binary files differ
diff --git a/src/quick/doc/snippets/pointerHandlers/dragReleaseMenu.qml b/src/quick/doc/snippets/pointerHandlers/dragReleaseMenu.qml
new file mode 100644
index 0000000000..e6d2266408
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/dragReleaseMenu.qml
@@ -0,0 +1,72 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//![0]
+import QtQuick
+
+Rectangle {
+ id: rect
+ width: 140; height: 100
+
+ //![1]
+ TapHandler {
+ id: menuPopupHandler
+ gesturePolicy: TapHandler.DragWithinBounds
+ onPressedChanged:
+ if (pressed) {
+ menu.x = point.position.x - menu.width / 2
+ menu.y = point.position.y - menu.height / 2
+ } else {
+ feedback.text = menu.highlightedMenuItem
+ selectFlash.start()
+ }
+ onCanceled: feedback.text = "canceled"
+ }
+ //![1]
+
+ Column {
+ id: menu
+ visible: menuPopupHandler.pressed
+ opacity: Math.min(1, menuPopupHandler.timeHeld)
+ property string highlightedMenuItem: ""
+ Repeater {
+ model: [ "top", "middle", "bottom" ]
+ delegate: Rectangle {
+ property bool highlighted: menuPopupHandler.pressed &&
+ contains(mapFromItem(rect, menuPopupHandler.point.position))
+ onHighlightedChanged: {
+ if (highlighted)
+ menu.highlightedMenuItem = menuItemText.text
+ else if (menu.highlightedMenuItem === menuItemText.text)
+ menu.highlightedMenuItem = ""
+ }
+ width: 100
+ height: 20
+ color: highlighted ? "lightsteelblue" : "aliceblue"
+ Text {
+ id: menuItemText
+ anchors.centerIn: parent
+ text: modelData
+ }
+ }
+ }
+ }
+
+ Text {
+ id: feedback
+ y: 6; anchors.horizontalCenter: parent.horizontalCenter
+ textFormat: Text.MarkdownText
+ text: "hold for context menu"
+
+ SequentialAnimation on font.weight {
+ id: selectFlash
+ running: false
+ loops: 3
+ PropertyAction { value: Font.Black }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: Font.Normal }
+ PauseAnimation { duration: 100 }
+ }
+ }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandler.qml b/src/quick/doc/snippets/pointerHandlers/pointHandler.qml
index f5fe29566e..d363150ab5 100644
--- a/src/quick/doc/snippets/pointerHandlers/pointHandler.qml
+++ b/src/quick/doc/snippets/pointerHandlers/pointHandler.qml
@@ -1,8 +1,7 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
//![0]
-import QtQuick 2.12
-import QtQuick.Window 2.2
+import QtQuick
Window {
width: 480
@@ -14,6 +13,7 @@ Window {
z: 10000
anchors.fill: parent
+ //![1]
PointHandler {
id: handler
acceptedDevices: PointerDevice.TouchScreen | PointerDevice.TouchPad
@@ -26,6 +26,7 @@ Window {
width: 20; height: width; radius: width / 2
}
}
+ //![1]
}
}
//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedButtons.qml b/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedButtons.qml
new file mode 100644
index 0000000000..3eab8b319b
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedButtons.qml
@@ -0,0 +1,21 @@
+// Copyright (C) 2023 Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+//![0]
+import QtQuick
+
+Item {
+ width: 480; height: 320
+
+ Rectangle {
+ color: handler.active ? "tomato" : "wheat"
+ x: handler.point.position.x - width / 2
+ y: handler.point.position.y - height / 2
+ width: 20; height: width; radius: width / 2
+ }
+
+ PointHandler {
+ id: handler
+ acceptedButtons: Qt.MiddleButton | Qt.RightButton
+ }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedModifiers.qml b/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedModifiers.qml
new file mode 100644
index 0000000000..9e3cb6f465
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedModifiers.qml
@@ -0,0 +1,36 @@
+// Copyright (C) 2023 Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+//![0]
+import QtQuick
+
+Item {
+ id: feedbackPane
+ width: 480; height: 320
+
+ PointHandler {
+ id: control
+ acceptedModifiers: Qt.ControlModifier
+ cursorShape: Qt.PointingHandCursor
+ target: Rectangle {
+ parent: feedbackPane
+ color: control.active ? "indianred" : "khaki"
+ x: control.point.position.x - width / 2
+ y: control.point.position.y - height / 2
+ width: 20; height: width; radius: width / 2
+ }
+ }
+
+ PointHandler {
+ id: shift
+ acceptedModifiers: Qt.ShiftModifier | Qt.MetaModifier
+ cursorShape: Qt.CrossCursor
+ target: Rectangle {
+ parent: feedbackPane
+ color: shift.active ? "darkslateblue" : "lightseagreen"
+ x: shift.point.position.x - width / 2
+ y: shift.point.position.y - height / 2
+ width: 30; height: width; radius: width / 2
+ }
+ }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandlerCanvasDrawing.qml b/src/quick/doc/snippets/pointerHandlers/pointHandlerCanvasDrawing.qml
new file mode 100644
index 0000000000..d04bd4f149
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/pointHandlerCanvasDrawing.qml
@@ -0,0 +1,54 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//![0]
+import QtQuick
+
+Canvas {
+ id: canvas
+ width: 800
+ height: 600
+ antialiasing: true
+ renderTarget: Canvas.FramebufferObject
+ property var points: []
+ onPaint: {
+ if (points.length < 2)
+ return
+ var ctx = canvas.getContext('2d');
+ ctx.save()
+ ctx.strokeStyle = stylusHandler.active ? "blue" : "white"
+ ctx.lineCap = "round"
+ ctx.beginPath()
+ ctx.moveTo(points[0].x, points[0].y)
+ for (var i = 1; i < points.length; i++)
+ ctx.lineTo(points[i].x, points[i].y)
+ ctx.lineWidth = 3
+ ctx.stroke()
+ points = points.slice(points.length - 2, 1)
+ ctx.restore()
+ }
+
+ PointHandler {
+ id: stylusHandler
+ acceptedPointerTypes: PointerDevice.Pen
+ onPointChanged: {
+ canvas.points.push(point.position)
+ canvas.requestPaint()
+ }
+ }
+
+ PointHandler {
+ id: eraserHandler
+ acceptedPointerTypes: PointerDevice.Eraser
+ onPointChanged: {
+ canvas.points.push(point.position)
+ canvas.requestPaint()
+ }
+ }
+
+ Rectangle {
+ width: 10; height: 10
+ color: stylusHandler.active ? "green" : eraserHandler.active ? "red" : "beige"
+ }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandlerMargin.qml b/src/quick/doc/snippets/pointerHandlers/pointHandlerMargin.qml
new file mode 100644
index 0000000000..1b66531dbf
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/pointHandlerMargin.qml
@@ -0,0 +1,36 @@
+// Copyright (C) 2023 Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+//![0]
+import QtQuick
+
+Item {
+ width: 480; height: 320
+
+ Rectangle {
+ anchors.fill: handlingContainer
+ anchors.margins: -handler.margin
+ color: "beige"
+ }
+
+ Rectangle {
+ id: handlingContainer
+ width: 200; height: 200
+ anchors.centerIn: parent
+ border.color: "green"
+ color: handler.active ? "lightsteelblue" : "khaki"
+
+ Text {
+ text: "X"
+ x: handler.point.position.x - width / 2
+ y: handler.point.position.y - height / 2
+ visible: handler.active
+ }
+
+ PointHandler {
+ id: handler
+ margin: 30
+ }
+ }
+
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonReleaseWithinBounds.qml b/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonReleaseWithinBounds.qml
new file mode 100644
index 0000000000..3e8634a605
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonReleaseWithinBounds.qml
@@ -0,0 +1,51 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+//![0]
+import QtQuick
+
+Item {
+ width: 120; height: 80
+
+ component Button : Rectangle {
+ id: button
+ signal clicked
+ property alias text: buttonLabel.text
+
+ width: 80
+ height: 40
+ radius: 3
+ property color dark: Qt.darker(palette.button, 1.3)
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: tapHandler.pressed ? dark : palette.button }
+ GradientStop { position: 1.0; color: dark }
+ }
+
+ SequentialAnimation on border.width {
+ id: tapFlash
+ running: false
+ loops: 3
+ PropertyAction { value: 2 }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: 0 }
+ PauseAnimation { duration: 100 }
+ }
+
+ //![1]
+ TapHandler {
+ id: tapHandler
+ gesturePolicy: TapHandler.ReleaseWithinBounds
+ onTapped: tapFlash.start()
+ }
+ //![1]
+
+ Text {
+ id: buttonLabel
+ text: "Click Me"
+ color: palette.buttonText
+ anchors.centerIn: parent
+ }
+ }
+
+ Button { x: 10; y: 10 }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonWithinBounds.qml b/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonWithinBounds.qml
new file mode 100644
index 0000000000..4563b44014
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonWithinBounds.qml
@@ -0,0 +1,51 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+//![0]
+import QtQuick
+
+Item {
+ width: 120; height: 80
+
+ component Button : Rectangle {
+ id: button
+ signal clicked
+ property alias text: buttonLabel.text
+
+ width: 80
+ height: 40
+ radius: 3
+ property color dark: Qt.darker(palette.button, 1.3)
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: tapHandler.pressed ? dark : palette.button }
+ GradientStop { position: 1.0; color: dark }
+ }
+
+ SequentialAnimation on border.width {
+ id: tapFlash
+ running: false
+ loops: 3
+ PropertyAction { value: 2 }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: 0 }
+ PauseAnimation { duration: 100 }
+ }
+
+ //![1]
+ TapHandler {
+ id: tapHandler
+ gesturePolicy: TapHandler.WithinBounds
+ onTapped: tapFlash.start()
+ }
+ //![1]
+
+ Text {
+ id: buttonLabel
+ text: "Click Me"
+ color: palette.buttonText
+ anchors.centerIn: parent
+ }
+ }
+
+ Button { x: 10; y: 10 }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/tapHandlerOverlappingButtons.qml b/src/quick/doc/snippets/pointerHandlers/tapHandlerOverlappingButtons.qml
new file mode 100644
index 0000000000..917c863e53
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/tapHandlerOverlappingButtons.qml
@@ -0,0 +1,51 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+//![0]
+import QtQuick
+
+Item {
+ width: 120; height: 80
+
+ component Button : Rectangle {
+ signal clicked
+ property alias text: buttonLabel.text
+
+ width: 80
+ height: 40
+ radius: 3
+ property color dark: Qt.darker(palette.button, 1.3)
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: tapHandler.pressed ? dark : palette.button }
+ GradientStop { position: 1.0; color: dark }
+ }
+
+ SequentialAnimation on border.width {
+ id: tapFlash
+ running: false
+ loops: 3
+ PropertyAction { value: 2 }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: 0 }
+ PauseAnimation { duration: 100 }
+ }
+
+ //![1]
+ TapHandler {
+ id: tapHandler
+ gesturePolicy: TapHandler.DragThreshold // the default
+ onTapped: tapFlash.start()
+ }
+ //![1]
+
+ Text {
+ id: buttonLabel
+ text: "Click Me"
+ color: palette.buttonText
+ anchors.centerIn: parent
+ }
+ }
+
+ Button { x: 10; y: 10 }
+ Button { x: 30; y: 30 }
+}
+//![0]
diff --git a/src/quick/doc/snippets/qml/item/itemGrab.qml b/src/quick/doc/snippets/qml/item/itemGrab.qml
new file mode 100644
index 0000000000..ef4430175a
--- /dev/null
+++ b/src/quick/doc/snippets/qml/item/itemGrab.qml
@@ -0,0 +1,39 @@
+// Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick 2.4
+
+Item {
+ width: 320
+ height: 480
+
+//! [grab-to-file]
+Rectangle {
+ id: sourceRectangle
+ width: 100
+ height: 100
+ gradient: Gradient {
+ GradientStop { position: 0; color: "steelblue" }
+ GradientStop { position: 1; color: "black" }
+ }
+
+ Component.onCompleted: {
+ sourceRectangle.grabToImage(function(result) {
+ result.saveToFile("something.png")
+ })
+ }
+}
+//! [grab-to-file]
+
+//! [grab-to-image]
+Image {
+ id: image
+}
+
+Component.onCompleted: {
+ sourceRectangle.grabToImage(function(result) {
+ image.source = result.url
+ }, Qt.size(50, 50))
+}
+//! [grab-to-image]
+}
diff --git a/src/quick/doc/snippets/qml/itemGrab.qml b/src/quick/doc/snippets/qml/itemGrab.qml
deleted file mode 100644
index dd02661894..0000000000
--- a/src/quick/doc/snippets/qml/itemGrab.qml
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import QtQuick 2.4
-
-Item {
- width: 320
- height: 480
-
-//! [grab-source]
-Rectangle {
- id: source
- width: 100
- height: 100
- gradient: Gradient {
- GradientStop { position: 0; color: "steelblue" }
- GradientStop { position: 1; color: "black" }
- }
-}
-//! [grab-source]
-
-//! [grab-image-target]
-Image {
- id: image
-}
-//! [grab-image-target]
- Timer {
- repeat: false
- running: true
- interval: 1000
- onTriggered: {
-//! [grab-to-file]
-
- // ...
- source.grabToImage(function(result) {
- result.saveToFile("something.png");
- });
-//! [grab-to-file]
-
-//! [grab-to-cache]
-
- // ...
- source.grabToImage(function(result) {
- image.source = result.url;
- },
- Qt.size(50, 50));
-//! [grab-to-cache]
- }
- }
-}
diff --git a/src/quick/doc/src/concepts/inputhandlers/qtquickhandlers-index.qdoc b/src/quick/doc/src/concepts/inputhandlers/qtquickhandlers-index.qdoc
index 182773b0f5..1157364df8 100644
--- a/src/quick/doc/src/concepts/inputhandlers/qtquickhandlers-index.qdoc
+++ b/src/quick/doc/src/concepts/inputhandlers/qtquickhandlers-index.qdoc
@@ -70,7 +70,8 @@
PointHandler) can work only with passive grabs; others require exclusive
grabs; and others can "lurk" with passive grabs until they detect that a
gesture is being performed, and then make the transition from passive to
- exclusive grab.
+ exclusive grab. TapHandler's grabbing behavior is
+ \l {TapHandler::gesturePolicy}{configurable}.
When a grab transition is requested, \l PointerHandler::grabPermissions,
\l QQuickItem::keepMouseGrab() and \l QQuickItem::keepTouchGrab() control
diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
index 505e7b570a..8163cf0dd6 100644
--- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc
@@ -1171,8 +1171,10 @@ with multiple windows.
\row
\li \c QSG_RHI_DEBUG_LAYER
\li \c 1
- \li Where applicable (Vulkan, Direct3D), enables the graphics API implementation's debug
- and/or validation layers, if available.
+ \li Where applicable (Vulkan, Direct3D), enables the graphics API implementation's
+ debug or validation layers, if available, either on the graphics device or the instance
+ object. For Metal on \macos, set the environment variable
+ \c{METAL_DEVICE_WRAPPER_TYPE=1} instead.
\row
\li \c QSG_RHI_PREFER_SOFTWARE_RENDERER
diff --git a/src/quick/doc/src/cppextensionpoints.qdoc b/src/quick/doc/src/cppextensionpoints.qdoc
index 148df0dce8..9a62f8f715 100644
--- a/src/quick/doc/src/cppextensionpoints.qdoc
+++ b/src/quick/doc/src/cppextensionpoints.qdoc
@@ -30,17 +30,16 @@ for more details.
\target scene-graph-related-classes
\section1 Scene Graph-Related Classes
-Qt Quick 2 makes use of a dedicated scene graph based on OpenGL ES 2.0 or OpenGL 2.0
-for its rendering. Using a scene graph for graphics rather than the traditional imperative
-painting systems (QPainter and similar), means the scene to be rendered can be retained
-between frames and the complete set of primitives to render is known before rendering
-starts. This opens up for a number of optimizations, such as batching the OpenGL draw calls
-to minimize state changes or discarding obscured primitives.
-
+Qt Quick 2 makes use of a dedicated scene graph based on graphics APIs such as
+OpenGL ES, OpenGL, Vulkan, Metal, or Direct 3D for its rendering. Using a scene
+graph for graphics rather than the traditional imperative painting systems
+(QPainter and similar), means the scene to be rendered can be retained between
+frames and the complete set of primitives to render is known before rendering
+starts. This opens up for a number of optimizations, such as batching the
+OpenGL draw calls to minimize state changes or discarding obscured primitives.
The \l {Qt Quick C++ Classes}{Qt Quick C++ API} provides various classes to
-enable custom nodes to be created in C++.
-
-See the \l {Qt Quick Scene Graph} documentation for details.
+enable custom nodes to be created in C++. See the \l {Qt Quick Scene Graph}
+documentation for details.
\target pixmap-and-threaded-image-support
\section1 Pixmap and Threaded Image Support
diff --git a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
index e3c64a85a1..bce8a2e11c 100644
--- a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
+++ b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
@@ -28,11 +28,16 @@ options that align with the latest UI design trends. If these UI controls do not
satisfy your application's needs, only then it is recommended to create a
custom control.
+You can use the controls when you design UIs in Qt Design Studio. In addition,
+it provides timeline-based animations, visual effects, layouts, and a
+live-preview for prototyping applications.
\section2 Related Information
\list
\li \l{Qt Quick Controls}
+\li \l{Customizing Qt Quick Controls}
\li \l{Qt Quick}
+\li \l{Qt Design Studio Manual}
\endlist
\omit
@@ -93,7 +98,7 @@ All QML files listed under \c {QML_FILES} will automatically get compiled \l {Ah
\li \l{The Qt Resource System}
\endlist
-\section1 Separate UI from Logic
+\section1 Separate UI from Business Logic
One of the key goals that most application developers want to achieve is to
create a maintainable application. One of the ways to achieve this goal is
@@ -109,8 +114,8 @@ reasons why an application's UI should be written in QML:
\li JavaScript can easily be used in QML to respond to events.
\endlist
-Being a strongly typed language, C++ is best suited for an application's logic.
-Typically, such code performs tasks such as complex calculations
+Being a strongly typed language, C++ is best suited for an application's
+business logic. Typically, such code performs tasks such as complex calculations
or data processing, which are faster in C++ than QML.
Qt offers various approaches to integrate QML and C++ code in an application.
@@ -154,6 +159,22 @@ see \l {Choosing the Correct Integration Method Between C++ and QML}.
\li \l{Qt Quick Controls - Chat Tutorial}{Chat application tutorial}
\endlist
+\section1 Using Qt Design Studio
+
+Qt Design Studio uses UI files that have the filename extension \e {.ui.qml}
+to separate the visual parts of the UI from the UI logic you implement in
+\e {.qml} files. You should edit UI files only in the \uicontrol {2D} view in
+Qt Design Studio. If you use some other tool to add code that Qt Design Studio
+does not support, it displays error messages. Fix the errors to enable visual
+editing of the UI files again. Typically, you should move the unsupported code
+to a \e {.qml} file.
+
+\section2 Related Information
+
+\list
+ \li \l{Qt Design Studio: UI Files}
+\endlist
+
\section1 Using Qt Quick Layouts
Qt offers Qt Quick Layouts to arrange Qt Quick items visually in a layout.
diff --git a/src/quick/doc/src/guidelines/qtquick-tool-qmllint.qdoc b/src/quick/doc/src/guidelines/qtquick-tool-qmllint.qdoc
index 6ca5f4f47b..0a9d6dbc58 100644
--- a/src/quick/doc/src/guidelines/qtquick-tool-qmllint.qdoc
+++ b/src/quick/doc/src/guidelines/qtquick-tool-qmllint.qdoc
@@ -129,9 +129,9 @@ that take precedence over the warning levels in settings.
\section2 Scripting
-qmllint can output JSON via the \c{--json} option which will return valid JSON
+qmllint can write or output JSON via the \c{--json <file>} option which will return valid JSON
with warning messages, file and line location of warnings, and their severity
-level.
+level. Use the special filename '-' to write to stdout instead of a file.
This can be used to more easily integrate qmllint in your pre-commit hooks or
CI testing.
diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc
index 2ad40fc315..c856a42b8a 100644
--- a/src/quick/doc/src/qmltypereference.qdoc
+++ b/src/quick/doc/src/qmltypereference.qdoc
@@ -56,10 +56,10 @@ available when you import \c QtQuick.
*/
/*!
+ \keyword colorvaluetypedocs
\qmlvaluetype color
\ingroup qtquickvaluetypes
\brief an ARGB color value.
- \target colorvaluetypedocs
The \c color type refers to an ARGB color value. It can be specified in a number of ways:
@@ -835,7 +835,7 @@ console.log(c + " " + d); // false true
\qmlvaluetype matrix4x4
\ingroup qtquickvaluetypes
- \brief A matrix4x4 type is a 4-row and 4-column matrix
+ \brief A matrix4x4 type is a 4-row and 4-column matrix.
A \c matrix4x4 type has sixteen values, each accessible via the properties
\c m11 through \c m44 in QML (in row/column order). Values of this type
diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp
index f90dd305d9..c31eb13d98 100644
--- a/src/quick/handlers/qquickdraghandler.cpp
+++ b/src/quick/handlers/qquickdraghandler.cpp
@@ -186,7 +186,7 @@ void QQuickDragHandler::handlePointerEventImpl(QPointerEvent *event)
QVector<QEventPoint> chosenPoints;
if (event->isBeginEvent())
- m_pressedInsideTarget = target() && currentPoints().count() > 0;
+ m_pressedInsideTarget = target() && currentPoints().size() > 0;
for (const QQuickHandlerPoint &p : currentPoints()) {
if (!allOverThreshold)
diff --git a/src/quick/handlers/qquickhandlerpoint.cpp b/src/quick/handlers/qquickhandlerpoint.cpp
index 2028c5c8ec..75848c2882 100644
--- a/src/quick/handlers/qquickhandlerpoint.cpp
+++ b/src/quick/handlers/qquickhandlerpoint.cpp
@@ -8,7 +8,7 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcTouchTarget)
/*!
- \qmltype HandlerPoint
+ \qmltype handlerPoint
\instantiates QQuickHandlerPoint
\inqmlmodule QtQuick
\brief An event point.
@@ -30,7 +30,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcTouchTarget)
and reused for subsequent event deliveries. Continuous bindings to its
properties are not possible, and an individual handler cannot rely on it
outside the period when that point is part of an active gesture which that
- handler is handling. HandlerPoint is a Q_GADGET that the handler owns.
+ handler is handling. handlerPoint is a Q_GADGET that the handler owns.
This allows you to make lifetime bindings to its properties.
\sa SinglePointHandler::point, MultiPointHandler::centroid
@@ -105,7 +105,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
qWarning("reset: no points");
return;
}
- if (points.count() == 1) {
+ if (points.size() == 1) {
*this = points.first(); // copy all values
return;
}
@@ -144,7 +144,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty int QtQuick::HandlerPoint::id
+ \qmlproperty int QtQuick::handlerPoint::id
\brief The ID number of the point
During a touch gesture, from the time that the first finger is pressed
@@ -162,7 +162,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty pointingDeviceUniqueId QtQuick::HandlerPoint::uniqueId
+ \qmlproperty pointingDeviceUniqueId QtQuick::handlerPoint::uniqueId
\brief The unique ID of the point, if any
This is normally empty, because touchscreens cannot uniquely identify fingers.
@@ -184,7 +184,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty QPointF QtQuick::HandlerPoint::position
+ \qmlproperty QPointF QtQuick::handlerPoint::position
\brief The position within the \c parent Item
This is the position of the event point relative to the bounds of
@@ -193,7 +193,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty QPointF QtQuick::HandlerPoint::scenePosition
+ \qmlproperty QPointF QtQuick::handlerPoint::scenePosition
\brief The position within the scene
This is the position of the event point relative to the bounds of the Qt
@@ -202,7 +202,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty QPointF QtQuick::HandlerPoint::pressPosition
+ \qmlproperty QPointF QtQuick::handlerPoint::pressPosition
\brief The pressed position within the \c parent Item
This is the position at which this point was pressed, relative to the
@@ -211,7 +211,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty QPointF QtQuick::HandlerPoint::scenePressPosition
+ \qmlproperty QPointF QtQuick::handlerPoint::scenePressPosition
\brief The pressed position within the scene
This is the position at which this point was pressed, in the coordinate
@@ -220,7 +220,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty QPointF QtQuick::HandlerPoint::sceneGrabPosition
+ \qmlproperty QPointF QtQuick::handlerPoint::sceneGrabPosition
\brief The grabbed position within the scene
If this point has been grabbed by a Pointer Handler or an Item, it means
@@ -231,7 +231,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty enumeration QtQuick::HandlerPoint::pressedButtons
+ \qmlproperty enumeration QtQuick::handlerPoint::pressedButtons
\brief Which mouse or stylus buttons are currently pressed
\sa MouseArea::pressedButtons
@@ -239,7 +239,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty enumeration QtQuick::HandlerPoint::modifiers
+ \qmlproperty enumeration QtQuick::handlerPoint::modifiers
\brief Which modifier keys are currently pressed
This property holds the keyboard modifiers that were pressed at the time
@@ -248,7 +248,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty QVector2D QtQuick::HandlerPoint::velocity
+ \qmlproperty QVector2D QtQuick::handlerPoint::velocity
\brief A vector representing the average speed and direction of movement
This is a velocity vector pointing in the direction of movement, in logical
@@ -261,7 +261,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty qreal QtQuick::HandlerPoint::rotation
+ \qmlproperty qreal QtQuick::handlerPoint::rotation
This property holds the rotation angle of the stylus on a graphics tablet
or the contact patch of a touchpoint on a touchscreen.
@@ -272,7 +272,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty qreal QtQuick::HandlerPoint::pressure
+ \qmlproperty qreal QtQuick::handlerPoint::pressure
This property tells how hard the user is pressing the stylus on a graphics
tablet or the finger against a touchscreen, in the range from \c 0 (no
@@ -285,7 +285,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
/*!
\readonly
- \qmlproperty size QtQuick::HandlerPoint::ellipseDiameters
+ \qmlproperty size QtQuick::handlerPoint::ellipseDiameters
This property holds the diameters of the contact patch, if the event
comes from a touchpoint and the device provides this information.
@@ -309,6 +309,13 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
\sa QtQuick::TouchPoint::ellipseDiameters, QEventPoint::ellipseDiameters
*/
+/*!
+ \readonly
+ \qmlproperty PointerDevice QtQuick::handlerPoint::device
+
+ This property holds the device that the point (and its event) came from.
+*/
+
QT_END_NAMESPACE
#include "moc_qquickhandlerpoint_p.cpp"
diff --git a/src/quick/handlers/qquickhandlerpoint_p.h b/src/quick/handlers/qquickhandlerpoint_p.h
index 79a05765c8..7a01aedca1 100644
--- a/src/quick/handlers/qquickhandlerpoint_p.h
+++ b/src/quick/handlers/qquickhandlerpoint_p.h
@@ -38,6 +38,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickHandlerPoint {
Q_PROPERTY(qreal pressure READ pressure)
Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters)
Q_PROPERTY(QPointingDevice *device READ device)
+ QML_ANONYMOUS
public:
QQuickHandlerPoint();
diff --git a/src/quick/handlers/qquickhoverhandler.cpp b/src/quick/handlers/qquickhoverhandler.cpp
index 59a2775c7b..ea7613550f 100644
--- a/src/quick/handlers/qquickhoverhandler.cpp
+++ b/src/quick/handlers/qquickhoverhandler.cpp
@@ -34,17 +34,64 @@ Q_LOGGING_CATEGORY(lcHoverHandler, "qt.quick.handler.hover")
\sa MouseArea, PointHandler
*/
+class QQuickHoverHandlerPrivate : public QQuickSinglePointHandlerPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickHoverHandler)
+
+public:
+ void onEnabledChanged() override;
+ void onParentChanged(QQuickItem *oldParent, QQuickItem *newParent) override;
+
+ void updateHasHoverInChild(QQuickItem *item, bool hasHover);
+};
+
+void QQuickHoverHandlerPrivate::onEnabledChanged()
+{
+ Q_Q(QQuickHoverHandler);
+
+ if (auto parent = q->parentItem())
+ updateHasHoverInChild(parent, enabled);
+ if (!enabled)
+ q->setHovered(false);
+
+ QQuickSinglePointHandlerPrivate::onEnabledChanged();
+}
+
+void QQuickHoverHandlerPrivate::onParentChanged(QQuickItem *oldParent, QQuickItem *newParent)
+{
+ if (oldParent)
+ updateHasHoverInChild(oldParent, false);
+ if (newParent)
+ updateHasHoverInChild(newParent, true);
+
+ QQuickSinglePointHandlerPrivate::onParentChanged(oldParent, newParent);
+}
+
+void QQuickHoverHandlerPrivate::updateHasHoverInChild(QQuickItem *item, bool hasHover)
+{
+ QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(item);
+ itemPriv->setHasHoverInChild(hasHover);
+ // The DA needs to resolve which items and handlers should now be hovered or unhovered.
+ // Marking the parent item dirty ensures that flushFrameSynchronousEvents() will be called from the render loop,
+ // even if this change is not in response to a mouse event and no item has already marked itself dirty.
+ itemPriv->dirty(QQuickItemPrivate::Content);
+}
+
QQuickHoverHandler::QQuickHoverHandler(QQuickItem *parent)
- : QQuickSinglePointHandler(parent)
+ : QQuickSinglePointHandler(*(new QQuickHoverHandlerPrivate), parent)
{
+ Q_D(QQuickHoverHandler);
// Tell QQuickPointerDeviceHandler::wantsPointerEvent() to ignore button state
- d_func()->acceptedButtons = Qt::NoButton;
+ d->acceptedButtons = Qt::NoButton;
+ if (parent)
+ d->updateHasHoverInChild(parent, true);
}
QQuickHoverHandler::~QQuickHoverHandler()
{
+ Q_D(QQuickHoverHandler);
if (auto parent = parentItem())
- QQuickItemPrivate::get(parent)->setHasHoverInChild(false);
+ d->updateHasHoverInChild(parent, false);
}
/*!
@@ -52,7 +99,7 @@ QQuickHoverHandler::~QQuickHoverHandler()
\since 6.3
Whether this handler prevents other items or handlers behind it from
- being hovered at the same timee. This property is \c false by default.
+ being hovered at the same time. This property is \c false by default.
*/
void QQuickHoverHandler::setBlocking(bool blocking)
{
@@ -81,10 +128,12 @@ bool QQuickHoverHandler::event(QEvent *event)
void QQuickHoverHandler::componentComplete()
{
+ Q_D(QQuickHoverHandler);
QQuickSinglePointHandler::componentComplete();
- if (auto par = parentItem()) {
- par->setAcceptHoverEvents(true);
- QQuickItemPrivate::get(par)->setHasHoverInChild(true);
+
+ if (d->enabled) {
+ if (auto parent = parentItem())
+ d->updateHasHoverInChild(parent, true);
}
}
@@ -108,6 +157,9 @@ bool QQuickHoverHandler::wantsPointerEvent(QPointerEvent *event)
// 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.
+ // But after kCursorOverrideTimeout ms, QQuickItemPrivate::effectiveCursorHandler()
+ // will ignore it, just in case there is no QQuickPointerTabletEvent to unset it.
+ // For example, a tablet proximity leave event could occur, but we don't deliver it to the window.
if (!(m_hoveredTablet && QQuickDeliveryAgentPrivate::isMouseEvent(event)))
setHovered(false);
@@ -284,6 +336,13 @@ void QQuickHoverHandler::setHovered(bool hovered)
\sa Qt::CursorShape, QQuickItem::cursor()
*/
+/*!
+ \internal
+ \qmlproperty flags HoverHandler::dragThreshold
+
+ This property is not used in HoverHandler.
+*/
+
QT_END_NAMESPACE
#include "moc_qquickhoverhandler_p.cpp"
diff --git a/src/quick/handlers/qquickhoverhandler_p.h b/src/quick/handlers/qquickhoverhandler_p.h
index 39ceb3df21..354a846428 100644
--- a/src/quick/handlers/qquickhoverhandler_p.h
+++ b/src/quick/handlers/qquickhoverhandler_p.h
@@ -22,6 +22,8 @@
QT_BEGIN_NAMESPACE
+class QQuickHoverHandlerPrivate;
+
class Q_QUICK_PRIVATE_EXPORT QQuickHoverHandler : public QQuickSinglePointHandler
{
Q_OBJECT
@@ -50,6 +52,8 @@ protected:
bool wantsPointerEvent(QPointerEvent *event) override;
void handleEventPoint(QPointerEvent *ev, QEventPoint &point) override;
+ Q_DECLARE_PRIVATE(QQuickHoverHandler)
+
private:
void setHovered(bool hovered);
diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp
index aaee15d2f0..c50de437cd 100644
--- a/src/quick/handlers/qquickmultipointhandler.cpp
+++ b/src/quick/handlers/qquickmultipointhandler.cpp
@@ -51,7 +51,7 @@ bool QQuickMultiPointHandler::wantsPointerEvent(QPointerEvent *event)
// currentPoints, because we don't want to lose the pressPosition, and do
// not want to reshuffle the order either).
const auto candidatePoints = eligiblePoints(event);
- if (candidatePoints.count() != d->currentPoints.count()) {
+ if (candidatePoints.size() != d->currentPoints.size()) {
d->currentPoints.clear();
if (active()) {
setActive(false);
@@ -64,7 +64,7 @@ bool QQuickMultiPointHandler::wantsPointerEvent(QPointerEvent *event)
ret = ret || (candidatePoints.size() >= minimumPointCount() && candidatePoints.size() <= maximumPointCount());
if (ret) {
- const int c = candidatePoints.count();
+ const int c = candidatePoints.size();
d->currentPoints.resize(c);
for (int i = 0; i < c; ++i) {
d->currentPoints[i].reset(event, candidatePoints[i]);
@@ -229,7 +229,7 @@ void QQuickMultiPointHandler::setMaximumPointCount(int maximumPointCount)
/*!
\readonly
- \qmlproperty QtQuick::HandlerPoint QtQuick::MultiPointHandler::centroid
+ \qmlproperty QtQuick::handlerPoint QtQuick::MultiPointHandler::centroid
A point exactly in the middle of the currently-pressed touch points.
If only one point is pressed, it's the same as that point.
@@ -265,7 +265,7 @@ bool QQuickMultiPointHandler::hasCurrentPoints(QPointerEvent *event)
return false;
// TODO optimize: either ensure the points are sorted,
// or use std::equal with a predicate
- for (const QQuickHandlerPoint &p : qAsConst(d->currentPoints)) {
+ for (const QQuickHandlerPoint &p : std::as_const(d->currentPoints)) {
const QEventPoint *ep = event->pointById(p.id());
if (!ep)
return false;
@@ -302,7 +302,7 @@ QVector<QQuickMultiPointHandler::PointData> QQuickMultiPointHandler::angles(cons
{
Q_D(const QQuickMultiPointHandler);
QVector<PointData> angles;
- angles.reserve(d->currentPoints.count());
+ angles.reserve(d->currentPoints.size());
for (const QQuickHandlerPoint &p : d->currentPoints) {
qreal angle = QLineF(ref, p.scenePosition()).angle();
angles.append(PointData(p.id(), -angle)); // convert to clockwise, to be consistent with QQuickItem::rotation
@@ -362,7 +362,7 @@ bool QQuickMultiPointHandler::grabPoints(QPointerEvent *event, const QVector<QEv
}
}
if (allowed) {
- for (auto point : points)
+ for (const auto &point : std::as_const(points))
setExclusiveGrab(event, point);
}
return allowed;
diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp
index 1ac08d5354..6cfe8d8936 100644
--- a/src/quick/handlers/qquickpinchhandler.cpp
+++ b/src/quick/handlers/qquickpinchhandler.cpp
@@ -203,8 +203,8 @@ void QQuickPinchHandler::onActiveChanged()
m_startRotation = t->rotation();
m_startPos = t->position();
} else {
- m_startScale = 1;
- m_startRotation = 0;
+ m_startScale = m_accumulatedScale;
+ m_startRotation = 0; // TODO m_accumulatedRotation (QTBUG-94168)
}
qCDebug(lcPinchHandler) << "activated with starting scale" << m_startScale << "rotation" << m_startRotation;
} else {
@@ -236,6 +236,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event)
return;
case Qt::ZoomNativeGesture:
m_activeScale *= 1 + gesture->value();
+ m_activeScale = qBound(m_minimumScale, m_activeScale, m_maximumScale);
break;
case Qt::RotateNativeGesture:
m_activeRotation += gesture->value();
@@ -333,9 +334,9 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event)
}
const bool requiredNumberOfPointsDraggedOverThreshold = numberOfPointsDraggedOverThreshold >= minimumPointCount() && numberOfPointsDraggedOverThreshold <= maximumPointCount();
- accumulatedMovementMagnitude /= currentPoints().count();
+ accumulatedMovementMagnitude /= currentPoints().size();
- QVector2D avgDrag = accumulatedDrag / currentPoints().count();
+ QVector2D avgDrag = accumulatedDrag / currentPoints().size();
if (!xAxis()->enabled())
avgDrag.setX(0);
if (!yAxis()->enabled())
@@ -425,8 +426,15 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event)
}
/*!
+ \internal
+ \qmlproperty flags QtQuick::PinchHandler::acceptedButtons
+
+ This property is not used in PinchHandler.
+*/
+
+/*!
\readonly
- \qmlproperty QtQuick::HandlerPoint QtQuick::PinchHandler::centroid
+ \qmlproperty QtQuick::handlerPoint QtQuick::PinchHandler::centroid
A point exactly in the middle of the currently-pressed touch points.
The \l target will be rotated around this point.
@@ -471,6 +479,9 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event)
The translation of the gesture \l centroid. It is \c (0, 0) when the
gesture begins.
+
+ \note On some touchpads, such as on a \macos trackpad, native gestures do
+ not generate any translation values, and this property stays at \c (0, 0).
*/
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpointerdevicehandler.cpp b/src/quick/handlers/qquickpointerdevicehandler.cpp
index 78e94d8c96..5da7849a44 100644
--- a/src/quick/handlers/qquickpointerdevicehandler.cpp
+++ b/src/quick/handlers/qquickpointerdevicehandler.cpp
@@ -31,7 +31,7 @@ QQuickPointerDeviceHandler::QQuickPointerDeviceHandler(QQuickPointerDeviceHandle
{
}
-QPointingDevice::DeviceTypes QQuickPointerDeviceHandler::acceptedDevices() const
+QInputDevice::DeviceTypes QQuickPointerDeviceHandler::acceptedDevices() const
{
Q_D(const QQuickPointerDeviceHandler);
return d->acceptedDevices;
@@ -139,7 +139,7 @@ void QQuickPointerDeviceHandler::setAcceptedDevices(QPointingDevice::DeviceTypes
By default, this property is set to
\l {QPointingDevice::PointerType} {PointerDevice.AllPointerTypes}.
If you set it to an OR combination of device types, it will ignore events
- from non-matching events.
+ from non-matching \l {PointerDevice}{devices}.
For example, a control could be made to respond to mouse, touch, and stylus clicks
in some way, but delete itself if tapped with an eraser tool on a graphics tablet,
diff --git a/src/quick/handlers/qquickpointerdevicehandler_p.h b/src/quick/handlers/qquickpointerdevicehandler_p.h
index 259b8a5ae7..1a62194d78 100644
--- a/src/quick/handlers/qquickpointerdevicehandler_p.h
+++ b/src/quick/handlers/qquickpointerdevicehandler_p.h
@@ -23,7 +23,8 @@ class QQuickPointerDeviceHandlerPrivate;
class Q_QUICK_PRIVATE_EXPORT QQuickPointerDeviceHandler : public QQuickPointerHandler
{
Q_OBJECT
- Q_PROPERTY(QPointingDevice::DeviceTypes acceptedDevices READ acceptedDevices WRITE setAcceptedDevices NOTIFY acceptedDevicesChanged)
+ Q_PROPERTY(QInputDevice::DeviceTypes acceptedDevices READ acceptedDevices WRITE
+ setAcceptedDevices NOTIFY acceptedDevicesChanged)
Q_PROPERTY(QPointingDevice::PointerTypes acceptedPointerTypes READ acceptedPointerTypes WRITE setAcceptedPointerTypes NOTIFY acceptedPointerTypesChanged)
Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged)
Q_PROPERTY(Qt::KeyboardModifiers acceptedModifiers READ acceptedModifiers WRITE setAcceptedModifiers NOTIFY acceptedModifiersChanged)
@@ -31,13 +32,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerDeviceHandler : public QQuickPointerHa
public:
explicit QQuickPointerDeviceHandler(QQuickItem *parent = nullptr);
- QPointingDevice::DeviceTypes acceptedDevices() const;
+ QInputDevice::DeviceTypes acceptedDevices() const;
QPointingDevice::PointerTypes acceptedPointerTypes() const;
Qt::MouseButtons acceptedButtons() const;
Qt::KeyboardModifiers acceptedModifiers() const;
public Q_SLOTS:
- void setAcceptedDevices(QPointingDevice::DeviceTypes acceptedDevices);
+ void setAcceptedDevices(QInputDevice::DeviceTypes acceptedDevices);
void setAcceptedPointerTypes(QPointingDevice::PointerTypes acceptedPointerTypes);
void setAcceptedButtons(Qt::MouseButtons buttons);
void setAcceptedModifiers(Qt::KeyboardModifiers acceptedModifiers);
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
index 018a09fcc2..a851334b0e 100644
--- a/src/quick/handlers/qquickpointerhandler.cpp
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -401,6 +401,8 @@ bool QQuickPointerHandler::approveGrabTransition(QPointerEvent *event, const QEv
This handler can take the exclusive grab from another handler of the same class.
\value PointerHandler.CanTakeOverFromHandlersOfDifferentType
This handler can take the exclusive grab from any kind of handler.
+ \value PointerHandler.CanTakeOverFromItems
+ This handler can take the exclusive grab from any type of Item.
\value PointerHandler.CanTakeOverFromAnything
This handler can take the exclusive grab from any type of Item or Handler.
\value PointerHandler.ApprovesTakeOverByHandlersOfSameType
@@ -553,6 +555,8 @@ void QQuickPointerHandler::setEnabled(bool enabled)
return;
d->enabled = enabled;
+ d->onEnabledChanged();
+
emit enabledChanged();
}
@@ -593,15 +597,18 @@ QQuickItem *QQuickPointerHandler::parentItem() const
void QQuickPointerHandler::setParentItem(QQuickItem *p)
{
+ Q_D(QQuickPointerHandler);
if (QObject::parent() == p)
return;
qCDebug(lcHandlerParent) << "reparenting handler" << this << ":" << parent() << "->" << p;
- if (auto *oldParent = static_cast<QQuickItem *>(QObject::parent()))
+ auto *oldParent = static_cast<QQuickItem *>(QObject::parent());
+ if (oldParent)
QQuickItemPrivate::get(oldParent)->removePointerHandler(this);
setParent(p);
if (p)
QQuickItemPrivate::get(p)->addPointerHandler(this);
+ d->onParentChanged(oldParent, p);
emit parentChanged();
}
@@ -645,6 +652,7 @@ void QQuickPointerHandler::handlePointerEvent(QPointerEvent *event)
d->currentEvent = event;
if (wants) {
handlePointerEventImpl(event);
+ d->lastEventTime = event->timestamp();
} else {
#if QT_CONFIG(gestures)
if (event->type() != QEvent::NativeGesture)
diff --git a/src/quick/handlers/qquickpointerhandler_p_p.h b/src/quick/handlers/qquickpointerhandler_p_p.h
index 8823bcb897..aa09f4edb7 100644
--- a/src/quick/handlers/qquickpointerhandler_p_p.h
+++ b/src/quick/handlers/qquickpointerhandler_p_p.h
@@ -38,11 +38,15 @@ public:
bool dragOverThreshold(QVector2D delta) const;
bool dragOverThreshold(const QEventPoint &point) const;
+ virtual void onParentChanged(QQuickItem * /*oldParent*/, QQuickItem * /*newParent*/) {}
+ virtual void onEnabledChanged() {}
+
static QVector<QObject *> &deviceDeliveryTargets(const QInputDevice *device);
QPointerEvent *currentEvent = nullptr;
QQuickItem *target = nullptr;
qreal m_margin = 0;
+ quint64 lastEventTime = 0;
qint16 dragThreshold = -1; // -1 means use the platform default
uint8_t grabPermissions : 8;
Qt::CursorShape cursorShape : 6;
diff --git a/src/quick/handlers/qquickpointhandler.cpp b/src/quick/handlers/qquickpointhandler.cpp
index 1c5f36b6dd..2a9e0ff9bb 100644
--- a/src/quick/handlers/qquickpointhandler.cpp
+++ b/src/quick/handlers/qquickpointhandler.cpp
@@ -66,7 +66,8 @@ QT_BEGIN_NAMESPACE
PointHandler will not automatically manipulate the \c target item in any way.
You need to use bindings to make it react to the \l point.
- \note On macOS, PointHandler does not react to the trackpad by default.
+ \note On macOS, PointHandler does not react to multiple fingers on the
+ trackpad by default, although it does react to a pressed point (mouse position).
That is because macOS can provide either native gesture recognition, or raw
touchpoints, but not both. We prefer to use the native gesture event in
PinchHandler, so we do not want to disable it by enabling touch. However
@@ -75,7 +76,7 @@ QT_BEGIN_NAMESPACE
want to react to all the touchpoints but do not require the smooth
native-gesture experience.
- \sa MultiPointTouchArea
+ \sa MultiPointTouchArea, HoverHandler, {Pointer Handlers Example}
*/
QQuickPointHandler::QQuickPointHandler(QQuickItem *parent)
@@ -128,6 +129,127 @@ QVector2D QQuickPointHandler::translation() const
return QVector2D(point().position() - point().pressPosition());
}
+/*!
+ \qmlproperty flags PointHandler::acceptedButtons
+
+ The mouse buttons that can activate this PointHandler.
+
+ By default, this property is set to \l {QtQuick::MouseEvent::button} {Qt.LeftButton}.
+ It can be set to an OR combination of mouse buttons, and will ignore events
+ in which other buttons are pressed or held.
+
+ \snippet pointerHandlers/pointHandlerAcceptedButtons.qml 0
+
+ \note On a touchscreen, there are no buttons, so this property does not
+ prevent PointHandler from reacting to touchpoints.
+*/
+
+/*!
+ \qmlproperty flags PointHandler::acceptedDevices
+
+ The types of pointing devices that can activate this PointHandler.
+
+ By default, this property is set to
+ \l{QInputDevice::DeviceType}{PointerDevice.AllDevices}.
+ If you set it to an OR combination of device types, it will ignore events
+ from non-matching \l {PointerDevice}{devices}:
+
+ \snippet pointerHandlers/pointHandler.qml 1
+*/
+
+/*!
+ \qmlproperty flags PointHandler::acceptedPointerTypes
+
+ The types of pointing instruments (finger, stylus, eraser, etc.)
+ that can activate this PointHandler.
+
+ By default, this property is set to
+ \l {QPointingDevice::PointerType} {PointerDevice.AllPointerTypes}.
+ If you set it to an OR combination of device types, it will ignore events
+ from non-matching \l {PointerDevice}{devices}:
+
+ \snippet pointerHandlers/pointHandlerCanvasDrawing.qml 0
+
+ The \l {Pointer Handlers Example} includes a more complex example for
+ drawing on a Canvas with a graphics tablet.
+*/
+
+/*!
+ \qmlproperty flags PointHandler::acceptedModifiers
+
+ If this property is set, PointHandler requires the given keyboard modifiers
+ to be pressed in order to react to \l {PointerEvent}{PointerEvents}, and
+ otherwise ignores them.
+
+ If this property is set to \c Qt.KeyboardModifierMask (the default value),
+ then PointHandler ignores the modifier keys.
+
+ For example, an \l [QML] Item could have two handlers, one of which is
+ enabled only if the required keyboard modifier is pressed:
+
+ \snippet pointerHandlers/pointHandlerAcceptedModifiers.qml 0
+
+ If you set \c acceptedModifiers to an OR combination of modifier keys,
+ it means \e all of those modifiers must be pressed to activate the handler.
+
+ The available modifiers are as follows:
+
+ \value NoModifier No modifier key is allowed.
+ \value ShiftModifier A Shift key on the keyboard must be pressed.
+ \value ControlModifier A Ctrl key on the keyboard must be pressed.
+ \value AltModifier An Alt key on the keyboard must be pressed.
+ \value MetaModifier A Meta key on the keyboard must be pressed.
+ \value KeypadModifier A keypad button must be pressed.
+ \value GroupSwitchModifier X11 only (unless activated on Windows by a command line argument).
+ A Mode_switch key on the keyboard must be pressed.
+ \value KeyboardModifierMask The handler does not care which modifiers are pressed.
+
+ \sa Qt::KeyboardModifier
+*/
+
+/*!
+ \readonly
+ \qmlproperty bool PointHandler::active
+
+ This holds \c true whenever the constraints are satisfied and this
+ PointHandler is reacting. This means that it is keeping its properties
+ up-to-date according to the movements of the \l {eventPoint}{eventPoints}
+ that satisfy the constraints.
+*/
+
+/*!
+ \internal
+ \qmlproperty flags PointHandler::dragThreshold
+
+ This property is not used in PointHandler.
+*/
+
+/*!
+ \qmlproperty real PointHandler::margin
+
+ The margin beyond the bounds of the \l {PointerHandler::parent}{parent}
+ item within which an \l eventPoint can activate this handler.
+
+ The default value is \c 0.
+
+ \snippet pointerHandlers/pointHandlerMargin.qml 0
+*/
+
+/*!
+ \qmlproperty real PointHandler::target
+
+ A property that can conveniently hold an Item to be manipulated or to show
+ feedback. Unlike other \l {Qt Quick Input Handlers}{Pointer Handlers},
+ PointHandler does not do anything with the \c target on its own: you
+ usually need to create reactive bindings to properties such as
+ \l SinglePointHandler::point and \l PointHandler::active. If you declare
+ an Item instance here, you need to explicitly set its \l {Item::}{parent},
+ because PointHandler is not an Item.
+
+ By default, it is the same as the \l {PointerHandler::}{parent}, the Item
+ within which the handler is declared.
+*/
+
QT_END_NAMESPACE
#include "moc_qquickpointhandler_p.cpp"
diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp
index c732a2562e..c7b642a7bc 100644
--- a/src/quick/handlers/qquicksinglepointhandler.cpp
+++ b/src/quick/handlers/qquicksinglepointhandler.cpp
@@ -171,7 +171,7 @@ QQuickHandlerPoint QQuickSinglePointHandler::point() const
/*!
\readonly
- \qmlproperty HandlerPoint QtQuick::SinglePointHandler::point
+ \qmlproperty handlerPoint QtQuick::SinglePointHandler::point
The event point currently being handled. When no point is currently being
handled, this object is reset to default values (all coordinates are 0).
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
index 0ec7c0ab65..96c67aa778 100644
--- a/src/quick/handlers/qquicktaphandler.cpp
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -117,24 +117,14 @@ bool QQuickTapHandler::wantsEventPoint(const QPointerEvent *event, const QEventP
void QQuickTapHandler::handleEventPoint(QPointerEvent *event, QEventPoint &point)
{
+ const bool isTouch = QQuickDeliveryAgentPrivate::isTouchEvent(event);
switch (point.state()) {
case QEventPoint::Pressed:
setPressed(true, false, event, point);
break;
case QEventPoint::Released: {
- // If the point has an exclusive grabber Item, then if it got the grab by filtering (like Flickable does),
- // it's OK for DragHandler to react in spite of that. But in other cases, if an exclusive grab
- // still exists at the time of release, TapHandler should not react, because it would be redundant:
- // some other item is already reacting, i.e. acting as if it has been clicked or tapped.
- // So in that case we cancel the pressed state and do not emit tapped().
- bool nonFilteringExclusiveGrabber = false;
- if (auto g = qmlobject_cast<QQuickItem *>(event->exclusiveGrabber(point))) {
- if (!g->filtersChildMouseEvents())
- nonFilteringExclusiveGrabber = true;
- }
- if (QQuickDeliveryAgentPrivate::isTouchEvent(event) ||
- (static_cast<const QSinglePointEvent *>(event)->buttons() & acceptedButtons()) == Qt::NoButton)
- setPressed(false, nonFilteringExclusiveGrabber, event, point);
+ if (isTouch || (static_cast<const QSinglePointEvent *>(event)->buttons() & acceptedButtons()) == Qt::NoButton)
+ setPressed(false, false, event, point);
break;
}
default:
@@ -142,6 +132,11 @@ void QQuickTapHandler::handleEventPoint(QPointerEvent *event, QEventPoint &point
}
QQuickSinglePointHandler::handleEventPoint(event, point);
+
+ // If TapHandler only needs a passive grab, it should not block other items and handlers from reacting.
+ // If the point is accepted, QQuickItemPrivate::localizedTouchEvent() would skip it.
+ if (isTouch && m_gesturePolicy == DragThreshold)
+ point.setAccepted(false);
}
/*!
@@ -194,16 +189,41 @@ void QQuickTapHandler::timerEvent(QTimerEvent *event)
The \c gesturePolicy also affects grab behavior as described below.
- \value TapHandler.DragThreshold
- (the default value) The event point must not move significantly.
- If the mouse, finger or stylus moves past the system-wide drag
- threshold (QStyleHints::startDragDistance), the tap gesture is
- canceled, even if the button or finger is still pressed. This policy
- can be useful whenever TapHandler needs to cooperate with other
- input handlers (for example \l DragHandler) or event-handling Items
- (for example QtQuick Controls), because in this case TapHandler
- will not take the exclusive grab, but merely a
- \l {QPointerEvent::addPassiveGrabber()}{passive grab}.
+ \table
+ \header
+ \li Constant
+ \li Description
+ \row
+ \li \c TapHandler.DragThreshold
+ \image pointerHandlers/tapHandlerOverlappingButtons.webp
+ Grab on press: \e passive
+ \li (the default value) The \l eventPoint must not move significantly.
+ If the mouse, finger or stylus moves past the system-wide drag
+ threshold (QStyleHints::startDragDistance), the tap gesture is
+ canceled, even if the device or finger is still pressed. This policy
+ can be useful whenever TapHandler needs to cooperate with other
+ input handlers (for example \l DragHandler) or event-handling Items
+ (for example \l {Qt Quick Controls}), because in this case TapHandler
+ will not take the exclusive grab, but merely a
+ \l {QPointerEvent::addPassiveGrabber()}{passive grab}.
+ That is, \c DragThreshold is especially useful to \e augment
+ existing behavior: it reacts to tap/click/long-press even when
+ another item or handler is already reacting, perhaps even in a
+ different layer of the UI. The following snippet shows one
+ TapHandler as used in one component; but if we stack up two
+ instances of the component, you will see the handlers in both of them
+ react simultaneously when a press occurs over both of them, because
+ the passive grab does not stop event propagation:
+ \quotefromfile pointerHandlers/tapHandlerOverlappingButtons.qml
+ \skipto Item
+ \printuntil component Button
+ \skipto TapHandler
+ \printuntil }
+ \skipuntil Text {
+ \skipuntil }
+ \printuntil Button
+ \printuntil Button
+ \printuntil }
\value TapHandler.WithinBounds
If the event point leaves the bounds of the \c parent Item, the tap
@@ -212,31 +232,47 @@ void QQuickTapHandler::timerEvent(QTimerEvent *event)
press, but will release the grab as soon as the boundary constraint
is no longer satisfied.
- \value TapHandler.ReleaseWithinBounds
- At the time of release (the mouse button is released or the finger
- is lifted), if the event point is outside the bounds of the
- \c parent Item, a tap gesture is not recognized. This corresponds to
- typical behavior for button widgets: you can cancel a click by
- dragging outside the button, and you can also change your mind by
- dragging back inside the button before release. Note that it's
- necessary for TapHandler to take the
- \l {QPointerEvent::setExclusiveGrabber}{exclusive grab} on press
- and retain it until release in order to detect this gesture.
-
- \value TapHandler.DragWithinBounds
- On press, TapHandler takes the
- \l {QPointerEvent::setExclusiveGrabber}{exclusive grab}; after that,
- the event point can be dragged within the bounds of the \c parent
- item, while the \l timeHeld property keeps counting, and the
- \l longPressed() signal will be emitted regardless of drag distance.
- However, like \c WithinBounds, if the point leaves the bounds,
- the tap gesture is \l {PointerHandler::}{canceled()}, \l active()
- becomes \c false, and \l timeHeld stops counting. This is suitable
- for implementing press-drag-release components, such as menus, in
- which a single TapHandler detects press, \c timeHeld drives an
- "opening" animation, and then the user can drag to a menu item and
- release, while never leaving the bounds of the parent scene containing
- the menu. This value was added in Qt 6.3.
+ \row
+ \li \c TapHandler.ReleaseWithinBounds
+ \image pointerHandlers/tapHandlerButtonReleaseWithinBounds.webp
+ Grab on press: \e exclusive
+ \li At the time of release (the mouse button is released or the finger
+ is lifted), if the \l eventPoint is outside the bounds of the
+ \c parent Item, a tap gesture is not recognized. This corresponds to
+ typical behavior for button widgets: you can cancel a click by
+ dragging outside the button, and you can also change your mind by
+ dragging back inside the button before release. Note that it's
+ necessary for TapHandler to take the
+ \l {QPointerEvent::setExclusiveGrabber}{exclusive grab} on press
+ and retain it until release in order to detect this gesture.
+ \snippet pointerHandlers/tapHandlerButtonReleaseWithinBounds.qml 1
+
+ \row
+ \li \c TapHandler.DragWithinBounds
+ \image pointerHandlers/dragReleaseMenu.webp
+ Grab on press: \e exclusive
+ \li On press, TapHandler takes the
+ \l {QPointerEvent::setExclusiveGrabber}{exclusive grab}; after that,
+ the \l eventPoint can be dragged within the bounds of the \c parent
+ item, while the \l timeHeld property keeps counting, and the
+ \l longPressed() signal will be emitted regardless of drag distance.
+ However, like \c WithinBounds, if the point leaves the bounds,
+ the tap gesture is \l {PointerHandler::}{canceled()}, \l active()
+ becomes \c false, and \l timeHeld stops counting. This is suitable
+ for implementing press-drag-release components, such as menus, in
+ which a single TapHandler detects press, \c timeHeld drives an
+ "opening" animation, and then the user can drag to a menu item and
+ release, while never leaving the bounds of the parent scene containing
+ the menu. This value was added in Qt 6.3.
+ \snippet pointerHandlers/dragReleaseMenu.qml 1
+ \endtable
+
+ \note If you find that TapHandler is reacting in cases that conflict with
+ some other behavior, the first thing you should try is to think about which
+ \c gesturePolicy is appropriate. If you cannot fix it by changing \c gesturePolicy,
+ some cases are better served by adjusting \l {PointerHandler::}{grabPermissions},
+ either in this handler, or in another handler that should \e prevent TapHandler
+ from reacting.
*/
void QQuickTapHandler::setGesturePolicy(QQuickTapHandler::GesturePolicy gesturePolicy)
{
diff --git a/src/quick/handlers/qquickwheelhandler.cpp b/src/quick/handlers/qquickwheelhandler.cpp
index ced584b0ad..84a3a69405 100644
--- a/src/quick/handlers/qquickwheelhandler.cpp
+++ b/src/quick/handlers/qquickwheelhandler.cpp
@@ -55,7 +55,7 @@ QQuickWheelHandler::QQuickWheelHandler(QQuickItem *parent)
}
/*!
- \qmlproperty enum QtQuick::WheelHandler::orientation
+ \qmlproperty enumeration QtQuick::WheelHandler::orientation
Which wheel to react to. The default is \c Qt.Vertical.
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index a6d58fec2c..0eb4fe40d3 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -616,6 +616,10 @@ void QQuickCanvasItem::invalidateSceneGraph()
d->textureProvider = nullptr;
delete d->nodeTexture;
d->nodeTexture = nullptr;
+
+ // As we can expect(/hope) that the SG will be "good again", we can requestPaint ( which does 'markDirty(canvasWindow);' )
+ // Otherwise this Canvas will be "blank" when SG comes back
+ requestPaint();
}
void QQuickCanvasItem::schedulePolish()
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index d2e24a8b30..d053da4766 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -101,7 +101,7 @@ Q_QUICK_PRIVATE_EXPORT QColor qt_color_from_string(const QV4::Value &name)
QByteArray str = name.toQString().toUtf8();
char *p = str.data();
- int len = str.length();
+ int len = str.size();
//rgb/hsl color string has at least 7 characters
if (!p || len > 255 || len <= 7)
return QColor::fromString(p);
diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h b/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h
index 3c18c68856..52ba4896ed 100644
--- a/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h
+++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h
@@ -168,7 +168,7 @@ public:
inline void setLineDash(const QVector<qreal> &pattern)
{
commands << QQuickContext2D::LineDash;
- reals << pattern.length();
+ reals << pattern.size();
for (qreal r : pattern)
reals << r;
}
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp
index 0dd95a9095..2dadae3ef7 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture.cpp
+++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp
@@ -113,7 +113,7 @@ bool QQuickContext2DTexture::setDirtyRect(const QRect &r)
{
bool doDirty = false;
if (m_tiledCanvas) {
- for (QQuickContext2DTile* t : qAsConst(m_tiles)) {
+ for (QQuickContext2DTile* t : std::as_const(m_tiles)) {
bool dirty = t->rect().intersected(r).isValid();
t->markDirty(dirty);
if (dirty)
@@ -197,7 +197,7 @@ void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb)
QRect tiledRegion = createTiles(m_canvasWindow.intersected(QRect(QPoint(0, 0), m_canvasSize)));
if (!tiledRegion.isEmpty()) {
QRect dirtyRect;
- for (QQuickContext2DTile* tile : qAsConst(m_tiles)) {
+ for (QQuickContext2DTile* tile : std::as_const(m_tiles)) {
if (tile->dirty()) {
if (dirtyRect.isEmpty())
dirtyRect = tile->rect();
@@ -208,7 +208,7 @@ void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb)
if (beginPainting()) {
QQuickContext2D::State oldState = m_state;
- for (QQuickContext2DTile* tile : qAsConst(m_tiles)) {
+ for (QQuickContext2DTile* tile : std::as_const(m_tiles)) {
if (tile->dirty()) {
ccb->replay(tile->createPainter(m_smooth, m_antialiasing), oldState, scaleFactor());
tile->drawFinished();
diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp
index 45219dc69c..865fb8bf11 100644
--- a/src/quick/items/qquickaccessibleattached.cpp
+++ b/src/quick/items/qquickaccessibleattached.cpp
@@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
This property sets an accessible description.
Similar to the name it describes the item. The description
can be a little more verbose and tell what the item does,
- for example the functionallity of the button it describes.
+ for example the functionality of the button it describes.
*/
/*!
@@ -312,11 +312,33 @@ QQuickAccessibleAttached::QQuickAccessibleAttached(QObject *parent)
QAccessibleEvent ev(item(), QAccessible::ObjectCreated);
QAccessible::updateAccessibility(&ev);
- if (!parent->property("value").isNull()) {
- connect(parent, SIGNAL(valueChanged()), this, SLOT(valueChanged()));
- }
- if (!parent->property("cursorPosition").isNull()) {
- connect(parent, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged()));
+ if (const QMetaObject *pmo = parent->metaObject()) {
+ auto connectPropertyChangeSignal = [parent, pmo, this](
+ const char *propertyName, const char *signalName, int slotIndex)
+ {
+ // basically does this:
+ // if the parent has the property \a propertyName with the associated \a signalName:
+ // connect(parent, signalName, this, slotIndex)
+
+ // Note that we explicitly want to only connect to standard property/signal naming
+ // convention: "value" & "valueChanged"
+ // (e.g. avoid a compound property with e.g. a signal notifier named "updated()")
+ int idxProperty = pmo->indexOfProperty(propertyName);
+ if (idxProperty != -1) {
+ const QMetaProperty property = pmo->property(idxProperty);
+ const QMetaMethod signal = property.notifySignal();
+ if (signal.name() == signalName)
+ QMetaObject::connect(parent, signal.methodIndex(), this, slotIndex);
+ }
+ return;
+ };
+ const QMetaObject &smo = staticMetaObject;
+ static const int valueChangedIndex = smo.indexOfSlot("valueChanged()");
+ connectPropertyChangeSignal("value", "valueChanged", valueChangedIndex);
+
+ static const int cursorPositionChangedIndex = smo.indexOfSlot("cursorPositionChanged()");
+ connectPropertyChangeSignal("cursorPosition", "cursorPositionChanged",
+ cursorPositionChangedIndex);
}
if (!sigPress.isValid()) {
diff --git a/src/quick/items/qquickcolorgroup.cpp b/src/quick/items/qquickcolorgroup.cpp
index fd913aba7a..273ee31fa2 100644
--- a/src/quick/items/qquickcolorgroup.cpp
+++ b/src/quick/items/qquickcolorgroup.cpp
@@ -45,6 +45,8 @@ QT_BEGIN_NAMESPACE
base: "green"
}
\endcode
+
+ The \l Palette type exposes color groups for each QML item state.
*/
/*!
@@ -180,8 +182,6 @@ QT_BEGIN_NAMESPACE
Additional signal indicates that the current state of this color group
has been changed. Usually it means that one of the colors is changed.
-
- \sa Palette
*/
/*!
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 4d54a28d8a..6c1f56de63 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -446,7 +446,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys)
\qmlattachedproperty stringlist QtQuick::Drag::mimeData
\since 5.2
- This property holds a map of mimeData that is used during startDrag.
+ This property holds a map from mime type to data that is used during startDrag.
+ The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded
+ according to the mime type.
*/
QVariantMap QQuickDragAttached::mimeData() const
@@ -731,8 +733,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
QDrag *drag = new QDrag(source ? source : q);
QMimeData *mimeData = new QMimeData();
- for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it)
- mimeData->setData(it.key(), it.value().toString().toUtf8());
+ for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
+ if (it.value().typeId() == QMetaType::QByteArray)
+ mimeData->setData(it.key(), it.value().toByteArray());
+ else
+ mimeData->setData(it.key(), it.value().toString().toUtf8());
+ }
drag->setMimeData(mimeData);
if (pixmapLoader.isReady()) {
diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h
index 611ed5df8f..806dbc7602 100644
--- a/src/quick/items/qquickdrag_p.h
+++ b/src/quick/items/qquickdrag_p.h
@@ -72,9 +72,12 @@ public:
void grab(QQuickItem *item) { m_items.insert(new Item(item)); }
iterator release(iterator at) { Item *item = *at; at = at.erase(); delete item; return at; }
+ auto& ignoreList() { return m_ignoreDragItems; }
+
private:
ItemList m_items;
+ QVarLengthArray<QQuickItem *, 4> m_ignoreDragItems;
QObject *m_target;
};
diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp
index a553d758c5..1c865a6327 100644
--- a/src/quick/items/qquickdroparea.cpp
+++ b/src/quick/items/qquickdroparea.cpp
@@ -125,7 +125,7 @@ void QQuickDropArea::setKeys(const QStringList &keys)
d->keyRegExp = QRegularExpression();
} else {
QString pattern = QLatin1Char('(') + QRegularExpression::escape(keys.first());
- for (int i = 1; i < keys.count(); ++i)
+ for (int i = 1; i < keys.size(); ++i)
pattern += QLatin1Char('|') + QRegularExpression::escape(keys.at(i));
pattern += QLatin1Char(')');
d->keyRegExp = QRegularExpression(
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index b1d274cb98..fdb294cdfc 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -318,7 +318,7 @@ void QQuickFlickablePrivate::AxisData::updateVelocity()
}
}
-void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &)
+void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeom)
{
Q_Q(QQuickFlickable);
if (item == contentItem) {
@@ -327,8 +327,14 @@ void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometr
orient |= Qt::Horizontal;
if (change.yChange())
orient |= Qt::Vertical;
- if (orient)
+ if (orient) {
q->viewportMoved(orient);
+ const QPointF deltaMoved = item->position() - oldGeom.topLeft();
+ if (hData.contentPositionChangedExternallyDuringDrag)
+ hData.pressPos += deltaMoved.x();
+ if (vData.contentPositionChangedExternallyDuringDrag)
+ vData.pressPos += deltaMoved.y();
+ }
if (orient & Qt::Horizontal)
emit q->contentXChanged();
if (orient & Qt::Vertical)
@@ -711,7 +717,8 @@ void QQuickFlickablePrivate::updateBeginningEnd()
/*!
\qmlsignal QtQuick::Flickable::flickEnded()
- This signal is emitted when the view stops moving due to a flick.
+ This signal is emitted when the view stops moving after a flick
+ or a series of flicks.
*/
/*!
@@ -788,8 +795,11 @@ void QQuickFlickable::setContentX(qreal pos)
d->hData.vTime = d->timeline.time();
if (isMoving() || isFlicking())
movementEnding(true, false);
- if (!qFuzzyCompare(-pos, d->hData.move.value()))
+ if (!qFuzzyCompare(-pos, d->hData.move.value())) {
+ d->hData.contentPositionChangedExternallyDuringDrag = d->hData.dragging;
d->hData.move.setValue(-pos);
+ d->hData.contentPositionChangedExternallyDuringDrag = false;
+ }
}
qreal QQuickFlickable::contentY() const
@@ -806,8 +816,11 @@ void QQuickFlickable::setContentY(qreal pos)
d->vData.vTime = d->timeline.time();
if (isMoving() || isFlicking())
movementEnding(false, true);
- if (!qFuzzyCompare(-pos, d->vData.move.value()))
+ if (!qFuzzyCompare(-pos, d->vData.move.value())) {
+ d->vData.contentPositionChangedExternallyDuringDrag = d->vData.dragging;
d->vData.move.setValue(-pos);
+ d->vData.contentPositionChangedExternallyDuringDrag = false;
+ }
}
/*!
@@ -1103,7 +1116,9 @@ void QQuickFlickablePrivate::maybeBeginDrag(qint64 currentTimestamp, const QPoin
pressPos = pressPosn;
hData.pressPos = hData.move.value();
vData.pressPos = vData.move.value();
- bool wasFlicking = hData.flicking || vData.flicking;
+ const bool wasFlicking = hData.flicking || vData.flicking;
+ hData.flickingWhenDragBegan = hData.flicking;
+ vData.flickingWhenDragBegan = vData.flicking;
if (hData.flicking) {
hData.flicking = false;
emit q->flickingHorizontallyChanged();
@@ -1434,8 +1449,15 @@ void QQuickFlickablePrivate::handleReleaseEvent(QPointerEvent *event)
fixupX();
flickingStarted(flickedHorizontally, flickedVertically);
- if (!isViewMoving())
+ if (!isViewMoving()) {
q->movementEnding();
+ } else {
+ if (flickedVertically)
+ vMoved = true;
+ if (flickedHorizontally)
+ hMoved = true;
+ q->movementStarting();
+ }
}
void QQuickFlickable::mousePressEvent(QMouseEvent *event)
@@ -2515,6 +2537,18 @@ bool QQuickFlickable::filterPointerEvent(QQuickItem *receiver, QPointerEvent *ev
if (isTouch && static_cast<QTouchEvent *>(event)->touchPointStates().testFlag(QEventPoint::State::Pressed))
d->stealMouse = false;
const auto &firstPoint = event->points().first();
+
+ if (event->pointCount() == 1 && event->exclusiveGrabber(firstPoint) == this) {
+ // We have an exclusive grab (since we're e.g dragging), but at the same time, we have
+ // a child with a passive grab (which is why this filter is being called). And because
+ // of that, we end up getting the same pointer events twice; First in our own event
+ // handlers (because of the grab), then once more in here, since we filter the child.
+ // To avoid processing the event twice (e.g avoid calling handleReleaseEvent once more
+ // from below), we mark the event as filtered, and simply return.
+ event->setAccepted(true);
+ return true;
+ }
+
QPointF localPos = mapFromScene(firstPoint.scenePosition());
bool receiverDisabled = receiver && !receiver->isEnabled();
bool stealThisEvent = d->stealMouse;
@@ -2884,6 +2918,12 @@ void QQuickFlickable::movementStarting()
if (!wasMoving && (d->hData.moving || d->vData.moving)) {
emit movingChanged();
emit movementStarted();
+#if QT_CONFIG(accessibility)
+ if (QAccessible::isActive()) {
+ QAccessibleEvent ev(this, QAccessible::ScrollingStart);
+ QAccessible::updateAccessibility(&ev);
+ }
+#endif
}
}
@@ -2897,7 +2937,7 @@ void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding)
Q_D(QQuickFlickable);
// emit flicking signals
- bool wasFlicking = d->hData.flicking || d->vData.flicking;
+ const bool wasFlicking = d->hData.flicking || d->vData.flicking;
if (hMovementEnding && d->hData.flicking) {
d->hData.flicking = false;
emit flickingHorizontallyChanged();
@@ -2909,6 +2949,10 @@ void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding)
if (wasFlicking && (!d->hData.flicking || !d->vData.flicking)) {
emit flickingChanged();
emit flickEnded();
+ } else if (d->hData.flickingWhenDragBegan || d->vData.flickingWhenDragBegan) {
+ d->hData.flickingWhenDragBegan = !hMovementEnding;
+ d->vData.flickingWhenDragBegan = !vMovementEnding;
+ emit flickEnded();
}
// emit moving signals
@@ -2928,6 +2972,12 @@ void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding)
if (wasMoving && !isMoving()) {
emit movingChanged();
emit movementEnded();
+#if QT_CONFIG(accessibility)
+ if (QAccessible::isActive()) {
+ QAccessibleEvent ev(this, QAccessible::ScrollingEnd);
+ QAccessible::updateAccessibility(&ev);
+ }
+#endif
}
if (hMovementEnding) {
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index ed7042ab90..04d27c0b8e 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -71,8 +71,9 @@ public:
, smoothVelocity(fp), atEnd(false), atBeginning(true)
, transitionToSet(false)
, fixingUp(false), inOvershoot(false), inRebound(false), moving(false), flicking(false)
- , dragging(false), extentsChanged(false)
+ , flickingWhenDragBegan(false), dragging(false), extentsChanged(false)
, explicitValue(false), minExtentDirty(true), maxExtentDirty(true)
+ , contentPositionChangedExternallyDuringDrag(false)
, unused(0)
{}
@@ -83,6 +84,7 @@ public:
dragStartOffset = 0;
fixingUp = false;
inOvershoot = false;
+ contentPositionChangedExternallyDuringDrag = false;
}
void markExtentsDirty() {
@@ -120,20 +122,22 @@ public:
int vTime;
QQuickFlickablePrivate::Velocity smoothVelocity;
QPODVector<qreal,10> velocityBuffer;
- bool atEnd : 1;
- bool atBeginning : 1;
- bool transitionToSet : 1;
- bool fixingUp : 1;
- bool inOvershoot : 1;
- bool inRebound : 1;
- bool moving : 1;
- bool flicking : 1;
- bool dragging : 1;
- bool extentsChanged : 1;
- bool explicitValue : 1;
- mutable bool minExtentDirty : 1;
- mutable bool maxExtentDirty : 1;
- uint unused : 19;
+ uint atEnd : 1;
+ uint atBeginning : 1;
+ uint transitionToSet : 1;
+ uint fixingUp : 1;
+ uint inOvershoot : 1;
+ uint inRebound : 1;
+ uint moving : 1;
+ uint flicking : 1;
+ uint flickingWhenDragBegan : 1;
+ uint dragging : 1;
+ uint extentsChanged : 1;
+ uint explicitValue : 1;
+ mutable uint minExtentDirty : 1;
+ mutable uint maxExtentDirty : 1;
+ uint contentPositionChangedExternallyDuringDrag : 1;
+ uint unused : 17;
};
bool flickX(qreal velocity);
diff --git a/src/quick/items/qquickflipable.cpp b/src/quick/items/qquickflipable.cpp
index d599618834..4ea085bb0c 100644
--- a/src/quick/items/qquickflipable.cpp
+++ b/src/quick/items/qquickflipable.cpp
@@ -3,7 +3,7 @@
#include "qquickflipable_p.h"
#include "qquickitem_p.h"
-
+#include "qquicktranslate_p.h"
#include <QtQml/qqmlinfo.h>
@@ -201,9 +201,20 @@ void QQuickFlipable::updatePolish()
d->updateSide();
}
-// determination on the currently visible side of the flipable
-// has to be done on the complete scene transform to give
-// correct results.
+/*! \internal
+ Flipable must use the complete scene transform to correctly determine the
+ currently visible side.
+
+ It must also be independent of camera distance, in case the contents are
+ too wide: for rotation transforms we simply call QMatrix4x4::rotate(),
+ whereas QQuickRotation::applyTo(QMatrix4x4*) calls
+ QMatrix4x4::projectedRotate() which by default assumes the camera distance
+ is 1024 virtual pixels. So for example if contents inside Flipable are to
+ be flipped around the y axis, and are wider than 1024*2, some of the
+ rendering goes behind the "camera". That's expected for rendering (since we
+ didn't provide API to change camera distance), but not ok for deciding when
+ to flip.
+*/
void QQuickFlipablePrivate::updateSide()
{
Q_Q(QQuickFlipable);
@@ -213,8 +224,39 @@ void QQuickFlipablePrivate::updateSide()
sideDirty = false;
- QTransform sceneTransform;
- itemToParentTransform(sceneTransform);
+ QMatrix4x4 sceneTransform;
+
+ const qreal tx = x.value();
+ const qreal ty = y.value();
+ if (!qFuzzyIsNull(tx) || !qFuzzyIsNull(ty))
+ sceneTransform.translate(tx, ty);
+
+ for (const auto *transform : std::as_const(transforms)) {
+ if (const auto *rot = qobject_cast<const QQuickRotation *>(transform)) {
+ // rotation is a special case: we want to call rotate() instead of projectedRotate()
+ const auto angle = rot->angle();
+ const auto axis = rot->axis();
+ if (!(qFuzzyIsNull(angle) || axis.isNull())) {
+ sceneTransform.translate(rot->origin());
+ sceneTransform.rotate(angle, axis.x(), axis.y(), axis.z());
+ sceneTransform.translate(-rot->origin());
+ }
+ } else {
+ transform->applyTo(&sceneTransform);
+ }
+ }
+
+ const bool hasRotation = !qFuzzyIsNull(rotation());
+ const bool hasScale = !qFuzzyCompare(scale(), 1);
+ if (hasScale || hasRotation) {
+ QPointF tp = computeTransformOrigin();
+ sceneTransform.translate(tp.x(), tp.y());
+ if (hasScale)
+ sceneTransform.scale(scale(), scale());
+ if (hasRotation)
+ sceneTransform.rotate(rotation(), 0, 0, 1);
+ sceneTransform.translate(-tp.x(), -tp.y());
+ }
QPointF p1(0, 0);
QPointF p2(1, 0);
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index d3dfe51d11..7f45d45708 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -462,7 +462,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
{
qreal colPos = colPosAt(visibleIndex);
qreal rowPos = rowPosAt(visibleIndex);
- if (visibleItems.count()) {
+ if (visibleItems.size()) {
FxGridItemSG *lastItem = static_cast<FxGridItemSG*>(visibleItems.constLast());
rowPos = lastItem->rowPos();
int colNum = qFloor((lastItem->colPos()+colSize()/2) / colSize());
@@ -476,7 +476,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
int modelIndex = findLastVisibleIndex();
modelIndex = modelIndex < 0 ? visibleIndex : modelIndex + 1;
- if (visibleItems.count() && (bufferFrom > rowPos + rowSize()*2
+ if (visibleItems.size() && (bufferFrom > rowPos + rowSize()*2
|| bufferTo < rowPosAt(visibleIndex) - rowSize())) {
// We've jumped more than a page. Estimate which items are now
// visible and fill from there.
@@ -520,7 +520,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
return changed;
// Find first column
- if (visibleItems.count()) {
+ if (visibleItems.size()) {
FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.constFirst());
rowPos = firstItem->rowPos();
colPos = firstItem->colPos();
@@ -569,7 +569,7 @@ bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
FxGridItemSG *item = nullptr;
bool changed = false;
- while (visibleItems.count() > 1
+ while (visibleItems.size() > 1
&& (item = static_cast<FxGridItemSG*>(visibleItems.constFirst()))
&& item->rowPos()+rowSize()-1 < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) {
if (item->attached->delayRemove())
@@ -581,12 +581,12 @@ bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
removeItem(item);
changed = true;
}
- while (visibleItems.count() > 1
+ while (visibleItems.size() > 1
&& (item = static_cast<FxGridItemSG*>(visibleItems.constLast()))
&& item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) {
if (item->attached->delayRemove())
break;
- qCDebug(lcItemViewDelegateLifecycle) << "refill: remove last" << visibleIndex+visibleItems.count()-1;
+ qCDebug(lcItemViewDelegateLifecycle) << "refill: remove last" << visibleIndex+visibleItems.size()-1;
visibleItems.removeLast();
removeItem(item);
changed = true;
@@ -603,7 +603,7 @@ void QQuickGridViewPrivate::updateViewport()
void QQuickGridViewPrivate::layoutVisibleItems(int fromModelIndex)
{
- if (visibleItems.count()) {
+ if (visibleItems.size()) {
const qreal from = isContentFlowReversed() ? -position()-displayMarginBeginning-size() : position()-displayMarginBeginning;
const qreal to = isContentFlowReversed() ? -position()+displayMarginEnd : position()+size()+displayMarginEnd;
@@ -616,7 +616,7 @@ void QQuickGridViewPrivate::layoutVisibleItems(int fromModelIndex)
firstItem->setPosition(colPos, rowPos);
}
firstItem->setVisible(firstItem->rowPos() + rowSize() >= from && firstItem->rowPos() <= to);
- for (int i = 1; i < visibleItems.count(); ++i) {
+ for (int i = 1; i < visibleItems.size(); ++i) {
FxGridItemSG *item = static_cast<FxGridItemSG*>(visibleItems.at(i));
if (++col >= columns) {
col = 0;
@@ -669,7 +669,7 @@ void QQuickGridViewPrivate::resetFirstItemPosition(qreal pos)
void QQuickGridViewPrivate::adjustFirstItem(qreal forwards, qreal backwards, int changeBeforeVisible)
{
- if (!visibleItems.count())
+ if (!visibleItems.size())
return;
int moveCount = (forwards - backwards) / rowSize();
@@ -802,7 +802,7 @@ void QQuickGridViewPrivate::updateFooter()
else
rowOffset += gridItem->item->height() - cellHeight;
}
- if (visibleItems.count()) {
+ if (visibleItems.size()) {
qreal endPos = lastPosition();
if (findLastVisibleIndex() == model->count()-1) {
gridItem->setPosition(colOffset, endPos + rowOffset);
@@ -855,7 +855,7 @@ void QQuickGridViewPrivate::updateHeader()
else
rowOffset += gridItem->item->height() - cellHeight;
}
- if (visibleItems.count()) {
+ if (visibleItems.size()) {
qreal startPos = originPosition();
if (visibleIndex == 0) {
gridItem->setPosition(colOffset, startPos + rowOffset);
@@ -2066,7 +2066,7 @@ void QQuickGridView::viewportMoved(Qt::Orientations orient)
// Set visibility of items to eliminate cost of items outside the visible area.
qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
- for (FxViewItem *item : qAsConst(d->visibleItems)) {
+ for (FxViewItem *item : std::as_const(d->visibleItems)) {
FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(item);
QQuickItemPrivate::get(gridItem->item)->setCulled(gridItem->rowPos() + d->rowSize() < from || gridItem->rowPos() > to);
}
@@ -2359,20 +2359,20 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
int modelIndex = change.index;
int count = change.count;
- int index = visibleItems.count() ? mapFromModel(modelIndex) : 0;
+ int index = visibleItems.size() ? mapFromModel(modelIndex) : 0;
if (index < 0) {
- int i = visibleItems.count() - 1;
+ int i = visibleItems.size() - 1;
while (i > 0 && visibleItems.at(i)->index == -1)
--i;
if (visibleItems.at(i)->index + 1 == modelIndex) {
// Special case of appending an item to the model.
- index = visibleItems.count();
+ index = visibleItems.size();
} else {
if (modelIndex <= visibleIndex) {
// Insert before visible items
visibleIndex += count;
- for (FxViewItem *item : qAsConst(visibleItems)) {
+ for (FxViewItem *item : std::as_const(visibleItems)) {
if (item->index != -1 && item->index >= modelIndex)
item->index += count;
}
@@ -2385,8 +2385,8 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
qreal colPos = 0;
qreal rowPos = 0;
int colNum = 0;
- if (visibleItems.count()) {
- if (index < visibleItems.count()) {
+ if (visibleItems.size()) {
+ if (index < visibleItems.size()) {
FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(visibleItems.at(index));
colPos = gridItem->colPos();
rowPos = gridItem->rowPos();
@@ -2405,7 +2405,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
}
// Update the indexes of the following visible items.
- for (FxViewItem *item : qAsConst(visibleItems)) {
+ for (FxViewItem *item : std::as_const(visibleItems)) {
if (item->index != -1 && item->index >= modelIndex) {
item->index += count;
if (change.isMove())
@@ -2415,7 +2415,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
}
}
- int prevVisibleCount = visibleItems.count();
+ int prevVisibleCount = visibleItems.size();
if (insertResult->visiblePos.isValid() && rowPos < insertResult->visiblePos) {
// Insert items before the visible item.
int insertionIdx = index;
@@ -2464,7 +2464,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
// of the index shift/update done before the insertion just above.
// Find if there is any...
int firstOkIdx = -1;
- for (int i = 0; i <= insertionIdx && i < visibleItems.count() - 1; i++) {
+ for (int i = 0; i <= insertionIdx && i < visibleItems.size() - 1; i++) {
if (visibleItems.at(i)->index + 1 != visibleItems.at(i + 1)->index) {
firstOkIdx = i + 1;
break;
@@ -2520,7 +2520,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
updateVisibleIndex();
- return visibleItems.count() > prevVisibleCount;
+ return visibleItems.size() > prevVisibleCount;
}
void QQuickGridViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult)
@@ -2529,7 +2529,7 @@ void QQuickGridViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex
return;
int markerItemIndex = -1;
- for (int i=0; i<visibleItems.count(); i++) {
+ for (int i=0; i<visibleItems.size(); i++) {
if (visibleItems.at(i)->index == afterModelIndex) {
markerItemIndex = i;
break;
@@ -2548,7 +2548,7 @@ void QQuickGridViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex
countItemsRemoved -= removalResult.countChangeAfterVisibleItems;
- for (int i=markerItemIndex+1; i<visibleItems.count(); i++) {
+ for (int i=markerItemIndex+1; i<visibleItems.size(); i++) {
FxGridItemSG *gridItem = static_cast<FxGridItemSG *>(visibleItems.at(i));
if (gridItem->position() >= viewEndPos)
break;
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index f10446b7b5..78dfecc42a 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -291,8 +291,10 @@ void QQuickImageBase::loadPixmap(const QUrl &url, LoadPixmapOptions loadOptions)
const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio());
d->devicePixelRatio = 1.0;
bool updatedDevicePixelRatio = false;
- if (d->sourcesize.isValid() || isScalableImageFormat(d->url))
+ if (d->sourcesize.isValid()
+ || (isScalableImageFormat(d->url) && d->url.scheme() != QLatin1String("image"))) {
updatedDevicePixelRatio = d->updateDevicePixelRatio(targetDevicePixelRatio);
+ }
if (!updatedDevicePixelRatio) {
// (possible) local file: loadUrl and d->devicePixelRatio will be modified if
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index dc1386fff9..b9f757dd78 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -61,6 +61,10 @@ Q_DECLARE_LOGGING_CATEGORY(lcPtr)
Q_DECLARE_LOGGING_CATEGORY(lcTransient)
Q_LOGGING_CATEGORY(lcHandlerParent, "qt.quick.handler.parent")
Q_LOGGING_CATEGORY(lcVP, "qt.quick.viewport")
+Q_LOGGING_CATEGORY(lcChangeListeners, "qt.quick.item.changelisteners")
+
+// after 100ms, a mouse/non-mouse cursor conflict is resolved in favor of the mouse handler
+static const quint64 kCursorOverrideTimeout = 100;
void debugFocusTree(QQuickItem *item, QQuickItem *scope = nullptr, int depth = 1)
{
@@ -319,6 +323,8 @@ void QQuickItemKeyFilter::shortcutOverride(QKeyEvent *event)
{
if (m_next)
m_next->shortcutOverride(event);
+ else
+ event->ignore();
}
void QQuickItemKeyFilter::componentComplete()
@@ -2614,6 +2620,12 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
\e {QObject parent}. An item's visual parent may not necessarily be the
same as its object parent. See \l {Concepts - Visual Parent in Qt Quick}
for more details.
+
+ \note The notification signal for this property gets emitted during destruction
+ of the visual parent. C++ signal handlers cannot assume that items in the
+ visual parent hierarchy are still fully constructed. Use \l qobject_cast to
+ verify that items in the parent hierarchy can be used safely as the expected
+ type.
*/
QQuickItem *QQuickItem::parentItem() const
{
@@ -3362,7 +3374,7 @@ void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
QQuickItem *quickItem = static_cast<QQuickItem *>(prop->object);
QQuickItemPrivate *quickItemPrivate = QQuickItemPrivate::get(quickItem);
if (quickItemPrivate->extra.isAllocated()) {//If extra is not allocated resources is empty.
- for (QObject *object : qAsConst(quickItemPrivate->extra->resourcesList)) {
+ for (QObject *object : std::as_const(quickItemPrivate->extra->resourcesList)) {
qmlobject_disconnect(object, QObject, SIGNAL(destroyed(QObject*)),
quickItem, QQuickItem, SLOT(_q_resourceObjectDeleted(QObject*)));
}
@@ -3890,9 +3902,23 @@ void QQuickItem::updatePolish()
{
}
+#define PRINT_LISTENERS() \
+do { \
+ qDebug().nospace() << q_func() << " (" << this \
+ << ") now has the following listeners:"; \
+ for (const auto &listener : std::as_const(changeListeners)) { \
+ const auto objectPrivate = dynamic_cast<QObjectPrivate*>(listener.listener); \
+ qDebug().nospace() << "- " << listener << " (QObject: " << (objectPrivate ? objectPrivate->q_func() : nullptr) << ")"; \
+ } \
+} \
+while (false)
+
void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
{
changeListeners.append(ChangeListener(listener, types));
+
+ if (lcChangeListeners().isDebugEnabled())
+ PRINT_LISTENERS();
}
void QQuickItemPrivate::updateOrAddItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
@@ -3903,12 +3929,18 @@ void QQuickItemPrivate::updateOrAddItemChangeListener(QQuickItemChangeListener *
changeListeners[index].types = changeListener.types;
else
changeListeners.append(changeListener);
+
+ if (lcChangeListeners().isDebugEnabled())
+ PRINT_LISTENERS();
}
void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
{
ChangeListener change(listener, types);
changeListeners.removeOne(change);
+
+ if (lcChangeListeners().isDebugEnabled())
+ PRINT_LISTENERS();
}
void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener,
@@ -3920,6 +3952,9 @@ void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListen
changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
else
changeListeners.append(change);
+
+ if (lcChangeListeners().isDebugEnabled())
+ PRINT_LISTENERS();
}
void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
@@ -3933,6 +3968,9 @@ void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeLis
if (index > -1)
changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
}
+
+ if (lcChangeListeners().isDebugEnabled())
+ PRINT_LISTENERS();
}
/*!
@@ -5192,6 +5230,13 @@ void QQuickItem::componentComplete()
d->addToDirtyList();
QQuickWindowPrivate::get(d->window)->dirtyItem(this);
}
+
+#if QT_CONFIG(accessibility)
+ if (d->isAccessible && d->effectiveVisible) {
+ QAccessibleEvent ev(this, QAccessible::ObjectShow);
+ QAccessible::updateAccessibility(&ev);
+ }
+#endif
}
QQuickStateGroup *QQuickItemPrivate::_states()
@@ -5477,9 +5522,10 @@ void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
void QQuickItemPrivate::deliverShortcutOverrideEvent(QKeyEvent *event)
{
- if (extra.isAllocated() && extra->keyHandler) {
+ if (extra.isAllocated() && extra->keyHandler)
extra->keyHandler->shortcutOverride(event);
- }
+ else
+ event->ignore();
}
bool QQuickItemPrivate::anyPointerHandlerWants(const QPointerEvent *event, const QEventPoint &point) const
@@ -5496,8 +5542,8 @@ bool QQuickItemPrivate::anyPointerHandlerWants(const QPointerEvent *event, const
/*!
\internal
Deliver the \a event to all this item's PointerHandlers, but skip
- HoverHandlers if the event is a QMouseEvent (they are visited in
- QQuickDeliveryAgentPrivate::deliverHoverEventToItem()), and skip handlers
+ HoverHandlers if the event is a QMouseEvent or QWheelEvent (they are visited
+ in QQuickDeliveryAgentPrivate::deliverHoverEventToItem()), and skip handlers
that are in QQuickPointerHandlerPrivate::deviceDeliveryTargets().
If \a avoidGrabbers is true, also skip delivery to any handler that
is exclusively or passively grabbing any point within \a event
@@ -5509,7 +5555,7 @@ bool QQuickItemPrivate::handlePointerEvent(QPointerEvent *event, bool avoidGrabb
if (extra.isAllocated()) {
for (QQuickPointerHandler *handler : extra->pointerHandlers) {
bool avoidThisHandler = false;
- if (QQuickDeliveryAgentPrivate::isMouseEvent(event) &&
+ if (QQuickDeliveryAgentPrivate::isMouseOrWheelEvent(event) &&
qmlobject_cast<const QQuickHoverHandler *>(handler)) {
avoidThisHandler = true;
} else if (avoidGrabbers) {
@@ -6247,6 +6293,12 @@ void QQuickItem::setOpacity(qreal newOpacity)
the parent's \c visible property. It does not change, for example, if this
item moves off-screen, or if the \l opacity changes to 0.
+ \note The notification signal for this property gets emitted during destruction
+ of the visual parent. C++ signal handlers cannot assume that items in the
+ visual parent hierarchy are still fully constructed. Use \l qobject_cast to
+ verify that items in the parent hierarchy can be used safely as the expected
+ type.
+
\sa opacity, enabled
*/
bool QQuickItem::isVisible() const
@@ -6305,6 +6357,15 @@ void QQuickItem::setVisible(bool v)
Setting this property to \c false automatically causes \l activeFocus to be
set to \c false, and this item will longer receive keyboard events.
+ \note Hover events are enabled separately by \l setAcceptHoverEvents().
+ Thus, a disabled item can continue to receive hover events, even when this
+ property is \c false. This makes it possible to show informational feedback
+ (such as \l ToolTip) even when an interactive item is disabled.
+ The same is also true for any \l {HoverHandlers}{QQuickHoverHandler}
+ added as children of the item. A HoverHandler can, however, be
+ \l{disabled}{QQuickHoverHandler::enabled} explicitly, or for example
+ be bound to the \c enabled state of the item.
+
\sa visible
*/
bool QQuickItem::isEnabled() const
@@ -7788,6 +7849,10 @@ void QQuickItem::setAcceptHoverEvents(bool enabled)
Q_D(QQuickItem);
d->hoverEnabled = enabled;
d->setHasHoverInChild(enabled);
+ // The DA needs to resolve which items and handlers should now be hovered or unhovered.
+ // Marking this item dirty ensures that flushFrameSynchronousEvents() will be called from the render loop,
+ // even if this change is not in response to a mouse event and no item has already marked itself dirty.
+ d->dirty(QQuickItemPrivate::Content);
}
/*!
@@ -7830,7 +7895,7 @@ void QQuickItemPrivate::setHasCursorInChild(bool hc)
if (!hc && subtreeCursorEnabled) {
if (hasCursor)
return; // nope! sorry, I have a cursor myself
- for (QQuickItem *otherChild : qAsConst(childItems)) {
+ for (QQuickItem *otherChild : std::as_const(childItems)) {
QQuickItemPrivate *otherChildPrivate = QQuickItemPrivate::get(otherChild);
if (otherChildPrivate->subtreeCursorEnabled || otherChildPrivate->hasCursor)
return; // nope! sorry, something else wants it kept on.
@@ -7857,11 +7922,14 @@ void QQuickItemPrivate::setHasHoverInChild(bool hasHover)
if (!hasHover && subtreeHoverEnabled) {
if (hoverEnabled)
return; // nope! sorry, I need hover myself
- for (QQuickItem *otherChild : qAsConst(childItems)) {
+ if (hasEnabledHoverHandlers())
+ return; // nope! sorry, this item has enabled HoverHandlers
+
+ for (QQuickItem *otherChild : std::as_const(childItems)) {
QQuickItemPrivate *otherChildPrivate = QQuickItemPrivate::get(otherChild);
if (otherChildPrivate->subtreeHoverEnabled || otherChildPrivate->hoverEnabled)
return; // nope! sorry, something else wants it kept on.
- if (otherChildPrivate->hasHoverHandlers())
+ if (otherChildPrivate->hasEnabledHoverHandlers())
return; // nope! sorry, we have pointer handlers which are interested.
}
}
@@ -7910,6 +7978,7 @@ void QQuickItem::setCursor(const QCursor &cursor)
Q_D(QQuickItem);
Qt::CursorShape oldShape = d->extra.isAllocated() ? d->extra->cursor.shape() : Qt::ArrowCursor;
+ qCDebug(lcHoverTrace) << oldShape << "->" << cursor.shape();
if (oldShape != cursor.shape() || oldShape >= Qt::LastCursor || cursor.shape() >= Qt::LastCursor) {
d->extra.value().cursor = cursor;
@@ -7946,6 +8015,7 @@ void QQuickItem::setCursor(const QCursor &cursor)
void QQuickItem::unsetCursor()
{
Q_D(QQuickItem);
+ qCDebug(lcHoverTrace) << "clearing cursor";
if (!d->hasCursor)
return;
d->hasCursor = false;
@@ -7997,27 +8067,82 @@ QCursor QQuickItemPrivate::effectiveCursor(const QQuickPointerHandler *handler)
Returns the Pointer Handler that is currently attempting to set the cursor shape,
or null if there is no such handler.
+ If there are multiple handlers attempting to set the cursor:
+ \list
+ \li an active handler has the highest priority (e.g. a DragHandler being dragged)
+ \li any HoverHandler that is reacting to a non-mouse device has priority for
+ kCursorOverrideTimeout ms (a tablet stylus is jittery so that's enough)
+ \li otherwise a HoverHandler that is reacting to the mouse, if any
+ \endlist
+
+ Within each category, if there are multiple handlers, the last-added one wins
+ (the one that is declared at the bottom wins, because users may intuitively
+ think it's "on top" even though there is no Z-order; or, one that is added
+ in a specific use case overrides an imported component).
+
\sa QtQuick::PointerHandler::cursor
*/
QQuickPointerHandler *QQuickItemPrivate::effectiveCursorHandler() const
{
if (!hasPointerHandlers())
return nullptr;
- QQuickPointerHandler *retHoverHandler = nullptr;
+ QQuickPointerHandler* activeHandler = nullptr;
+ QQuickPointerHandler* mouseHandler = nullptr;
+ QQuickPointerHandler* nonMouseHandler = 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;
+ // Prioritize any HoverHandler that is reacting to a non-mouse device.
+ // Otherwise, choose the first hovered handler that is found.
+ // TODO maybe: there was an idea to add QPointerDevice* as argument to this function
+ // and check the device type, but why? HoverHandler already does that.
+ if (!activeHandler && hoverHandler && hoverHandler->isHovered()) {
+ qCDebug(lcHoverTrace) << hoverHandler << hoverHandler->acceptedDevices() << "wants to set cursor" << hoverHandler->cursorShape();
+ if (hoverHandler->acceptedDevices().testFlag(QPointingDevice::DeviceType::Mouse)) {
+ // If there's a conflict, the last-added HoverHandler wins. Maybe the user is overriding a default...
+ if (mouseHandler && mouseHandler->cursorShape() != hoverHandler->cursorShape()) {
+ qCDebug(lcHoverTrace) << "mouse cursor conflict:" << mouseHandler << "wants" << mouseHandler->cursorShape()
+ << "but" << hoverHandler << "wants" << hoverHandler->cursorShape();
+ }
+ mouseHandler = hoverHandler;
+ } else {
+ // If there's a conflict, the last-added HoverHandler wins.
+ if (nonMouseHandler && nonMouseHandler->cursorShape() != hoverHandler->cursorShape()) {
+ qCDebug(lcHoverTrace) << "non-mouse cursor conflict:" << nonMouseHandler << "wants" << nonMouseHandler->cursorShape()
+ << "but" << hoverHandler << "wants" << hoverHandler->cursorShape();
+ }
+ nonMouseHandler = hoverHandler;
+ }
+ }
if (!hoverHandler && h->active())
- return h;
+ activeHandler = h;
+ }
+ if (activeHandler) {
+ qCDebug(lcHoverTrace) << "active handler choosing cursor" << activeHandler << activeHandler->cursorShape();
+ return activeHandler;
+ }
+ // Mouse events are often synthetic; so if a HoverHandler for a non-mouse device wanted to set the cursor,
+ // let it win, unless more than kCursorOverrideTimeout ms have passed
+ // since the last time the non-mouse handler actually reacted to an event.
+ // We could miss the fact that a tablet stylus has left proximity, because we don't deliver proximity events to windows.
+ if (nonMouseHandler) {
+ if (mouseHandler) {
+ const bool beforeTimeout =
+ QQuickPointerHandlerPrivate::get(mouseHandler)->lastEventTime <
+ QQuickPointerHandlerPrivate::get(nonMouseHandler)->lastEventTime + kCursorOverrideTimeout;
+ QQuickPointerHandler *winner = (beforeTimeout ? nonMouseHandler : mouseHandler);
+ qCDebug(lcHoverTrace) << "non-mouse handler reacted last time:" << QQuickPointerHandlerPrivate::get(nonMouseHandler)->lastEventTime
+ << "and mouse handler reacted at time:" << QQuickPointerHandlerPrivate::get(mouseHandler)->lastEventTime
+ << "choosing cursor according to" << winner << winner->cursorShape();
+ return winner;
+ }
+ qCDebug(lcHoverTrace) << "non-mouse handler choosing cursor" << nonMouseHandler << nonMouseHandler->cursorShape();
+ return nonMouseHandler;
}
- return retHoverHandler;
+ if (mouseHandler)
+ qCDebug(lcHoverTrace) << "mouse handler choosing cursor" << mouseHandler << mouseHandler->cursorShape();
+ return mouseHandler;
}
#endif
@@ -8667,18 +8792,18 @@ bool QQuickItem::event(QEvent *ev)
#endif // gestures
case QEvent::LanguageChange:
case QEvent::LocaleChange:
- for (QQuickItem *item : qAsConst(d->childItems))
+ for (QQuickItem *item : std::as_const(d->childItems))
QCoreApplication::sendEvent(item, ev);
break;
case QEvent::WindowActivate:
case QEvent::WindowDeactivate:
if (d->providesPalette())
d->setCurrentColorGroup();
- for (QQuickItem *item : qAsConst(d->childItems))
+ for (QQuickItem *item : std::as_const(d->childItems))
QCoreApplication::sendEvent(item, ev);
break;
case QEvent::ApplicationPaletteChange:
- for (QQuickItem *item : qAsConst(d->childItems))
+ for (QQuickItem *item : std::as_const(d->childItems))
QCoreApplication::sendEvent(item, ev);
break;
default:
@@ -8873,8 +8998,8 @@ void QQuickItemPrivate::localizedTouchEvent(const QTouchEvent *event, bool isFil
// So hopefully if we start from one passive grabber and go up the parent chain from there,
// we will find any filtering parent items that exist.
auto handler = qmlobject_cast<QQuickPointerHandler *>(pg.first());
- Q_ASSERT(handler);
- pointGrabber = handler->parentItem();
+ if (handler)
+ pointGrabber = handler->parentItem();
}
}
@@ -8935,12 +9060,12 @@ bool QQuickItemPrivate::hasPointerHandlers() const
return extra.isAllocated() && !extra->pointerHandlers.isEmpty();
}
-bool QQuickItemPrivate::hasHoverHandlers() const
+bool QQuickItemPrivate::hasEnabledHoverHandlers() const
{
if (!hasPointerHandlers())
return false;
for (QQuickPointerHandler *h : extra->pointerHandlers)
- if (qmlobject_cast<QQuickHoverHandler *>(h))
+ if (auto *hh = qmlobject_cast<QQuickHoverHandler *>(h); hh && hh->enabled())
return true;
return false;
}
@@ -9460,7 +9585,8 @@ void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
{
QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
- Q_ASSERT(l);
+ if (!l)
+ return;
l->setVisible(m_item->isVisible());
}
@@ -9469,21 +9595,24 @@ void QQuickItemLayer::updateZ()
if (!m_componentComplete || !m_enabled)
return;
QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
- Q_ASSERT(l);
+ if (!l)
+ return;
l->setZ(m_item->z());
}
void QQuickItemLayer::updateOpacity()
{
QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
- Q_ASSERT(l);
+ if (!l)
+ return;
l->setOpacity(m_item->opacity());
}
void QQuickItemLayer::updateGeometry()
{
QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
- Q_ASSERT(l);
+ if (!l)
+ return;
// Avoid calling QQuickImage::boundingRect() or other overrides
// which may not be up-to-date at this time (QTBUG-104442, 104536)
QRectF bounds = m_item->QQuickItem::boundingRect();
@@ -9498,7 +9627,8 @@ void QQuickItemLayer::updateMatrix()
if (!m_componentComplete || !m_enabled)
return;
QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
- Q_ASSERT(l);
+ if (!l)
+ return;
QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
l->setScale(m_item->scale());
l->setRotation(m_item->rotation());
@@ -9558,7 +9688,7 @@ void QV4::Heap::QQuickItemWrapper::markObjects(QV4::Heap::Base *that, QV4::MarkS
{
QObjectWrapper *This = static_cast<QObjectWrapper *>(that);
if (QQuickItem *item = static_cast<QQuickItem*>(This->object())) {
- for (QQuickItem *child : qAsConst(QQuickItemPrivate::get(item)->childItems))
+ for (QQuickItem *child : std::as_const(QQuickItemPrivate::get(item)->childItems))
QV4::QObjectWrapper::markWrapper(child, markStack);
}
QObjectWrapper::markObjects(that, markStack);
@@ -9569,6 +9699,13 @@ quint64 QQuickItemPrivate::_q_createJSWrapper(QV4::ExecutionEngine *engine)
return (engine->memoryManager->allocate<QQuickItemWrapper>(q_func()))->asReturnedValue();
}
+QDebug operator<<(QDebug debug, const QQuickItemPrivate::ChangeListener &listener)
+{
+ QDebugStateSaver stateSaver(debug);
+ debug.nospace() << "ChangeListener listener=" << listener.listener << " types=" << listener.types;
+ return debug;
+}
+
QT_END_NAMESPACE
#include <moc_qquickitem.cpp>
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 4e5e5bb34a..428878c45d 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -248,7 +248,7 @@ public:
void localizedTouchEvent(const QTouchEvent *event, bool isFiltering, QMutableTouchEvent *localized);
bool hasPointerHandlers() const;
- bool hasHoverHandlers() const;
+ bool hasEnabledHoverHandlers() const;
virtual void addPointerHandler(QQuickPointerHandler *h);
virtual void removePointerHandler(QQuickPointerHandler *h);
@@ -323,6 +323,11 @@ public:
QQuickItemChangeListener *listener;
ChangeTypes types;
QQuickGeometryChange gTypes; //NOTE: not used for ==
+
+#ifndef QT_NO_DEBUG_STREAM
+ private:
+ friend QDebug operator<<(QDebug debug, const QQuickItemPrivate::ChangeListener &listener);
+#endif // QT_NO_DEBUG_STREAM
};
// call QQuickItemChangeListener PMF
diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp
index 2a79908a3e..51fd2a3588 100644
--- a/src/quick/items/qquickitemanimation.cpp
+++ b/src/quick/items/qquickitemanimation.cpp
@@ -173,7 +173,7 @@ struct QQuickParentAnimationData : public QAbstractAnimationAction
QList<QQuickParentChange *> pc;
void doAction() override
{
- for (int ii = 0; ii < actions.count(); ++ii) {
+ for (int ii = 0; ii < actions.size(); ++ii) {
const QQuickStateAction &action = actions.at(ii);
if (reverse)
action.event->reverse();
@@ -329,7 +329,7 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act
}
}
- if (data->actions.count()) {
+ if (data->actions.size()) {
QSequentialAnimationGroupJob *topLevelGroup = new QSequentialAnimationGroupJob;
QActionAnimation *viaAction = d->via ? new QActionAnimation : nullptr;
QActionAnimation *targetAction = new QActionAnimation;
@@ -343,7 +343,7 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act
//take care of any child animations
bool valid = d->defaultProperty.isValid();
QAbstractAnimationJob* anim;
- for (int ii = 0; ii < d->animations.count(); ++ii) {
+ for (int ii = 0; ii < d->animations.size(); ++ii) {
if (valid)
d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
anim = d->animations.at(ii)->transition(actions, modified, direction, defaultTarget);
@@ -488,7 +488,7 @@ QAbstractAnimationJob* QQuickAnchorAnimation::transition(QQuickStateActions &act
data->fromIsSourced = false;
data->fromIsDefined = false;
- for (int ii = 0; ii < actions.count(); ++ii) {
+ for (int ii = 0; ii < actions.size(); ++ii) {
QQuickStateAction &action = actions[ii];
if (action.event && action.event->type() == QQuickStateActionEvent::AnchorChanges
&& (d->targets.isEmpty() || d->targets.contains(static_cast<QQuickAnchorChanges*>(action.event)->object()))) {
@@ -497,7 +497,7 @@ QAbstractAnimationJob* QQuickAnchorAnimation::transition(QQuickStateActions &act
}
QQuickBulkValueAnimator *animator = new QQuickBulkValueAnimator;
- if (data->actions.count()) {
+ if (data->actions.size()) {
animator->setAnimValue(data);
animator->setFromIsSourcedValue(&data->fromIsSourced);
} else {
@@ -823,9 +823,9 @@ QAbstractAnimationJob* QQuickPathAnimation::transition(QQuickStateActions &actio
data->fromIsSourced = false;
data->fromIsDefined = (d->path && d->path->hasStartX() && d->path->hasStartY()) ? true : false;
data->toIsDefined = d->path ? true : false;
- int origModifiedSize = modified.count();
+ int origModifiedSize = modified.size();
- for (int i = 0; i < actions.count(); ++i) {
+ for (int i = 0; i < actions.size(); ++i) {
QQuickStateAction &action = actions[i];
if (action.event)
continue;
@@ -841,7 +841,7 @@ QAbstractAnimationJob* QQuickPathAnimation::transition(QQuickStateActions &actio
}
}
- if (target && d->path && (modified.count() > origModifiedSize || data->toIsDefined)) {
+ if (target && d->path && (modified.size() > origModifiedSize || data->toIsDefined)) {
data->target = target;
data->path = d->path;
data->path->invalidateSequentialHistory();
diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp
index e14a4c25dd..bcd1afc19d 100644
--- a/src/quick/items/qquickitemgrabresult.cpp
+++ b/src/quick/items/qquickitemgrabresult.cpp
@@ -187,7 +187,7 @@ bool QQuickItemGrabResult::saveToFile(const QUrl &filePath) const
*/
bool QQuickItemGrabResult::saveToFile(const QString &fileName)
{
- return qAsConst(*this).saveToFile(fileName);
+ return std::as_const(*this).saveToFile(fileName);
}
#endif
#endif // < Qt 6
@@ -345,17 +345,15 @@ QSharedPointer<QQuickItemGrabResult> QQuickItem::grabToImage(const QSize &target
*
* If the grab could not be initiated, the function returns \c false.
*
- * The following snippet shows how to grab an item and store the results to
- * a file.
+ * The following snippet shows how to grab an item and store the results in
+ * a file:
*
- * \snippet qml/itemGrab.qml grab-source
- * \snippet qml/itemGrab.qml grab-to-file
+ * \snippet qml/item/itemGrab.qml grab-to-file
*
* The following snippet shows how to grab an item and use the results in
- * another image element.
+ * another image element:
*
- * \snippet qml/itemGrab.qml grab-image-target
- * \snippet qml/itemGrab.qml grab-to-cache
+ * \snippet qml/item/itemGrab.qml grab-to-image
*
* \note This function will render the item to an offscreen surface and
* copy that surface from the GPU's memory into the CPU's memory, which can
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 9cff9c4c4f..88136d7fad 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -160,4 +160,138 @@ void QQuickItemsModule::defineModule()
qt_quickitems_defineModule();
}
+/*!
+ \qmltype PointerEvent
+ \instantiates QPointerEvent
+ \inqmlmodule QtQuick
+ \brief QML equivalent for \l QPointerEvent.
+
+ PointerEvent is the QML name of the QPointerEvent class.
+*/
+
+/*!
+ \qmltype PointerDevice
+ \instantiates QPointingDevice
+ \inqmlmodule QtQuick
+ \brief QML equivalent for \l QPointingDevice.
+
+ PointerDevice is the QML name of the QPointingDevice class.
+ It has the same properties and enums as \l QPointingDevice.
+*/
+
+/*!
+ \qmlproperty enumeration PointerDevice::deviceType
+
+ This property tells the type of device that generated a PointerEvent.
+
+ Valid values are:
+
+ \value PointerDevice.Unknown The device cannot be identified.
+ \value PointerDevice.Mouse A mouse.
+ \value PointerDevice.TouchScreen A touchscreen.
+ \value PointerDevice.TouchPad A touchpad or trackpad.
+ \value PointerDevice.Stylus A stylus on a graphics tablet.
+ \value PointerDevice.Airbrush An airbrush on a graphics tablet.
+ \value PointerDevice.Puck A digitizer with crosshairs, on a graphics tablet.
+
+ \sa QInputDevice::DeviceType, PointerDeviceHandler::acceptedDevices
+*/
+
+/*!
+ \qmlproperty enumeration PointerDevice::pointerType
+
+ This property tells what is interacting with the PointerDevice.
+
+ There is some redundancy between this property and \l deviceType.
+ For example, if a touchscreen is used, then \c deviceType is
+ \c TouchScreen and \c pointerType is \c Finger. But on a graphics
+ tablet, it's often possible for both ends of the stylus to be used,
+ and programs need to distinguish them.
+ \l PointerDeviceHandler::acceptedDevices and
+ \l PointerDeviceHandler::acceptedPointerTypes can be used in combination
+ to filter the subset of events that a particular handler should react to.
+
+ Valid values are:
+
+ \value PointerDevice.Unknown The device cannot be identified.
+ \value PointerDevice.Generic A mouse or a device that emulates a mouse.
+ \value PointerDevice.Finger A finger on a touchscreen.
+ \value PointerDevice.Pen A stylus on a graphics tablet.
+ \value PointerDevice.Eraser An eraser on a graphics tablet.
+ \value PointerDevice.Cursor A digitizer with crosshairs, on a graphics tablet.
+
+ \sa QPointingDevice::PointerType, PointerDeviceHandler::acceptedPointerTypes
+*/
+
+/*!
+ \qmlproperty int PointerDevice::maximumPoints
+
+ This property tells the maximum number of simultaneous touch points
+ (fingers) that can be detected.
+*/
+
+/*!
+ \qmlproperty int PointerDevice::buttonCount
+
+ This property tells the maximum number of on-device buttons that can be
+ detected.
+*/
+
+/*!
+ \qmltype pointingDeviceUniqueId
+ \instantiates QPointingDeviceUniqueId
+ \inqmlmodule QtQuick
+ \brief QML equivalent for \l QPointingDeviceUniqueId.
+
+ pointingDeviceUniqueId is the QML name of the QPointingDeviceUniqueId class.
+*/
+
+/*!
+ \qmlproperty qint64 pointingDeviceUniqueId::numericId
+
+ This property gives the numeric ID of the \l PointerDevice, if available;
+ otherwise it is \c -1.
+*/
+
+/*!
+ \qmlproperty pointingDeviceUniqueId PointerDevice::uniqueId
+
+ This property may provide a unique ID for the device, if available. For
+ example, a graphics tablet stylus device may have a unique serial number.
+
+ \sa eventPoint, QEventPoint::uniqueId()
+*/
+
+/*!
+ \qmlsignal PointerDevice::grabChanged(QtObject grabber, enumeration transition, PointerEvent event, eventPoint point)
+
+ This signal is emitted when the \a grabber object gains or loses an
+ exclusive or passive grab of \a point during delivery of \a event.
+ The \a transition tells what happened, from the perspective of the
+ \c grabber object, which may be either an \l Item or an
+ \l {Qt Quick Input Handlers}{Input Handler}.
+
+ Valid values for \a transition are:
+
+ \value GrabExclusive
+ The \a grabber has taken primary responsibility for handling the \a point.
+ \value UngrabExclusive
+ The \a grabber has given up its previous exclusive grab.
+ \value CancelGrabExclusive
+ The exclusive grab of \a grabber has been taken over or cancelled.
+ \value GrabPassive
+ The \a grabber has acquired a passive grab, to monitor the \a point.
+ \value UngrabPassive
+ The \a grabber has given up its previous passive grab.
+ \value CancelGrabPassive
+ The previous passive grab has terminated abnormally.
+
+ \note A grab transition from one object to another results in two signals,
+ to notify that one object has lost its grab, and to notify that there is
+ another grabber. In other cases, when transitioning to or from a non-grabbing
+ state, only one signal is emitted.
+
+ \sa QPointerEvent::setExclusiveGrabber(), QPointerEvent::addPassiveGrabber(), QPointerEvent::removePassiveGrabber()
+*/
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 627ee1e933..1f3ec79190 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -964,7 +964,7 @@ void QQuickItemViewPrivate::applyPendingChanges()
int QQuickItemViewPrivate::findMoveKeyIndex(QQmlChangeSet::MoveKey key, const QVector<QQmlChangeSet::Change> &changes) const
{
- for (int i=0; i<changes.count(); i++) {
+ for (int i=0; i<changes.size(); i++) {
for (int j=changes[i].index; j<changes[i].index + changes[i].count; j++) {
if (changes[i].moveKey(j) == key)
return j;
@@ -1101,7 +1101,7 @@ void QQuickItemViewPrivate::applyDelegateChange()
void QQuickItemViewPrivate::checkVisible() const
{
int skip = 0;
- for (int i = 0; i < visibleItems.count(); ++i) {
+ for (int i = 0; i < visibleItems.size(); ++i) {
FxViewItem *item = visibleItems.at(i);
if (item->index == -1) {
++skip;
@@ -1353,7 +1353,7 @@ qreal QQuickItemView::maxYExtent() const
{
Q_D(const QQuickItemView);
if (d->layoutOrientation() == Qt::Horizontal)
- return height();
+ return QQuickFlickable::maxYExtent();
if (d->vData.maxExtentDirty) {
d->maxExtent = d->maxExtentForAxis(d->vData, false);
@@ -1381,7 +1381,7 @@ qreal QQuickItemView::maxXExtent() const
{
Q_D(const QQuickItemView);
if (d->layoutOrientation() == Qt::Vertical)
- return width();
+ return QQuickFlickable::maxXExtent();
if (d->hData.maxExtentDirty) {
d->maxExtent = d->maxExtentForAxis(d->hData, true);
@@ -1564,8 +1564,8 @@ int QQuickItemViewPrivate::findLastVisibleIndex(int defaultValue) const
}
FxViewItem *QQuickItemViewPrivate::visibleItem(int modelIndex) const {
- if (modelIndex >= visibleIndex && modelIndex < visibleIndex + visibleItems.count()) {
- for (int i = modelIndex - visibleIndex; i < visibleItems.count(); ++i) {
+ if (modelIndex >= visibleIndex && modelIndex < visibleIndex + visibleItems.size()) {
+ for (int i = modelIndex - visibleIndex; i < visibleItems.size(); ++i) {
FxViewItem *item = visibleItems.at(i);
if (item->index == modelIndex)
return item;
@@ -1580,7 +1580,7 @@ FxViewItem *QQuickItemViewPrivate::firstItemInView() const {
if (item->index != -1 && item->endPosition() > pos)
return item;
}
- return visibleItems.count() ? visibleItems.first() : 0;
+ return visibleItems.size() ? visibleItems.first() : 0;
}
int QQuickItemViewPrivate::findLastIndexInView() const
@@ -1599,9 +1599,9 @@ int QQuickItemViewPrivate::findLastIndexInView() const
// e.g. doing a removal animation
int QQuickItemViewPrivate::mapFromModel(int modelIndex) const
{
- if (modelIndex < visibleIndex || modelIndex >= visibleIndex + visibleItems.count())
+ if (modelIndex < visibleIndex || modelIndex >= visibleIndex + visibleItems.size())
return -1;
- for (int i = 0; i < visibleItems.count(); ++i) {
+ for (int i = 0; i < visibleItems.size(); ++i) {
FxViewItem *item = visibleItems.at(i);
if (item->index == modelIndex)
return i;
@@ -1682,7 +1682,7 @@ void QQuickItemViewPrivate::clear(bool onDestruction)
releaseVisibleItems(QQmlInstanceModel::NotReusable);
visibleIndex = 0;
- for (FxViewItem *item : qAsConst(releasePendingTransition)) {
+ for (FxViewItem *item : std::as_const(releasePendingTransition)) {
item->releaseAfterTransition = false;
releaseItem(item, QQmlInstanceModel::NotReusable);
}
@@ -1832,7 +1832,7 @@ void QQuickItemViewPrivate::layout()
// viewBounds contains bounds before any add/remove/move operation to the view
QRectF viewBounds(q->contentX(), q->contentY(), q->width(), q->height());
- if (!isValid() && !visibleItems.count()) {
+ if (!isValid() && !visibleItems.size()) {
clear();
setPosition(contentStartOffset());
updateViewport();
@@ -1846,7 +1846,7 @@ void QQuickItemViewPrivate::layout()
&& transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false)) {
// assume that any items moving now are moving due to the remove - if they schedule
// a different transition, that will override this one anyway
- for (int i=0; i<visibleItems.count(); i++)
+ for (int i=0; i<visibleItems.size(); i++)
visibleItems[i]->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false);
}
@@ -1866,7 +1866,7 @@ void QQuickItemViewPrivate::layout()
// Give the view one more chance to refill itself,
// in case its size is changed such that more delegates become visible after component completed
refill();
- for (FxViewItem *item : qAsConst(visibleItems)) {
+ for (FxViewItem *item : std::as_const(visibleItems)) {
if (!item->transitionScheduledOrRunning())
item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::PopulateTransition, true);
}
@@ -1903,14 +1903,14 @@ void QQuickItemViewPrivate::layout()
prepareVisibleItemTransitions();
// We cannot use iterators here as erasing from a container invalidates them.
- for (int i = 0, count = releasePendingTransition.count(); i < count;) {
+ for (int i = 0, count = releasePendingTransition.size(); i < count;) {
auto success = prepareNonVisibleItemTransition(releasePendingTransition[i], viewBounds);
// prepareNonVisibleItemTransition() may remove items while in fast flicking.
// Invisible animating items are kicked in or out the viewPort.
// Recheck count to test if the item got removed. In that case the same index points
// to a different item now.
const int old_count = count;
- count = releasePendingTransition.count();
+ count = releasePendingTransition.size();
if (old_count > count)
continue;
@@ -1923,15 +1923,18 @@ void QQuickItemViewPrivate::layout()
}
}
- for (int i=0; i<visibleItems.count(); i++)
+ for (int i=0; i<visibleItems.size(); i++)
visibleItems[i]->startTransition(transitioner);
- for (int i=0; i<releasePendingTransition.count(); i++)
+ for (int i=0; i<releasePendingTransition.size(); i++)
releasePendingTransition[i]->startTransition(transitioner);
transitioner->setPopulateTransitionEnabled(false);
transitioner->resetTargetLists();
}
+ if (!currentItem)
+ updateCurrent(currentIndex);
+
runDelayedRemoveTransition = false;
inLayout = false;
}
@@ -1949,9 +1952,9 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
updateUnrequestedIndexes();
- FxViewItem *prevVisibleItemsFirst = visibleItems.count() ? *visibleItems.constBegin() : nullptr;
+ FxViewItem *prevVisibleItemsFirst = visibleItems.size() ? *visibleItems.constBegin() : nullptr;
int prevItemCount = itemCount;
- int prevVisibleItemsCount = visibleItems.count();
+ int prevVisibleItemsCount = visibleItems.size();
bool visibleAffected = false;
bool viewportChanged = !currentChanges.pendingChanges.removes().isEmpty()
|| !currentChanges.pendingChanges.inserts().isEmpty();
@@ -1963,7 +1966,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
prevFirstItemInViewPos = prevFirstItemInView->position();
prevFirstItemInViewIndex = prevFirstItemInView->index;
}
- qreal prevVisibleItemsFirstPos = visibleItems.count() ? firstVisibleItemPosition : 0.0;
+ qreal prevVisibleItemsFirstPos = visibleItems.size() ? firstVisibleItemPosition : 0.0;
totalInsertionResult->visiblePos = prevFirstItemInViewPos;
totalRemovalResult->visiblePos = prevFirstItemInViewPos;
@@ -2016,7 +2019,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
QList<FxViewItem *> newItems;
QList<MovedItem> movingIntoView;
- for (int i=0; i<insertions.count(); i++) {
+ for (int i=0; i<insertions.size(); i++) {
bool wasEmpty = visibleItems.isEmpty();
if (applyInsertionChange(insertions[i], &insertionResult, &newItems, &movingIntoView))
visibleAffected = true;
@@ -2027,14 +2030,14 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
*totalInsertionResult += insertionResult;
// set positions correctly for the next insertion
- if (i < insertions.count() - 1) {
+ if (i < insertions.size() - 1) {
repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstItemInView, &insertionResult, &removalResult);
layoutVisibleItems(insertions[i].index);
storeFirstVisibleItemPosition();
}
itemCount += insertions[i].count;
}
- for (FxViewItem *item : qAsConst(newItems)) {
+ for (FxViewItem *item : std::as_const(newItems)) {
if (item->attached)
item->attached->emitAdd();
}
@@ -2043,7 +2046,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
// find the index it was moved from in order to set its initial position, so that we
// can transition it from this "original" position to its new position in the view
if (transitioner && transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition, true)) {
- for (const MovedItem &m : qAsConst(movingIntoView)) {
+ for (const MovedItem &m : std::as_const(movingIntoView)) {
int fromIndex = findMoveKeyIndex(m.moveKey, removals);
if (fromIndex >= 0) {
if (prevFirstItemInViewIndex >= 0 && fromIndex < prevFirstItemInViewIndex)
@@ -2099,7 +2102,7 @@ bool QQuickItemViewPrivate::applyRemovalChange(const QQmlChangeSet::Change &remo
Q_Q(QQuickItemView);
bool visibleAffected = false;
- if (visibleItems.count() && removal.index + removal.count > visibleItems.constLast()->index) {
+ if (visibleItems.size() && removal.index + removal.count > visibleItems.constLast()->index) {
if (removal.index > visibleItems.constLast()->index)
removeResult->countChangeAfterVisibleItems += removal.count;
else
@@ -2177,7 +2180,7 @@ void QQuickItemViewPrivate::repositionFirstItem(FxViewItem *prevVisibleItemsFirs
const QQmlNullableValue<qreal> prevViewPos = insertionResult->visiblePos;
// reposition visibleItems.first() correctly so that the content y doesn't jump
- if (visibleItems.count()) {
+ if (visibleItems.size()) {
if (prevVisibleItemsFirst && insertionResult->changedFirstItem)
resetFirstItemPosition(prevVisibleItemsFirstPos);
@@ -2224,7 +2227,7 @@ void QQuickItemViewPrivate::prepareVisibleItemTransitions()
// must call for every visible item to init or discard transitions
QRectF viewBounds(q->contentX(), q->contentY(), q->width(), q->height());
- for (int i=0; i<visibleItems.count(); i++)
+ for (int i=0; i<visibleItems.size(); i++)
visibleItems[i]->prepareTransition(transitioner, viewBounds);
}
@@ -2276,7 +2279,7 @@ bool QQuickItemViewPrivate::prepareNonVisibleItemTransition(FxViewItem *item, co
void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitionableItem *item)
{
- for (int i=0; i<releasePendingTransition.count(); i++) {
+ for (int i=0; i<releasePendingTransition.size(); i++) {
if (releasePendingTransition.at(i)->transitionableItem == item) {
releaseItem(releasePendingTransition.takeAt(i), reusableFlag);
return;
@@ -2296,7 +2299,7 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, QQmlIncubator::Inc
if (requestedIndex == modelIndex && incubationMode == QQmlIncubator::Asynchronous)
return nullptr;
- for (int i=0; i<releasePendingTransition.count(); i++) {
+ for (int i=0; i<releasePendingTransition.size(); i++) {
if (releasePendingTransition.at(i)->index == modelIndex
&& !releasePendingTransition.at(i)->isPendingRemoval()) {
releasePendingTransition[i]->releaseAfterTransition = false;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 9ea4624997..043c5e08d3 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -451,7 +451,7 @@ FxViewItem *QQuickListViewPrivate::itemBefore(int modelIndex) const
return nullptr;
int idx = 1;
int lastIndex = -1;
- while (idx < visibleItems.count()) {
+ while (idx < visibleItems.size()) {
FxViewItem *item = visibleItems.at(idx);
if (item->index != -1)
lastIndex = item->index;
@@ -497,7 +497,7 @@ qreal QQuickListViewPrivate::lastPosition() const
if (!visibleItems.isEmpty()) {
int invisibleCount = INT_MIN;
int delayRemovedCount = 0;
- for (int i = visibleItems.count()-1; i >= 0; --i) {
+ for (int i = visibleItems.size()-1; i >= 0; --i) {
FxViewItem *item = visibleItems.at(i);
if (item->index != -1) {
// Find the invisible count after the last visible item with known index
@@ -576,7 +576,7 @@ qreal QQuickListViewPrivate::snapPosAt(qreal pos)
{
if (FxListItemSG *snapItem = static_cast<FxListItemSG*>(snapItemAt(pos)))
return snapItem->itemPosition();
- if (visibleItems.count()) {
+ if (visibleItems.size()) {
qreal firstPos = (*visibleItems.constBegin())->position();
qreal endPos = (*(visibleItems.constEnd() - 1))->position();
if (pos < firstPos) {
@@ -593,7 +593,7 @@ FxViewItem *QQuickListViewPrivate::snapItemAt(qreal pos)
FxViewItem *snapItem = nullptr;
FxViewItem *prevItem = nullptr;
qreal prevItemSize = 0;
- for (FxViewItem *item : qAsConst(visibleItems)) {
+ for (FxViewItem *item : std::as_const(visibleItems)) {
if (item->index == -1)
continue;
@@ -721,7 +721,7 @@ bool QQuickListViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::Reu
bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer)
{
qreal itemEnd = visiblePos;
- if (visibleItems.count()) {
+ if (visibleItems.size()) {
visiblePos = (*visibleItems.constBegin())->position();
itemEnd = (*(visibleItems.constEnd() - 1))->endPosition() + spacing;
}
@@ -807,7 +807,7 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
// removed, otherwise a zero-sized item is infinitely added and removed over and
// over by refill().
int index = 0;
- while (visibleItems.count() > 1 && index < visibleItems.count()
+ while (visibleItems.size() > 1 && index < visibleItems.size()
&& (item = visibleItems.at(index)) && item->endPosition() < bufferFrom) {
if (item->attached->delayRemove())
break;
@@ -830,10 +830,10 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
}
}
- while (visibleItems.count() > 1 && (item = visibleItems.constLast()) && item->position() > bufferTo) {
+ while (visibleItems.size() > 1 && (item = visibleItems.constLast()) && item->position() > bufferTo) {
if (item->attached->delayRemove())
break;
- qCDebug(lcItemViewDelegateLifecycle) << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position() << (QObject *)(item->item);
+ qCDebug(lcItemViewDelegateLifecycle) << "refill: remove last" << visibleIndex+visibleItems.size()-1 << item->position() << (QObject *)(item->item);
visibleItems.removeLast();
removeItem(item);
changed = true;
@@ -844,7 +844,7 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
void QQuickListViewPrivate::visibleItemsChanged()
{
- if (visibleItems.count())
+ if (visibleItems.size())
visiblePos = (*visibleItems.constBegin())->position();
updateAverage();
if (currentIndex >= 0 && currentItem && !visibleItem(currentIndex)) {
@@ -874,7 +874,7 @@ void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex)
if (firstItem->section())
firstItem->setPosition(firstItem->position());
- for (int i=1; i < visibleItems.count(); ++i) {
+ for (int i=1; i < visibleItems.size(); ++i) {
FxListItemSG *item = static_cast<FxListItemSG*>(visibleItems.at(i));
if (item->index >= fromModelIndex) {
item->setPosition(pos);
@@ -884,7 +884,7 @@ void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex)
sum += item->size();
fixedCurrent = fixedCurrent || (currentItem && item->item == currentItem->item);
}
- averageSize = qRound(sum / visibleItems.count());
+ averageSize = qRound(sum / visibleItems.size());
// move current item if it is not a visible item.
if (currentIndex >= 0 && currentItem && !fixedCurrent)
@@ -929,7 +929,7 @@ void QQuickListViewPrivate::resetFirstItemPosition(qreal pos)
void QQuickListViewPrivate::adjustFirstItem(qreal forwards, qreal backwards, int)
{
- if (!visibleItems.count())
+ if (!visibleItems.size())
return;
qreal diff = forwards - backwards;
static_cast<FxListItemSG*>(visibleItems.constFirst())->setPosition(visibleItems.constFirst()->position() + diff);
@@ -1114,7 +1114,7 @@ void QQuickListViewPrivate::releaseSectionItem(QQuickItem *item)
void QQuickListViewPrivate::releaseSectionItems()
{
- for (FxViewItem *item : qAsConst(visibleItems)) {
+ for (FxViewItem *item : std::as_const(visibleItems)) {
FxListItemSG *listItem = static_cast<FxListItemSG *>(item);
if (listItem->section()) {
qreal pos = listItem->position();
@@ -1166,7 +1166,7 @@ void QQuickListViewPrivate::updateStickySections()
QQuickItem *sectionItem = nullptr;
QQuickItem *lastSectionItem = nullptr;
int index = 0;
- while (index < visibleItems.count()) {
+ while (index < visibleItems.size()) {
if (QQuickItem *section = static_cast<FxListItemSG *>(visibleItems.at(index))->section()) {
// Find the current section header and last visible section header
// and hide them if they will overlap a static section header.
@@ -1193,7 +1193,7 @@ void QQuickListViewPrivate::updateStickySections()
}
// Current section header
- if (sectionCriteria->labelPositioning() & QQuickViewSection::CurrentLabelAtStart && isValid() && visibleItems.count()) {
+ if (sectionCriteria->labelPositioning() & QQuickViewSection::CurrentLabelAtStart && isValid() && visibleItems.size()) {
if (!currentSectionItem) {
currentSectionItem = getSectionItem(currentSection);
} else if (QString::compare(currentStickySection, currentSection, Qt::CaseInsensitive)) {
@@ -1227,7 +1227,7 @@ void QQuickListViewPrivate::updateStickySections()
}
// Next section footer
- if (sectionCriteria->labelPositioning() & QQuickViewSection::NextLabelAtEnd && isValid() && visibleItems.count()) {
+ if (sectionCriteria->labelPositioning() & QQuickViewSection::NextLabelAtEnd && isValid() && visibleItems.size()) {
if (!nextSectionItem) {
nextSectionItem = getSectionItem(nextSection);
} else if (QString::compare(nextStickySection, nextSection, Qt::CaseInsensitive)) {
@@ -1274,7 +1274,7 @@ void QQuickListViewPrivate::updateSections()
QQuickListViewAttached *prevAtt = nullptr;
int prevIdx = -1;
int idx = -1;
- for (FxViewItem *item : qAsConst(visibleItems)) {
+ for (FxViewItem *item : std::as_const(visibleItems)) {
QQuickListViewAttached *attached = static_cast<QQuickListViewAttached*>(item->attached);
attached->setPrevSection(prevSection);
if (item->index != -1) {
@@ -1315,7 +1315,7 @@ void QQuickListViewPrivate::updateCurrentSection()
qreal startPos = hasStickyHeader() ? header->endPosition() : viewPos;
int index = 0;
int modelIndex = visibleIndex;
- while (index < visibleItems.count()) {
+ while (index < visibleItems.size()) {
FxViewItem *item = visibleItems.at(index);
if (item->endPosition() > startPos)
break;
@@ -1325,7 +1325,7 @@ void QQuickListViewPrivate::updateCurrentSection()
}
QString newSection = currentSection;
- if (index < visibleItems.count())
+ if (index < visibleItems.size())
newSection = visibleItems.at(index)->attached->section();
else
newSection = (*visibleItems.constBegin())->attached->section();
@@ -1344,7 +1344,7 @@ void QQuickListViewPrivate::updateCurrentSection()
qreal endPos = hasStickyFooter() ? footer->position() : viewPos + size();
if (nextSectionItem && !inlineSections)
endPos -= orient == QQuickListView::Vertical ? nextSectionItem->height() : nextSectionItem->width();
- while (index < visibleItems.count()) {
+ while (index < visibleItems.size()) {
FxListItemSG *listItem = static_cast<FxListItemSG *>(visibleItems.at(index));
if (listItem->itemPosition() >= endPos)
break;
@@ -1379,7 +1379,7 @@ void QQuickListViewPrivate::initializeCurrentItem()
// don't reposition the item if it is already in the visibleItems list
FxViewItem *actualItem = visibleItem(currentIndex);
if (!actualItem) {
- if (currentIndex == visibleIndex - 1 && visibleItems.count()) {
+ if (currentIndex == visibleIndex - 1 && visibleItems.size()) {
// We can calculate exact postion in this case
listItem->setPosition(visibleItems.constFirst()->position() - currentItem->size() - spacing);
} else {
@@ -1396,12 +1396,12 @@ void QQuickListViewPrivate::initializeCurrentItem()
void QQuickListViewPrivate::updateAverage()
{
- if (!visibleItems.count())
+ if (!visibleItems.size())
return;
qreal sum = 0.0;
- for (FxViewItem *item : qAsConst(visibleItems))
+ for (FxViewItem *item : std::as_const(visibleItems))
sum += item->size();
- averageSize = qRound(sum / visibleItems.count());
+ averageSize = qRound(sum / visibleItems.size());
}
qreal QQuickListViewPrivate::headerSize() const
@@ -1440,10 +1440,12 @@ void QQuickListViewPrivate::updateFooter()
FxListItemSG *listItem = static_cast<FxListItemSG*>(footer);
if (footerPositioning == QQuickListView::OverlayFooter) {
listItem->setPosition(isContentFlowReversed() ? -position() - footerSize() : position() + size() - footerSize());
- } else if (visibleItems.count()) {
+ } else if (visibleItems.size()) {
if (footerPositioning == QQuickListView::PullBackFooter) {
qreal viewPos = isContentFlowReversed() ? -position() : position() + size();
- qreal clampedPos = qBound(originPosition() - footerSize() + size(), listItem->position(), lastPosition());
+ // using qBound() would throw an assert here, because max < min is a valid case
+ // here, if the list's delegates do not fill the whole view
+ qreal clampedPos = qMax(originPosition() - footerSize() + size(), qMin(listItem->position(), lastPosition()));
listItem->setPosition(qBound(viewPos - footerSize(), clampedPos, viewPos));
} else {
qreal endPos = lastPosition();
@@ -1473,7 +1475,7 @@ void QQuickListViewPrivate::fixupHeader()
{
FxListItemSG *listItem = static_cast<FxListItemSG*>(header);
const bool fixingUp = (orient == QQuickListView::Vertical ? vData : hData).fixingUp;
- if (fixingUp && headerPositioning == QQuickListView::PullBackHeader && visibleItems.count()) {
+ if (fixingUp && headerPositioning == QQuickListView::PullBackHeader && visibleItems.size()) {
int fixupDura = timeline.duration();
if (fixupDura < 0)
fixupDura = fixupDuration/2;
@@ -1504,7 +1506,7 @@ void QQuickListViewPrivate::updateHeader()
FxListItemSG *listItem = static_cast<FxListItemSG*>(header);
if (headerPositioning == QQuickListView::OverlayHeader) {
listItem->setPosition(isContentFlowReversed() ? -position() - size() : position());
- } else if (visibleItems.count()) {
+ } else if (visibleItems.size()) {
const bool fixingUp = (orient == QQuickListView::Vertical ? vData : hData).fixingUp;
if (headerPositioning == QQuickListView::PullBackHeader) {
qreal headerPosition = listItem->position();
@@ -1512,7 +1514,9 @@ void QQuickListViewPrivate::updateHeader()
// Make sure the header is not shown if we absolutely do not have any plans to show it
if (fixingUp && !headerNeedsSeparateFixup)
headerPosition = viewPos - headerSize();
- qreal clampedPos = qBound(originPosition() - headerSize(), headerPosition, lastPosition() - size());
+ // using qBound() would throw an assert here, because max < min is a valid case
+ // here, if the list's delegates do not fill the whole view
+ qreal clampedPos = qMax(originPosition() - headerSize(), qMin(headerPosition, lastPosition() - size()));
listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos));
} else {
qreal startPos = originPosition();
@@ -1573,7 +1577,7 @@ void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometry
// if visibleItems.first() has resized, adjust its pos since it is used to
// position all subsequent items
- if (visibleItems.count() && item == visibleItems.constFirst()->item) {
+ if (visibleItems.size() && item == visibleItems.constFirst()->item) {
FxListItemSG *listItem = static_cast<FxListItemSG*>(visibleItems.constFirst());
if (listItem->transitionScheduledOrRunning())
return;
@@ -1619,7 +1623,7 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
}
// update footer if all visible items have been removed
- if (visibleItems.count() == 0)
+ if (visibleItems.size() == 0)
updateFooter();
correctFlick = false;
@@ -1824,15 +1828,15 @@ bool QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
return QQuickItemViewPrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity);
}
qreal maxDistance = 0;
- qreal dataValue = isContentFlowReversed() ? -data.move.value()+size() : data.move.value();
+ const qreal dataValue =
+ isContentFlowReversed() ? -data.move.value() + size() : data.move.value();
// -ve velocity means list is moving up/left
if (velocity > 0) {
if (data.move.value() < minExtent) {
if (snapMode == QQuickListView::SnapOneItem && !hData.flicking && !vData.flicking) {
- // if we've been dragged < averageSize/2 then bias towards the next item
- qreal dist = data.move.value() - data.pressPos;
- qreal bias = dist < averageSize/2 ? averageSize/2 : 0;
+ // averageSize/2 + 1 - next item
+ qreal bias = averageSize / 2 + 1 - (pressed ? data.pressPos : 0);
if (isContentFlowReversed())
bias = -bias;
data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) - bias) + highlightRangeStart;
@@ -1847,12 +1851,12 @@ bool QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
} else {
if (data.move.value() > maxExtent) {
if (snapMode == QQuickListView::SnapOneItem && !hData.flicking && !vData.flicking) {
- // if we've been dragged < averageSize/2 then bias towards the next item
- qreal dist = data.move.value() - data.pressPos;
- qreal bias = -dist < averageSize/2 ? averageSize/2 : 0;
+ // averageSize/2 + 1 - next item
+ qreal bias = averageSize / 2 + 1 - (pressed ? data.pressPos : 0);
if (isContentFlowReversed())
bias = -bias;
- data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) + bias) + highlightRangeStart;
+ data.flickTarget =
+ -snapPosAt(-(dataValue - highlightRangeStart) + bias) + highlightRangeStart;
maxDistance = qAbs(data.flickTarget - data.move.value());
velocity = -maxVelocity;
} else {
@@ -2707,7 +2711,8 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
\c section.delegate holds the delegate component for each section. The
default \l {QQuickItem::z}{stacking order} of section delegate instances
- is \c 2.
+ is \c 2. If you declare a \c required property named "section" in it,
+ that property will contain the section's title.
\c section.labelPositioning determines whether the current and/or
next section labels stick to the start/end of the view, and whether
@@ -3385,7 +3390,7 @@ void QQuickListView::viewportMoved(Qt::Orientations orient)
// Set visibility of items to eliminate cost of items outside the visible area.
qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
- for (FxViewItem *item : qAsConst(d->visibleItems)) {
+ for (FxViewItem *item : std::as_const(d->visibleItems)) {
if (item->item)
QQuickItemPrivate::get(item->item)->setCulled(item->endPosition() < from || item->position() > to);
}
@@ -3610,25 +3615,25 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
int count = change.count;
qreal tempPos = isContentFlowReversed() ? -position()-size() : position();
- int index = visibleItems.count() ? mapFromModel(modelIndex) : 0;
+ int index = visibleItems.size() ? mapFromModel(modelIndex) : 0;
qreal lastVisiblePos = buffer + displayMarginEnd + tempPos + size();
if (index < 0) {
- int i = visibleItems.count() - 1;
+ int i = visibleItems.size() - 1;
while (i > 0 && visibleItems.at(i)->index == -1)
--i;
if (i == 0 && visibleItems.constFirst()->index == -1) {
// there are no visible items except items marked for removal
- index = visibleItems.count();
+ index = visibleItems.size();
} else if (visibleItems.at(i)->index + 1 == modelIndex
&& visibleItems.at(i)->endPosition() <= lastVisiblePos) {
// Special case of appending an item to the model.
- index = visibleItems.count();
+ index = visibleItems.size();
} else {
if (modelIndex < visibleIndex) {
// Insert before visible items
visibleIndex += count;
- for (FxViewItem *item : qAsConst(visibleItems)) {
+ for (FxViewItem *item : std::as_const(visibleItems)) {
if (item->index != -1 && item->index >= modelIndex)
item->index += count;
}
@@ -3639,13 +3644,13 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
// index can be the next item past the end of the visible items list (i.e. appended)
qreal pos = 0;
- if (visibleItems.count()) {
- pos = index < visibleItems.count() ? visibleItems.at(index)->position()
+ if (visibleItems.size()) {
+ pos = index < visibleItems.size() ? visibleItems.at(index)->position()
: visibleItems.constLast()->endPosition() + spacing;
}
// Update the indexes of the following visible items.
- for (FxViewItem *item : qAsConst(visibleItems)) {
+ for (FxViewItem *item : std::as_const(visibleItems)) {
if (item->index != -1 && item->index >= modelIndex) {
item->index += count;
if (change.isMove())
@@ -3698,7 +3703,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
}
int firstOkIdx = -1;
- for (int i = 0; i <= insertionIdx && i < visibleItems.count() - 1; i++) {
+ for (int i = 0; i <= insertionIdx && i < visibleItems.size() - 1; i++) {
if (visibleItems.at(i)->index + 1 != visibleItems.at(i + 1)->index) {
firstOkIdx = i + 1;
break;
@@ -3749,13 +3754,13 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
}
it.disconnect();
- if (0 < index && index < visibleItems.count()) {
+ if (0 < index && index < visibleItems.size()) {
FxViewItem *prevItem = visibleItems.at(index - 1);
FxViewItem *item = visibleItems.at(index);
if (prevItem->index != item->index - 1) {
int i = index;
qreal prevPos = prevItem->position();
- while (i < visibleItems.count()) {
+ while (i < visibleItems.size()) {
FxListItemSG *nvItem = static_cast<FxListItemSG *>(visibleItems.takeLast());
insertResult->sizeChangesAfterVisiblePos -= nvItem->size() + spacing;
addedItems->removeOne(nvItem);
@@ -3780,7 +3785,7 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex
return;
int markerItemIndex = -1;
- for (int i=0; i<visibleItems.count(); i++) {
+ for (int i=0; i<visibleItems.size(); i++) {
if (visibleItems.at(i)->index == afterModelIndex) {
markerItemIndex = i;
break;
@@ -3793,7 +3798,7 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex
qreal sizeRemoved = -removalResult.sizeChangesAfterVisiblePos
- (removalResult.countChangeAfterVisibleItems * (averageSize + spacing));
- for (int i=markerItemIndex+1; i<visibleItems.count(); i++) {
+ for (int i=markerItemIndex+1; i<visibleItems.size(); i++) {
FxListItemSG *listItem = static_cast<FxListItemSG *>(visibleItems.at(i));
if (listItem->position() >= viewEndPos)
break;
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 7bb21a6d9d..d33e06a273 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -768,7 +768,7 @@ void QQuickLoader::componentComplete()
{
Q_D(QQuickLoader);
QQuickItem::componentComplete();
- if (active()) {
+ if (active() && (status() != Ready)) {
if (d->loadingFromSource)
d->createComponent();
d->load();
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 53ce213a3c..31c74765f7 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -24,7 +24,7 @@ DEFINE_BOOL_CONFIG_OPTION(qmlVisualTouchDebugging, QML_VISUAL_TOUCH_DEBUGGING)
Q_DECLARE_LOGGING_CATEGORY(lcHoverTrace)
QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
-: enabled(true), scrollGestureEnabled(true), hovered(false), longPress(false),
+: enabled(true), hoverEnabled(false), scrollGestureEnabled(true), hovered(false), longPress(false),
moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
propagateComposedEvents(false), overThreshold(false),
pressAndHoldInterval(-1)
@@ -117,7 +117,7 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
}
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
- for (int ii = children.count() - 1; ii >= 0; --ii) {
+ for (int ii = children.size() - 1; ii >= 0; --ii) {
QQuickItem *child = children.at(ii);
if (!child->isVisible() || !child->isEnabled())
continue;
@@ -453,6 +453,7 @@ void QQuickMouseArea::setEnabled(bool a)
Q_D(QQuickMouseArea);
if (a != d->enabled) {
d->enabled = a;
+ setAcceptHoverEvents(a && d->hoverEnabled);
emit enabledChanged();
}
}
@@ -767,7 +768,7 @@ void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event)
d->drag->setActive(false);
#endif
// If we don't accept hover, we need to reset containsMouse.
- if (!acceptHoverEvents())
+ if (!hoverEnabled())
setHovered(false);
QQuickWindow *w = window();
if (w && w->mouseGrabberItem() == this)
@@ -802,6 +803,14 @@ void QQuickMouseArea::hoverEnterEvent(QHoverEvent *event)
{
Q_D(QQuickMouseArea);
if (!d->enabled && !d->pressed) {
+ // Note: The fact that MouseArea doesn't update 'containsMouse' when it's disabled, is a
+ // legacy behavior that is different from how hover events are supposed to work; Hover
+ // events are always delivered to both enabled and disabled items (when they explicitly
+ // subscribe for them), to open up for hover effects, like showing tooltips. Because of
+ // this difference, you cannot use a MouseArea to e.g trigger a tooltop on a parent that
+ // is disabled. But since MouseArea has always worked this way, it should (probably) stay
+ // that way to avoid regressions. HoverHandlers do not suffer from this limitation, and
+ // can therefore be used as a replacement to solve such cases.
QQuickItem::hoverEnterEvent(event);
} else {
d->lastPos = event->position();
@@ -843,7 +852,7 @@ void QQuickMouseArea::hoverMoveEvent(QHoverEvent *event)
void QQuickMouseArea::hoverLeaveEvent(QHoverEvent *event)
{
Q_D(QQuickMouseArea);
- if (!d->enabled && !d->pressed)
+ if (!d->enabled && !d->pressed && !d->hovered)
QQuickItem::hoverLeaveEvent(event);
else
setHovered(false);
@@ -1030,13 +1039,43 @@ void QQuickMouseArea::itemChange(ItemChange change, const ItemChangeData &value)
Q_D(QQuickMouseArea);
switch (change) {
case ItemVisibleHasChanged:
- if (d->effectiveEnable && d->enabled && acceptHoverEvents() && d->hovered != (isVisible() && isUnderMouse())) {
- if (!d->hovered) {
- QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
- d->lastScenePos = d->window->mapFromGlobal(cursorPos.toPoint());
- d->lastPos = mapFromScene(d->lastScenePos);
+ if (d->effectiveEnable && d->enabled && hoverEnabled()
+ && d->hovered != (isVisible() && isUnderMouse())) {
+ if (d->hovered) {
+ // If hovered but no longer under the mouse then un-hover.
+ setHovered(false);
+ } else {
+ // If under the mouse but not hovered then hover the QQuickMouseArea if it is
+ // marked as a hovered item under the windows QQuickDeliveryAgentPrivate instance.
+ // This is required as this QQuickMouseArea may be masked by another hoverable
+ // QQuickMouseArea higher up in the scenes z-index ordering.
+ QPointF globalPos{ QGuiApplicationPrivate::lastCursorPosition.toPoint() };
+ QPointF scenePos{ d->window->mapFromGlobal(globalPos) };
+
+ QQuickWindowPrivate *wd = QQuickWindowPrivate::get(d->window);
+ QQuickDeliveryAgentPrivate *dap = wd->deliveryAgentPrivate();
+
+ // If the QQuickDeliveryAgentPrivate has not already found a hovered leaf
+ // item then attempt to find one.
+ if (!dap->hoveredLeafItemFound) {
+ dap->deliverHoverEvent(scenePos, scenePos, Qt::NoModifier,
+ QDateTime::currentSecsSinceEpoch());
+ }
+
+ // Now if the QQuickDeliveryAgentPrivate has found a hovered leaf item check
+ // that this QQuickMouseArea item was one of the hovered items.
+ if (dap->hoveredLeafItemFound) {
+ for (auto hoverItem : dap->hoverItems) {
+ if (hoverItem.first == this) {
+ // Found a match so update the hover state.
+ d->lastScenePos = scenePos;
+ d->lastPos = mapFromScene(d->lastScenePos);
+ setHovered(true);
+ break;
+ }
+ }
+ }
}
- setHovered(!d->hovered);
}
if (d->pressed && (!isVisible())) {
// This happens when the mouse area sets itself disabled or hidden
@@ -1065,15 +1104,18 @@ void QQuickMouseArea::itemChange(ItemChange change, const ItemChangeData &value)
*/
bool QQuickMouseArea::hoverEnabled() const
{
- return acceptHoverEvents();
+ return d_func()->hoverEnabled;
}
void QQuickMouseArea::setHoverEnabled(bool h)
{
- if (h == acceptHoverEvents())
+ Q_D(QQuickMouseArea);
+ if (h == d->hoverEnabled)
return;
- setAcceptHoverEvents(h);
+ d->hoverEnabled = h;
+ setAcceptHoverEvents(h && d->enabled);
+
emit hoverEnabledChanged();
}
@@ -1082,8 +1124,10 @@ void QQuickMouseArea::setHoverEnabled(bool h)
\qmlproperty bool QtQuick::MouseArea::containsMouse
This property holds whether the mouse is currently inside the mouse area.
- \warning If hoverEnabled is false, containsMouse will only be valid
+ \warning If hoverEnabled is \c false, \c containsMouse will be \c true
when the mouse is pressed while the mouse cursor is inside the MouseArea.
+ But if you set \c {mouse.accepted = false} in an \c onPressed handler,
+ \c containsMouse will remain \c false because the press was rejected.
*/
bool QQuickMouseArea::hovered() const
{
@@ -1193,6 +1237,8 @@ bool QQuickMouseArea::setPressed(Qt::MouseButton button, bool p, Qt::MouseEventS
if (!me.isAccepted()) {
d->pressed = Qt::NoButton;
+ if (!hoverEnabled())
+ setHovered(false);
}
if (!oldPressed) {
diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h
index 25287671a2..ede16e110b 100644
--- a/src/quick/items/qquickmousearea_p_p.h
+++ b/src/quick/items/qquickmousearea_p_p.h
@@ -51,6 +51,7 @@ public:
#endif
bool enabled : 1;
+ bool hoverEnabled : 1;
bool scrollGestureEnabled : 1;
bool hovered : 1;
bool longPress : 1;
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index d594861ee7..fc994fd18c 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -419,7 +419,7 @@ QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent)
QQuickMultiPointTouchArea::~QQuickMultiPointTouchArea()
{
clearTouchLists();
- for (QObject *obj : qAsConst(_touchPoints)) {
+ for (QObject *obj : std::as_const(_touchPoints)) {
QQuickTouchPoint *dtp = static_cast<QQuickTouchPoint*>(obj);
if (!dtp->isQmlDefined())
delete dtp;
@@ -578,9 +578,9 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event, RemapEventPoints
break;
}
- int numTouchPoints = touchPoints.count();
+ int numTouchPoints = touchPoints.size();
//always remove released touches, and make sure we handle all releases before adds.
- for (const QEventPoint &p : qAsConst(touchPoints)) {
+ for (const QEventPoint &p : std::as_const(touchPoints)) {
QEventPoint::State touchPointState = p.state();
int id = p.id();
if (touchPointState & QEventPoint::State::Released) {
@@ -625,7 +625,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event, RemapEventPoints
if (!_stealMouse /* !ignoring gesture*/) {
bool offerGrab = false;
const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
- for (const QEventPoint &p : qAsConst(touchPoints)) {
+ for (const QEventPoint &p : std::as_const(touchPoints)) {
if (p.state() == QEventPoint::State::Released)
continue;
const QPointF &currentPos = p.scenePosition();
@@ -659,7 +659,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event, RemapEventPoints
void QQuickMultiPointTouchArea::clearTouchLists()
{
- for (QObject *obj : qAsConst(_releasedTouchPoints)) {
+ for (QObject *obj : std::as_const(_releasedTouchPoints)) {
QQuickTouchPoint *dtp = static_cast<QQuickTouchPoint*>(obj);
if (!dtp->isQmlDefined()) {
_touchPoints.remove(dtp->pointId());
@@ -676,7 +676,7 @@ void QQuickMultiPointTouchArea::clearTouchLists()
void QQuickMultiPointTouchArea::addTouchPoint(const QEventPoint *p)
{
QQuickTouchPoint *dtp = nullptr;
- for (QQuickTouchPoint* tp : qAsConst(_touchPrototypes)) {
+ for (QQuickTouchPoint* tp : std::as_const(_touchPrototypes)) {
if (!tp->inUse()) {
tp->setInUse(true);
dtp = tp;
@@ -696,7 +696,7 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QEventPoint *p)
void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e)
{
QQuickTouchPoint *dtp = nullptr;
- for (QQuickTouchPoint *tp : qAsConst(_touchPrototypes)) {
+ for (QQuickTouchPoint *tp : std::as_const(_touchPrototypes)) {
if (!tp->inUse()) {
tp->setInUse(true);
dtp = tp;
@@ -743,7 +743,7 @@ void QQuickMultiPointTouchArea::setTouchEventsEnabled(bool enable)
void QQuickMultiPointTouchArea::addTouchPrototype(QQuickTouchPoint *prototype)
{
- int id = _touchPrototypes.count();
+ int id = _touchPrototypes.size();
prototype->setPointId(id);
_touchPrototypes.insert(id, prototype);
}
@@ -796,7 +796,7 @@ void QQuickMultiPointTouchArea::mousePressEvent(QMouseEvent *event)
if (event->source() != Qt::MouseEventNotSynthesized && event->source() != Qt::MouseEventSynthesizedByQt)
return;
- if (_touchPoints.count() >= _minimumTouchPoints - 1 && _touchPoints.count() < _maximumTouchPoints) {
+ if (_touchPoints.size() >= _minimumTouchPoints - 1 && _touchPoints.size() < _maximumTouchPoints) {
updateTouchData(event);
}
}
@@ -844,13 +844,13 @@ void QQuickMultiPointTouchArea::ungrab(bool normalRelease)
if (!normalRelease)
ungrabTouchPoints();
- if (_touchPoints.count()) {
- for (QObject *obj : qAsConst(_touchPoints))
+ if (_touchPoints.size()) {
+ for (QObject *obj : std::as_const(_touchPoints))
static_cast<QQuickTouchPoint*>(obj)->setPressed(false);
if (!normalRelease)
emit canceled(_touchPoints.values());
clearTouchLists();
- for (QObject *obj : qAsConst(_touchPoints)) {
+ for (QObject *obj : std::as_const(_touchPoints)) {
QQuickTouchPoint *dtp = static_cast<QQuickTouchPoint*>(obj);
if (!dtp->isQmlDefined())
delete dtp;
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index f6d2886716..f92705f28e 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -210,7 +210,7 @@ public:
static qsizetype touchPoint_count(QQmlListProperty<QQuickTouchPoint> *list) {
QQuickMultiPointTouchArea *q = static_cast<QQuickMultiPointTouchArea*>(list->object);
- return q->_touchPrototypes.count();
+ return q->_touchPrototypes.size();
}
static QQuickTouchPoint* touchPoint_at(QQmlListProperty<QQuickTouchPoint> *list, qsizetype index) {
diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp
index 83eb88ff3e..d363fbcd31 100644
--- a/src/quick/items/qquickpainteditem.cpp
+++ b/src/quick/items/qquickpainteditem.cpp
@@ -47,6 +47,8 @@ public:
\note It important to understand the performance implications such items
can incur. See QQuickPaintedItem::RenderTarget and
QQuickPaintedItem::renderTarget.
+
+ \sa {Scene Graph - Painted Item}, {Writing QML Extensions with C++}
*/
/*!
diff --git a/src/quick/items/qquickpalette.cpp b/src/quick/items/qquickpalette.cpp
index 9a72807fe1..d8d01a7588 100644
--- a/src/quick/items/qquickpalette.cpp
+++ b/src/quick/items/qquickpalette.cpp
@@ -33,7 +33,7 @@ static constexpr bool is_valid(QPalette::ColorGroup cg) noexcept
\internal
\class QQuickPalette
- \brief The QQuickPalette class contains color groups for each QML item state.
+ \brief Contains color groups for each QML item state.
\inmodule QtQuick
\since 6.0
@@ -48,7 +48,7 @@ static constexpr bool is_valid(QPalette::ColorGroup cg) noexcept
\inherits QQuickColorGroup
\inqmlmodule QtQuick
\ingroup qtquick-visual
- \brief The QQuickPalette class contains color groups for each QML item state.
+ \brief Contains color groups for each QML item state.
A palette consists of three color groups: Active, Disabled, and Inactive.
Active color group is the default group, its colors are used for other groups
@@ -108,7 +108,7 @@ static constexpr bool is_valid(QPalette::ColorGroup cg) noexcept
*/
/*!
- \qmlproperty QQuickColorGroup QtQuick::Palette::active
+ \qmlproperty ColorGroup QtQuick::Palette::active
The Active group is used for windows that are in focus.
@@ -116,7 +116,7 @@ static constexpr bool is_valid(QPalette::ColorGroup cg) noexcept
*/
/*!
- \qmlproperty QQuickColorGroup QtQuick::Palette::inactive
+ \qmlproperty ColorGroup QtQuick::Palette::inactive
The Inactive group is used for windows that have no keyboard focus.
@@ -124,7 +124,7 @@ static constexpr bool is_valid(QPalette::ColorGroup cg) noexcept
*/
/*!
- \qmlproperty QQuickColorGroup QtQuick::Palette::disabled
+ \qmlproperty ColorGroup QtQuick::Palette::disabled
The Disabled group is used for elements that are disabled for some reason.
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 3b4ced67c3..3e30f410f0 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -210,10 +210,10 @@ void QQuickPathViewPrivate::clear()
currentItem = nullptr;
}
- for (QQuickItem *p : qAsConst(items))
+ for (QQuickItem *p : std::as_const(items))
releaseItem(p);
- for (QQuickItem *p : qAsConst(itemCache))
+ for (QQuickItem *p : std::as_const(itemCache))
releaseItem(p);
if (requestedIndex >= 0) {
@@ -386,7 +386,7 @@ void QQuickPathViewPrivate::setHighlightPosition(qreal pos)
void QQuickPathView::pathUpdated()
{
Q_D(QQuickPathView);
- for (QQuickItem *item : qAsConst(d->items)) {
+ for (QQuickItem *item : std::as_const(d->items)) {
if (QQuickPathViewAttached *att = d->attached(item))
att->m_percent = -1;
}
@@ -1619,21 +1619,21 @@ void QQuickPathView::mousePressEvent(QMouseEvent *event)
void QQuickPathViewPrivate::handleMousePressEvent(QMouseEvent *event)
{
Q_Q(QQuickPathView);
- if (!interactive || !items.count() || !model || !modelCount)
+ if (!interactive || !items.size() || !model || !modelCount)
return;
velocityBuffer.clear();
int idx = 0;
- for (; idx < items.count(); ++idx) {
+ for (; idx < items.size(); ++idx) {
QQuickItem *item = items.at(idx);
if (item->contains(item->mapFromScene(event->scenePosition())))
break;
}
- if (idx == items.count() && qFuzzyIsNull(dragMargin)) // didn't click on an item
+ if (idx == items.size() && qFuzzyIsNull(dragMargin)) // didn't click on an item
return;
startPoint = pointNear(event->position(), &startPc);
startPos = event->position();
- if (idx == items.count()) {
+ if (idx == items.size()) {
qreal distance = qAbs(event->position().x() - startPoint.x()) + qAbs(event->position().y() - startPoint.y());
if (distance > dragMargin)
return;
@@ -1978,7 +1978,7 @@ void QQuickPathView::refill()
bool waiting = false;
if (d->modelCount) {
// add items as needed
- if (d->items.count() < count+d->cacheSize) {
+ if (d->items.size() < count+d->cacheSize) {
int endIdx = 0;
qreal endPos;
int startIdx = 0;
@@ -1989,7 +1989,7 @@ void QQuickPathView::refill()
endPos = -1;
startPos = 2;
- for (QQuickItem * item : qAsConst(d->items)) {
+ for (QQuickItem * item : std::as_const(d->items)) {
int idx = d->model->indexOf(item, nullptr);
qreal curPos = d->positionOfIndex(idx);
if (curPos > endPos) {
@@ -2016,9 +2016,9 @@ void QQuickPathView::refill()
if (idx >= d->modelCount)
idx = 0;
qreal nextPos = d->positionOfIndex(idx);
- while ((d->isInBound(nextPos, endPos, 1 + d->mappedCache) || !d->items.count())
- && d->items.count() < count+d->cacheSize) {
- qCDebug(lcItemViewDelegateLifecycle) << "append" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
+ while ((d->isInBound(nextPos, endPos, 1 + d->mappedCache) || !d->items.size())
+ && d->items.size() < count+d->cacheSize) {
+ qCDebug(lcItemViewDelegateLifecycle) << "append" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.size();
QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1);
if (!item) {
waiting = true;
@@ -2049,8 +2049,8 @@ void QQuickPathView::refill()
idx = d->modelCount - 1;
nextPos = d->positionOfIndex(idx);
while (!waiting && d->isInBound(nextPos, d->mappedRange - d->mappedCache, startPos)
- && d->items.count() < count+d->cacheSize) {
- qCDebug(lcItemViewDelegateLifecycle) << "prepend" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
+ && d->items.size() < count+d->cacheSize) {
+ qCDebug(lcItemViewDelegateLifecycle) << "prepend" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.size();
QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1);
if (!item) {
waiting = true;
@@ -2078,8 +2078,8 @@ void QQuickPathView::refill()
// new items appear in the middle. This more generic addition iteration handles this
// Since this is the rare case, we try append/prepend first and only do this if
// there are gaps still left to fill.
- if (!waiting && d->items.count() < count+d->cacheSize) {
- qCDebug(lcItemViewDelegateLifecycle) << "Checking for pathview middle inserts, items count was" << d->items.count();
+ if (!waiting && d->items.size() < count+d->cacheSize) {
+ qCDebug(lcItemViewDelegateLifecycle) << "Checking for pathview middle inserts, items count was" << d->items.size();
idx = startIdx;
QQuickItem *lastItem = d->items.at(0);
while (idx != endIdx) {
@@ -2095,7 +2095,7 @@ void QQuickPathView::refill()
if (!d->items.contains(item)) { //We found a hole
qCDebug(lcItemViewDelegateLifecycle) << "middle insert" << idx << "@" << nextPos
<< (d->currentIndex == idx ? "current" : "")
- << "items count was" << d->items.count();
+ << "items count was" << d->items.size();
if (d->currentIndex == idx) {
currentVisible = true;
d->currentItemOffset = nextPos;
@@ -2149,7 +2149,7 @@ void QQuickPathView::refill()
if (QQuickPathViewAttached *att = d->attached(d->highlightItem))
att->setOnPath(currentVisible);
}
- for (QQuickItem *item : qAsConst(d->itemCache))
+ for (QQuickItem *item : std::as_const(d->itemCache))
d->releaseItem(item);
d->itemCache.clear();
@@ -2235,7 +2235,7 @@ void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
d->items.clear();
if (!d->modelCount) {
- for (QQuickItem * item : qAsConst(d->itemCache))
+ for (QQuickItem * item : std::as_const(d->itemCache))
d->releaseItem(item);
d->itemCache.clear();
d->offset = 0;
@@ -2288,7 +2288,7 @@ void QQuickPathView::movementEnding()
int QQuickPathViewPrivate::calcCurrentIndex()
{
int current = 0;
- if (modelCount && model && items.count()) {
+ if (modelCount && model && items.size()) {
offset = std::fmod(offset, qreal(modelCount));
if (offset < 0)
offset += modelCount;
@@ -2305,7 +2305,7 @@ void QQuickPathViewPrivate::createCurrentItem()
return;
bool inItems = false;
- for (QQuickItem *item : qAsConst(items)) {
+ for (QQuickItem *item : std::as_const(items)) {
if (model->indexOf(item, nullptr) == currentIndex) {
inItems = true;
break;
@@ -2360,7 +2360,7 @@ void QQuickPathViewPrivate::fixOffsetCallback(void *d)
void QQuickPathViewPrivate::fixOffset()
{
Q_Q(QQuickPathView);
- if (model && items.count()) {
+ if (model && items.size()) {
if (haveHighlightRange && (highlightRangeMode == QQuickPathView::StrictlyEnforceRange
|| snapMode != QQuickPathView::NoSnap)) {
int curr = calcCurrentIndex();
diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp
index 02086bc4bd..d547fae6c9 100644
--- a/src/quick/items/qquickpincharea.cpp
+++ b/src/quick/items/qquickpincharea.cpp
@@ -324,7 +324,7 @@ void QQuickPinchArea::touchEvent(QTouchEvent *event)
void QQuickPinchArea::clearPinch(QTouchEvent *event)
{
Q_D(QQuickPinchArea);
- qCDebug(lcPA, "clear: %" PRIdQSIZETYPE " touchpoints", d->touchPoints.count());
+ qCDebug(lcPA, "clear: %" PRIdQSIZETYPE " touchpoints", d->touchPoints.size());
d->touchPoints.clear();
if (d->inPinch) {
d->inPinch = false;
@@ -354,12 +354,13 @@ void QQuickPinchArea::clearPinch(QTouchEvent *event)
}
}
setKeepTouchGrab(false);
+ setKeepMouseGrab(false);
}
void QQuickPinchArea::cancelPinch(QTouchEvent *event)
{
Q_D(QQuickPinchArea);
- qCDebug(lcPA, "cancel: %" PRIdQSIZETYPE " touchpoints", d->touchPoints.count());
+ qCDebug(lcPA, "cancel: %" PRIdQSIZETYPE " touchpoints", d->touchPoints.size());
d->touchPoints.clear();
if (d->inPinch) {
d->inPinch = false;
@@ -395,15 +396,17 @@ void QQuickPinchArea::cancelPinch(QTouchEvent *event)
event->setExclusiveGrabber(point, nullptr);
}
setKeepTouchGrab(false);
+ setKeepMouseGrab(false);
}
void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering)
{
Q_D(QQuickPinchArea);
- if (d->touchPoints.count() < 2) {
+ if (d->touchPoints.size() < 2) {
// A pinch gesture is not occurring, so stealing the grab is permitted.
setKeepTouchGrab(false);
+ setKeepMouseGrab(false);
// During filtering, there's no need to hold a grab for one point,
// because filtering happens for every event anyway.
// But if we receive the event via direct delivery, and give up the grab,
@@ -414,7 +417,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering)
event->setExclusiveGrabber(d->touchPoints.first(), nullptr);
}
- if (d->touchPoints.count() == 0) {
+ if (d->touchPoints.size() == 0) {
if (d->inPinch) {
d->inPinch = false;
QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
@@ -427,6 +430,8 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering)
pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
pe.setPoint1(mapFromScene(d->lastPoint1));
pe.setPoint2(mapFromScene(d->lastPoint2));
+ setKeepTouchGrab(false);
+ setKeepMouseGrab(false);
emit pinchFinished(&pe);
d->pinchStartDist = 0;
d->pinchActivated = false;
@@ -439,7 +444,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering)
}
QEventPoint touchPoint1 = d->touchPoints.at(0);
- QEventPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);
+ QEventPoint touchPoint2 = d->touchPoints.at(d->touchPoints.size() >= 2 ? 1 : 0);
if (touchPoint1.state() == QEventPoint::State::Pressed)
d->sceneStartPoint1 = touchPoint1.scenePosition();
@@ -453,7 +458,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering)
// Pinch is not started unless there are exactly two touch points
// AND one or more of the points has just now been pressed (wasn't pressed already)
// AND both points are inside the bounds.
- if (d->touchPoints.count() == 2
+ if (d->touchPoints.size() == 2
&& (touchPoint1.state() == QEventPoint::State::Pressed || touchPoint2.state() == QEventPoint::State::Pressed) &&
bounds.contains(touchPoint1.position()) && bounds.contains(touchPoint2.position())) {
d->id1 = touchPoint1.id();
@@ -463,6 +468,8 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering)
d->initPinch = true;
event->setExclusiveGrabber(touchPoint1, this);
event->setExclusiveGrabber(touchPoint2, this);
+ setKeepTouchGrab(true);
+ setKeepMouseGrab(true);
}
if (d->pinchActivated && !d->pinchRejected) {
const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
@@ -473,7 +480,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering)
qreal dist = qSqrt(dx*dx + dy*dy);
QPointF sceneCenter = (p1 + p2)/2;
qreal angle = QLineF(p1, p2).angle();
- if (d->touchPoints.count() == 1) {
+ if (d->touchPoints.size() == 1) {
// If we only have one point then just move the center
if (d->id1 == touchPoint1.id())
sceneCenter = d->sceneLastCenter + touchPoint1.scenePosition() - d->lastPoint1;
@@ -487,7 +494,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering)
qCDebug(lcPA, "pinch \u2316 %.1lf,%.1lf \u21e4%.1lf\u21e5 \u2220 %.1lf",
sceneCenter.x(), sceneCenter.y(), dist, angle);
if (!d->inPinch || d->initPinch) {
- if (d->touchPoints.count() >= 2) {
+ if (d->touchPoints.size() >= 2) {
if (d->initPinch) {
if (!d->inPinch)
d->pinchStartDist = dist;
@@ -518,13 +525,16 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering)
pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
pe.setPoint1(mapFromScene(d->lastPoint1));
pe.setPoint2(mapFromScene(d->lastPoint2));
- pe.setPointCount(d->touchPoints.count());
+ pe.setPointCount(d->touchPoints.size());
emit pinchStarted(&pe);
if (pe.accepted()) {
d->inPinch = true;
event->setExclusiveGrabber(touchPoint1, this);
event->setExclusiveGrabber(touchPoint2, this);
setKeepTouchGrab(true);
+ // So that PinchArea works in PathView, grab mouse events too.
+ // We should be able to remove these setKeepMouseGrab calls when QTBUG-105567 is fixed.
+ setKeepMouseGrab(true);
d->inPinch = true;
if (d->pinch && d->pinch->target()) {
auto targetParent = pinch()->target()->parentItem();
@@ -558,7 +568,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering)
pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
pe.setPoint1(touchPoint1.position());
pe.setPoint2(touchPoint2.position());
- pe.setPointCount(d->touchPoints.count());
+ pe.setPointCount(d->touchPoints.size());
d->pinchLastScale = scale;
d->sceneLastCenter = sceneCenter;
d->pinchLastAngle = angle;
diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp
index f7eca278ea..5bb1f4f6d9 100644
--- a/src/quick/items/qquickpositioners.cpp
+++ b/src/quick/items/qquickpositioners.cpp
@@ -223,7 +223,7 @@ void QQuickBasePositioner::componentComplete()
QQuickItem::componentComplete();
if (d->transitioner)
d->transitioner->setPopulateTransitionEnabled(true);
- positionedItems.reserve(childItems().count());
+ positionedItems.reserve(childItems().size());
prePositioning();
if (d->transitioner)
d->transitioner->setPopulateTransitionEnabled(false);
@@ -277,7 +277,7 @@ void QQuickBasePositioner::prePositioning()
unpositionedItems.clear();
int addedIndex = -1;
- for (int ii = 0; ii < children.count(); ++ii) {
+ for (int ii = 0; ii < children.size(); ++ii) {
QQuickItem *child = children.at(ii);
if (QQuickItemPrivate::get(child)->isTransparentForPositioner())
continue;
diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp
index 499856a3d2..7037526264 100644
--- a/src/quick/items/qquickrectangle.cpp
+++ b/src/quick/items/qquickrectangle.cpp
@@ -542,8 +542,13 @@ QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
if (d->pen && d->pen->isValid()) {
rectangle->setPenColor(d->pen->color());
- rectangle->setPenWidth(d->pen->width());
- rectangle->setAligned(d->pen->pixelAligned());
+ qreal penWidth = d->pen->width();
+ if (d->pen->pixelAligned()) {
+ qreal dpr = window() ? window()->effectiveDevicePixelRatio() : 1.0;
+ penWidth = qRound(penWidth * dpr) / dpr; // Ensures integer width after dpr scaling
+ }
+ rectangle->setPenWidth(penWidth);
+ rectangle->setAligned(false); // width rounding already done, so the Node should not do it
} else {
rectangle->setPenWidth(0);
}
diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
index b12667776c..62cfea12e3 100644
--- a/src/quick/items/qquickrendercontrol.cpp
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -193,7 +193,7 @@ void QQuickRenderControlPrivate::windowDestroyed()
QQuickWindowPrivate::get(window)->animationController.reset();
#if QT_CONFIG(quick_shadereffect)
- QSGRhiShaderEffectNode::cleanupMaterialTypeCache();
+ QSGRhiShaderEffectNode::cleanupMaterialTypeCache(window);
#endif
window = nullptr;
}
@@ -509,7 +509,7 @@ void QQuickRenderControlPrivate::maybeUpdate()
Reimplemented in subclasses to return the real window this render control
is rendering into.
- If \a offset in non-null, it is set to the offset of the control
+ If \a offset is non-null, it is set to the offset of the control
inside the window.
\note While not mandatory, reimplementing this function becomes essential for
@@ -521,7 +521,7 @@ void QQuickRenderControlPrivate::maybeUpdate()
/*!
Returns the real window that \a win is being rendered to, if any.
- If \a offset in non-null, it is set to the offset of the rendering
+ If \a offset is non-null, it is set to the offset of the rendering
inside its window.
*/
diff --git a/src/quick/items/qquickrendertarget.cpp b/src/quick/items/qquickrendertarget.cpp
index e29e8839ba..460ce7335f 100644
--- a/src/quick/items/qquickrendertarget.cpp
+++ b/src/quick/items/qquickrendertarget.cpp
@@ -591,6 +591,8 @@ QQuickRenderTarget QQuickRenderTarget::fromRhiRenderTarget(QRhiRenderTarget *ren
\note The QQuickRenderTarget does not take ownship of \a device, it is the
caller's responsibility to ensure the object exists as long as necessary.
+ \since 6.4
+
\sa QQuickWindow::setRenderTarget(), QQuickRenderControl
*/
QQuickRenderTarget QQuickRenderTarget::fromPaintDevice(QPaintDevice *device)
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index 811ea316fc..2c892a596c 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -297,7 +297,7 @@ int QQuickRepeater::count() const
QQuickItem *QQuickRepeater::itemAt(int index) const
{
Q_D(const QQuickRepeater);
- if (index >= 0 && index < d->deletables.count())
+ if (index >= 0 && index < d->deletables.size())
return d->deletables[index];
return nullptr;
}
@@ -329,14 +329,14 @@ void QQuickRepeater::clear()
if (d->model) {
// We remove in reverse order deliberately; so that signals are emitted
// with sensible indices.
- for (int i = d->deletables.count() - 1; i >= 0; --i) {
+ for (int i = d->deletables.size() - 1; i >= 0; --i) {
if (QQuickItem *item = d->deletables.at(i)) {
if (complete)
emit itemRemoved(i, item);
d->model->release(item);
}
}
- for (QQuickItem *item : qAsConst(d->deletables)) {
+ for (QQuickItem *item : std::as_const(d->deletables)) {
if (item)
item->setParentItem(nullptr);
}
@@ -441,8 +441,8 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
int difference = 0;
QHash<int, QVector<QPointer<QQuickItem> > > moved;
for (const QQmlChangeSet::Change &remove : changeSet.removes()) {
- int index = qMin(remove.index, d->deletables.count());
- int count = qMin(remove.index + remove.count, d->deletables.count()) - index;
+ int index = qMin(remove.index, d->deletables.size());
+ int count = qMin(remove.index + remove.count, d->deletables.size()) - index;
if (remove.isMove()) {
moved.insert(remove.moveId, d->deletables.mid(index, count));
d->deletables.erase(
@@ -463,16 +463,16 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
}
for (const QQmlChangeSet::Change &insert : changeSet.inserts()) {
- int index = qMin(insert.index, d->deletables.count());
+ int index = qMin(insert.index, d->deletables.size());
if (insert.isMove()) {
QVector<QPointer<QQuickItem> > items = moved.value(insert.moveId);
d->deletables = d->deletables.mid(0, index) + items + d->deletables.mid(index);
- QQuickItem *stackBefore = index + items.count() < d->deletables.count()
- ? d->deletables.at(index + items.count())
+ QQuickItem *stackBefore = index + items.size() < d->deletables.size()
+ ? d->deletables.at(index + items.size())
: this;
if (stackBefore) {
- for (int i = index; i < index + items.count(); ++i) {
- if (i < d->deletables.count()) {
+ for (int i = index; i < index + items.size(); ++i) {
+ if (i < d->deletables.size()) {
QPointer<QQuickItem> item = d->deletables.at(i);
if (item)
item->stackBefore(stackBefore);
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 97d0c581b7..4b6505c998 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -1129,6 +1129,8 @@ QSGNode *QQuickShaderEffectImpl::handleUpdatePaintNode(QSGNode *oldNode, QQuickI
sd.fragment.shader = &m_shaders[Fragment];
sd.fragment.dirtyConstants = &m_dirtyConstants[Fragment];
sd.fragment.dirtyTextures = &m_dirtyTextures[Fragment];
+ sd.materialTypeCacheKey = m_item->window();
+
node->syncMaterial(&sd);
if (m_dirty & QSGShaderEffectNode::DirtyShaderMesh) {
@@ -1207,6 +1209,7 @@ bool QQuickShaderEffectImpl::updateUniformValue(const QByteArray &name, const QV
sd.fragment.shader = &m_shaders[Fragment];
sd.fragment.dirtyConstants = &dirtyConstants[Fragment];
sd.fragment.dirtyTextures = {};
+ sd.materialTypeCacheKey = m_item->window();
node->syncMaterial(&sd);
@@ -1218,7 +1221,7 @@ void QQuickShaderEffectImpl::handleItemChange(QQuickItem::ItemChange change, con
// Move the window ref.
if (change == QQuickItem::ItemSceneChange) {
for (int shaderType = 0; shaderType < NShader; ++shaderType) {
- for (const auto &vd : qAsConst(m_shaders[shaderType].varData)) {
+ for (const auto &vd : std::as_const(m_shaders[shaderType].varData)) {
if (vd.specialType == QSGShaderEffectNode::VariableData::Source) {
QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(vd.value));
if (source) {
@@ -1260,7 +1263,7 @@ void QQuickShaderEffectImpl::disconnectSignals(Shader shaderType)
if (mapper)
QObjectPrivate::disconnect(m_item, mapper->signalIndex(), &a);
}
- for (const auto &vd : qAsConst(m_shaders[shaderType].varData)) {
+ for (const auto &vd : std::as_const(m_shaders[shaderType].varData)) {
if (vd.specialType == QSGShaderEffectNode::VariableData::Source) {
QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(vd.value));
if (source) {
@@ -1274,7 +1277,7 @@ void QQuickShaderEffectImpl::disconnectSignals(Shader shaderType)
void QQuickShaderEffectImpl::clearMappers(QQuickShaderEffectImpl::Shader shaderType)
{
- for (auto *mapper : qAsConst(m_mappers[shaderType])) {
+ for (auto *mapper : std::as_const(m_mappers[shaderType])) {
if (mapper)
mapper->destroyIfLastRef();
}
@@ -1311,7 +1314,7 @@ bool QQuickShaderEffectImpl::updateShader(Shader shaderType, const QUrl &fileUrl
disconnectSignals(shaderType);
- m_shaders[shaderType].shaderInfo = QSGGuiThreadShaderEffectManager::ShaderInfo();
+ m_shaders[shaderType].shaderInfo.variables.clear();
m_shaders[shaderType].varData.clear();
if (!fileUrl.isEmpty()) {
@@ -1348,7 +1351,7 @@ bool QQuickShaderEffectImpl::updateShader(Shader shaderType, const QUrl &fileUrl
// provided and monitored like with an application-provided shader.
QSGGuiThreadShaderEffectManager::ShaderInfo::Variable v;
v.name = QByteArrayLiteral("source");
- v.bindPoint = 0; // fake
+ v.bindPoint = 1; // fake, must match the default source bindPoint in qquickshadereffectnode.cpp
v.type = texturesSeparate ? QSGGuiThreadShaderEffectManager::ShaderInfo::Texture
: QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler;
m_shaders[shaderType].shaderInfo.variables.append(v);
@@ -1399,7 +1402,7 @@ void QQuickShaderEffectImpl::updateShaderVars(Shader shaderType)
const bool texturesSeparate = mgr->hasSeparateSamplerAndTextureObjects();
- const int varCount = m_shaders[shaderType].shaderInfo.variables.count();
+ const int varCount = m_shaders[shaderType].shaderInfo.variables.size();
m_shaders[shaderType].varData.resize(varCount);
// Recreate signal mappers when the shader has changed.
@@ -1496,7 +1499,7 @@ void QQuickShaderEffectImpl::updateShaderVars(Shader shaderType)
bool QQuickShaderEffectImpl::sourceIsUnique(QQuickItem *source, Shader typeToSkip, int indexToSkip) const
{
for (int shaderType = 0; shaderType < NShader; ++shaderType) {
- for (int idx = 0; idx < m_shaders[shaderType].varData.count(); ++idx) {
+ for (int idx = 0; idx < m_shaders[shaderType].varData.size(); ++idx) {
if (shaderType != typeToSkip || idx != indexToSkip) {
const auto &vd(m_shaders[shaderType].varData[idx]);
if (vd.specialType == QSGShaderEffectNode::VariableData::Source && qvariant_cast<QObject *>(vd.value) == source)
@@ -1511,7 +1514,7 @@ std::optional<int> QQuickShaderEffectImpl::findMappedShaderVariableId(const QByt
{
for (int shaderType = 0; shaderType < NShader; ++shaderType) {
const auto &vars = m_shaders[shaderType].shaderInfo.variables;
- for (int idx = 0; idx < vars.count(); ++idx) {
+ for (int idx = 0; idx < vars.size(); ++idx) {
if (vars[idx].name == name)
return indexToMappedId(shaderType, idx);
}
@@ -1527,10 +1530,11 @@ void QQuickShaderEffectImpl::propertyChanged(int mappedId)
const auto &v(m_shaders[type].shaderInfo.variables[idx]);
auto &vd(m_shaders[type].varData[idx]);
+ QVariant oldValue = vd.value;
vd.value = getValueFromProperty(m_item, m_itemMetaObject, v.name, vd.propertyIndex);
if (vd.specialType == QSGShaderEffectNode::VariableData::Source) {
- QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(vd.value));
+ QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(oldValue));
if (source) {
if (m_item->window())
QQuickItemPrivate::get(source)->derefWindow();
diff --git a/src/quick/items/qquickshadereffectmesh.cpp b/src/quick/items/qquickshadereffectmesh.cpp
index 118ae18df5..2acd1bcf31 100644
--- a/src/quick/items/qquickshadereffectmesh.cpp
+++ b/src/quick/items/qquickshadereffectmesh.cpp
@@ -54,7 +54,7 @@ QQuickGridMesh::QQuickGridMesh(QObject *parent)
bool QQuickGridMesh::validateAttributes(const QList<QByteArray> &attributes, int *posIndex)
{
- const int attrCount = attributes.count();
+ const int attrCount = attributes.size();
int positionIndex = attributes.indexOf(qtPositionAttributeName());
int texCoordIndex = attributes.indexOf(qtTexCoordAttributeName());
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index fd5b28b2ed..5d33092e6d 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -267,7 +267,7 @@ int QQuickSpriteEngine::spriteCount() const //TODO: Actually image state count,
void QQuickStochasticEngine::setGoal(int state, int sprite, bool jump)
{
- if (sprite >= m_things.count() || state >= m_states.count()
+ if (sprite >= m_things.size() || state >= m_states.size()
|| sprite < 0 || state < 0)
return;
if (!jump){
@@ -316,12 +316,13 @@ void QQuickSpriteEngine::startAssemblingImage()
return;
m_loaded = false;
m_errorsPrinted = false;
+ m_sprites.clear();
//This could also trigger the start of the image loading in Sprites, however that currently happens in Sprite::setSource
QList<QQuickStochasticState*> removals;
- for (QQuickStochasticState* s : qAsConst(m_states)) {
+ for (QQuickStochasticState* s : std::as_const(m_states)) {
QQuickSprite* sprite = qobject_cast<QQuickSprite*>(s);
if (sprite) {
m_sprites << sprite;
@@ -330,7 +331,7 @@ void QQuickSpriteEngine::startAssemblingImage()
qDebug() << "Error: Non-sprite in QQuickSpriteEngine";
}
}
- for (QQuickStochasticState* s : qAsConst(removals))
+ for (QQuickStochasticState* s : std::as_const(removals))
m_states.removeAll(s);
m_startedImageAssembly = true;
}
@@ -339,7 +340,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize)
{
QQuickPixmap::Status stat = status();
if (!m_errorsPrinted && stat == QQuickPixmap::Error) {
- for (QQuickSprite* s : qAsConst(m_sprites))
+ for (QQuickSprite* s : std::as_const(m_sprites))
if (s->m_pix.isError())
qmlWarning(s) << s->m_pix.error();
m_errorsPrinted = true;
@@ -354,7 +355,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize)
m_imageStateCount = 0;
qreal pixelRatio = 1.0;
- for (QQuickSprite* state : qAsConst(m_sprites)) {
+ for (QQuickSprite* state : std::as_const(m_sprites)) {
if (state->frames() > m_maxFrames)
m_maxFrames = state->frames();
@@ -414,7 +415,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize)
image.fill(0);
QPainter p(&image);
int y = 0;
- for (QQuickSprite* state : qAsConst(m_sprites)) {
+ for (QQuickSprite* state : std::as_const(m_sprites)) {
QImage img(state->m_pix.image());
const int frameWidth = state->m_frameWidth;
const int frameHeight = state->m_frameHeight;
@@ -488,7 +489,7 @@ void QQuickStochasticEngine::setCount(int c)
void QQuickStochasticEngine::start(int index, int state)
{
- if (index >= m_things.count())
+ if (index >= m_things.size())
return;
m_things[index] = state;
m_duration[index] = m_states.at(state)->variedDuration();
@@ -504,10 +505,10 @@ void QQuickStochasticEngine::start(int index, int state)
void QQuickStochasticEngine::stop(int index)
{
- if (index >= m_things.count())
+ if (index >= m_things.size())
return;
//Will never change until start is called again with a new state (or manually advanced) - this is not a 'pause'
- for (int i=0; i<m_stateUpdates.count(); i++)
+ for (int i=0; i<m_stateUpdates.size(); i++)
m_stateUpdates[i].second.removeAll(index);
}
@@ -520,7 +521,7 @@ void QQuickStochasticEngine::restart(int index)
if (randomStart)
m_startTimes[index] -= QRandomGenerator::global()->bounded(m_duration.at(index));
int time = m_duration.at(index) + m_startTimes.at(index);
- for (int i=0; i<m_stateUpdates.count(); i++)
+ for (int i=0; i<m_stateUpdates.size(); i++)
m_stateUpdates[i].second.removeAll(index);
if (m_duration.at(index) >= 0)
addToUpdateList(time, index);
@@ -546,7 +547,7 @@ void QQuickSpriteEngine::restart(int index) //Reimplemented to recognize and han
time += spriteDuration(index);
}
- for (int i=0; i<m_stateUpdates.count(); i++)
+ for (int i=0; i<m_stateUpdates.size(); i++)
m_stateUpdates[i].second.removeAll(index);
addToUpdateList(time, index);
}
@@ -554,7 +555,7 @@ void QQuickSpriteEngine::restart(int index) //Reimplemented to recognize and han
void QQuickStochasticEngine::advance(int idx)
{
- if (idx >= m_things.count())
+ if (idx >= m_things.size())
return;//TODO: Proper fix(because this has happened and I just ignored it)
int nextIdx = nextState(m_things.at(idx), idx);
m_things[idx] = nextIdx;
@@ -571,7 +572,7 @@ void QQuickSpriteEngine::advance(int idx) //Reimplemented to recognize and handl
return;
}
- if (idx >= m_things.count())
+ if (idx >= m_things.size())
return;//TODO: Proper fix(because this has happened and I just ignored it)
if (m_duration.at(idx) == 0) {
if (m_sprites.at(m_things.at(idx))->frameSync()) {
@@ -614,7 +615,7 @@ int QQuickStochasticEngine::nextState(int curState, int curThing)
iter!=m_states.at(curState)->m_to.constEnd(); ++iter){
if (r < (*iter).toReal()){
bool superBreak = false;
- for (int i=0; i<m_states.count(); i++){
+ for (int i=0; i<m_states.size(); i++){
if (m_states.at(i)->name() == iter.key()){
nextIdx = i;
superBreak = true;
@@ -640,7 +641,7 @@ uint QQuickStochasticEngine::updateSprites(uint time)//### would returning a lis
m_timeOffset = time;
m_addAdvance = false;
int i = 0;
- for (; i < m_stateUpdates.count() && time >= m_stateUpdates.at(i).first; ++i) {
+ for (; i < m_stateUpdates.size() && time >= m_stateUpdates.at(i).first; ++i) {
const auto copy = m_stateUpdates.at(i).second;
for (int idx : copy)
advance(idx);
@@ -665,16 +666,16 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
return -1;
//TODO: caching instead of excessively redoing iterative deepening (which was chosen arbitrarily anyways)
// Paraphrased - implement in an *efficient* manner
- for (int i=0; i<m_states.count(); i++)
+ for (int i=0; i<m_states.size(); i++)
if (m_states.at(curIdx)->name() == goalName)
return curIdx;
if (dist < 0)
- dist = m_states.count();
+ dist = m_states.size();
QQuickStochasticState* curState = m_states.at(curIdx);
for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
iter!=curState->m_to.constEnd(); ++iter){
if (iter.key() == goalName)
- for (int i=0; i<m_states.count(); i++)
+ for (int i=0; i<m_states.size(); i++)
if (m_states.at(i)->name() == goalName)
return i;
}
@@ -683,7 +684,7 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
iter!=curState->m_to.constEnd(); ++iter){
int option = -1;
- for (int j=0; j<m_states.count(); j++)//One place that could be a lot more efficient...
+ for (int j=0; j<m_states.size(); j++)//One place that could be a lot more efficient...
if (m_states.at(j)->name() == iter.key())
if (goalSeek(j, spriteIdx, i) != -1)
option = j;
@@ -691,7 +692,7 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
options << option;
}
if (!options.isEmpty()){
- if (options.count()==1)
+ if (options.size()==1)
return *(options.begin());
int option = -1;
qreal r = QRandomGenerator::global()->generateDouble();
@@ -703,7 +704,7 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
iter!=curState->m_to.constEnd(); ++iter){
bool superContinue = true;
- for (int j=0; j<m_states.count(); j++)
+ for (int j=0; j<m_states.size(); j++)
if (m_states.at(j)->name() == iter.key())
if (options.contains(j))
superContinue = false;
@@ -711,7 +712,7 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
continue;
if (r < (*iter).toReal()){
bool superBreak = false;
- for (int j=0; j<m_states.count(); j++){
+ for (int j=0; j<m_states.size(); j++){
if (m_states.at(j)->name() == iter.key()){
option = j;
superBreak = true;
@@ -731,7 +732,7 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
void QQuickStochasticEngine::addToUpdateList(uint t, int idx)
{
- for (int i=0; i<m_stateUpdates.count(); i++){
+ for (int i=0; i<m_stateUpdates.size(); i++){
if (m_stateUpdates.at(i).first == t){
m_stateUpdates[i].second << idx;
return;
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index 3b74df241a..ee2fa34f72 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -168,7 +168,7 @@ public:
return m_globalGoal;
}
- int count() const {return m_things.count();}
+ int count() const {return m_things.size();}
void setCount(int c);
void setGoal(int state, int sprite=0, bool jump=false);
@@ -181,13 +181,13 @@ public:
QQuickStochasticState* state(int idx) const {return m_states[idx];}
int stateIndex(QQuickStochasticState* s) const {return m_states.indexOf(s);}
int stateIndex(const QString& s) const {
- for (int i=0; i<m_states.count(); i++)
+ for (int i=0; i<m_states.size(); i++)
if (m_states[i]->name() == s)
return i;
return -1;
}
- int stateCount() {return m_states.count();}
+ int stateCount() {return m_states.size();}
private:
Q_SIGNALS:
@@ -291,7 +291,7 @@ inline void spriteClear(QQmlListProperty<QQuickSprite> *p)
inline qsizetype spriteCount(QQmlListProperty<QQuickSprite> *p)
{
- return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->count();
+ return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->size();
}
inline void spriteReplace(QQmlListProperty<QQuickSprite> *p, qsizetype idx, QQuickSprite *s)
diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp
index 7e005935e4..4feb3402b1 100644
--- a/src/quick/items/qquickspritesequence.cpp
+++ b/src/quick/items/qquickspritesequence.cpp
@@ -161,7 +161,7 @@ void QQuickSpriteSequence::createEngine()
//TODO: delay until component complete
if (d->m_spriteEngine)
delete d->m_spriteEngine;
- if (d->m_sprites.count()) {
+ if (d->m_sprites.size()) {
d->m_spriteEngine = new QQuickSpriteEngine(d->m_sprites, this);
if (!d->m_goalState.isEmpty())
d->m_spriteEngine->setGoal(d->m_spriteEngine->stateIndex(d->m_goalState));
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index 9e1d771364..a6e5eed56c 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -504,7 +504,7 @@ void QQuickParentChange::saveCurrentValues()
return;
QList<QQuickItem *> children = d->rewind->parent->childItems();
- for (int ii = 0; ii < children.count() - 1; ++ii) {
+ for (int ii = 0; ii < children.size() - 1; ++ii) {
if (children.at(ii) == d->target) {
d->rewind->stackBefore = children.at(ii + 1);
break;
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 54781968b4..cc5c45db72 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -188,13 +188,80 @@
\note \l{Qt Quick Controls} offers a SelectionRectangle that can be used
to let the user select cells.
+ \note By default, a cell will become
+ \l {QQuickItemSelectionModel::currentIndex()}{current}, and any selections will
+ be removed, when the user taps on it. If such default tap behavior is not wanted
+ (e.g if you use custom pointer handlers inside your delegate), you can set
+ \l pointerNavigationEnabled to \c false.
+
\section1 Keyboard navigation
In order to support keyboard navigation, you need to assign an \l ItemSelectionModel
to the \l selectionModel property. TableView will then use this model to manipulate
- the model's \l {QQuickItemSelectionModel::currentIndex()}{currentIndex}. You can
+ the model's \l {ItemSelectionModel::currentIndex}{currentIndex}. You can
disable keyboard navigation fully (in case you want to implement your own key
handlers) by setting \l keyNavigationEnabled to \c false.
+
+ \section1 Copy and paste
+
+ Implementing copy and paste operations for a TableView usually also includes using
+ a QUndoStack (or some other undo/redo framework). The QUndoStack can be used to
+ store the different operations done on the model, like adding or removing rows, or
+ pasting data from the clipboard, with a way to undo it again later. However, an
+ accompanying QUndoStack that describes the possible operations, and how to undo them,
+ should be designed according to the needs of the model and the application.
+ As such, TableView doesn't offer a built-in API for handling copy and paste.
+
+ The following snippet can be used as a reference for how to add copy and paste support
+ to your model and TableView. It uses the existing mime data API in QAbstractItemModel,
+ together with QClipboard. The snippet will work as it is, but can also be extended to
+ use a QUndoStack.
+
+ \code
+ // Inside your C++ QAbstractTableModel subclass:
+
+ Q_INVOKABLE void copyToClipboard(const QModelIndexList &indexes) const
+ {
+ QGuiApplication::clipboard()->setMimeData(mimeData(indexes));
+ }
+
+ Q_INVOKABLE bool pasteFromClipboard(const QModelIndex &targetIndex)
+ {
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData();
+ // Consider using a QUndoCommand for the following call. It should store
+ // the (mime) data for the model items that are about to be overwritten, so
+ // that a later call to undo can revert it.
+ return dropMimeData(mimeData, Qt::CopyAction, -1, -1, targetIndex);
+ }
+ \endcode
+
+ The two functions can, for example, be used from QML like this:
+
+ \code
+ TableView {
+ id: tableView
+ model: tableModel
+ selectionModel: ItemSelectionModel {}
+
+ Shortcut {
+ sequence: StandardKey.Copy
+ onActivated: {
+ let indexes = tableView.selectionModel.selectedIndexes
+ tableView.model.copyToClipboard(indexes)
+ }
+ }
+
+ Shortcut {
+ sequence: StandardKey.Paste
+ onActivated: {
+ let targetIndex = tableView.selectionModel.currentIndex
+ tableView.model.pasteFromClipboard(targetIndex)
+ }
+ }
+ }
+ \endcode
+
+ \sa mimeData(), dropMimeData(), QUndoStack, QUndoCommand, QClipboard
*/
/*!
@@ -792,13 +859,14 @@
/*!
\qmlmethod QModelIndex QtQuick::TableView::modelIndex(int column, int row)
\since 6.4
+ \deprecated
- Returns the \l QModelIndex that maps to \a column and \a row in the view.
-
- \a row and \a column should be the row and column in the view (table row and
- table column), and not a row and column in the model.
+ Use \l index(row, column) instead.
- \sa rowAtIndex(), columnAtIndex()
+ \note Because of an API incompatible change between Qt 6.4.0 and Qt 6.4.2, the
+ order of \c row and \c column was specified in the opposite order. If you
+ rely on the order to be \c {modelIndex(column, row)}, you can set the
+ environment variable \c QT_QUICK_TABLEVIEW_COMPAT_VERSION to \c 6.4
*/
/*!
@@ -811,8 +879,25 @@
\endcode
A cell is simply a \l point that combines row and column into
- a single type. Note that \c point.x will map to the column, and
- \c point.y will map to the row.
+ a single type.
+
+ \note \c {point.x} will map to the column, and \c {point.y} will map to the row.
+*/
+
+/*!
+ \qmlmethod QModelIndex QtQuick::TableView::index(int row, int column)
+ \since 6.4.3
+
+ Returns the \l QModelIndex that maps to \a row and \a column in the view.
+
+ \a row and \a column should be the row and column in the view (table row and
+ table column), and not a row and column in the model. For a plain
+ TableView, this is equivalent of calling \c {model.index(row, column).}
+ But for a subclass of TableView, like TreeView, where the data model is
+ wrapped inside an internal proxy model that flattens the tree structure
+ into a table, you need to use this function to resolve the model index.
+
+ \sa rowAtIndex(), columnAtIndex()
*/
/*!
@@ -821,7 +906,7 @@
Returns the row in the view that maps to \a modelIndex in the model.
- \sa columnAtIndex(), modelIndex()
+ \sa columnAtIndex(), index()
*/
/*!
@@ -830,7 +915,7 @@
Returns the column in the view that maps to \a modelIndex in the model.
- \sa rowAtIndex(), modelIndex()
+ \sa rowAtIndex(), index()
*/
/*!
@@ -845,8 +930,10 @@
\endcode
A cell is simply a \l point that combines row and column into
- a single type. Note that \c point.x will map to the column, and
- \c point.y will map to the row.
+ a single type.
+
+ \note that \c {point.x} will map to the column, and
+ \c {point.y} will map to the row.
*/
/*!
@@ -1693,7 +1780,7 @@ void QQuickTableViewPrivate::updateExtents()
relayoutTableItems();
// Inform the sync children that they need to rebuild to stay in sync
- for (auto syncChild : qAsConst(syncChildren)) {
+ for (auto syncChild : std::as_const(syncChildren)) {
auto syncChild_d = syncChild->d_func();
syncChild_d->scheduledRebuildOptions |= RebuildOption::ViewportOnly;
if (tableMovedHorizontally)
@@ -2687,19 +2774,20 @@ void QQuickTableViewPrivate::processRebuildTable()
if (rebuildState == RebuildState::LayoutTable) {
layoutAfterLoadingInitialTable();
+ loadAndUnloadVisibleEdges();
if (!moveToNextRebuildState())
return;
}
- if (rebuildState == RebuildState::LoadAndUnloadAfterLayout) {
+ if (rebuildState == RebuildState::CancelOvershoot) {
+ cancelOvershootAfterLayout();
loadAndUnloadVisibleEdges();
if (!moveToNextRebuildState())
return;
}
- if (rebuildState == RebuildState::CancelOvershoot) {
- cancelOvershootAfterLayout();
- loadAndUnloadVisibleEdges();
+ if (rebuildState == RebuildState::UpdateContentSize) {
+ updateContentSize();
if (!moveToNextRebuildState())
return;
}
@@ -2961,12 +3049,8 @@ void QQuickTableViewPrivate::loadInitialTable()
loadAndUnloadVisibleEdges();
}
-void QQuickTableViewPrivate::layoutAfterLoadingInitialTable()
+void QQuickTableViewPrivate::updateContentSize()
{
- clearEdgeSizeCache();
- relayoutTableItems();
- syncLoadedTableRectFromLoadedTable();
-
const bool allColumnsLoaded = atTableEnd(Qt::LeftEdge) && atTableEnd(Qt::RightEdge);
if (rebuildOptions.testFlag(RebuildOption::CalculateNewContentWidth) || allColumnsLoaded) {
updateAverageColumnWidth();
@@ -2980,6 +3064,16 @@ void QQuickTableViewPrivate::layoutAfterLoadingInitialTable()
}
updateExtents();
+}
+
+void QQuickTableViewPrivate::layoutAfterLoadingInitialTable()
+{
+ clearEdgeSizeCache();
+ relayoutTableItems();
+ syncLoadedTableRectFromLoadedTable();
+
+ updateContentSize();
+
adjustViewportXAccordingToAlignment();
adjustViewportYAccordingToAlignment();
}
@@ -3098,7 +3192,7 @@ void QQuickTableViewPrivate::unloadEdge(Qt::Edge edge)
void QQuickTableViewPrivate::loadEdge(Qt::Edge edge, QQmlIncubator::IncubationMode incubationMode)
{
const int edgeIndex = nextVisibleEdgeIndexAroundLoadedTable(edge);
- qCDebug(lcTableViewDelegateLifecycle) << edge << edgeIndex;
+ qCDebug(lcTableViewDelegateLifecycle) << edge << edgeIndex << q_func();
const auto &visibleCells = edge & (Qt::LeftEdge | Qt::RightEdge)
? loadedRows.values() : loadedColumns.values();
@@ -3653,6 +3747,13 @@ void QQuickTableViewPrivate::syncSyncView()
q->setLeftMargin(syncView->leftMargin());
q->setRightMargin(syncView->rightMargin());
updateContentWidth();
+
+ if (syncView->leftColumn() != q->leftColumn()) {
+ // The left column is no longer the same as the left
+ // column in syncView. This requires a rebuild.
+ scheduledRebuildOptions |= QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftColumn;
+ scheduledRebuildOptions.setFlag(RebuildOption::ViewportOnly);
+ }
}
if (syncVertically) {
@@ -3661,6 +3762,13 @@ void QQuickTableViewPrivate::syncSyncView()
q->setTopMargin(syncView->topMargin());
q->setBottomMargin(syncView->bottomMargin());
updateContentHeight();
+
+ if (syncView->topRow() != q->topRow()) {
+ // The top row is no longer the same as the top
+ // row in syncView. This requires a rebuild.
+ scheduledRebuildOptions |= QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftRow;
+ scheduledRebuildOptions.setFlag(RebuildOption::ViewportOnly);
+ }
}
if (syncView && loadedItems.isEmpty() && !tableSize.isEmpty()) {
@@ -4010,10 +4118,26 @@ void QQuickTableViewPrivate::setLocalViewportY(qreal contentY)
void QQuickTableViewPrivate::syncViewportRect()
{
- // Sync viewportRect so that it contains the actual geometry of the viewport
+ // Sync viewportRect so that it contains the actual geometry of the viewport.
+ // Since the column (and row) size of a sync child is decided by the column size
+ // of its sync view, the viewport width of a sync view needs to be the maximum of
+ // the sync views width, and its sync childrens width. This to ensure that no sync
+ // child loads a column which is not yet loaded by the sync view, since then the
+ // implicit column size cannot be resolved.
Q_Q(QQuickTableView);
- viewportRect = QRectF(q->contentX(), q->contentY(), q->width(), q->height());
- qCDebug(lcTableViewDelegateLifecycle) << viewportRect;
+
+ qreal w = q->width();
+ qreal h = q->height();
+
+ for (auto syncChild : std::as_const(syncChildren)) {
+ auto syncChild_d = syncChild->d_func();
+ if (syncChild_d->syncHorizontally)
+ w = qMax(w, syncChild->width());
+ if (syncChild_d->syncHorizontally)
+ h = qMax(h, syncChild->height());
+ }
+
+ viewportRect = QRectF(q->contentX(), q->contentY(), w, h);
}
void QQuickTableViewPrivate::init()
@@ -4030,7 +4154,7 @@ void QQuickTableViewPrivate::init()
positionYAnimation.setProperty(QStringLiteral("contentY"));
positionYAnimation.setEasing(QEasingCurve::OutQuart);
- auto tapHandler = new QQuickTapHandler(q->contentItem());
+ auto tapHandler = new QQuickTableViewTapHandler(q);
QObject::connect(tapHandler, &QQuickTapHandler::pressedChanged, [this, q, tapHandler] {
if (!pointerNavigationEnabled || !tapHandler->isPressed())
@@ -4071,7 +4195,7 @@ void QQuickTableViewPrivate::syncViewportPosRecursive()
}
}
- for (auto syncChild : qAsConst(syncChildren)) {
+ for (auto syncChild : std::as_const(syncChildren)) {
auto syncChild_d = syncChild->d_func();
if (!syncChild_d->inSyncViewportPosRecursive) {
if (syncChild_d->syncHorizontally)
@@ -4634,14 +4758,22 @@ void QQuickTableView::positionViewAtColumn(int column, PositionMode mode, qreal
void QQuickTableView::positionViewAtCell(const QPoint &cell, PositionMode mode, const QPointF &offset, const QRectF &subRect)
{
- positionViewAtRow(cell.y(), mode, offset.y(), subRect);
- positionViewAtColumn(cell.x(), mode, offset.x(), subRect);
+ positionViewAtCell(cell.x(), cell.y(), mode, offset, subRect);
}
void QQuickTableView::positionViewAtCell(int column, int row, PositionMode mode, const QPointF &offset, const QRectF &subRect)
{
- positionViewAtRow(row, mode, offset.y(), subRect);
- positionViewAtColumn(column, mode, offset.x(), subRect);
+ PositionMode horizontalMode = mode & ~(AlignTop | AlignBottom | AlignVCenter);
+ PositionMode verticalMode = mode & ~(AlignLeft | AlignRight | AlignHCenter);
+ if (!horizontalMode && !verticalMode) {
+ qmlWarning(this) << "Unsupported mode:" << int(mode);
+ return;
+ }
+
+ if (horizontalMode)
+ positionViewAtColumn(column, horizontalMode, offset.x(), subRect);
+ if (verticalMode)
+ positionViewAtRow(row, verticalMode, offset.y(), subRect);
}
QQuickItem *QQuickTableView::itemAtCell(const QPoint &cell) const
@@ -4814,7 +4946,26 @@ QPoint QQuickTableView::cellAtIndex(const QModelIndex &index) const
return {index.column(), index.row()};
}
-QModelIndex QQuickTableView::modelIndex(int column, int row) const
+#if QT_DEPRECATED_SINCE(6, 4)
+QModelIndex QQuickTableView::modelIndex(int row, int column) const
+{
+ static bool compat6_4 = qEnvironmentVariable("QT_QUICK_TABLEVIEW_COMPAT_VERSION") == QStringLiteral("6.4");
+ if (compat6_4) {
+ // In Qt 6.4.0 and 6.4.1, a source incompatible change led to row and column
+ // being documented to be specified in the opposite order.
+ // QT_QUICK_TABLEVIEW_COMPAT_VERSION can therefore be set to force tableview
+ // to continue accepting calls to modelIndex(column, row).
+ return modelIndex({row, column});
+ } else {
+ qmlWarning(this) << "modelIndex(row, column) is deprecated. "
+ "Use index(row, column) instead. For more information, see "
+ "https://doc.qt.io/qt-6/qml-qtquick-tableview-obsolete.html";
+ return modelIndex({column, row});
+ }
+}
+#endif
+
+QModelIndex QQuickTableView::index(int row, int column) const
{
return modelIndex({column, row});
}
@@ -4850,7 +5001,10 @@ void QQuickTableView::geometryChange(const QRectF &newGeometry, const QRectF &ol
d->tableModel->drainReusableItemsPool(0);
}
- polish();
+ d->scheduleRebuildTable(
+ QQuickTableViewPrivate::RebuildOption::LayoutOnly |
+ QQuickTableViewPrivate::RebuildOption::CalculateNewContentWidth |
+ QQuickTableViewPrivate::RebuildOption::CalculateNewContentHeight);
}
void QQuickTableView::viewportMoved(Qt::Orientations orientation)
@@ -4918,7 +5072,7 @@ void QQuickTableView::keyPressEvent(QKeyEvent *e)
case Qt::Key_Right:
// Special case: the current index doesn't map to a cell in the view (perhaps
// because it isn't set yet). In that case, we set it to be the top-left cell.
- const QModelIndex topLeftIndex = modelIndex(leftColumn(), topRow());
+ const QModelIndex topLeftIndex = index(topRow(), leftColumn());
d->selectionModel->setCurrentIndex(topLeftIndex, QItemSelectionModel::NoUpdate);
}
return;
@@ -5134,6 +5288,20 @@ QQuickTableSectionSizeProviderPrivate::~QQuickTableSectionSizeProviderPrivate()
}
+// ----------------------------------------------
+
+QQuickTableViewTapHandler::QQuickTableViewTapHandler(QQuickTableView *view)
+ : QQuickTapHandler(view->contentItem())
+{
+}
+
+bool QQuickTableViewTapHandler::wantsEventPoint(const QPointerEvent *event, const QEventPoint &point)
+{
+ auto tableView = static_cast<QQuickTableView *>(parentItem()->parent());
+ auto tableViewPrivate = QQuickTableViewPrivate::get(tableView);
+ return tableViewPrivate->pointerNavigationEnabled && QQuickTapHandler::wantsEventPoint(event, point);
+}
+
QT_END_NAMESPACE
#include "moc_qquicktableview_p.cpp"
diff --git a/src/quick/items/qquicktableview_p.h b/src/quick/items/qquicktableview_p.h
index 598e109093..442e490a87 100644
--- a/src/quick/items/qquicktableview_p.h
+++ b/src/quick/items/qquicktableview_p.h
@@ -77,8 +77,8 @@ public:
Visible = 0x01000,
Contain = 0x02000
};
- Q_FLAG(PositionModeFlag)
Q_DECLARE_FLAGS(PositionMode, PositionModeFlag)
+ Q_FLAG(PositionMode)
enum SelectionBehavior {
SelectionDisabled,
@@ -159,6 +159,8 @@ public:
Q_REVISION(6, 4) Q_INVOKABLE QPoint cellAtPosition(const QPointF &position, bool includeSpacing = false) const;
Q_REVISION(6, 4) Q_INVOKABLE QPoint cellAtPosition(qreal x, qreal y, bool includeSpacing = false) const;
#if QT_DEPRECATED_SINCE(6, 4)
+ QT_DEPRECATED_VERSION_X_6_4("Use index(row, column) instead")
+ Q_REVISION(6, 4) Q_INVOKABLE virtual QModelIndex modelIndex(int row, int column) const;
QT_DEPRECATED_VERSION_X_6_4("Use cellAtPosition() instead")
Q_INVOKABLE QPoint cellAtPos(const QPointF &position, bool includeSpacing = false) const;
Q_INVOKABLE QPoint cellAtPos(qreal x, qreal y, bool includeSpacing = false) const;
@@ -172,8 +174,8 @@ public:
Q_REVISION(6, 2) Q_INVOKABLE qreal implicitColumnWidth(int column) const;
Q_REVISION(6, 2) Q_INVOKABLE qreal implicitRowHeight(int row) const;
+ Q_REVISION(6, 4) Q_INVOKABLE QModelIndex index(int row, int column) const;
Q_REVISION(6, 4) Q_INVOKABLE virtual QModelIndex modelIndex(const QPoint &cell) const;
- Q_REVISION(6, 4) Q_INVOKABLE virtual QModelIndex modelIndex(int column, int row) const;
Q_REVISION(6, 4) Q_INVOKABLE virtual QPoint cellAtIndex(const QModelIndex &index) const;
Q_REVISION(6, 4) Q_INVOKABLE int rowAtIndex(const QModelIndex &index) const;
Q_REVISION(6, 4) Q_INVOKABLE int columnAtIndex(const QModelIndex &index) const;
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index 608eee8558..7c865169cb 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -29,6 +29,7 @@
#include <QtQuick/private/qquickitemviewfxitem_p_p.h>
#include <QtQuick/private/qquickanimation_p.h>
#include <QtQuick/private/qquickselectable_p.h>
+#include <QtQuick/private/qquicktaphandler_p.h>
QT_BEGIN_NAMESPACE
@@ -60,6 +61,21 @@ private:
Q_DECLARE_PRIVATE(QQuickTableSectionSizeProvider)
};
+/*! \internal
+ * QQuickTableViewTapHandler used to handle tap events explicitly for table view
+ */
+class QQuickTableViewTapHandler : public QQuickTapHandler
+{
+ Q_OBJECT
+
+public:
+ explicit QQuickTableViewTapHandler(QQuickTableView *view);
+ bool wantsEventPoint(const QPointerEvent *event, const QEventPoint &point) override;
+
+ friend class QQuickTableViewPrivate;
+};
+
+
class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate, public QQuickSelectable
{
public:
@@ -105,7 +121,7 @@ public:
inline bool isActive() const { return m_active; }
inline QPoint currentCell() const { return cellAt(m_currentIndex); }
- inline bool hasCurrentCell() const { return m_currentIndex < m_visibleCellsInEdge.count(); }
+ inline bool hasCurrentCell() const { return m_currentIndex < m_visibleCellsInEdge.size(); }
inline void moveToNextCell() { ++m_currentIndex; }
inline Qt::Edge edge() const { return m_edge; }
@@ -168,8 +184,8 @@ public:
LoadInitalTable,
VerifyTable,
LayoutTable,
- LoadAndUnloadAfterLayout,
CancelOvershoot,
+ UpdateContentSize,
PreloadColumns,
PreloadRows,
MovePreloadedItemsToPool,
@@ -416,6 +432,7 @@ public:
void adjustViewportXAccordingToAlignment();
void adjustViewportYAccordingToAlignment();
void cancelOvershootAfterLayout();
+ void updateContentSize();
void scheduleRebuildTable(QQuickTableViewPrivate::RebuildOptions options);
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 877e120644..e25df1512f 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -285,7 +285,7 @@ void QQuickText::imageDownloadFinished()
if (d->extra.isAllocated() && d->extra->nbActiveDownloads == 0) {
bool needToUpdateLayout = false;
- for (QQuickStyledTextImgTag *img : qAsConst(d->extra->visibleImgTags)) {
+ for (QQuickStyledTextImgTag *img : std::as_const(d->extra->visibleImgTags)) {
if (!img->size.isValid()) {
img->size = img->pix->implicitSize();
needToUpdateLayout = true;
@@ -617,7 +617,7 @@ void QQuickTextPrivate::elideFormats(
{
const int end = start + length;
const QVector<QTextLayout::FormatRange> formats = layout.formats();
- for (int i = 0; i < formats.count(); ++i) {
+ for (int i = 0; i < formats.size(); ++i) {
QTextLayout::FormatRange format = formats.at(i);
const int formatLength = qMin(format.start + format.length, end) - qMax(format.start, start);
if (formatLength > 0) {
@@ -628,7 +628,7 @@ void QQuickTextPrivate::elideFormats(
}
}
-QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine) const
+QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, const QTextLine *nextLine) const
{
if (nextLine) {
return layout.engine()->elidedText(
@@ -641,7 +641,7 @@ QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, QT
QString elideText = layout.text().mid(line.textStart(), line.textLength());
if (!styledText) {
// QFontMetrics won't help eliding styled text.
- elideText[elideText.length() - 1] = elideChar;
+ elideText[elideText.size() - 1] = elideChar;
// Appending the elide character may push the line over the maximum width
// in which case the elided text will need to be elided.
QFontMetricsF metrics(layout.font());
@@ -792,12 +792,14 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
br = QRectF();
QRectF unelidedRect;
- QTextLine line = layout.createLine();
+ QTextLine line;
for (visibleCount = 1; ; ++visibleCount) {
+ line = layout.createLine();
+
if (noBreakLastLine && visibleCount == maxLineCount)
layout.engine()->option.setWrapMode(QTextOption::WrapAnywhere);
if (customLayout) {
- setupCustomLineGeometry(line, naturalHeight, layoutText.length());
+ setupCustomLineGeometry(line, naturalHeight, layoutText.size());
} else {
setLineGeometry(line, lineWidth, naturalHeight);
}
@@ -819,7 +821,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
visibleCount -= 1;
- QTextLine previousLine = layout.lineAt(visibleCount - 1);
+ const QTextLine previousLine = layout.lineAt(visibleCount - 1);
elideText = layoutText.at(line.textStart() - 1) != QChar::LineSeparator
? elidedText(line.width(), previousLine, &line)
: elidedText(line.width(), previousLine);
@@ -830,10 +832,9 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
break;
}
- const QTextLine previousLine = line;
- line = layout.createLine();
- if (!line.isValid()) {
- if (singlelineElide && visibleCount == 1 && previousLine.naturalTextWidth() > previousLine.width()) {
+ const bool isLastLine = line.textStart() + line.textLength() >= layoutText.size();
+ if (isLastLine) {
+ if (singlelineElide && visibleCount == 1 && line.naturalTextWidth() > line.width()) {
// Elide a single previousLine of text if its width exceeds the element width.
elide = true;
widthExceeded = true;
@@ -843,26 +844,25 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
truncated = true;
elideText = layout.engine()->elidedText(
Qt::TextElideMode(elideMode),
- QFixed::fromReal(previousLine.width()),
+ QFixed::fromReal(line.width()),
0,
- previousLine.textStart(),
- previousLine.textLength());
- elideStart = previousLine.textStart();
- elideEnd = elideStart + previousLine.textLength();
+ line.textStart(),
+ line.textLength());
+ elideStart = line.textStart();
+ elideEnd = elideStart + line.textLength();
} else {
br = unelidedRect;
height = naturalHeight;
}
break;
} else {
- const bool wrappedLine = layoutText.at(line.textStart() - 1) != QChar::LineSeparator;
+ const bool wrappedLine = layoutText.at(line.textStart() + line.textLength() - 1) != QChar::LineSeparator;
wrapped |= wrappedLine;
if (!wrappedLine)
++unwrappedLineCount;
- // Stop if the maximum number of lines has been reached and elide the last line
- // if enabled.
+ // Stop if the maximum number of lines has been reached
if (visibleCount == maxLineCount) {
truncated = true;
heightExceeded |= wrapped;
@@ -871,10 +871,12 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
elide = true;
if (eos != -1) // There's an abbreviated string available
break;
+
+ const QTextLine nextLine = layout.createLine();
elideText = wrappedLine
- ? elidedText(previousLine.width(), previousLine, &line)
- : elidedText(previousLine.width(), previousLine);
- elideStart = previousLine.textStart();
+ ? elidedText(line.width(), line, &nextLine)
+ : elidedText(line.width(), line);
+ elideStart = line.textStart();
// elideEnd isn't required for right eliding.
} else {
br = unelidedRect;
@@ -911,8 +913,8 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
// implicit width.
const int eol = line.isValid()
? line.textStart() + line.textLength()
- : layoutText.length();
- if (eol < layoutText.length() && layoutText.at(eol) != QChar::LineSeparator)
+ : layoutText.size();
+ if (eol < layoutText.size() && layoutText.at(eol) != QChar::LineSeparator)
line = layout.createLine();
for (; line.isValid() && unwrappedLineCount <= maxLineCount; ++unwrappedLineCount)
line = layout.createLine();
@@ -1109,18 +1111,18 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
QVector<QTextLayout::FormatRange> formats;
switch (elideMode) {
case QQuickText::ElideRight:
- elideFormats(elideStart, elideText.length() - 1, 0, &formats);
+ elideFormats(elideStart, elideText.size() - 1, 0, &formats);
break;
case QQuickText::ElideLeft:
- elideFormats(elideEnd - elideText.length() + 1, elideText.length() - 1, 1, &formats);
+ elideFormats(elideEnd - elideText.size() + 1, elideText.size() - 1, 1, &formats);
break;
case QQuickText::ElideMiddle: {
const int index = elideText.indexOf(elideChar);
if (index != -1) {
elideFormats(elideStart, index, 0, &formats);
elideFormats(
- elideEnd - elideText.length() + index + 1,
- elideText.length() - index - 1,
+ elideEnd - elideText.size() + index + 1,
+ elideText.size() - index - 1,
index + 1,
&formats);
}
@@ -1140,7 +1142,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
QTextLine elidedLine = elideLayout->createLine();
elidedLine.setPosition(QPointF(0, height));
if (customLayout) {
- setupCustomLineGeometry(elidedLine, height, elideText.length(), visibleCount - 1);
+ setupCustomLineGeometry(elidedLine, height, elideText.size(), visibleCount - 1);
} else {
setLineGeometry(elidedLine, lineWidth, height);
}
@@ -1194,7 +1196,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
QList<QQuickStyledTextImgTag *> imagesInLine;
if (extra.isAllocated()) {
- for (QQuickStyledTextImgTag *image : qAsConst(extra->imgTags)) {
+ for (QQuickStyledTextImgTag *image : std::as_const(extra->imgTags)) {
if (image->position >= line.textStart() &&
image->position < line.textStart() + line.textLength()) {
@@ -1232,7 +1234,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
}
}
- for (QQuickStyledTextImgTag *image : qAsConst(imagesInLine)) {
+ for (QQuickStyledTextImgTag *image : std::as_const(imagesInLine)) {
totalLineHeight = qMax(totalLineHeight, textTop + image->pos.y() + image->size.height());
const int leadX = line.cursorToX(image->position);
const int trailX = line.cursorToX(image->position, QTextLine::Trailing);
@@ -2409,21 +2411,23 @@ void QQuickText::geometryChange(const QRectF &newGeometry, const QRectF &oldGeom
goto geomChangeDone;
if (!(widthChanged || widthMaximum) && !d->isLineLaidOutConnected()) { // only height has changed
- if (newGeometry.height() > oldGeometry.height()) {
- if (!d->heightExceeded && !qFuzzyIsNull(oldGeometry.height())) {
- // Height is adequate and growing, and it wasn't 0 previously.
- goto geomChangeDone;
- }
- if (d->lineCount == d->maximumLineCount()) // Reached maximum line and height is growing.
- goto geomChangeDone;
- } else if (newGeometry.height() < oldGeometry.height()) {
- if (d->lineCount < 2 && !verticalScale && newGeometry.height() > 0) // A single line won't be truncated until the text is 0 height.
- goto geomChangeDone;
-
- if (!verticalScale // no scaling, no eliding, and either unwrapped, or no maximum line count.
- && d->elideMode != QQuickText::ElideRight
- && !(d->maximumLineCountValid && d->widthExceeded)) {
- goto geomChangeDone;
+ if (!verticalPositionChanged) {
+ if (newGeometry.height() > oldGeometry.height()) {
+ if (!d->heightExceeded && !qFuzzyIsNull(oldGeometry.height())) {
+ // Height is adequate and growing, and it wasn't 0 previously.
+ goto geomChangeDone;
+ }
+ if (d->lineCount == d->maximumLineCount()) // Reached maximum line and height is growing.
+ goto geomChangeDone;
+ } else if (newGeometry.height() < oldGeometry.height()) {
+ if (d->lineCount < 2 && !verticalScale && newGeometry.height() > 0) // A single line won't be truncated until the text is 0 height.
+ goto geomChangeDone;
+
+ if (!verticalScale // no scaling, no eliding, and either unwrapped, or no maximum line count.
+ && d->elideMode != QQuickText::ElideRight
+ && !(d->maximumLineCountValid && d->widthExceeded)) {
+ goto geomChangeDone;
+ }
}
}
} else if (!heightChanged && widthMaximum) {
@@ -2509,7 +2513,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
node->addTextLayout(QPointF(dx, dy), d->elideLayout, color, d->style, styleColor, linkColor);
if (d->extra.isAllocated()) {
- for (QQuickStyledTextImgTag *img : qAsConst(d->extra->visibleImgTags)) {
+ for (QQuickStyledTextImgTag *img : std::as_const(d->extra->visibleImgTags)) {
QQuickPixmap *pix = img->pix;
if (pix && pix->isReady())
node->addImage(QRectF(img->pos.x() + dx, img->pos.y() + dy, pix->width(), pix->height()), pix->image());
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 5966ff5f75..bfcca403bf 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -48,7 +48,7 @@ public:
void setLineGeometry(QTextLine &line, qreal lineWidth, qreal &height);
int lineHeightOffset() const;
- QString elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine = nullptr) const;
+ QString elidedText(qreal lineWidth, const QTextLine &line, const QTextLine *nextLine = nullptr) const;
void elideFormats(int start, int length, int offset, QVector<QTextLayout::FormatRange> *elidedFormats);
void clearFormats();
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index cbc9f10f9e..929ce10136 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -742,8 +742,7 @@ void QQuickTextControl::processEvent(QEvent *e, const QTransform &transform)
case QEvent::ShortcutOverride:
if (d->interactionFlags & Qt::TextEditable) {
QKeyEvent* ke = static_cast<QKeyEvent *>(e);
- if (isCommonTextEditShortcut(ke))
- ke->accept();
+ ke->setAccepted(isCommonTextEditShortcut(ke));
}
break;
default:
@@ -963,7 +962,7 @@ QRectF QQuickTextControlPrivate::rectForPosition(int position) const
if (relativePos == preeditPos)
relativePos += preeditCursor;
else if (relativePos > preeditPos)
- relativePos += layout->preeditAreaText().length();
+ relativePos += layout->preeditAreaText().size();
}
#endif
QTextLine line = layout->lineForTextPosition(relativePos);
@@ -1272,7 +1271,7 @@ bool QQuickTextControlPrivate::sendMouseEventToInputContext(QMouseEvent *e, cons
QTextLayout *layout = cursor.block().layout();
int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position();
- if (cursorPos >= 0 && cursorPos <= layout->preeditAreaText().length()) {
+ if (cursorPos >= 0 && cursorPos <= layout->preeditAreaText().size()) {
if (e->type() == QEvent::MouseButtonRelease) {
QGuiApplication::inputMethod()->invokeAction(QInputMethod::Click, cursorPos);
}
@@ -1344,7 +1343,7 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
emit q->preeditTextChanged();
}
QVector<QTextLayout::FormatRange> overrides;
- preeditCursor = e->preeditString().length();
+ preeditCursor = e->preeditString().size();
hasImState = !e->preeditString().isEmpty();
cursorVisible = true;
for (int i = 0; i < e->attributes().size(); ++i) {
@@ -1417,7 +1416,7 @@ QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property, cons
QTextCursor tmpCursor = d->cursor;
int localPos = d->cursor.position() - block.position();
QString result = block.text().mid(localPos);
- while (result.length() < maxLength) {
+ while (result.size() < maxLength) {
int currentBlock = tmpCursor.blockNumber();
tmpCursor.movePosition(QTextCursor::NextBlock);
if (tmpCursor.blockNumber() == currentBlock)
diff --git a/src/quick/items/qquicktextdocument.cpp b/src/quick/items/qquicktextdocument.cpp
index 4f585f8333..ce0efb4d2a 100644
--- a/src/quick/items/qquicktextdocument.cpp
+++ b/src/quick/items/qquicktextdocument.cpp
@@ -183,7 +183,7 @@ QQuickPixmap *QQuickTextDocumentWithImageResources::loadPixmap(
void QQuickTextDocumentWithImageResources::clearResources()
{
- for (QQuickPixmap *pixmap : qAsConst(m_resources))
+ for (QQuickPixmap *pixmap : std::as_const(m_resources))
pixmap->clear(this);
qDeleteAll(m_resources);
m_resources.clear();
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 8ce622d176..b1158899bf 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -405,6 +405,11 @@ void QQuickTextEdit::setText(const QString &text)
void QQuickTextEdit::invalidate()
{
+ QMetaObject::invokeMethod(this, &QQuickTextEdit::q_invalidate);
+}
+
+void QQuickTextEdit::q_invalidate()
+{
Q_D(QQuickTextEdit);
if (isComponentComplete()) {
if (d->document != nullptr)
@@ -1088,7 +1093,7 @@ int QQuickTextEdit::positionAt(qreal x, qreal y) const
// preedit or the next text block.
QTextLayout *layout = cursor.block().layout();
const int preeditLength = layout
- ? layout->preeditAreaText().length()
+ ? layout->preeditAreaText().size()
: 0;
if (preeditLength > 0
&& d->document->documentLayout()->blockBoundingRect(cursor.block()).contains(x, y)) {
@@ -2214,7 +2219,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
// Having nodes spanning across frame boundaries will break the current bookkeeping mechanism. We need to prevent that.
QList<int> frameBoundaries;
frameBoundaries.reserve(frames.size());
- for (QTextFrame *frame : qAsConst(frames))
+ for (QTextFrame *frame : std::as_const(frames))
frameBoundaries.append(frame->firstPosition());
std::sort(frameBoundaries.begin(), frameBoundaries.end());
@@ -2241,13 +2246,16 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
if (coveredRegion.top() > viewport.top() + 1) {
qCDebug(lcVP) << "checking backwards from block" << block.blockNumber() << "@" << nodeOffset.y() << coveredRegion;
while (it != textFrame->begin() && it.currentBlock().layout() &&
- it.currentBlock().layout()->boundingRect().top() + nodeOffset.y() > viewport.top())
+ it.currentBlock().layout()->boundingRect().top() + nodeOffset.y() > viewport.top()) {
+ nodeOffset = d->document->documentLayout()->blockBoundingRect(it.currentBlock()).topLeft();
--it;
+ }
if (!it.currentBlock().layout())
++it;
if (Q_LIKELY(it.currentBlock().layout())) {
block = it.currentBlock();
coveredRegion = block.layout()->boundingRect().adjusted(nodeOffset.x(), nodeOffset.y(), nodeOffset.x(), nodeOffset.y());
+ firstDirtyPos = it.currentBlock().position();
} else {
qCWarning(lcVP) << "failed to find a text block with layout during back-scrolling";
}
@@ -2271,11 +2279,13 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
}
}
+ bool createdNodeInView = false;
if (inView) {
if (!engine.hasContents()) {
if (node && !node->parent())
d->addCurrentTextNodeToRoot(&engine, rootNode, node, nodeIterator, nodeStart);
node = d->createTextNode();
+ createdNodeInView = true;
updateNodeTransform(node, nodeOffset);
nodeStart = block.position();
}
@@ -2285,18 +2295,18 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
if ((it.atEnd()) || block.next().position() >= firstCleanNode.startPos())
break; // last node that needed replacing or last block of the frame
-
QList<int>::const_iterator lowerBound = std::lower_bound(frameBoundaries.constBegin(), frameBoundaries.constEnd(), block.next().position());
if (node && (currentNodeSize > nodeBreakingSize || lowerBound == frameBoundaries.constEnd() || *lowerBound > nodeStart)) {
currentNodeSize = 0;
if (!node->parent())
d->addCurrentTextNodeToRoot(&engine, rootNode, node, nodeIterator, nodeStart);
- node = d->createTextNode();
+ if (!createdNodeInView)
+ node = d->createTextNode();
resetEngine(&engine, d->color, d->selectedTextColor, d->selectionColor);
nodeStart = block.next().position();
}
++it;
- }
+ } // loop over blocks in frame
}
if (Q_LIKELY(node && !node->parent()))
d->addCurrentTextNodeToRoot(&engine, rootNode, node, nodeIterator, nodeStart);
@@ -3357,6 +3367,16 @@ void QQuickTextEdit::clear()
d->control->clear();
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const QQuickTextEditPrivate::Node &n)
+{
+ QDebugStateSaver saver(debug);
+ debug.space();
+ debug << "Node(startPos:" << n.m_startPos << "dirty:" << n.m_dirty << n.m_node << ')';
+ return debug;
+}
+#endif
+
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
void QQuickTextEdit::setOldSelectionDefault()
{
@@ -3365,7 +3385,7 @@ void QQuickTextEdit::setOldSelectionDefault()
setKeepMouseGrab(false);
d->control->setTextInteractionFlags(d->control->textInteractionFlags() & ~Qt::TextSelectableByMouse);
d->control->setTouchDragSelectionEnabled(true);
- qCDebug(lcTextEdit, "pre-6.4 behavior chosen by import version: selectByMouse defaults false; if enabled, touchscreen acts like a mouse");
+ qCDebug(lcTextEdit, "pre-6.4 behavior chosen: selectByMouse defaults false; if enabled, touchscreen acts like a mouse");
}
// TODO in 6.7.0: remove the note about versions prior to 6.4 in selectByMouse() documentation
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index b4a8e95cf4..c98d062c6b 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -338,6 +338,7 @@ public Q_SLOTS:
Q_REVISION(2, 7) void clear();
private Q_SLOTS:
+ void q_invalidate();
void q_textChanged();
void q_contentsChange(int, int, int);
void updateSelection();
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index b2cbd80626..db07462a5a 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -53,6 +53,10 @@ public:
int m_startPos;
QQuickTextNode* m_node;
bool m_dirty;
+
+#ifndef QT_NO_DEBUG_STREAM
+ friend QDebug Q_QUICK_PRIVATE_EXPORT operator<<(QDebug, const Node &);
+#endif
};
typedef QList<Node>::iterator TextNodeIterator;
@@ -202,6 +206,10 @@ public:
static const int largeTextSizeThreshold;
};
+#ifndef QT_NO_DEBUG_STREAM
+QDebug Q_QUICK_PRIVATE_EXPORT operator<<(QDebug debug, const QQuickTextEditPrivate::Node &);
+#endif
+
QT_END_NAMESPACE
#endif // QQUICKTEXTEDIT_P_P_H
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index a980e7fbaf..660496734b 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -31,7 +31,7 @@
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
-Q_LOGGING_CATEGORY(lcTextInput, "qt.quick.textInput")
+Q_LOGGING_CATEGORY(lcQuickTextInput, "qt.quick.textInput")
/*!
\qmltype TextInput
@@ -173,7 +173,7 @@ void QQuickTextInput::setRenderType(QQuickTextInput::RenderType renderType)
int QQuickTextInput::length() const
{
Q_D(const QQuickTextInput);
- return d->m_text.length();
+ return d->m_text.size();
}
/*!
@@ -833,7 +833,7 @@ int QQuickTextInput::cursorPosition() const
void QQuickTextInput::setCursorPosition(int cp)
{
Q_D(QQuickTextInput);
- if (cp < 0 || cp > text().length())
+ if (cp < 0 || cp > text().size())
return;
d->moveCursor(cp);
}
@@ -866,7 +866,7 @@ QRectF QQuickTextInput::cursorRectangle() const
qreal y = l.y() - d->vscroll + topPadding();
qreal w = 1;
if (d->overwriteMode) {
- if (c < text().length())
+ if (c < text().size())
w = l.cursorToX(c + 1) - x;
else
w = QFontMetrics(font()).horizontalAdvance(QLatin1Char(' ')); // in sync with QTextLine::draw()
@@ -922,7 +922,7 @@ int QQuickTextInput::selectionEnd() const
void QQuickTextInput::select(int start, int end)
{
Q_D(QQuickTextInput);
- if (start < 0 || end < 0 || start > d->m_text.length() || end > d->m_text.length())
+ if (start < 0 || end < 0 || start > d->m_text.size() || end > d->m_text.size())
return;
d->setSelection(start, end-start);
}
@@ -937,10 +937,10 @@ void QQuickTextInput::select(int start, int end)
It is equivalent to the following snippet, but is faster and easier
to use.
- \js
+ \qml
myTextInput.text.toString().substring(myTextInput.selectionStart,
myTextInput.selectionEnd);
- \endjs
+ \endqml
*/
QString QQuickTextInput::selectedText() const
{
@@ -1365,7 +1365,7 @@ QRectF QQuickTextInput::positionToRectangle(int pos) const
pos = 0;
#if QT_CONFIG(im)
else if (pos > d->m_cursor)
- pos += d->preeditAreaText().length();
+ pos += d->preeditAreaText().size();
#endif
QTextLine l = d->m_textLayout.lineForTextPosition(pos);
if (!l.isValid())
@@ -1374,7 +1374,7 @@ QRectF QQuickTextInput::positionToRectangle(int pos) const
qreal y = l.y() - d->vscroll;
qreal w = 1;
if (d->overwriteMode) {
- if (pos < text().length())
+ if (pos < text().size())
w = l.cursorToX(pos + 1) - x;
else
w = QFontMetrics(font()).horizontalAdvance(QLatin1Char(' ')); // in sync with QTextLine::draw()
@@ -1435,7 +1435,7 @@ void QQuickTextInput::positionAt(QQmlV4Function *args) const
const int cursor = d->m_cursor;
if (pos > cursor) {
#if QT_CONFIG(im)
- const int preeditLength = d->preeditAreaText().length();
+ const int preeditLength = d->preeditAreaText().size();
pos = pos > cursor + preeditLength
? pos - preeditLength
: cursor;
@@ -1503,7 +1503,7 @@ void QQuickTextInput::keyPressEvent(QKeyEvent* ev)
int cursorPosition = d->m_cursor;
if (cursorPosition == 0)
ignore = ev->key() == (d->layoutDirection() == Qt::LeftToRight ? Qt::Key_Left : Qt::Key_Right);
- if (!ignore && cursorPosition == d->m_text.length())
+ if (!ignore && cursorPosition == d->m_text.size())
ignore = ev->key() == (d->layoutDirection() == Qt::LeftToRight ? Qt::Key_Right : Qt::Key_Left);
}
if (ignore) {
@@ -1593,10 +1593,13 @@ void QQuickTextInput::mousePressEvent(QMouseEvent *event)
void QQuickTextInput::mouseMoveEvent(QMouseEvent *event)
{
- if (!QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(event))
- return;
-
Q_D(QQuickTextInput);
+ if (!QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(event)
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+ && ! d->selectByTouchDrag
+#endif
+ )
+ return;
if (d->selectPressed) {
if (qAbs(int(event->position().x() - d->pressPos.x())) > QGuiApplication::styleHints()->startDragDistance())
@@ -1629,7 +1632,12 @@ void QQuickTextInput::mouseReleaseEvent(QMouseEvent *event)
d->selectPressed = false;
setKeepMouseGrab(false);
}
- const bool isMouse = QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(event);
+ const bool isMouse = QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(event)
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+ || d->selectByTouchDrag
+#endif
+ ;
+
#if QT_CONFIG(clipboard)
if (isMouse && QGuiApplication::clipboard()->supportsSelection()) {
if (event->button() == Qt::LeftButton) {
@@ -1640,9 +1648,11 @@ void QQuickTextInput::mouseReleaseEvent(QMouseEvent *event)
}
}
#endif
+
// On a touchscreen or with a stylus, set cursor position and focus on release, not on press;
// if Flickable steals the grab in the meantime, the cursor won't move.
- if (!isMouse)
+ // Check d->hasSelectedText() to keep touch-and-hold word selection working.
+ if (!isMouse && !d->hasSelectedText())
d->moveCursor(d->positionAt(event->position()), false);
if (d->focusOnPress && qGuiApp->styleHints()->setFocusOnTouchRelease())
@@ -1658,7 +1668,7 @@ bool QQuickTextInputPrivate::sendMouseEventToInputContext(QMouseEvent *event)
if (composeMode()) {
int tmp_cursor = positionAt(event->position());
int mousePos = tmp_cursor - m_cursor;
- if (mousePos >= 0 && mousePos <= m_textLayout.preeditAreaText().length()) {
+ if (mousePos >= 0 && mousePos <= m_textLayout.preeditAreaText().size()) {
if (event->type() == QEvent::MouseButtonRelease) {
QGuiApplication::inputMethod()->invokeAction(QInputMethod::Click, mousePos);
}
@@ -1684,8 +1694,10 @@ bool QQuickTextInput::event(QEvent* ev)
#if QT_CONFIG(shortcut)
Q_D(QQuickTextInput);
if (ev->type() == QEvent::ShortcutOverride) {
- if (d->m_readOnly)
+ if (d->m_readOnly) {
+ ev->ignore();
return false;
+ }
QKeyEvent* ke = static_cast<QKeyEvent*>(ev);
if (ke == QKeySequence::Copy
|| ke == QKeySequence::Paste
@@ -1728,6 +1740,7 @@ bool QQuickTextInput::event(QEvent* ev)
}
}
}
+ ev->ignore();
}
#endif
@@ -1799,7 +1812,7 @@ void QQuickTextInputPrivate::updateHorizontalScroll()
{
if (autoScroll && m_echoMode != QQuickTextInput::NoEcho) {
#if QT_CONFIG(im)
- const int preeditLength = m_textLayout.preeditAreaText().length();
+ const int preeditLength = m_textLayout.preeditAreaText().size();
ensureVisible(m_cursor, m_preeditCursor, preeditLength);
#else
ensureVisible(m_cursor);
@@ -1813,7 +1826,7 @@ void QQuickTextInputPrivate::updateVerticalScroll()
{
Q_Q(QQuickTextInput);
#if QT_CONFIG(im)
- const int preeditLength = m_textLayout.preeditAreaText().length();
+ const int preeditLength = m_textLayout.preeditAreaText().size();
#endif
const qreal height = qMax<qreal>(0, q->height() - q->topPadding() - q->bottomPadding());
qreal heightUsed = contentSize.height();
@@ -2038,7 +2051,7 @@ void QQuickTextInput::deselect()
void QQuickTextInput::selectAll()
{
Q_D(QQuickTextInput);
- d->setSelection(0, text().length());
+ d->setSelection(0, text().size());
}
/*!
@@ -2151,7 +2164,7 @@ void QQuickTextInput::insert(int position, const QString &text)
if (d->m_passwordMaskDelay > 0)
d->m_passwordEchoTimer.start(d->m_passwordMaskDelay, this);
}
- if (position < 0 || position > d->m_text.length())
+ if (position < 0 || position > d->m_text.size())
return;
const int priorState = d->m_undoState;
@@ -2164,31 +2177,31 @@ void QQuickTextInput::insert(int position, const QString &text)
}
if (d->m_maskData) {
insertText = d->maskString(position, insertText);
- for (int i = 0; i < insertText.length(); ++i) {
+ for (int i = 0; i < insertText.size(); ++i) {
d->addCommand(QQuickTextInputPrivate::Command(
QQuickTextInputPrivate::DeleteSelection, position + i, d->m_text.at(position + i), -1, -1));
d->addCommand(QQuickTextInputPrivate::Command(
QQuickTextInputPrivate::Insert, position + i, insertText.at(i), -1, -1));
}
- d->m_text.replace(position, insertText.length(), insertText);
+ d->m_text.replace(position, insertText.size(), insertText);
if (!insertText.isEmpty())
d->m_textDirty = true;
- if (position < d->m_selend && position + insertText.length() > d->m_selstart)
+ if (position < d->m_selend && position + insertText.size() > d->m_selstart)
d->m_selDirty = true;
} else {
- int remaining = d->m_maxLength - d->m_text.length();
+ int remaining = d->m_maxLength - d->m_text.size();
if (remaining != 0) {
insertText = insertText.left(remaining);
d->m_text.insert(position, insertText);
- for (int i = 0; i < insertText.length(); ++i)
+ for (int i = 0; i < insertText.size(); ++i)
d->addCommand(QQuickTextInputPrivate::Command(
QQuickTextInputPrivate::Insert, position + i, insertText.at(i), -1, -1));
if (d->m_cursor >= position)
- d->m_cursor += insertText.length();
+ d->m_cursor += insertText.size();
if (d->m_selstart >= position)
- d->m_selstart += insertText.length();
+ d->m_selstart += insertText.size();
if (d->m_selend >= position)
- d->m_selend += insertText.length();
+ d->m_selend += insertText.size();
d->m_textDirty = true;
if (position >= d->m_selstart && position <= d->m_selend)
d->m_selDirty = true;
@@ -2221,8 +2234,8 @@ void QQuickTextInput::remove(int start, int end)
{
Q_D(QQuickTextInput);
- start = qBound(0, start, d->m_text.length());
- end = qBound(0, end, d->m_text.length());
+ start = qBound(0, start, d->m_text.size());
+ end = qBound(0, end, d->m_text.size());
if (start > end)
qSwap(start, end);
@@ -2320,7 +2333,7 @@ QString QQuickTextInput::passwordCharacter() const
void QQuickTextInput::setPasswordCharacter(const QString &str)
{
Q_D(QQuickTextInput);
- if (str.length() < 1)
+ if (str.size() < 1)
return;
d->m_passwordCharacter = str.constData()[0];
if (d->m_echoMode == Password || d->m_echoMode == PasswordEchoOnEdit)
@@ -2619,7 +2632,7 @@ void QQuickTextInput::moveCursorSelection(int pos, SelectionMode mode)
finder.setPosition(anchor);
const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons();
- if (anchor < text.length() && (reasons == QTextBoundaryFinder::NotAtBoundary
+ if (anchor < text.size() && (reasons == QTextBoundaryFinder::NotAtBoundary
|| (reasons & QTextBoundaryFinder::EndOfItem))) {
finder.toPreviousBoundary();
}
@@ -2628,7 +2641,7 @@ void QQuickTextInput::moveCursorSelection(int pos, SelectionMode mode)
finder.setPosition(pos);
if (pos > 0 && !finder.boundaryReasons())
finder.toNextBoundary();
- const int cursor = finder.position() != -1 ? finder.position() : text.length();
+ const int cursor = finder.position() != -1 ? finder.position() : text.size();
d->setSelection(anchor, cursor - anchor);
} else if (anchor > pos || (anchor == pos && cursor > pos)) {
@@ -2641,10 +2654,10 @@ void QQuickTextInput::moveCursorSelection(int pos, SelectionMode mode)
|| (reasons & QTextBoundaryFinder::StartOfItem))) {
finder.toNextBoundary();
}
- anchor = finder.position() != -1 ? finder.position() : text.length();
+ anchor = finder.position() != -1 ? finder.position() : text.size();
finder.setPosition(pos);
- if (pos < text.length() && !finder.boundaryReasons())
+ if (pos < text.size() && !finder.boundaryReasons())
finder.toPreviousBoundary();
const int cursor = finder.position() != -1 ? finder.position() : 0;
@@ -2900,7 +2913,7 @@ void QQuickTextInputPrivate::updateDisplayText(bool forceUpdate)
if (m_echoMode == QQuickTextInput::Password) {
str.fill(m_passwordCharacter);
- if (m_passwordEchoTimer.isActive() && m_cursor > 0 && m_cursor <= m_text.length()) {
+ if (m_passwordEchoTimer.isActive() && m_cursor > 0 && m_cursor <= m_text.size()) {
int cursor = m_cursor - 1;
QChar uc = m_text.at(cursor);
str[cursor] = uc;
@@ -2920,7 +2933,7 @@ void QQuickTextInputPrivate::updateDisplayText(bool forceUpdate)
// drawing boxes when using fonts that don't have glyphs for such
// characters)
QChar* uc = str.data();
- for (int i = 0; i < str.length(); ++i) {
+ for (int i = 0; i < str.size(); ++i) {
if (uc[i] == QChar::LineSeparator
|| uc[i] == QChar::ParagraphSeparator
|| uc[i] == QChar::ObjectReplacementCharacter)
@@ -3292,7 +3305,7 @@ void QQuickTextInputPrivate::clear()
int priorState = m_undoState;
separateSelection();
m_selstart = 0;
- m_selend = m_text.length();
+ m_selend = m_text.size();
removeSelectedText();
separate();
finishChange(priorState, /*update*/false, /*edited*/false);
@@ -3313,7 +3326,7 @@ void QQuickTextInputPrivate::setSelection(int start, int length)
commitPreedit();
#endif
- if (start < 0 || start > m_text.length()) {
+ if (start < 0 || start > m_text.size()) {
qWarning("QQuickTextInputPrivate::setSelection: Invalid start position");
return;
}
@@ -3322,7 +3335,7 @@ void QQuickTextInputPrivate::setSelection(int start, int length)
if (start == m_selstart && start + length == m_selend && m_cursor == m_selend)
return;
m_selstart = start;
- m_selend = qMin(start + length, m_text.length());
+ m_selend = qMin(start + length, m_text.size());
m_cursor = m_selend;
} else if (length < 0) {
if (start == m_selend && start + length == m_selstart && m_cursor == m_selstart)
@@ -3454,14 +3467,14 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
if (m_echoMode == QQuickTextInput::PasswordEchoOnEdit && !m_passwordEchoEditing) {
updatePasswordEchoEditing(true);
m_selstart = 0;
- m_selend = m_text.length();
+ m_selend = m_text.size();
}
removeSelectedText();
}
int c = m_cursor; // cursor position after insertion of commit string
if (event->replacementStart() <= 0)
- c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength());
+ c += event->commitString().size() - qMin(-event->replacementStart(), event->replacementLength());
int cursorInsertPos = m_cursor + event->replacementStart();
if (cursorInsertPos < 0)
@@ -3471,7 +3484,7 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
if (event->replacementLength()) {
m_selstart = cursorInsertPos;
m_selend = m_selstart + event->replacementLength();
- m_selend = qMin(m_selend, m_text.length());
+ m_selend = qMin(m_selend, m_text.size());
removeSelectedText();
}
m_cursor = cursorInsertPos;
@@ -3480,7 +3493,7 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
internalInsert(event->commitString());
cursorPositionChanged = true;
} else {
- m_cursor = qBound(0, c, m_text.length());
+ m_cursor = qBound(0, c, m_text.size());
}
for (int i = 0; i < event->attributes().size(); ++i) {
@@ -3491,15 +3504,16 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
// not seem to take the mask into account, so it will reset cursor
// to an invalid position in such case.
if (!cursorPositionChanged)
- m_cursor = qBound(0, a.start + a.length, m_text.length());
+ m_cursor = qBound(0, a.start + a.length, m_text.size());
if (a.length) {
- m_selstart = qMax(0, qMin(a.start, m_text.length()));
+ m_selstart = qMax(0, qMin(a.start, m_text.size()));
m_selend = m_cursor;
if (m_selend < m_selstart) {
qSwap(m_selstart, m_selend);
}
selectionChange = true;
} else {
+ selectionChange = m_selstart != m_selend;
m_selstart = m_selend = 0;
}
cursorPositionChanged = true;
@@ -3514,7 +3528,7 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
m_undoPreeditState = priorState;
}
const int oldPreeditCursor = m_preeditCursor;
- m_preeditCursor = event->preeditString().length();
+ m_preeditCursor = event->preeditString().size();
hasImState = !event->preeditString().isEmpty();
bool cursorVisible = true;
QVector<QTextLayout::FormatRange> formats;
@@ -3642,7 +3656,7 @@ bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bo
validateFromState = m_undoPreeditState;
#endif
if (validateFromState >= 0 && wasValidInput && !m_validInput) {
- if (m_transactions.count())
+ if (m_transactions.size())
return false;
internalUndo(validateFromState);
m_history.resize(m_undoState);
@@ -3707,7 +3721,7 @@ void QQuickTextInputPrivate::internalSetText(const QString &txt, int pos, bool e
QString oldText = m_text;
if (m_maskData) {
m_text = maskString(0, txt, true);
- m_text += clearString(m_text.length(), m_maxLength - m_text.length());
+ m_text += clearString(m_text.size(), m_maxLength - m_text.size());
} else {
m_text = txt.isEmpty() ? txt : txt.left(m_maxLength);
}
@@ -3716,7 +3730,7 @@ void QQuickTextInputPrivate::internalSetText(const QString &txt, int pos, bool e
#if QT_CONFIG(im)
m_undoPreeditState = -1;
#endif
- m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos;
+ m_cursor = (pos < 0 || pos > m_text.size()) ? m_text.size() : pos;
m_textDirty = (oldText != m_text);
bool changed = finishChange(-1, true, edited);
@@ -3772,16 +3786,16 @@ void QQuickTextInputPrivate::internalInsert(const QString &s)
Q_ASSERT(!hasSelectedText()); // insert(), processInputMethodEvent() call removeSelectedText() first.
if (m_maskData) {
QString ms = maskString(m_cursor, s);
- for (int i = 0; i < ms.length(); ++i) {
+ for (int i = 0; i < ms.size(); ++i) {
addCommand (Command(DeleteSelection, m_cursor + i, m_text.at(m_cursor + i), -1, -1));
addCommand(Command(Insert, m_cursor + i, ms.at(i), -1, -1));
}
- m_text.replace(m_cursor, ms.length(), ms);
- m_cursor += ms.length();
+ m_text.replace(m_cursor, ms.size(), ms);
+ m_cursor += ms.size();
m_cursor = nextMaskBlank(m_cursor);
m_textDirty = true;
} else {
- int remaining = m_maxLength - m_text.length();
+ int remaining = m_maxLength - m_text.size();
if (remaining != 0) {
const QStringView remainingStr = QStringView{s}.left(remaining);
m_text.insert(m_cursor, remainingStr);
@@ -3805,7 +3819,7 @@ void QQuickTextInputPrivate::internalInsert(const QString &s)
*/
void QQuickTextInputPrivate::internalDelete(bool wasBackspace)
{
- if (m_cursor < m_text.length()) {
+ if (m_cursor < m_text.size()) {
cancelPasswordEchoTimer();
Q_ASSERT(!hasSelectedText()); // del(), backspace() call removeSelectedText() first.
addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)),
@@ -3831,7 +3845,7 @@ void QQuickTextInputPrivate::internalDelete(bool wasBackspace)
*/
void QQuickTextInputPrivate::removeSelectedText()
{
- if (m_selstart < m_selend && m_selend <= m_text.length()) {
+ if (m_selstart < m_selend && m_selend <= m_text.size()) {
cancelPasswordEchoTimer();
int i ;
if (m_selstart <= m_cursor && m_cursor < m_selend) {
@@ -3901,13 +3915,13 @@ void QQuickTextInputPrivate::parseInputMask(const QString &maskFields)
m_inputMask = maskFields;
} else {
m_inputMask = maskFields.left(delimiter);
- m_blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
+ m_blank = (delimiter + 1 < maskFields.size()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
}
// calculate m_maxLength / m_maskData length
m_maxLength = 0;
QChar c = u'\0';
- for (int i=0; i<m_inputMask.length(); i++) {
+ for (int i=0; i<m_inputMask.size(); i++) {
c = m_inputMask.at(i);
if (i > 0 && m_inputMask.at(i-1) == QLatin1Char('\\')) {
m_maxLength++;
@@ -3927,7 +3941,7 @@ void QQuickTextInputPrivate::parseInputMask(const QString &maskFields)
bool s;
bool escape = false;
int index = 0;
- for (int i = 0; i < m_inputMask.length(); i++) {
+ for (int i = 0; i < m_inputMask.size(); i++) {
c = m_inputMask.at(i);
if (escape) {
s = true;
@@ -4078,7 +4092,7 @@ QQuickTextInputPrivate::ValidatorState QQuickTextInputPrivate::hasAcceptableInpu
if (!m_maskData)
return AcceptableInput;
- if (str.length() != m_maxLength)
+ if (str.size() != m_maxLength)
return InvalidInput;
for (int i=0; i < m_maxLength; ++i) {
@@ -4113,7 +4127,7 @@ QString QQuickTextInputPrivate::maskString(uint pos, const QString &str, bool cl
QString s = QString::fromLatin1("");
int i = pos;
while (i < m_maxLength) {
- if (strIndex < str.length()) {
+ if (strIndex < str.size()) {
if (m_maskData[i].separator) {
s += m_maskData[i].maskChar;
if (str[strIndex] == m_maskData[i].maskChar)
@@ -4136,7 +4150,7 @@ QString QQuickTextInputPrivate::maskString(uint pos, const QString &str, bool cl
// search for separator first
int n = findInMask(i, true, true, str[strIndex]);
if (n != -1) {
- if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[strIndex]))) {
+ if (str.size() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[strIndex]))) {
s += QStringView{fill}.mid(i, n-i+1);
i = n + 1; // update i to find + 1
}
@@ -4204,7 +4218,7 @@ QString QQuickTextInputPrivate::stripString(const QString &str) const
return str;
QString s;
- int end = qMin(m_maxLength, str.length());
+ int end = qMin(m_maxLength, str.size());
for (int i = 0; i < end; ++i) {
if (m_maskData[i].separator)
s += m_maskData[i].maskChar;
@@ -4629,7 +4643,7 @@ void QQuickTextInputPrivate::processKeyEvent(QKeyEvent* event)
// no need to call del() if we have a selection, insert
// does it already
&& !hasSelectedText()
- && !(m_cursor == q_func()->text().length())) {
+ && !(m_cursor == q_func()->text().size())) {
del();
}
@@ -4872,7 +4886,7 @@ void QQuickTextInput::setOldSelectionDefault()
Q_D(QQuickTextInput);
d->selectByMouse = false;
d->selectByTouchDrag = true;
- qCDebug(lcTextInput, "pre-6.4 behavior chosen by import version: selectByMouse defaults false; if enabled, touchscreen acts like a mouse");
+ qCDebug(lcQuickTextInput, "pre-6.4 behavior chosen: selectByMouse defaults false; if enabled, touchscreen acts like a mouse");
}
// TODO in 6.7.0: remove the note about versions prior to 6.4 in selectByMouse() documentation
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index 3facf42496..01d90f6b10 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -315,7 +315,7 @@ public:
#endif
}
- bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); }
+ bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.size(); }
bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; }
void setSelection(int start, int length);
@@ -342,7 +342,7 @@ public:
}
int start() const { return 0; }
- int end() const { return m_text.length(); }
+ int end() const { return m_text.size(); }
QString realText() const;
@@ -379,18 +379,18 @@ public:
void cursorWordBackward(bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
void home(bool mark) { moveCursor(0, mark); }
- void end(bool mark) { moveCursor(q_func()->text().length(), mark); }
+ void end(bool mark) { moveCursor(q_func()->text().size(), mark); }
void backspace();
void del();
void deselect() { internalDeselect(); finishChange(); }
- void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.length(), true); }
+ void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.size(), true); }
void insert(const QString &);
void clear();
void selectWordAtPos(int);
- void setCursorPosition(int pos) { if (pos <= m_text.length()) moveCursor(qMax(0, pos)); }
+ void setCursorPosition(int pos) { if (pos <= m_text.size()) moveCursor(qMax(0, pos)); }
bool fixup();
diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp
index 84fae432d3..171cbdee8b 100644
--- a/src/quick/items/qquicktextnode.cpp
+++ b/src/quick/items/qquicktextnode.cpp
@@ -223,7 +223,7 @@ void QQuickTextNode::addTextLayout(const QPointF &position, QTextLayout *textLay
engine.setPosition(position);
#if QT_CONFIG(im)
- int preeditLength = textLayout->preeditAreaText().length();
+ int preeditLength = textLayout->preeditAreaText().size();
int preeditPosition = textLayout->preeditAreaPosition();
#endif
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index df96a4af41..d2256128cf 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -175,10 +175,7 @@ void QQuickTextNodeEngine::addTextDecorations(const QVarLengthArray<TextDecorati
{
QRectF &rect = textDecoration.rect;
- rect.setY(qRound(rect.y()
- + m_currentLine.ascent()
- + (m_currentLine.leadingIncluded() ? m_currentLine.leading() : qreal(0.0f))
- + offset));
+ rect.setY(qRound(rect.y() + m_currentLine.ascent() + offset));
rect.setHeight(thickness);
}
@@ -960,7 +957,7 @@ void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QText
{
Q_ASSERT(textDocument);
#if QT_CONFIG(im)
- int preeditLength = block.isValid() ? block.layout()->preeditAreaText().length() : 0;
+ int preeditLength = block.isValid() ? block.layout()->preeditAreaText().size() : 0;
int preeditPosition = block.isValid() ? block.layout()->preeditAreaPosition() : -1;
#endif
@@ -1082,14 +1079,14 @@ void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QText
}
QQuickTextNodeEngine::SelectionState selectionState =
- (selectionStart < textPos + text.length()
+ (selectionStart < textPos + text.size()
&& selectionEnd >= textPos)
? QQuickTextNodeEngine::Selected
: QQuickTextNodeEngine::Unselected;
addTextObject(block, QPointF(), charFormat, selectionState, textDocument, textPos);
}
- textPos += text.length();
+ textPos += text.size();
} else {
if (charFormat.foreground().style() != Qt::NoBrush)
setTextColor(charFormat.foreground().color());
diff --git a/src/quick/items/qquicktreeview.cpp b/src/quick/items/qquicktreeview.cpp
index a8df1ac00a..3ba739d0ca 100644
--- a/src/quick/items/qquicktreeview.cpp
+++ b/src/quick/items/qquicktreeview.cpp
@@ -67,7 +67,7 @@
\li \c {required property bool expanded}
- Is \c true if the model item drawn by the delegate is expanded
in the view.
- \li \c {required property int hasChildren}
+ \li \c {required property bool hasChildren}
- Is \c true if the model item drawn by the delegate has children
in the model.
\li \c {required property int depth}
@@ -338,8 +338,8 @@ void QQuickTreeViewPrivate::updateSelection(const QRect &oldSelection, const QRe
for (int row = newRect.y(); row <= newRect.y() + newRect.height(); ++row) {
if (oldRect.y() != -1 && oldRect.y() <= row && row <= oldRect.y() + oldRect.height())
continue;
- const QModelIndex startIndex = q->modelIndex(newRect.x(), row);
- const QModelIndex endIndex = q->modelIndex(newRect.x() + newRect.width(), row);
+ const QModelIndex startIndex = q->index(row, newRect.x());
+ const QModelIndex endIndex = q->index(row, newRect.x() + newRect.width());
selectionModel->select(QItemSelection(startIndex, endIndex), QItemSelectionModel::Select);
}
@@ -351,15 +351,15 @@ void QQuickTreeViewPrivate::updateSelection(const QRect &oldSelection, const QRe
if (oldRect.x() <= column && column <= oldRect.x() + oldRect.width())
continue;
for (int row = newRect.y(); row <= newRect.y() + newRect.height(); ++row)
- selectionModel->select(q->modelIndex(column, row), QItemSelectionModel::Select);
+ selectionModel->select(q->index(row, column), QItemSelectionModel::Select);
}
// Unselect the rows inside oldRect that don't overlap with newRect
for (int row = oldRect.y(); row <= oldRect.y() + oldRect.height(); ++row) {
if (newRect.y() <= row && row <= newRect.y() + newRect.height())
continue;
- const QModelIndex startIndex = q->modelIndex(oldRect.x(), row);
- const QModelIndex endIndex = q->modelIndex(oldRect.x() + oldRect.width(), row);
+ const QModelIndex startIndex = q->index(row, oldRect.x());
+ const QModelIndex endIndex = q->index(row, oldRect.x() + oldRect.width());
selectionModel->select(QItemSelection(startIndex, endIndex), QItemSelectionModel::Deselect);
}
@@ -375,7 +375,7 @@ void QQuickTreeViewPrivate::updateSelection(const QRect &oldSelection, const QRe
// performance. But large selections containing a lot of columns is not normally
// the case for a treeview, so accept this potential corner case for now.
for (int row = newRect.y(); row <= newRect.y() + newRect.height(); ++row)
- selectionModel->select(q->modelIndex(column, row), QItemSelectionModel::Deselect);
+ selectionModel->select(q->index(row, column), QItemSelectionModel::Deselect);
}
}
}
@@ -588,10 +588,25 @@ QPoint QQuickTreeView::cellAtIndex(const QModelIndex &index) const
return QPoint(tableIndex.column(), tableIndex.row());
}
-QModelIndex QQuickTreeView::modelIndex(int column, int row) const
+#if QT_DEPRECATED_SINCE(6, 4)
+QModelIndex QQuickTreeView::modelIndex(int row, int column) const
{
- return modelIndex({column, row});
+ static const bool compat6_4 = qEnvironmentVariable("QT_QUICK_TABLEVIEW_COMPAT_VERSION") == QStringLiteral("6.4");
+ if (compat6_4) {
+ // XXX Qt 7: Remove this compatibility path here and in QQuickTableView.
+ // In Qt 6.4.0 and 6.4.1, a source incompatible change led to row and column
+ // being documented to be specified in the opposite order.
+ // QT_QUICK_TABLEVIEW_COMPAT_VERSION can therefore be set to force tableview
+ // to continue accepting calls to modelIndex(column, row).
+ return modelIndex({row, column});
+ } else {
+ qmlWarning(this) << "modelIndex(row, column) is deprecated. "
+ "Use index(row, column) instead. For more information, see "
+ "https://doc.qt.io/qt-6/qml-qtquick-tableview-obsolete.html";
+ return modelIndex({column, row});
+ }
}
+#endif
void QQuickTreeView::keyPressEvent(QKeyEvent *event)
{
diff --git a/src/quick/items/qquicktreeview_p.h b/src/quick/items/qquicktreeview_p.h
index f86d6f9369..3b77477684 100644
--- a/src/quick/items/qquicktreeview_p.h
+++ b/src/quick/items/qquicktreeview_p.h
@@ -44,9 +44,13 @@ public:
Q_REVISION(6, 4) Q_INVOKABLE void expandToIndex(const QModelIndex &index);
Q_INVOKABLE QModelIndex modelIndex(const QPoint &cell) const override;
- Q_INVOKABLE QModelIndex modelIndex(int column, int row) const override;
Q_INVOKABLE QPoint cellAtIndex(const QModelIndex &index) const override;
+#if QT_DEPRECATED_SINCE(6, 4)
+ QT_DEPRECATED_VERSION_X_6_4("Use index(row, column) instead")
+ Q_REVISION(6, 4) Q_INVOKABLE QModelIndex modelIndex(int row, int column) const override;
+#endif
+
Q_SIGNALS:
void expanded(int row, int depth);
void collapsed(int row, bool recursively);
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 2026d41fdf..692e7f284d 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -53,6 +53,7 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcHoverTrace)
Q_DECLARE_LOGGING_CATEGORY(lcMouse)
Q_DECLARE_LOGGING_CATEGORY(lcTouch)
Q_DECLARE_LOGGING_CATEGORY(lcPtr)
@@ -279,7 +280,7 @@ struct PolishLoopDetector
**/
bool check(QQuickItem *item, int itemsRemainingBeforeUpdatePolish)
{
- if (itemsToPolish.count() > itemsRemainingBeforeUpdatePolish) {
+ if (itemsToPolish.size() > itemsRemainingBeforeUpdatePolish) {
// Detected potential polish loop.
++numPolishLoopsInSequence;
if (numPolishLoopsInSequence >= 1000) {
@@ -338,7 +339,7 @@ void QQuickWindowPrivate::polishItems()
QQuickItem *item = itemsToPolish.takeLast();
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
itemPrivate->polishScheduled = false;
- const int itemsRemaining = itemsToPolish.count();
+ const int itemsRemaining = itemsToPolish.size();
itemPrivate->updatePolish();
item->updatePolish();
if (polishLoopDetector.check(item, itemsRemaining) == true)
@@ -651,7 +652,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
pixelSize = size * devicePixelRatio;
else
pixelSize = surfaceSize;
- QSizeF logicalSize = QSizeF(pixelSize) / devicePixelRatio;
+ QSize logicalSize = pixelSize / devicePixelRatio;
renderer->setDevicePixelRatio(devicePixelRatio);
renderer->setDeviceRect(QRect(QPoint(0, 0), pixelSize));
@@ -1078,7 +1079,11 @@ QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent)
}
/*!
- \internal
+ Constructs a window for displaying a QML scene, whose rendering will
+ be controlled by the \a control object.
+ Please refer to QQuickRenderControl's documentation for more information.
+
+ \since 5.4
*/
QQuickWindow::QQuickWindow(QQuickRenderControl *control)
: QWindow(*(new QQuickWindowPrivate), nullptr)
@@ -1381,6 +1386,7 @@ bool QQuickWindow::event(QEvent *event)
for (pt : pe->points()) would only iterate once, so we might as well skip that logic.
*/
if (pe->pointCount()) {
+ const bool synthMouse = QQuickDeliveryAgentPrivate::isSynthMouse(pe);
if (QQuickDeliveryAgentPrivate::subsceneAgentsExist) {
bool ret = false;
// Split up the multi-point event according to the relevant QQuickDeliveryAgent that should deliver to each existing grabber
@@ -1389,7 +1395,7 @@ bool QQuickWindow::event(QEvent *event)
QEventPoint::States eventStates;
auto insert = [&](QQuickDeliveryAgent *ptda, const QEventPoint &pt) {
- if (pt.state() == QEventPoint::Pressed)
+ if (pt.state() == QEventPoint::Pressed && !synthMouse)
pe->clearPassiveGrabbers(pt);
auto &ptList = deliveryAgentsNeedingPoints[ptda];
auto idEquals = [](auto id) { return [id] (const auto &e) { return e.id() == id; }; };
@@ -1452,7 +1458,9 @@ bool QQuickWindow::event(QEvent *event)
if (ret)
return true;
- } else {
+ } else if (!synthMouse) {
+ // clear passive grabbers unless it's a system synth-mouse event
+ // QTBUG-104890: Windows sends synth mouse events (which should be ignored) after touch events
for (const auto &pt : pe->points()) {
if (pt.state() == QEventPoint::Pressed)
pe->clearPassiveGrabbers(pt);
@@ -1665,10 +1673,14 @@ void QQuickWindowPrivate::updateCursor(const QPointF &scenePos, QQuickItem *root
QWindow *window = renderWindow ? renderWindow : q;
cursorItem = cursorItemAndHandler.first;
cursorHandler = cursorItemAndHandler.second;
- if (cursorItem)
- window->setCursor(QQuickItemPrivate::get(cursorItem)->effectiveCursor(cursorHandler));
- else
+ if (cursorItem) {
+ const auto cursor = QQuickItemPrivate::get(cursorItem)->effectiveCursor(cursorHandler);
+ qCDebug(lcHoverTrace) << "setting cursor" << cursor << "from" << cursorHandler << "or" << cursorItem;
+ window->setCursor(cursor);
+ } else {
+ qCDebug(lcHoverTrace) << "unsetting cursor";
window->unsetCursor();
+ }
}
}
@@ -1683,7 +1695,7 @@ QPair<QQuickItem*, QQuickPointerHandler*> QQuickWindowPrivate::findCursorItemAnd
if (itemPrivate->subtreeCursorEnabled) {
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
- for (int ii = children.count() - 1; ii >= 0; --ii) {
+ for (int ii = children.size() - 1; ii >= 0; --ii) {
QQuickItem *child = children.at(ii);
if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
continue;
@@ -1806,7 +1818,7 @@ void QQuickWindowPrivate::rhiCreationFailureMessage(const QString &backendName,
void QQuickWindowPrivate::cleanupNodes()
{
- for (int ii = 0; ii < cleanupNodeList.count(); ++ii)
+ for (int ii = 0; ii < cleanupNodeList.size(); ++ii)
delete cleanupNodeList.at(ii);
cleanupNodeList.clear();
}
@@ -1841,7 +1853,7 @@ void QQuickWindowPrivate::cleanupNodesOnShutdown(QQuickItem *item)
}
}
- for (int ii = 0; ii < p->childItems.count(); ++ii)
+ for (int ii = 0; ii < p->childItems.size(); ++ii)
cleanupNodesOnShutdown(p->childItems.at(ii));
}
@@ -1896,7 +1908,7 @@ static QSGNode *fetchNextNode(QQuickItemPrivate *itemPriv, int &ii, bool &return
{
QList<QQuickItem *> orderedChildren = itemPriv->paintOrderChildItems();
- for (; ii < orderedChildren.count() && orderedChildren.at(ii)->z() < 0; ++ii) {
+ for (; ii < orderedChildren.size() && orderedChildren.at(ii)->z() < 0; ++ii) {
QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(orderedChildren.at(ii));
if (!childPrivate->explicitVisible &&
(!childPrivate->extra.isAllocated() || !childPrivate->extra->effectRefCount))
@@ -1911,7 +1923,7 @@ static QSGNode *fetchNextNode(QQuickItemPrivate *itemPriv, int &ii, bool &return
return itemPriv->paintNode;
}
- for (; ii < orderedChildren.count(); ++ii) {
+ for (; ii < orderedChildren.size(); ++ii) {
QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(orderedChildren.at(ii));
if (!childPrivate->explicitVisible &&
(!childPrivate->extra.isAllocated() || !childPrivate->extra->effectRefCount))
@@ -1939,7 +1951,7 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
if (itemPriv->x != 0. || itemPriv->y != 0.)
matrix.translate(itemPriv->x, itemPriv->y);
- for (int ii = itemPriv->transforms.count() - 1; ii >= 0; --ii)
+ for (int ii = itemPriv->transforms.size() - 1; ii >= 0; --ii)
itemPriv->transforms.at(ii)->applyTo(&matrix);
if (itemPriv->scale() != 1. || itemPriv->rotation() != 0.) {
@@ -3706,7 +3718,7 @@ void QQuickWindowPrivate::runAndClearJobs(QList<QRunnable *> *jobs)
jobs->clear();
renderJobMutex.unlock();
- for (QRunnable *r : qAsConst(jobList)) {
+ for (QRunnable *r : std::as_const(jobList)) {
r->run();
delete r;
}
@@ -3824,7 +3836,7 @@ QSGRendererInterface *QQuickWindow::rendererInterface() const
graphics API based on the platform and other conditions, set \a api to
QSGRendererInterface::Unknown.
- \since 5.8
+ \since 6.0
*/
void QQuickWindow::setGraphicsApi(QSGRendererInterface::GraphicsApi api)
{
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index 4da188bbfe..0c0ee5e579 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -107,6 +107,18 @@ void QSGSoftwareRenderContext::initializeIfNeeded()
void QSGSoftwareRenderContext::invalidate()
{
+ qDeleteAll(m_texturesToDelete);
+ m_texturesToDelete.clear();
+
+ qDeleteAll(m_textures);
+ m_textures.clear();
+
+ qDeleteAll(m_fontEnginesToClean);
+ m_fontEnginesToClean.clear();
+
+ qDeleteAll(m_glyphCaches);
+ m_glyphCaches.clear();
+
m_sg->renderContextInvalidated(this);
emit invalidated();
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp
index 71e9c7b2aa..488f622dce 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp
@@ -84,7 +84,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st
{
//normalize stops
bool needsNormalization = false;
- for (const QGradientStop &stop : qAsConst(stops)) {
+ for (const QGradientStop &stop : std::as_const(stops)) {
if (stop.first < 0.0 || stop.first > 1.0) {
needsNormalization = true;
break;
@@ -93,7 +93,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st
if (needsNormalization) {
QGradientStops normalizedStops;
- if (stops.count() == 1) {
+ if (stops.size() == 1) {
//If there is only one stop, then the position does not matter
//It is just treated as a color
QGradientStop stop = stops.at(0);
@@ -104,7 +104,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st
int below = -1;
int above = -1;
QVector<int> between;
- for (int i = 0; i < stops.count(); ++i) {
+ for (int i = 0; i < stops.size(); ++i) {
if (stops.at(i).first < 0.0) {
below = i;
} else if (stops.at(i).first > 1.0) {
@@ -118,7 +118,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st
//Interpoloate new color values for above and below
if (below != -1 ) {
//If there are more than one stops left, interpolate
- if (below + 1 < stops.count()) {
+ if (below + 1 < stops.size()) {
normalizedStops.append(interpolateStop(stops.at(below), stops.at(below + 1), 0.0));
} else {
QGradientStop singleStop;
@@ -128,7 +128,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st
}
}
- for (int i = 0; i < between.count(); ++i)
+ for (int i = 0; i < between.size(); ++i)
normalizedStops.append(stops.at(between.at(i)));
if (above != -1) {
@@ -249,8 +249,8 @@ bool QSGSoftwareInternalRectangleNode::isOpaque() const
return false;
if (m_penWidth > 0.0f && m_penColor.alpha() < 255)
return false;
- if (m_stops.count() > 0) {
- for (const QGradientStop &stop : qAsConst(m_stops)) {
+ if (m_stops.size() > 0) {
+ for (const QGradientStop &stop : std::as_const(m_stops)) {
if (stop.second.alpha() < 255)
return false;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
index 56400161bb..20e1ca5b8b 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
@@ -47,7 +47,7 @@ void QSGSoftwareRenderableNodeUpdater::endVisit(QSGTransformNode *)
bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node)
{
// Make sure to translate the clip rect into world coordinates
- if (m_clipState.count() == 0 || (m_clipState.count() == 1 && m_clipState.top().isNull())) {
+ if (m_clipState.size() == 0 || (m_clipState.size() == 1 && m_clipState.top().isNull())) {
m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect())));
m_hasClip = true;
} else {
@@ -61,7 +61,7 @@ bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node)
void QSGSoftwareRenderableNodeUpdater::endVisit(QSGClipNode *)
{
m_clipState.pop();
- if (m_clipState.count() == 0 || (m_clipState.count() == 1 && m_clipState.top().isNull()))
+ if (m_clipState.size() == 0 || (m_clipState.size() == 1 && m_clipState.top().isNull()))
m_hasClip = false;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index fa709deea2..d12deec9f6 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -754,7 +754,7 @@ void QSGSoftwareThreadedRenderLoop::onAnimationStarted()
{
startOrStopAnimationTimer();
- for (const WindowData &w : qAsConst(m_windows))
+ for (const WindowData &w : std::as_const(m_windows))
w.window->requestUpdate();
}
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
index 8ae245f07e..46c2c1022f 100644
--- a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
@@ -63,7 +63,7 @@ public:
QSGTexture *removedFromAtlas(QRhiResourceUpdateBatch *) const override;
const QByteArray &data() const { return m_data; }
- int sizeInBytes() const { return m_data.length(); }
+ int sizeInBytes() const { return m_data.size(); }
private:
QRectF m_texture_coords_rect;
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index df7575a33e..29d507a8fb 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -272,14 +272,14 @@ void ShaderManager::invalidated()
void ShaderManager::clearCachedRendererData()
{
- for (ShaderManager::Shader *sms : qAsConst(stockShaders)) {
+ for (ShaderManager::Shader *sms : std::as_const(stockShaders)) {
QSGMaterialShader *s = sms->programRhi.program;
if (s) {
QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
sd->clearCachedRendererData();
}
}
- for (ShaderManager::Shader *sms : qAsConst(rewrittenShaders)) {
+ for (ShaderManager::Shader *sms : std::as_const(rewrittenShaders)) {
QSGMaterialShader *s = sms->programRhi.program;
if (s) {
QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
@@ -915,8 +915,14 @@ Renderer::~Renderer()
qsg_wipeBatch(m_batchPool.at(i));
}
- for (Node *n : qAsConst(m_nodes))
+ for (Node *n : std::as_const(m_nodes)) {
+ if (n->type() == QSGNode::GeometryNodeType) {
+ Element *e = n->element();
+ if (!e->removed)
+ m_elementsToDelete.add(e);
+ }
m_nodeAllocator.release(n);
+ }
// Remaining elements...
for (int i=0; i<m_elementsToDelete.size(); ++i)
@@ -1980,7 +1986,7 @@ void Renderer::uploadBatch(Batch *b)
bool canMerge = (g->drawingMode() == QSGGeometry::DrawTriangles || g->drawingMode() == QSGGeometry::DrawTriangleStrip ||
g->drawingMode() == QSGGeometry::DrawLines || g->drawingMode() == QSGGeometry::DrawPoints)
&& b->positionAttribute >= 0
- && g->indexType() == QSGGeometry::UnsignedShortType
+ && (g->indexType() == QSGGeometry::UnsignedShortType && g->indexCount() > 0)
&& (flags & (QSGMaterial::NoBatching | QSGMaterial_FullMatrix)) == 0
&& ((flags & QSGMaterial::RequiresFullMatrixExceptTranslate) == 0 || b->isTranslateOnlyToRoot())
&& b->isSafeToBatch();
@@ -2869,11 +2875,11 @@ void Renderer::updateMaterialDynamicData(ShaderManager::Shader *sms,
pd->samplerBindingTable[binding] = samplers; // does not own
}
- if (pd->textureBindingTable[binding].count() == pd->samplerBindingTable[binding].count()) {
+ if (pd->textureBindingTable[binding].size() == pd->samplerBindingTable[binding].size()) {
QVarLengthArray<QRhiShaderResourceBinding::TextureAndSampler, 4> textureSamplers;
- for (int i = 0; i < pd->textureBindingTable[binding].count(); ++i) {
+ for (int i = 0; i < pd->textureBindingTable[binding].size(); ++i) {
QRhiTexture *texture = pd->textureBindingTable[binding].at(i)->rhiTexture();
@@ -2960,7 +2966,7 @@ void Renderer::updateMaterialDynamicData(ShaderManager::Shader *sms,
// with increasing binding points afterwards, so the list is already sorted based
// on the binding points, thus we can save some time by telling the QRhi backend
// not to sort again.
- if (pd->ubufBinding <= 0 || bindings.count() <= 1)
+ if (pd->ubufBinding <= 0 || bindings.size() <= 1)
flags |= QRhiShaderResourceBindings::BindingsAreSorted;
e->srb->updateResources(flags);
@@ -3440,7 +3446,7 @@ void Renderer::releaseElement(Element *e, bool inDestructor)
} else {
if (e->srb) {
if (!inDestructor) {
- if (m_shaderManager->srbPool.count() < m_srbPoolThreshold)
+ if (m_shaderManager->srbPool.size() < m_srbPoolThreshold)
m_shaderManager->srbPool.insert(e->srb->serializedLayoutDescription(), e->srb);
else
delete e->srb;
@@ -3783,7 +3789,7 @@ void Renderer::recordRenderPass(RenderPassContext *ctx)
QRhiCommandBuffer *cb = commandBuffer();
cb->debugMarkBegin(QByteArrayLiteral("Qt Quick scene render"));
- for (int i = 0, ie = ctx->opaqueRenderBatches.count(); i != ie; ++i) {
+ for (int i = 0, ie = ctx->opaqueRenderBatches.size(); i != ie; ++i) {
PreparedRenderBatch *renderBatch = &ctx->opaqueRenderBatches[i];
if (renderBatch->batch->merged)
renderMergedBatch(renderBatch);
@@ -3791,7 +3797,7 @@ void Renderer::recordRenderPass(RenderPassContext *ctx)
renderUnmergedBatch(renderBatch);
}
- for (int i = 0, ie = ctx->alphaRenderBatches.count(); i != ie; ++i) {
+ for (int i = 0, ie = ctx->alphaRenderBatches.size(); i != ie; ++i) {
PreparedRenderBatch *renderBatch = &ctx->alphaRenderBatches[i];
if (renderBatch->batch->merged)
renderMergedBatch(renderBatch);
@@ -3803,7 +3809,7 @@ void Renderer::recordRenderPass(RenderPassContext *ctx)
if (m_renderMode == QSGRendererInterface::RenderMode3D) {
// depth post-pass
- for (int i = 0, ie = ctx->alphaRenderBatches.count(); i != ie; ++i) {
+ for (int i = 0, ie = ctx->alphaRenderBatches.size(); i != ie; ++i) {
PreparedRenderBatch *renderBatch = &ctx->alphaRenderBatches[i];
if (renderBatch->batch->merged)
renderMergedBatch(renderBatch, true);
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 06771d2686..5b0c024466 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -115,7 +115,7 @@ public:
// one. when an item is released, we'll reset m_freePage anyway.
if (!p) {
p = new AllocatorPage<Type, PageSize>();
- m_freePage = pages.count();
+ m_freePage = pages.size();
pages.push_back(p);
}
uint pos = p->blocks[PageSize - p->available];
diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp
index bd082a8d79..9541107b78 100644
--- a/src/quick/scenegraph/coreapi/qsggeometry.cpp
+++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp
@@ -370,8 +370,10 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D()
Geometry objects are constructed by default with DrawTriangleStrip as
the drawing mode.
- The attribute structure is assumed to be POD and the geometry object
- assumes this will not go away. There is no memory management involved.
+ \note \a attributes and the \l Attribute objects referenced by it must
+ stay valid for the entire lifetime of the QSGGeometry.
+ QSGGeometry stores a reference to \a attributes and does not delete
+ the \l Attribute objects.
*/
QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes,
@@ -494,13 +496,18 @@ const void *QSGGeometry::indexData() const
Specifies the drawing mode, also called primitive topology.
+ \note Starting with Qt 6 the scene graph only exposes topologies that are
+ supported across all the supported 3D graphics APIs. As a result, the
+ values \c DrawLineLoop and \c DrawTriangleFan are no longer supported at
+ run time in Qt 6, even though the enum values themselves are still present.
+
\value DrawPoints
\value DrawLines
- \value DrawLineLoop
+ \omitvalue DrawLineLoop
\value DrawLineStrip
\value DrawTriangles
\value DrawTriangleStrip
- \value DrawTriangleFan
+ \omitvalue DrawTriangleFan
*/
/*!
@@ -534,10 +541,10 @@ void QSGGeometry::setDrawingMode(unsigned int mode)
}
/*!
- Gets the current line or point width or to be used for this
- geometry. This property only applies to line width when the drawingMode
- is DrawLines, DarwLineStrip, or DrawLineLoop. When supported, it also
- applies to point size when the drawingMode is DrawPoints.
+ Gets the current line or point width or to be used for this geometry. This
+ property only applies to line width when the drawingMode is DrawLines or
+ DrawLineStrip. When supported, it also applies to point size when the
+ drawingMode is DrawPoints.
The default value is \c 1.0
@@ -556,10 +563,10 @@ float QSGGeometry::lineWidth() const
}
/*!
- Sets the line or point width to be used for this geometry to \a
- width. This property only applies to line width when the drawingMode is
- DrawLines, DrawLineStrip, or DrawLineLoop. When supported, it also
- applies to point size when the drawingMode is DrawPoints.
+ Sets the line or point width to be used for this geometry to \a width. This
+ property only applies to line width when the drawingMode is DrawLines or
+ DrawLineStrip. When supported, it also applies to point size when the
+ drawingMode is DrawPoints.
\note Support for point and line drawing may be limited at run time,
depending on the platform and graphics API. For example, some APIs do
diff --git a/src/quick/scenegraph/coreapi/qsggeometry.h b/src/quick/scenegraph/coreapi/qsggeometry.h
index 1583bfd5b2..4392070b6e 100644
--- a/src/quick/scenegraph/coreapi/qsggeometry.h
+++ b/src/quick/scenegraph/coreapi/qsggeometry.h
@@ -165,6 +165,7 @@ public:
void setLineWidth(float w);
private:
+ Q_DISABLE_COPY_MOVE(QSGGeometry)
friend class QSGGeometryData;
int m_drawing_mode;
diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp b/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp
index e1edbc2445..a3e8b179b3 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp
@@ -247,7 +247,7 @@ void QSGMaterialShaderPrivate::prepare(QShader::Variant vertexShaderVariant)
const QShaderDescription desc = it->shader.description();
const QVector<QShaderDescription::UniformBlock> ubufs = desc.uniformBlocks();
- const int ubufCount = ubufs.count();
+ const int ubufCount = ubufs.size();
if (ubufCount > 1) {
qWarning("Multiple uniform blocks found in shader. "
"This should be avoided as Qt Quick supports only one.");
@@ -272,7 +272,7 @@ void QSGMaterialShaderPrivate::prepare(QShader::Variant vertexShaderVariant)
}
const QVector<QShaderDescription::InOutVariable> imageSamplers = desc.combinedImageSamplers();
- const int imageSamplersCount = imageSamplers.count();
+ const int imageSamplersCount = imageSamplers.size();
for (int i = 0; i < imageSamplersCount; ++i) {
const QShaderDescription::InOutVariable &var(imageSamplers[i]);
diff --git a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
index 4352b9e795..9183de29d9 100644
--- a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
@@ -275,7 +275,7 @@ QRhiGraphicsPipeline *RhiVisualizer::PipelineCache::pipeline(RhiVisualizer *visu
quint32 vertexStride,
bool blendOneOne)
{
- for (int i = 0, ie = pipelines.count(); i != ie; ++i) {
+ for (int i = 0, ie = pipelines.size(); i != ie; ++i) {
const Pipeline &p(pipelines.at(i));
if (p.topology == topology && p.format == vertexFormat && p.stride == vertexStride)
return p.ps;
@@ -316,7 +316,7 @@ QRhiGraphicsPipeline *RhiVisualizer::PipelineCache::pipeline(RhiVisualizer *visu
void RhiVisualizer::PipelineCache::releaseResources()
{
- for (int i = 0, ie = pipelines.count(); i != ie; ++i)
+ for (int i = 0, ie = pipelines.size(); i != ie; ++i)
delete pipelines.at(i).ps;
pipelines.clear();
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp
index 15167f8ae5..f9c1f86436 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.cpp
+++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp
@@ -686,6 +686,7 @@ namespace QNativeInterface {
\inmodule QtQuick
\ingroup native-interfaces
\ingroup native-interfaces-qsgtexture
+ \inheaderfile QSGTexture
\brief Provides access to and enables adopting OpenGL texture objects.
\since 6.0
*/
@@ -786,6 +787,7 @@ namespace QNativeInterface {
\inmodule QtQuick
\ingroup native-interfaces
\ingroup native-interfaces-qsgtexture
+ \inheaderfile QSGTexture
\brief Provides access to and enables adopting Direct3D 11 texture objects.
\since 6.0
*/
@@ -846,6 +848,7 @@ namespace QNativeInterface {
\inmodule QtQuick
\ingroup native-interfaces
\ingroup native-interfaces-qsgtexture
+ \inheaderfile QSGTexture
\brief Provides access to and enables adopting Metal texture objects.
\since 6.0
*/
@@ -893,6 +896,7 @@ namespace QNativeInterface {
\inmodule QtQuick
\ingroup native-interfaces
\ingroup native-interfaces-qsgtexture
+ \inheaderfile QSGTexture
\brief Provides access to and enables adopting Vulkan image objects.
\since 6.0
*/
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index b2932a12ea..c20a126dce 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -91,7 +91,7 @@ void QSGDistanceFieldGlyphCache::populate(const QVector<glyph_t> &glyphs)
{
QSet<glyph_t> referencedGlyphs;
QSet<glyph_t> newGlyphs;
- int count = glyphs.count();
+ int count = glyphs.size();
for (int i = 0; i < count; ++i) {
glyph_t glyphIndex = glyphs.at(i);
if ((int) glyphIndex >= glyphCount() && glyphCount() > 0) {
@@ -124,7 +124,7 @@ void QSGDistanceFieldGlyphCache::populate(const QVector<glyph_t> &glyphs)
void QSGDistanceFieldGlyphCache::release(const QVector<glyph_t> &glyphs)
{
QSet<glyph_t> unusedGlyphs;
- int count = glyphs.count();
+ int count = glyphs.size();
for (int i = 0; i < count; ++i) {
glyph_t glyphIndex = glyphs.at(i);
GlyphData &gd = glyphData(glyphIndex);
@@ -180,7 +180,7 @@ void QSGDistanceFieldGlyphCache::update()
storeGlyphs(distanceFields);
#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
- for (Texture texture : qAsConst(m_textures))
+ for (Texture texture : std::as_const(m_textures))
saveTexture(texture.texture, m_referenceFont.familyName());
#endif
@@ -203,7 +203,7 @@ void QSGDistanceFieldGlyphCache::setGlyphsPosition(const QList<GlyphPosition> &g
{
QVector<quint32> invalidatedGlyphs;
- int count = glyphs.count();
+ int count = glyphs.size();
for (int i = 0; i < count; ++i) {
GlyphPosition glyph = glyphs.at(i);
GlyphData &gd = glyphData(glyph.glyph);
@@ -254,7 +254,7 @@ void QSGDistanceFieldGlyphCache::setGlyphsTexture(const QVector<glyph_t> &glyphs
QVector<quint32> invalidatedGlyphs;
- int count = glyphs.count();
+ int count = glyphs.size();
for (int j = 0; j < count; ++j) {
glyph_t glyphIndex = glyphs.at(j);
GlyphData &gd = glyphData(glyphIndex);
@@ -272,14 +272,14 @@ void QSGDistanceFieldGlyphCache::setGlyphsTexture(const QVector<glyph_t> &glyphs
void QSGDistanceFieldGlyphCache::markGlyphsToRender(const QVector<glyph_t> &glyphs)
{
- int count = glyphs.count();
+ int count = glyphs.size();
for (int i = 0; i < count; ++i)
m_pendingGlyphs.add(glyphs.at(i));
}
void QSGDistanceFieldGlyphCache::updateRhiTexture(QRhiTexture *oldTex, QRhiTexture *newTex, const QSize &newTexSize)
{
- int count = m_textures.count();
+ int count = m_textures.size();
for (int i = 0; i < count; ++i) {
Texture &tex = m_textures[i];
if (tex.texture == oldTex) {
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index c20a99a8a9..a1edc97f52 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -256,7 +256,6 @@ public:
Texture // for APIs with separate texture and sampler objects
};
struct Variable {
- Variable() {}
VariableType type = Constant;
QByteArray name;
uint offset = 0; // for cbuffer members
@@ -337,6 +336,7 @@ public:
};
ShaderSyncData vertex;
ShaderSyncData fragment;
+ void *materialTypeCacheKey;
};
// Each ShaderEffect item has one node (render thread) and one manager (gui thread).
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index 192bd565a9..e21f2fbb6f 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -81,7 +81,7 @@ QSGAdaptationBackendData *contextFactory()
const QStringList args = QGuiApplication::arguments();
QString requestedBackend = backendData->quickWindowBackendRequest; // empty or set via QQuickWindow::setSceneGraphBackend()
- for (int index = 0; index < args.count(); ++index) {
+ for (int index = 0; index < args.size(); ++index) {
if (args.at(index).startsWith(QLatin1String("--device="))) {
requestedBackend = args.at(index).mid(9);
break;
@@ -129,7 +129,7 @@ QSGAdaptationBackendData *contextFactory()
qCDebug(QSG_LOG_INFO, "Loading backend %s", qUtf8Printable(requestedBackend));
// First look for a built-in adaptation.
- for (QSGContextFactoryInterface *builtInBackend : qAsConst(backendData->builtIns)) {
+ for (QSGContextFactoryInterface *builtInBackend : std::as_const(backendData->builtIns)) {
if (builtInBackend->keys().contains(requestedBackend)) {
backendData->factory = builtInBackend;
backendData->name = requestedBackend;
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index 429d7ad4e1..43a7e919bc 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -472,9 +472,11 @@ void QSGTextMaskMaterial::populate(const QPointF &p,
bool supportsSubPixelPositions = fontD->fontEngine->supportsHorizontalSubPixelPositions();
for (int i=0; i<glyphIndexes.size(); ++i) {
QPointF glyphPosition = glyphPositions.at(i) + position;
+ QFixedPoint fixedPointPosition = fixedPointPositions.at(i);
+
QFixed subPixelPosition;
if (supportsSubPixelPositions)
- subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPosition.x() * glyphCacheScaleX));
+ subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(fixedPointPosition.x.toReal() * glyphCacheScaleX));
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i),
QFixedPoint(subPixelPosition, 0));
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 3fee9d9faf..cd0a5b6d28 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -119,7 +119,7 @@ void QSGDefaultRenderContext::invalidate()
qDeleteAll(m_glyphCaches);
m_glyphCaches.clear();
- releaseGlyphCacheResourceUpdates();
+ resetGlyphCacheResources();
m_rhi = nullptr;
@@ -264,12 +264,23 @@ QRhiResourceUpdateBatch *QSGDefaultRenderContext::glyphCacheResourceUpdates()
return m_glyphCacheResourceUpdates;
}
-void QSGDefaultRenderContext::releaseGlyphCacheResourceUpdates()
+void QSGDefaultRenderContext::deferredReleaseGlyphCacheTexture(QRhiTexture *texture)
+{
+ if (texture)
+ m_pendingGlyphCacheTextures.insert(texture);
+}
+
+void QSGDefaultRenderContext::resetGlyphCacheResources()
{
if (m_glyphCacheResourceUpdates) {
m_glyphCacheResourceUpdates->release();
m_glyphCacheResourceUpdates = nullptr;
}
+
+ for (QRhiTexture *t : std::as_const(m_pendingGlyphCacheTextures))
+ t->deleteLater(); // the QRhiTexture object stays valid for the current frame
+
+ m_pendingGlyphCacheTextures.clear();
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index 448255a594..580a973e85 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -24,6 +24,7 @@ class QRhi;
class QRhiCommandBuffer;
class QRhiRenderPassDescriptor;
class QRhiResourceUpdateBatch;
+class QRhiTexture;
class QSGMaterialShader;
class QSurface;
@@ -102,7 +103,8 @@ public:
QRhiResourceUpdateBatch *maybeGlyphCacheResourceUpdates();
QRhiResourceUpdateBatch *glyphCacheResourceUpdates();
- void releaseGlyphCacheResourceUpdates();
+ void deferredReleaseGlyphCacheTexture(QRhiTexture *texture);
+ void resetGlyphCacheResources();
protected:
static QString fontKey(const QRawFont &font, int renderTypeQuality);
@@ -116,6 +118,7 @@ protected:
qreal m_currentDevicePixelRatio;
bool m_useDepthBufferFor2D;
QRhiResourceUpdateBatch *m_glyphCacheResourceUpdates;
+ QSet<QRhiTexture *> m_pendingGlyphCacheTextures;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
index bff5d0404d..64f862f948 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
@@ -101,11 +101,11 @@ void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphR
m_glyph_cache->populate(glyphs.glyphIndexes());
const QVector<quint32> glyphIndexes = m_glyphs.glyphIndexes();
- for (int i = 0; i < glyphIndexes.count(); ++i)
+ for (int i = 0; i < glyphIndexes.size(); ++i)
m_allGlyphIndexesLookup.insert(glyphIndexes.at(i));
qCDebug(lcSgText, "inserting %" PRIdQSIZETYPE " glyphs, %" PRIdQSIZETYPE " unique",
- glyphIndexes.count(),
- m_allGlyphIndexesLookup.count());
+ glyphIndexes.size(),
+ m_allGlyphIndexesLookup.size());
#ifdef QSG_RUNTIME_DESCRIPTION
qsgnode_set_description(this, QString::number(glyphs.glyphIndexes().count()) + QStringLiteral(" DF glyphs: ") +
m_glyphs.rawFont().familyName() + QStringLiteral(" ") + QString::number(m_glyphs.rawFont().pixelSize()));
@@ -147,7 +147,7 @@ void QSGDistanceFieldGlyphNode::invalidateGlyphs(const QVector<quint32> &glyphs)
if (m_dirtyGeometry)
return;
- for (int i = 0; i < glyphs.count(); ++i) {
+ for (int i = 0; i < glyphs.size(); ++i) {
if (m_allGlyphIndexesLookup.contains(glyphs.at(i))) {
m_dirtyGeometry = true;
setFlag(UsePreprocess);
@@ -289,12 +289,12 @@ void QSGDistanceFieldGlyphNode::updateGeometry()
Q_ASSERT(m_glyphsInOtherTextures.isEmpty());
} else {
if (!m_glyphsInOtherTextures.isEmpty())
- qCDebug(lcSgText, "%" PRIdQSIZETYPE " 'other' textures", m_glyphsInOtherTextures.count());
+ qCDebug(lcSgText, "%" PRIdQSIZETYPE " 'other' textures", m_glyphsInOtherTextures.size());
QHash<const QSGDistanceFieldGlyphCache::Texture *, GlyphInfo>::const_iterator ite = m_glyphsInOtherTextures.constBegin();
while (ite != m_glyphsInOtherTextures.constEnd()) {
QGlyphRun subNodeGlyphRun(m_glyphs);
- for (int i = 0; i < ite->indexes.count(); i += maxIndexCount) {
- int len = qMin(maxIndexCount, ite->indexes.count() - i);
+ for (int i = 0; i < ite->indexes.size(); i += maxIndexCount) {
+ int len = qMin(maxIndexCount, ite->indexes.size() - i);
subNodeGlyphRun.setRawData(ite->indexes.constData() + i, ite->positions.constData() + i, len);
qCDebug(lcSgText) << "subNodeGlyphRun has" << len << "positions:"
<< *(ite->positions.constData() + i) << "->" << *(ite->positions.constData() + i + len - 1);
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 5545ea05d9..6dee0304ab 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -329,7 +329,7 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window)
d->cleanupNodesOnShutdown();
#if QT_CONFIG(quick_shadereffect)
- QSGRhiShaderEffectNode::cleanupMaterialTypeCache();
+ QSGRhiShaderEffectNode::cleanupMaterialTypeCache(window);
#endif
if (m_windows.size() == 0) {
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
index abd0f9c790..54cf298943 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
@@ -32,19 +32,10 @@ QSGRhiDistanceFieldGlyphCache::QSGRhiDistanceFieldGlyphCache(QSGDefaultRenderCon
QSGRhiDistanceFieldGlyphCache::~QSGRhiDistanceFieldGlyphCache()
{
- // A plain delete should work, but just in case commitResourceUpdates was
- // not called and something is enqueued on the update batch for a texture,
- // defer until the end of the frame.
- for (int i = 0; i < m_textures.count(); ++i) {
- if (m_textures[i].texture)
- m_textures[i].texture->deleteLater();
- }
+ for (const TextureInfo &t : std::as_const(m_textures))
+ m_rc->deferredReleaseGlyphCacheTexture(t.texture);
delete m_areaAllocator;
-
- // should be empty, but just in case
- for (QRhiTexture *t : qAsConst(m_pendingDispose))
- t->deleteLater();
}
void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs)
@@ -113,7 +104,7 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs)
bool QSGRhiDistanceFieldGlyphCache::isActive() const
{
- return m_unusedGlyphs.size() != m_glyphsTexture.size();
+ return !m_referencedGlyphs.empty();
}
void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &glyphs)
@@ -176,11 +167,13 @@ void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &gly
void QSGRhiDistanceFieldGlyphCache::referenceGlyphs(const QSet<glyph_t> &glyphs)
{
+ m_referencedGlyphs += glyphs;
m_unusedGlyphs -= glyphs;
}
void QSGRhiDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyphs)
{
+ m_referencedGlyphs -= glyphs;
m_unusedGlyphs += glyphs;
}
@@ -241,7 +234,7 @@ void QSGRhiDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int widt
resourceUpdates->copyTexture(texInfo->texture, oldTexture);
}
- m_pendingDispose.insert(oldTexture);
+ m_rc->deferredReleaseGlyphCacheTexture(oldTexture);
}
bool QSGRhiDistanceFieldGlyphCache::useTextureResizeWorkaround() const
@@ -520,14 +513,8 @@ void QSGRhiDistanceFieldGlyphCache::commitResourceUpdates(QRhiResourceUpdateBatc
{
if (QRhiResourceUpdateBatch *resourceUpdates = m_rc->maybeGlyphCacheResourceUpdates()) {
mergeInto->merge(resourceUpdates);
- m_rc->releaseGlyphCacheResourceUpdates();
+ m_rc->resetGlyphCacheResources();
}
-
- // now let's assume the resource updates will be committed in this frame
- for (QRhiTexture *t : qAsConst(m_pendingDispose))
- t->deleteLater(); // will be deleted after the frame is submitted -> safe
-
- m_pendingDispose.clear();
}
bool QSGRhiDistanceFieldGlyphCache::eightBitFormatIsAlphaSwizzled() const
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
index aed2739c89..b7653881f5 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
@@ -71,7 +71,7 @@ private:
TextureInfo *textureInfo(int index)
{
- for (int i = m_textures.count(); i <= index; ++i) {
+ for (int i = m_textures.size(); i <= index; ++i) {
if (createFullSizeTextures())
m_textures.append(QRect(0, 0, maxTextureSize(), maxTextureSize()));
else
@@ -89,6 +89,7 @@ private:
QList<TextureInfo> m_textures;
QHash<glyph_t, TextureInfo *> m_glyphsTexture;
QSet<glyph_t> m_unusedGlyphs;
+ QSet<glyph_t> m_referencedGlyphs;
QSet<QRhiTexture *> m_pendingDispose;
};
diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
index e831c97a80..e7c2b0fb0d 100644
--- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp
+++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
@@ -11,6 +11,7 @@
#include <QQmlFile>
#include <QFile>
#include <QFileSelector>
+#include <QMutexLocker>
QT_BEGIN_NAMESPACE
@@ -27,14 +28,18 @@ void QSGRhiShaderLinker::reset(const QShader &vs, const QShader &fs)
m_samplers.clear();
m_samplerNameMap.clear();
m_subRectBindings.clear();
+
+ m_constants.reserve(8);
+ m_samplers.reserve(4);
+ m_samplerNameMap.reserve(4);
}
void QSGRhiShaderLinker::feedConstants(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices)
{
- Q_ASSERT(shader.shaderInfo.variables.count() == shader.varData.count());
+ Q_ASSERT(shader.shaderInfo.variables.size() == shader.varData.size());
if (!dirtyIndices) {
m_constantBufferSize = qMax(m_constantBufferSize, shader.shaderInfo.constantDataSize);
- for (int i = 0; i < shader.shaderInfo.variables.count(); ++i) {
+ for (int i = 0; i < shader.shaderInfo.variables.size(); ++i) {
const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &var(shader.shaderInfo.variables.at(i));
if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Constant) {
const QSGShaderEffectNode::VariableData &vd(shader.varData.at(i));
@@ -75,11 +80,17 @@ void QSGRhiShaderLinker::feedConstants(const QSGShaderEffectNode::ShaderData &sh
void QSGRhiShaderLinker::feedSamplers(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices)
{
if (!dirtyIndices) {
- for (int i = 0; i < shader.shaderInfo.variables.count(); ++i) {
+ for (int i = 0; i < shader.shaderInfo.variables.size(); ++i) {
const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &var(shader.shaderInfo.variables.at(i));
const QSGShaderEffectNode::VariableData &vd(shader.varData.at(i));
if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler) {
Q_ASSERT(vd.specialType == QSGShaderEffectNode::VariableData::Source);
+
+#ifndef QT_NO_DEBUG
+ int existingBindPoint = m_samplerNameMap.value(var.name, -1);
+ Q_ASSERT(existingBindPoint < 0 || existingBindPoint == var.bindPoint);
+#endif
+
m_samplers.insert(var.bindPoint, vd.value);
m_samplerNameMap.insert(var.name, var.bindPoint);
}
@@ -88,6 +99,12 @@ void QSGRhiShaderLinker::feedSamplers(const QSGShaderEffectNode::ShaderData &sha
for (int idx : *dirtyIndices) {
const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &var(shader.shaderInfo.variables.at(idx));
const QSGShaderEffectNode::VariableData &vd(shader.varData.at(idx));
+
+#ifndef QT_NO_DEBUG
+ int existingBindPoint = m_samplerNameMap.value(var.name, -1);
+ Q_ASSERT(existingBindPoint < 0 || existingBindPoint == var.bindPoint);
+#endif
+
m_samplers.insert(var.bindPoint, vd.value);
m_samplerNameMap.insert(var.name, var.bindPoint);
}
@@ -142,11 +159,18 @@ struct QSGRhiShaderMaterialTypeCache
void reset() { qDeleteAll(m_types); m_types.clear(); }
struct Key {
- QShader blob[2];
- Key() { }
- Key(const QShader &vs, const QShader &fs) { blob[0] = vs; blob[1] = fs; }
+ QShader vs;
+ QShader fs;
+ size_t hash;
+ Key(const QShader &vs, const QShader &fs)
+ : vs(vs),
+ fs(fs)
+ {
+ QtPrivate::QHashCombine hashGen;
+ hash = hashGen(hashGen(0, vs), fs);
+ }
bool operator==(const Key &other) const {
- return blob[0] == other.blob[0] && blob[1] == other.blob[1];
+ return vs == other.vs && fs == other.fs;
}
};
QHash<Key, QSGMaterialType *> m_types;
@@ -154,10 +178,7 @@ struct QSGRhiShaderMaterialTypeCache
size_t qHash(const QSGRhiShaderMaterialTypeCache::Key &key, size_t seed = 0)
{
- size_t hash = seed;
- for (int i = 0; i < 2; ++i)
- hash = hash * 31337 + qHash(key.blob[i]);
- return hash;
+ return seed ^ key.hash;
}
QSGMaterialType *QSGRhiShaderMaterialTypeCache::get(const QShader &vs, const QShader &fs)
@@ -171,7 +192,8 @@ QSGMaterialType *QSGRhiShaderMaterialTypeCache::get(const QShader &vs, const QSh
return t;
}
-static QSGRhiShaderMaterialTypeCache shaderMaterialTypeCache;
+static QHash<void *, QSGRhiShaderMaterialTypeCache> shaderMaterialTypeCache;
+static QMutex shaderMaterialTypeCacheMutex;
class QSGRhiShaderEffectMaterialShader : public QSGMaterialShader
{
@@ -447,7 +469,7 @@ int QSGRhiShaderEffectMaterial::compare(const QSGMaterial *other) const
if (int diff = m_cullMode - o->m_cullMode)
return diff;
- if (int diff = m_textureProviders.count() - o->m_textureProviders.count())
+ if (int diff = m_textureProviders.size() - o->m_textureProviders.size())
return diff;
if (m_linker.m_constants != o->m_linker.m_constants)
@@ -459,7 +481,7 @@ int QSGRhiShaderEffectMaterial::compare(const QSGMaterial *other) const
if (hasAtlasTexture(o->m_textureProviders) && !o->m_geometryUsesTextureSubRect)
return 1;
- for (int binding = 0, count = m_textureProviders.count(); binding != count; ++binding) {
+ for (int binding = 0, count = m_textureProviders.size(); binding != count; ++binding) {
QSGTextureProvider *tp1 = m_textureProviders.at(binding);
QSGTextureProvider *tp2 = o->m_textureProviders.at(binding);
if (tp1 && tp2) {
@@ -559,7 +581,7 @@ QRectF QSGRhiShaderEffectNode::updateNormalizedTextureSubRect(bool supportsAtlas
bool geometryUsesTextureSubRect = false;
if (supportsAtlasTextures) {
QSGTextureProvider *tp = nullptr;
- for (int binding = 0, count = m_material.m_textureProviders.count(); binding != count; ++binding) {
+ for (int binding = 0, count = m_material.m_textureProviders.size(); binding != count; ++binding) {
if (QSGTextureProvider *candidate = m_material.m_textureProviders.at(binding)) {
if (!tp) {
tp = candidate;
@@ -627,7 +649,12 @@ void QSGRhiShaderEffectNode::syncMaterial(SyncData *syncData)
m_material.m_fragmentShader = defaultFragmentShader;
}
- m_material.m_materialType = shaderMaterialTypeCache.get(m_material.m_vertexShader, m_material.m_fragmentShader);
+ {
+ QMutexLocker lock(&shaderMaterialTypeCacheMutex);
+ m_material.m_materialType = shaderMaterialTypeCache[syncData->materialTypeCacheKey].get(m_material.m_vertexShader,
+ m_material.m_fragmentShader);
+ }
+
m_material.m_linker.reset(m_material.m_vertexShader, m_material.m_fragmentShader);
if (m_material.m_hasCustomVertexShader) {
@@ -675,7 +702,7 @@ void QSGRhiShaderEffectNode::syncMaterial(SyncData *syncData)
v.bindPoint = 1;
v.type = QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler;
defaultSD.shaderInfo.variables.append(v);
- for (const QSGShaderEffectNode::VariableData &extVarData : qAsConst(syncData->fragment.shader->varData)) {
+ for (const QSGShaderEffectNode::VariableData &extVarData : std::as_const(syncData->fragment.shader->varData)) {
if (extVarData.specialType == QSGShaderEffectNode::VariableData::Source) {
vd.value = extVarData.value;
break;
@@ -745,9 +772,10 @@ void QSGRhiShaderEffectNode::preprocess()
}
}
-void QSGRhiShaderEffectNode::cleanupMaterialTypeCache()
+void QSGRhiShaderEffectNode::cleanupMaterialTypeCache(void *materialTypeCacheKey)
{
- shaderMaterialTypeCache.reset();
+ QMutexLocker lock(&shaderMaterialTypeCacheMutex);
+ shaderMaterialTypeCache[materialTypeCacheKey].reset();
}
bool QSGRhiGuiThreadShaderEffectManager::hasSeparateSamplerAndTextureObjects() const
@@ -818,7 +846,7 @@ bool QSGRhiGuiThreadShaderEffectManager::reflect(ShaderInfo *result)
int ubufBinding = -1;
const QVector<QShaderDescription::UniformBlock> ubufs = desc.uniformBlocks();
- const int ubufCount = ubufs.count();
+ const int ubufCount = ubufs.size();
for (int i = 0; i < ubufCount; ++i) {
const QShaderDescription::UniformBlock &ubuf(ubufs[i]);
if (ubufBinding == -1 && ubuf.binding >= 0) {
@@ -839,7 +867,7 @@ bool QSGRhiGuiThreadShaderEffectManager::reflect(ShaderInfo *result)
}
const QVector<QShaderDescription::InOutVariable> combinedImageSamplers = desc.combinedImageSamplers();
- const int samplerCount = combinedImageSamplers.count();
+ const int samplerCount = combinedImageSamplers.size();
for (int i = 0; i < samplerCount; ++i) {
const QShaderDescription::InOutVariable &combinedImageSampler(combinedImageSamplers[i]);
ShaderInfo::Variable v;
diff --git a/src/quick/scenegraph/qsgrhishadereffectnode_p.h b/src/quick/scenegraph/qsgrhishadereffectnode_p.h
index a901a6651e..b606871af6 100644
--- a/src/quick/scenegraph/qsgrhishadereffectnode_p.h
+++ b/src/quick/scenegraph/qsgrhishadereffectnode_p.h
@@ -99,7 +99,7 @@ public:
void syncMaterial(SyncData *syncData) override;
void preprocess() override;
- static void cleanupMaterialTypeCache();
+ static void cleanupMaterialTypeCache(void *materialTypeCacheKey);
private Q_SLOTS:
void handleTextureChange();
diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp
index ede98e865a..d37786901c 100644
--- a/src/quick/scenegraph/qsgrhisupport.cpp
+++ b/src/quick/scenegraph/qsgrhisupport.cpp
@@ -883,7 +883,7 @@ int QSGRhiSupport::chooseSampleCount(int samples, QRhi *rhi)
const QVector<int> supportedSampleCounts = rhi->supportedSampleCounts();
if (!supportedSampleCounts.contains(msaaSampleCount)) {
int reducedSampleCount = 1;
- for (int i = supportedSampleCounts.count() - 1; i >= 0; --i) {
+ for (int i = supportedSampleCounts.size() - 1; i >= 0; --i) {
if (supportedSampleCounts[i] <= msaaSampleCount) {
reducedSampleCount = supportedSampleCounts[i];
break;
diff --git a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp
index a2d7de9a0a..9fe1b2ad01 100644
--- a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp
+++ b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp
@@ -23,15 +23,7 @@ QSGRhiTextureGlyphCache::QSGRhiTextureGlyphCache(QSGDefaultRenderContext *rc,
QSGRhiTextureGlyphCache::~QSGRhiTextureGlyphCache()
{
- // A plain delete should work, but just in case commitResourceUpdates was
- // not called and something is enqueued on the update batch for m_texture,
- // defer until the end of the frame.
- if (m_texture)
- m_texture->deleteLater();
-
- // should be empty, but just in case
- for (QRhiTexture *t : qAsConst(m_pendingDispose))
- t->deleteLater();
+ m_rc->deferredReleaseGlyphCacheTexture(m_texture);
}
QRhiTexture *QSGRhiTextureGlyphCache::createEmptyTexture(QRhiTexture::Format format)
@@ -97,7 +89,7 @@ void QSGRhiTextureGlyphCache::resizeTextureData(int width, int height)
resourceUpdates->uploadTexture(t, QRhiTextureUploadEntry(0, 0, subresDesc));
}
- m_pendingDispose.insert(m_texture);
+ m_rc->deferredReleaseGlyphCacheTexture(m_texture);
m_texture = t;
}
}
@@ -197,7 +189,10 @@ void QSGRhiTextureGlyphCache::endFillTexture()
int QSGRhiTextureGlyphCache::glyphPadding() const
{
- return 1;
+ if (m_format == QFontEngine::Format_Mono)
+ return 8;
+ else
+ return 1;
}
int QSGRhiTextureGlyphCache::maxTextureWidth() const
@@ -217,14 +212,8 @@ void QSGRhiTextureGlyphCache::commitResourceUpdates(QRhiResourceUpdateBatch *mer
{
if (QRhiResourceUpdateBatch *resourceUpdates = m_rc->maybeGlyphCacheResourceUpdates()) {
mergeInto->merge(resourceUpdates);
- m_rc->releaseGlyphCacheResourceUpdates();
+ m_rc->resetGlyphCacheResources();
}
-
- // now let's assume the resource updates will be committed in this frame
- for (QRhiTexture *t : qAsConst(m_pendingDispose))
- t->deleteLater(); // will be deleted after the frame is submitted -> safe
-
- m_pendingDispose.clear();
}
bool QSGRhiTextureGlyphCache::eightBitFormatIsAlphaSwizzled() const
diff --git a/src/quick/scenegraph/qsgrhitextureglyphcache_p.h b/src/quick/scenegraph/qsgrhitextureglyphcache_p.h
index 2960c91b01..3c6b99bc9f 100644
--- a/src/quick/scenegraph/qsgrhitextureglyphcache_p.h
+++ b/src/quick/scenegraph/qsgrhitextureglyphcache_p.h
@@ -60,7 +60,6 @@ private:
QSize m_size;
bool m_bgra = false;
QVarLengthArray<QRhiTextureUploadEntry, 16> m_uploads;
- QSet<QRhiTexture *> m_pendingDispose;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index e20ded6c5a..c9b7ca2084 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -476,7 +476,7 @@ void QSGRenderThread::invalidateGraphics(QQuickWindow *window, bool inDestructor
if (wipeSG) {
dd->cleanupNodesOnShutdown();
#if QT_CONFIG(quick_shadereffect)
- QSGRhiShaderEffectNode::cleanupMaterialTypeCache();
+ QSGRhiShaderEffectNode::cleanupMaterialTypeCache(window);
#endif
} else {
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent SG, avoiding cleanup");
@@ -505,6 +505,7 @@ void QSGRenderThread::invalidateGraphics(QQuickWindow *window, bool inDestructor
if (ownRhi)
QSGRhiSupport::instance()->destroyRhi(rhi);
rhi = nullptr;
+ dd->rhi = nullptr;
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- QRhi destroyed");
} else {
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent GL, avoiding cleanup");
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index b2bf0c6d19..2301e0780b 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -965,7 +965,7 @@ void QQuickScriptActionPrivate::debugAction(QDebug d, int indentLevel) const
QString exprStr = expr.expression();
int endOfFirstLine = exprStr.indexOf(u'\n');
d << "\n" << ind.constData() << QStringView{exprStr}.left(endOfFirstLine);
- if (endOfFirstLine != -1 && endOfFirstLine < exprStr.length())
+ if (endOfFirstLine != -1 && endOfFirstLine < exprStr.size())
d << "...";
}
}
@@ -998,7 +998,7 @@ QAbstractAnimationJob* QQuickScriptAction::transition(QQuickStateActions &action
d->hasRunScriptScript = false;
d->reversing = (direction == Backward);
if (!d->name.isEmpty()) {
- for (int ii = 0; ii < actions.count(); ++ii) {
+ for (int ii = 0; ii < actions.size(); ++ii) {
QQuickStateAction &action = actions[ii];
if (action.event && action.event->type() == QQuickStateActionEvent::Script
@@ -1178,14 +1178,14 @@ QAbstractAnimationJob* QQuickPropertyAction::transition(QQuickStateActions &acti
QQuickStateActions actions;
void doAction() override
{
- for (int ii = 0; ii < actions.count(); ++ii) {
+ for (int ii = 0; ii < actions.size(); ++ii) {
const QQuickStateAction &action = actions.at(ii);
QQmlPropertyPrivate::write(action.property, action.toValue, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding);
}
}
void debugAction(QDebug d, int indentLevel) const override {
QByteArray ind(indentLevel, ' ');
- for (int ii = 0; ii < actions.count(); ++ii) {
+ for (int ii = 0; ii < actions.size(); ++ii) {
const QQuickStateAction &action = actions.at(ii);
d << "\n" << ind.constData() << "target:" << action.property.object() << "property:" << action.property.name()
<< "value:" << action.toValue;
@@ -1194,7 +1194,7 @@ QAbstractAnimationJob* QQuickPropertyAction::transition(QQuickStateActions &acti
};
QStringList props = d->properties.isEmpty() ? QStringList() : d->properties.split(QLatin1Char(','));
- for (int ii = 0; ii < props.count(); ++ii)
+ for (int ii = 0; ii < props.size(); ++ii)
props[ii] = props.at(ii).trimmed();
if (!d->propertyName.isEmpty())
props << d->propertyName;
@@ -1218,8 +1218,8 @@ QAbstractAnimationJob* QQuickPropertyAction::transition(QQuickStateActions &acti
bool hasExplicit = false;
//an explicit animation has been specified
if (d->value.isValid()) {
- for (int i = 0; i < props.count(); ++i) {
- for (int j = 0; j < targets.count(); ++j) {
+ for (int i = 0; i < props.size(); ++i) {
+ for (int j = 0; j < targets.size(); ++j) {
QQuickStateAction myAction;
myAction.property = d->createProperty(targets.at(j), props.at(i), this);
if (myAction.property.isValid()) {
@@ -1227,7 +1227,7 @@ QAbstractAnimationJob* QQuickPropertyAction::transition(QQuickStateActions &acti
QQuickPropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyMetaType());
data->actions << myAction;
hasExplicit = true;
- for (int ii = 0; ii < actions.count(); ++ii) {
+ for (int ii = 0; ii < actions.size(); ++ii) {
QQuickStateAction &action = actions[ii];
if (action.property.object() == myAction.property.object() &&
myAction.property.name() == action.property.name()) {
@@ -1241,7 +1241,7 @@ QAbstractAnimationJob* QQuickPropertyAction::transition(QQuickStateActions &acti
}
if (!hasExplicit)
- for (int ii = 0; ii < actions.count(); ++ii) {
+ for (int ii = 0; ii < actions.size(); ++ii) {
QQuickStateAction &action = actions[ii];
QObject *obj = action.property.object();
@@ -1266,7 +1266,7 @@ QAbstractAnimationJob* QQuickPropertyAction::transition(QQuickStateActions &acti
}
QActionAnimation *action = new QActionAnimation;
- if (data->actions.count()) {
+ if (data->actions.size()) {
action->setAnimAction(data);
} else {
delete data;
@@ -1688,7 +1688,7 @@ QQuickAbstractAnimation *QQuickAnimationGroupPrivate::at_animation(QQmlListPrope
qsizetype QQuickAnimationGroupPrivate::count_animation(QQmlListProperty<QQuickAbstractAnimation> *list)
{
if (auto q = qmlobject_cast<QQuickAnimationGroup *>(list->object))
- return q->d_func()->animations.count();
+ return q->d_func()->animations.size();
return 0;
}
@@ -1696,7 +1696,7 @@ void QQuickAnimationGroupPrivate::clear_animation(QQmlListProperty<QQuickAbstrac
{
QQuickAnimationGroup *q = qobject_cast<QQuickAnimationGroup *>(list->object);
if (q) {
- while (q->d_func()->animations.count()) {
+ while (q->d_func()->animations.size()) {
QQuickAbstractAnimation *firstAnim = q->d_func()->animations.at(0);
firstAnim->setGroup(nullptr);
}
@@ -1723,7 +1723,7 @@ void QQuickAnimationGroupPrivate::removeLast_animation(QQmlListProperty<QQuickAb
QQuickAnimationGroup::~QQuickAnimationGroup()
{
Q_D(QQuickAnimationGroup);
- for (int i = 0; i < d->animations.count(); ++i)
+ for (int i = 0; i < d->animations.size(); ++i)
d->animations.at(i)->d_func()->group = nullptr;
d->animations.clear();
}
@@ -1812,14 +1812,14 @@ QAbstractAnimationJob* QQuickSequentialAnimation::transition(QQuickStateActions
int from = 0;
if (direction == Backward) {
inc = -1;
- from = d->animations.count() - 1;
+ from = d->animations.size() - 1;
}
ThreadingModel execution = threadingModel();
bool valid = d->defaultProperty.isValid();
QAbstractAnimationJob* anim;
- for (int ii = from; ii < d->animations.count() && ii >= 0; ii += inc) {
+ for (int ii = from; ii < d->animations.size() && ii >= 0; ii += inc) {
if (valid)
d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
anim = d->animations.at(ii)->transition(actions, modified, direction, defaultTarget);
@@ -1902,7 +1902,7 @@ QAbstractAnimationJob* QQuickParallelAnimation::transition(QQuickStateActions &a
bool valid = d->defaultProperty.isValid();
QAbstractAnimationJob* anim;
- for (int ii = 0; ii < d->animations.count(); ++ii) {
+ for (int ii = 0; ii < d->animations.size(); ++ii) {
if (valid)
d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
anim = d->animations.at(ii)->transition(actions, modified, direction, defaultTarget);
@@ -2084,7 +2084,7 @@ void QQuickBulkValueAnimator::debugAnimation(QDebug d) const
Note that PropertyAnimation inherits the abstract \l Animation type.
This includes additional properties and methods for controlling the animation.
- \section1 Modifying Properties Duration Animations
+ \section1 Modifying running animations
Since Qt 6.4, it is possible to set the \l from, \l to, \l duration, and
\l easing properties on a top-level animation while it is running. The
@@ -2594,7 +2594,7 @@ void QQuickAnimationPropertyUpdater::setValue(qreal v)
wasDeleted = &deleted;
if (reverse)
v = 1 - v;
- for (int ii = 0; ii < actions.count(); ++ii) {
+ for (int ii = 0; ii < actions.size(); ++ii) {
QQuickStateAction &action = actions[ii];
if (v == 1.) {
@@ -2626,7 +2626,7 @@ void QQuickAnimationPropertyUpdater::setValue(qreal v)
void QQuickAnimationPropertyUpdater::debugUpdater(QDebug d, int indentLevel) const
{
QByteArray ind(indentLevel, ' ');
- for (int i = 0; i < actions.count(); ++i) {
+ for (int i = 0; i < actions.size(); ++i) {
const QQuickStateAction &action = actions.at(i);
d << "\n" << ind.constData() << "target:" << action.property.object() << "property:" << action.property.name()
<< "from:" << action.fromValue << "to:" << action.toValue;
@@ -2641,7 +2641,7 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA
QQuickStateActions newActions;
QStringList props = d->properties.isEmpty() ? QStringList() : d->properties.split(QLatin1Char(','));
- for (int ii = 0; ii < props.count(); ++ii)
+ for (int ii = 0; ii < props.size(); ++ii)
props[ii] = props.at(ii).trimmed();
if (!d->propertyName.isEmpty())
props << d->propertyName;
@@ -2673,8 +2673,8 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA
QVector<QString> errorMessages;
bool successfullyCreatedDefaultProperty = false;
- for (int i = 0; i < props.count(); ++i) {
- for (int j = 0; j < targets.count(); ++j) {
+ for (int i = 0; i < props.size(); ++i) {
+ for (int j = 0; j < targets.size(); ++j) {
QQuickStateAction myAction;
QString errorMessage;
const QString &propertyName = props.at(i);
@@ -2691,7 +2691,7 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA
d->convertVariant(myAction.toValue, d->interpolatorType ? QMetaType(d->interpolatorType) : myAction.property.propertyMetaType());
newActions << myAction;
hasExplicit = true;
- for (int ii = 0; ii < actions.count(); ++ii) {
+ for (int ii = 0; ii < actions.size(); ++ii) {
QQuickStateAction &action = actions[ii];
if (action.property.object() == myAction.property.object() &&
myAction.property.name() == action.property.name()) {
@@ -2706,13 +2706,13 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA
}
if (!successfullyCreatedDefaultProperty) {
- for (const QString &errorMessage : qAsConst(errorMessages))
+ for (const QString &errorMessage : std::as_const(errorMessages))
qmlWarning(this) << errorMessage;
}
}
if (!hasExplicit)
- for (int ii = 0; ii < actions.count(); ++ii) {
+ for (int ii = 0; ii < actions.size(); ++ii) {
QQuickStateAction &action = actions[ii];
QObject *obj = action.property.object();
diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp
index ab3ea93a71..d7c25dadc1 100644
--- a/src/quick/util/qquickanimatorcontroller.cpp
+++ b/src/quick/util/qquickanimatorcontroller.cpp
@@ -36,7 +36,7 @@ static void qquickanimator_invalidate_jobs(QAbstractAnimationJob *job)
void QQuickAnimatorController::windowNodesDestroyed()
{
- for (const QSharedPointer<QAbstractAnimationJob> &toStop : qAsConst(m_rootsPendingStop)) {
+ for (const QSharedPointer<QAbstractAnimationJob> &toStop : std::as_const(m_rootsPendingStop)) {
qquickanimator_invalidate_jobs(toStop.data());
toStop->stop();
}
@@ -59,14 +59,14 @@ void QQuickAnimatorController::windowNodesDestroyed()
void QQuickAnimatorController::advance()
{
bool running = false;
- for (const QSharedPointer<QAbstractAnimationJob> &job : qAsConst(m_animationRoots)) {
+ for (const QSharedPointer<QAbstractAnimationJob> &job : std::as_const(m_animationRoots)) {
if (job->isRunning()) {
running = true;
break;
}
}
- for (QQuickAnimatorJob *job : qAsConst(m_runningAnimators))
+ for (QQuickAnimatorJob *job : std::as_const(m_runningAnimators))
job->commit();
if (running)
@@ -85,18 +85,18 @@ static void qquickanimator_sync_before_start(QAbstractAnimationJob *job)
void QQuickAnimatorController::beforeNodeSync()
{
- for (const QSharedPointer<QAbstractAnimationJob> &toStop : qAsConst(m_rootsPendingStop)) {
+ for (const QSharedPointer<QAbstractAnimationJob> &toStop : std::as_const(m_rootsPendingStop)) {
toStop->stop();
m_animationRoots.remove(toStop.data());
}
m_rootsPendingStop.clear();
- for (QQuickAnimatorJob *job : qAsConst(m_runningAnimators))
+ for (QQuickAnimatorJob *job : std::as_const(m_runningAnimators))
job->preSync();
// Start pending jobs
- for (const QSharedPointer<QAbstractAnimationJob> &job : qAsConst(m_rootsPendingStart)) {
+ for (const QSharedPointer<QAbstractAnimationJob> &job : std::as_const(m_rootsPendingStart)) {
Q_ASSERT(!job->isRunning());
// We want to make sure that presync is called before
@@ -118,7 +118,7 @@ void QQuickAnimatorController::beforeNodeSync()
void QQuickAnimatorController::afterNodeSync()
{
- for (QQuickAnimatorJob *job : qAsConst(m_runningAnimators))
+ for (QQuickAnimatorJob *job : std::as_const(m_runningAnimators))
job->postSync();
}
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index af49244b6d..599b5515cb 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -358,11 +358,12 @@ void QQuickTransformAnimatorJob::Helper::sync()
wasSynced = true;
}
+ // We update the node before checking on dirty, as the node might have changed without the animator running
+ node = d->itemNode();
+
if (dirty == 0)
return;
- node = d->itemNode();
-
if (dirty & QQuickItemPrivate::Position) {
dx = item->x();
dy = item->y();
diff --git a/src/quick/util/qquickapplication.cpp b/src/quick/util/qquickapplication.cpp
index ee3e15d15f..bee3b7313f 100644
--- a/src/quick/util/qquickapplication.cpp
+++ b/src/quick/util/qquickapplication.cpp
@@ -277,7 +277,7 @@ void QQuickApplication::setDisplayName(const QString &displayName)
qsizetype screens_count(QQmlListProperty<QQuickScreenInfo> *prop)
{
- return static_cast<QVector<QQuickScreenInfo *> *>(prop->data)->count();
+ return static_cast<QVector<QQuickScreenInfo *> *>(prop->data)->size();
}
QQuickScreenInfo *screens_at(QQmlListProperty<QQuickScreenInfo> *prop, qsizetype idx)
@@ -294,8 +294,8 @@ QQmlListProperty<QQuickScreenInfo> QQuickApplication::screens()
void QQuickApplication::updateScreens()
{
const QList<QScreen *> screenList = QGuiApplication::screens();
- m_screens.resize(screenList.count());
- for (int i = 0; i < screenList.count(); ++i) {
+ m_screens.resize(screenList.size());
+ for (int i = 0; i < screenList.size(); ++i) {
if (!m_screens[i])
m_screens[i] = new QQuickScreenInfo(this);
m_screens[i]->setWrappedScreen(screenList[i]);
diff --git a/src/quick/util/qquickdeliveryagent.cpp b/src/quick/util/qquickdeliveryagent.cpp
index 2bb0d52b09..78a95aa33c 100644
--- a/src/quick/util/qquickdeliveryagent.cpp
+++ b/src/quick/util/qquickdeliveryagent.cpp
@@ -48,6 +48,7 @@ void QQuickDeliveryAgentPrivate::touchToMouseEvent(QEvent::Type type, const QEve
(type == QEvent::MouseButtonRelease ? Qt::NoButton : Qt::LeftButton),
touchEvent->modifiers(), Qt::MouseEventSynthesizedByQt);
ret.setAccepted(true); // this now causes the persistent touchpoint to be accepted too
+ ret.setTimestamp(touchEvent->timestamp());
*mouseEvent = ret;
}
@@ -119,7 +120,7 @@ bool QQuickDeliveryAgentPrivate::deliverTouchAsMouse(QQuickItem *item, QTouchEve
// FIXME: make this work for mouse events too and get rid of the asTouchEvent in here.
QMutableTouchEvent event;
QQuickItemPrivate::get(item)->localizedTouchEvent(pointerEvent, false, &event);
- if (!event.points().count())
+ if (!event.points().size())
return false;
// For each point, check if it is accepted, if not, try the next point.
@@ -424,7 +425,7 @@ void QQuickDeliveryAgentPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *
emit rootItem->window()->focusObjectChanged(activeFocusItem);
if (!changed.isEmpty())
- notifyFocusChangesRecur(changed.data(), changed.count() - 1, reason);
+ notifyFocusChangesRecur(changed.data(), changed.size() - 1, reason);
if (isSubsceneAgent) {
auto da = QQuickWindowPrivate::get(rootItem->window())->deliveryAgent;
qCDebug(lcFocus) << " delegating setFocusInScope to" << da;
@@ -524,8 +525,12 @@ void QQuickDeliveryAgentPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem
emit rootItem->window()->focusObjectChanged(activeFocusItem);
if (!changed.isEmpty())
- notifyFocusChangesRecur(changed.data(), changed.count() - 1, reason);
-
+ notifyFocusChangesRecur(changed.data(), changed.size() - 1, reason);
+ if (isSubsceneAgent) {
+ auto da = QQuickWindowPrivate::get(rootItem->window())->deliveryAgent;
+ qCDebug(lcFocus) << " delegating clearFocusInScope to" << da;
+ QQuickWindowPrivate::get(rootItem->window())->deliveryAgentPrivate()->clearFocusInScope(da->rootItem(), item, reason, options);
+ }
if (oldActiveFocusItem == activeFocusItem)
qCDebug(lcFocus) << "activeFocusItem remains" << activeFocusItem << "in" << q;
else
@@ -717,10 +722,13 @@ bool QQuickDeliveryAgent::event(QEvent *ev)
if (!d->rootItem)
return false;
QEnterEvent *enter = static_cast<QEnterEvent*>(ev);
- bool accepted = d->deliverHoverEvent(enter->scenePosition(),
+ const auto scenePos = enter->scenePosition();
+ bool accepted = d->deliverHoverEvent(scenePos,
enter->points().first().sceneLastPosition(),
enter->modifiers(), enter->timestamp());
- d->lastMousePosition = enter->scenePosition();
+ d->lastMousePosition = scenePos;
+ // deliverHoverEvent() constructs QHoverEvents: check that EPD didn't end up with corrupted scenePos
+ Q_ASSERT(enter->scenePosition() == scenePos);
enter->setAccepted(accepted);
#if QT_CONFIG(cursor)
QQuickWindowPrivate::get(d->rootItem->window())->updateCursor(enter->scenePosition(), d->rootItem);
@@ -751,8 +759,7 @@ bool QQuickDeliveryAgent::event(QEvent *ev)
break;
#endif
case QEvent::ShortcutOverride:
- if (d->activeFocusItem)
- QCoreApplication::sendEvent(d->activeFocusItem, ev);
+ d->deliverKeyEvent(static_cast<QKeyEvent *>(ev));
break;
case QEvent::InputMethod:
case QEvent::InputMethodQuery:
@@ -792,7 +799,13 @@ bool QQuickDeliveryAgent::event(QEvent *ev)
case QEvent::TabletPress:
case QEvent::TabletMove:
case QEvent::TabletRelease:
- d->deliverPointerEvent(static_cast<QPointerEvent *>(ev));
+ {
+ auto *tabletEvent = static_cast<QTabletEvent *>(ev);
+ d->deliverPointerEvent(tabletEvent); // visits HoverHandlers too (unlike the mouse event case)
+#if QT_CONFIG(cursor)
+ QQuickWindowPrivate::get(d->rootItem->window())->updateCursor(tabletEvent->scenePosition(), d->rootItem);
+#endif
+ }
break;
#endif
default:
@@ -806,10 +819,16 @@ void QQuickDeliveryAgentPrivate::deliverKeyEvent(QKeyEvent *e)
{
if (activeFocusItem) {
const bool keyPress = (e->type() == QEvent::KeyPress);
- if (keyPress)
+ switch (e->type()) {
+ case QEvent::KeyPress:
Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyPress, e->key(), e->modifiers());
- else
+ break;
+ case QEvent::KeyRelease:
Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyRelease, e->key(), e->modifiers());
+ break;
+ default:
+ break;
+ }
QQuickItem *item = activeFocusItem;
@@ -819,12 +838,10 @@ void QQuickDeliveryAgentPrivate::deliverKeyEvent(QKeyEvent *e)
e->key(), e->modifiers(), e->text(),
e->isAutoRepeat(), e->count());
- e->accept();
- QCoreApplication::sendEvent(item, e);
- while (!e->isAccepted() && (item = item->parentItem())) {
+ do {
e->accept();
QCoreApplication::sendEvent(item, e);
- }
+ } while (!e->isAccepted() && (item = item->parentItem()));
}
}
@@ -926,11 +943,11 @@ bool QQuickDeliveryAgentPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *i
const auto transform = itemPrivate->windowToItemTransform();
const auto transformToGlobal = itemPrivate->windowToGlobalTransform();
auto globalPos = transformToGlobal.map(scenePos);
- QHoverEvent hoverEvent(type, transform.map(scenePos), globalPos, transform.map(lastScenePos), modifiers);
+ QHoverEvent hoverEvent(type, scenePos, globalPos, transform.map(lastScenePos), modifiers);
hoverEvent.setTimestamp(timestamp);
hoverEvent.setAccepted(true);
QEventPoint &point = hoverEvent.point(0);
- QMutableEventPoint::setScenePosition(point, scenePos);
+ QMutableEventPoint::setPosition(point, transform.map(scenePos));
QMutableEventPoint::setGlobalLastPosition(point, transformToGlobal.map(lastScenePos));
hasFiltered.clear();
@@ -952,9 +969,6 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEvent(
const QPointF &scenePos, const QPointF &lastScenePos,
Qt::KeyboardModifiers modifiers, ulong timestamp)
{
- if (!QQuickItemPrivate::get(rootItem)->subtreeHoverEnabled)
- return false;
-
// The first time this function is called, hoverItems is empty.
// We then call deliverHoverEventRecursive from the rootItem, and
// populate the list with all the children and grandchildren that
@@ -970,11 +984,19 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEvent(
// visit will still have an old hoverId. We can therefore go through the
// list at the end of this function and look for items with an old hoverId,
// remove them from the list, and update their state accordingly.
- currentHoverId++;
- hoveredLeafItemFound = false;
+ const bool subtreeHoverEnabled = QQuickItemPrivate::get(rootItem)->subtreeHoverEnabled;
const bool itemsWasHovered = !hoverItems.isEmpty();
- deliverHoverEventRecursive(rootItem, scenePos, lastScenePos, modifiers, timestamp);
+
+ if (!subtreeHoverEnabled && !itemsWasHovered)
+ return false;
+
+ currentHoverId++;
+
+ if (subtreeHoverEnabled) {
+ hoveredLeafItemFound = false;
+ deliverHoverEventRecursive(rootItem, scenePos, lastScenePos, modifiers, timestamp);
+ }
// Prune the list for items that are no longer hovered
for (auto it = hoverItems.begin(); it != hoverItems.end();) {
@@ -1005,10 +1027,11 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEvent(
accepted, recursion stops. Returns \c true in that case, or \c false if the
event is rejected.
- All items that have hover enabled (either explicitly, from
- setAcceptHoverEvents(), or implicitly by having HoverHandlers) will have
- the QQuickItemPrivate::hoverEnabled flag set. And all their anchestors will
- have the QQuickItemPrivate::subtreeHoverEnabledset. This function will
+ Each item that has hover enabled (from setAcceptHoverEvents()) has the
+ QQuickItemPrivate::hoverEnabled flag set. This only controls whether we
+ should send hover events to the item itself. (HoverHandlers no longer set
+ this flag.) When an item has hoverEnabled set, all its ancestors have the
+ QQuickItemPrivate::subtreeHoverEnabled set. This function will
follow the subtrees that have subtreeHoverEnabled by recursing into each
child with that flag set. And for each child (in addition to the item
itself) that also has hoverEnabled set, we call deliverHoverEventToItem()
@@ -1020,10 +1043,19 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEvent(
of an item that is stacked underneath, will not. Note that since siblings
can overlap, there can be more than one leaf item under the mouse.
+ Note that HoverHandler doesn't set the hoverEnabled flag on the parent item.
+ But still, adding a HoverHandler to an item will set its subtreeHoverEnabled flag.
+ So all the propagation logic described above will otherwise be the same.
+ But the hoverEnabled flag can be used to resolve if subtreeHoverEnabled is on
+ because the application explicitly requested it (setAcceptHoverEvents()), or
+ indirectly, because the item has HoverHandlers.
+
For legacy reasons (Qt 6.1), as soon as we find a leaf item that has hover
enabled, and therefore receives the event, we stop recursing into the remaining
siblings (even if the event was ignored). This means that we only allow hover
events to propagate up the direct parent-child hierarchy, and not to siblings.
+ However, if the first candidate HoverHandler is disabled, delivery continues
+ to the next one, which may be a sibling (QTBUG-106548).
*/
bool QQuickDeliveryAgentPrivate::deliverHoverEventRecursive(
QQuickItem *item, const QPointF &scenePos, const QPointF &lastScenePos,
@@ -1033,13 +1065,13 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEventRecursive(
const QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
const QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
- for (int ii = children.count() - 1; ii >= 0; --ii) {
+ for (int ii = children.size() - 1; ii >= 0; --ii) {
QQuickItem *child = children.at(ii);
const QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
if (!child->isVisible() || childPrivate->culled)
continue;
- if (!child->isEnabled() && !childPrivate->subtreeHoverEnabled)
+ if (!childPrivate->subtreeHoverEnabled)
continue;
if (childPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
const QPointF localPos = child->mapFromScene(scenePos);
@@ -1061,8 +1093,7 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEventRecursive(
// All decendants have been visited.
// Now deliver the event to the item
- if (itemPrivate->hoverEnabled)
- return deliverHoverEventToItem(item, scenePos, lastScenePos, modifiers, timestamp, false);
+ return deliverHoverEventToItem(item, scenePos, lastScenePos, modifiers, timestamp, false);
// Continue propagation / recursion
return false;
@@ -1089,14 +1120,17 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEventToItem(
qCDebug(lcHoverTrace) << "item:" << item << "scene pos:" << scenePos << "localPos:" << localPos
<< "wasHovering:" << wasHovering << "isHovering:" << isHovering;
- if (isHovering)
- hoveredLeafItemFound = true;
-
- // Send enter/move/leave event to the item
bool accepted = false;
- if (isHovering && !clearHover) {
+
+ // Start by sending out enter/move/leave events to the item.
+ // Note that hoverEnabled only controls if we should send out hover events to the
+ // item itself. HoverHandlers are not included, and are dealt with separately below.
+ if (itemPrivate->hoverEnabled && isHovering && !clearHover) {
// Add the item to the list of hovered items (if it doesn't exist there
// from before), and update hoverId to mark that it's (still) hovered.
+ // Also set hoveredLeafItemFound, so that only propagate in a straight
+ // line towards the root from now on.
+ hoveredLeafItemFound = true;
hoverItems[item] = currentHoverId;
if (wasHovering)
accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, timestamp);
@@ -1111,6 +1145,7 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEventToItem(
if (!itemPrivate->hasPointerHandlers())
return accepted;
+ // Next, send out hover events to the hover handlers.
// If the item didn't accept the hover event, 'accepted' is now false.
// Otherwise it's true, and then it should stay the way regardless of
// whether or not the hoverhandlers themselves are hovered.
@@ -1124,6 +1159,8 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEventToItem(
for (QQuickPointerHandler *h : itemPrivate->extra->pointerHandlers) {
if (QQuickHoverHandler *hh = qmlobject_cast<QQuickHoverHandler *>(h)) {
+ if (!hh->isHovered())
+ continue;
hoverEvent.setAccepted(true);
QCoreApplication::sendEvent(hh, &hoverEvent);
}
@@ -1134,11 +1171,14 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEventToItem(
for (QQuickPointerHandler *h : itemPrivate->extra->pointerHandlers) {
if (QQuickHoverHandler *hh = qmlobject_cast<QQuickHoverHandler *>(h)) {
+ if (!hh->enabled())
+ continue;
hoverEvent.setAccepted(true);
hh->handlePointerEvent(&hoverEvent);
if (hh->isHovered()) {
// Mark the whole item as updated, even if only the handler is
// actually in a hovered state (because of HoverHandler.margins)
+ hoveredLeafItemFound = true;
hoverItems[item] = currentHoverId;
if (hh->isBlocking()) {
qCDebug(lcHoverTrace) << "skipping rest of hover delivery due to blocking" << hh;
@@ -1157,7 +1197,7 @@ bool QQuickDeliveryAgentPrivate::deliverHoverEventToItem(
// in the usual reverse-paint-order until propagation is stopped
bool QQuickDeliveryAgentPrivate::deliverSinglePointEventUntilAccepted(QPointerEvent *event)
{
- Q_ASSERT(event->points().count() == 1);
+ Q_ASSERT(event->points().size() == 1);
QQuickPointerHandlerPrivate::deviceDeliveryTargets(event->pointingDevice()).clear();
QEventPoint &point = event->point(0);
QVector<QQuickItem *> targetItems = pointerTargets(rootItem, event, point, false, false);
@@ -1331,6 +1371,11 @@ bool QQuickDeliveryAgentPrivate::isMouseEvent(const QPointerEvent *ev)
}
}
+bool QQuickDeliveryAgentPrivate::isMouseOrWheelEvent(const QPointerEvent *ev)
+{
+ return isMouseEvent(ev) || ev->type() == QEvent::Wheel;
+}
+
bool QQuickDeliveryAgentPrivate::isHoverEvent(const QPointerEvent *ev)
{
switch (ev->type()) {
@@ -1377,6 +1422,11 @@ bool QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(const QPointerEvent
devType == QInputDevice::DeviceType::TouchPad;
}
+bool QQuickDeliveryAgentPrivate::isSynthMouse(const QPointerEvent *ev)
+{
+ return (!isEventFromMouseOrTouchpad(ev) && isMouseEvent(ev));
+}
+
QQuickPointingDeviceExtra *QQuickDeliveryAgentPrivate::deviceExtra(const QInputDevice *device)
{
QInputDevicePrivate *devPriv = QInputDevicePrivate::get(const_cast<QInputDevice *>(device));
@@ -1417,6 +1467,11 @@ QQuickPointingDeviceExtra *QQuickDeliveryAgentPrivate::deviceExtra(const QInputD
*/
bool QQuickDeliveryAgentPrivate::compressTouchEvent(QTouchEvent *event)
{
+ // If this is a subscene agent, don't store any events, because
+ // flushFrameSynchronousEvents() is only called on the window's DA.
+ if (isSubsceneAgent)
+ return false;
+
QEventPoint::States states = event->touchPointStates();
if (states.testFlag(QEventPoint::State::Pressed) || states.testFlag(QEventPoint::State::Released)) {
qCDebug(lcTouchCmprs) << "no compression" << event;
@@ -1554,17 +1609,18 @@ void QQuickDeliveryAgentPrivate::handleMouseEvent(QMouseEvent *event)
Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseMove,
event->position().x(), event->position().y());
-#if QT_CONFIG(cursor)
- QQuickWindowPrivate::get(rootItem->window())->updateCursor(event->scenePosition());
-#endif
const QPointF last = lastMousePosition.isNull() ? event->scenePosition() : lastMousePosition;
lastMousePosition = event->scenePosition();
qCDebug(lcHoverTrace) << q << "mouse pos" << last << "->" << lastMousePosition;
- if (!event->points().count() || !event->exclusiveGrabber(event->point(0))) {
+ if (!event->points().size() || !event->exclusiveGrabber(event->point(0))) {
bool accepted = deliverHoverEvent(event->scenePosition(), last, event->modifiers(), event->timestamp());
event->setAccepted(accepted);
}
deliverPointerEvent(event);
+#if QT_CONFIG(cursor)
+ // The pointer event could result in a cursor change (reaction), so update it afterwards.
+ QQuickWindowPrivate::get(rootItem->window())->updateCursor(event->scenePosition());
+#endif
break;
}
default:
@@ -1641,64 +1697,59 @@ void QQuickDeliveryAgentPrivate::onGrabChanged(QObject *grabber, QPointingDevice
handler->onGrabChanged(handler, transition, const_cast<QPointerEvent *>(event),
const_cast<QEventPoint &>(point));
}
- } else {
+ } else if (auto *grabberItem = qmlobject_cast<QQuickItem *>(grabber)) {
switch (transition) {
case QPointingDevice::CancelGrabExclusive:
case QPointingDevice::UngrabExclusive:
- if (auto *item = qmlobject_cast<QQuickItem *>(grabber)) {
- bool filtered = false;
- if (isDeliveringTouchAsMouse() ||
- point.device()->type() == QInputDevice::DeviceType::Mouse ||
- point.device()->type() == QInputDevice::DeviceType::TouchPad) {
- QMutableSinglePointEvent e(QEvent::UngrabMouse, point.device(), point);
- hasFiltered.clear();
- filtered = sendFilteredMouseEvent(&e, item, item->parentItem());
- if (!filtered) {
- lastUngrabbed = item;
- item->mouseUngrabEvent();
- }
+ if (isDeliveringTouchAsMouse()
+ || point.device()->type() == QInputDevice::DeviceType::Mouse
+ || point.device()->type() == QInputDevice::DeviceType::TouchPad) {
+ QMutableSinglePointEvent e(QEvent::UngrabMouse, point.device(), point);
+ hasFiltered.clear();
+ if (!sendFilteredMouseEvent(&e, grabberItem, grabberItem->parentItem())) {
+ lastUngrabbed = grabberItem;
+ grabberItem->mouseUngrabEvent();
}
- if (point.device()->type() == QInputDevice::DeviceType::TouchScreen) {
- bool allReleasedOrCancelled = true;
- if (transition == QPointingDevice::UngrabExclusive && event) {
- for (const auto &pt : event->points()) {
- if (pt.state() != QEventPoint::State::Released) {
- allReleasedOrCancelled = false;
- break;
- }
+ }
+ if (point.device()->type() == QInputDevice::DeviceType::TouchScreen) {
+ bool allReleasedOrCancelled = true;
+ if (transition == QPointingDevice::UngrabExclusive && event) {
+ for (const auto &pt : event->points()) {
+ if (pt.state() != QEventPoint::State::Released) {
+ allReleasedOrCancelled = false;
+ break;
}
}
- if (allReleasedOrCancelled)
- item->touchUngrabEvent();
}
+ if (allReleasedOrCancelled)
+ grabberItem->touchUngrabEvent();
}
break;
default:
break;
}
- auto grabberItem = static_cast<QQuickItem *>(grabber); // cannot be a handler: we checked above
- if (grabberItem) {
- auto itemPriv = QQuickItemPrivate::get(grabberItem);
- deliveryAgent = itemPriv->deliveryAgent();
- // An item that is NOT a subscene root needs to track whether it got a grab via a subscene delivery agent,
- // whereas the subscene root item already knows it has its own DA.
- if (isSubsceneAgent && grabGained && (!itemPriv->extra.isAllocated() || !itemPriv->extra->subsceneDeliveryAgent))
- itemPriv->maybeHasSubsceneDeliveryAgent = true;
- }
+ auto *itemPriv = QQuickItemPrivate::get(grabberItem);
+ deliveryAgent = itemPriv->deliveryAgent();
+ // An item that is NOT a subscene root needs to track whether it got a grab via a subscene delivery agent,
+ // whereas the subscene root item already knows it has its own DA.
+ if (isSubsceneAgent && grabGained && (!itemPriv->extra.isAllocated() || !itemPriv->extra->subsceneDeliveryAgent))
+ itemPriv->maybeHasSubsceneDeliveryAgent = true;
}
if (currentEventDeliveryAgent == q && event && event->device()) {
- auto epd = QPointingDevicePrivate::get(const_cast<QPointingDevice*>(event->pointingDevice()))->queryPointById(point.id());
- Q_ASSERT(epd);
switch (transition) {
case QPointingDevice::GrabPassive: {
+ auto epd = QPointingDevicePrivate::get(const_cast<QPointingDevice*>(event->pointingDevice()))->queryPointById(point.id());
+ Q_ASSERT(epd);
QPointingDevicePrivate::setPassiveGrabberContext(epd, grabber, q);
qCDebug(lcPtr) << "remembering that" << q << "handles point" << point.id() << "after" << transition;
} break;
- case QPointingDevice::GrabExclusive:
+ case QPointingDevice::GrabExclusive: {
+ auto epd = QPointingDevicePrivate::get(const_cast<QPointingDevice*>(event->pointingDevice()))->queryPointById(point.id());
+ Q_ASSERT(epd);
epd->exclusiveGrabberContext = q;
qCDebug(lcPtr) << "remembering that" << q << "handles point" << point.id() << "after" << transition;
- break;
+ } break;
case QPointingDevice::CancelGrabExclusive:
case QPointingDevice::UngrabExclusive:
// taken care of in QPointingDevicePrivate::setExclusiveGrabber(,,nullptr), removeExclusiveGrabber()
@@ -1831,7 +1882,7 @@ QVector<QQuickItem *> QQuickDeliveryAgentPrivate::pointerTargets(QQuickItem *ite
children.insert(it, item);
}
- for (int ii = children.count() - 1; ii >= 0; --ii) {
+ for (int ii = children.size() - 1; ii >= 0; --ii) {
QQuickItem *child = children.at(ii);
auto childPrivate = QQuickItemPrivate::get(child);
if (!child->isVisible() || !child->isEnabled() || childPrivate->culled ||
@@ -1855,8 +1906,8 @@ QVector<QQuickItem *> QQuickDeliveryAgentPrivate::mergePointerTargets(const QVec
// start at the end of list2
// if item not in list, append it
// if item found, move to next one, inserting before the last found one
- int insertPosition = targets.length();
- for (int i = list2.length() - 1; i >= 0; --i) {
+ int insertPosition = targets.size();
+ for (int i = list2.size() - 1; i >= 0; --i) {
int newInsertPosition = targets.lastIndexOf(list2.at(i), insertPosition);
if (newInsertPosition >= 0) {
Q_ASSERT(newInsertPosition <= insertPosition);
@@ -1912,7 +1963,7 @@ void QQuickDeliveryAgentPrivate::deliverUpdatedPoints(QPointerEvent *event)
continue;
}
QList<QPointer<QObject>> relevantPassiveGrabbers;
- for (int i = 0; i < epd->passiveGrabbersContext.count(); ++i) {
+ for (int i = 0; i < epd->passiveGrabbersContext.size(); ++i) {
if (epd->passiveGrabbersContext.at(i).data() == q)
relevantPassiveGrabbers << epd->passiveGrabbers.at(i);
}
@@ -1932,7 +1983,7 @@ void QQuickDeliveryAgentPrivate::deliverUpdatedPoints(QPointerEvent *event)
if (point.state() == QEventPoint::Pressed || qmlobject_cast<QQuickItem *>(event->exclusiveGrabber(point)))
continue;
QVector<QQuickItem *> targetItemsForPoint = pointerTargets(rootItem, event, point, false, false);
- if (targetItems.count()) {
+ if (targetItems.size()) {
targetItems = mergePointerTargets(targetItems, targetItemsForPoint);
} else {
targetItems = targetItemsForPoint;
@@ -1975,7 +2026,7 @@ bool QQuickDeliveryAgentPrivate::deliverPressOrReleaseEvent(QPointerEvent *event
for (int i = 0; i < event->pointCount(); ++i) {
auto &point = event->point(i);
QVector<QQuickItem *> targetItemsForPoint = pointerTargets(rootItem, event, point, !isTouch, isTouch);
- if (targetItems.count()) {
+ if (targetItems.size()) {
targetItems = mergePointerTargets(targetItems, targetItemsForPoint);
} else {
targetItems = targetItemsForPoint;
@@ -2069,7 +2120,7 @@ void QQuickDeliveryAgentPrivate::deliverMatchingPointsToItem(QQuickItem *item, b
item->mouseUngrabEvent();
lastUngrabbed = item;
}
- } else if (item->isEnabled() && item->isVisible() && point.state() != QEventPoint::State::Released) {
+ } else if (item->isEnabled() && item->isVisible() && point.state() == QEventPoint::State::Pressed) {
pointerEvent->setExclusiveGrabber(point, item);
}
point.setAccepted(true);
@@ -2099,18 +2150,16 @@ void QQuickDeliveryAgentPrivate::deliverMatchingPointsToItem(QQuickItem *item, b
qCDebug(lcTouch) << "actually delivering" << &touchEvent << " to " << item;
QCoreApplication::sendEvent(item, &touchEvent);
eventAccepted = touchEvent.isAccepted();
- } else if (Q_LIKELY(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents))) {
+ } else {
// If the touch event wasn't accepted, synthesize a mouse event and see if the item wants it.
- if (!eventAccepted && (itemPrivate->acceptedMouseButtons() & Qt::LeftButton)) {
- // send mouse event
- if (deliverTouchAsMouse(item, &touchEvent))
- eventAccepted = true;
- }
+ if (Q_LIKELY(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)) &&
+ !eventAccepted && (itemPrivate->acceptedMouseButtons() & Qt::LeftButton))
+ deliverTouchAsMouse(item, &touchEvent);
+ return;
}
+ Q_ASSERT(item->acceptTouchEvents()); // else we would've returned early above
if (eventAccepted) {
- // If the touch was accepted (regardless by whom or in what form),
- // update accepted new points.
bool isPressOrRelease = pointerEvent->isBeginEvent() || pointerEvent->isEndEvent();
for (int i = 0; i < touchEvent.pointCount(); ++i) {
auto &point = touchEvent.point(i);
@@ -2163,6 +2212,7 @@ void QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QE
QDragLeaveEvent leaveEvent;
for (; grabItem != grabber->end(); grabItem = grabber->release(grabItem))
QCoreApplication::sendEvent(**grabItem, &leaveEvent);
+ grabber->ignoreList().clear();
return;
} else {
QDragMoveEvent *moveEvent = static_cast<QDragMoveEvent *>(event);
@@ -2220,6 +2270,8 @@ void QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QE
e->modifiers());
QQuickDropEventEx::copyActions(&enterEvent, *e);
event->setAccepted(deliverDragEvent(grabber, rootItem, &enterEvent));
+ } else {
+ grabber->ignoreList().clear();
}
}
@@ -2233,8 +2285,13 @@ bool QQuickDeliveryAgentPrivate::deliverDragEvent(
QPointF p = item->mapFromScene(event->position().toPoint());
bool itemContained = item->contains(p);
- if (!itemContained && itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
- return false;
+ const int itemIndex = grabber->ignoreList().indexOf(item);
+ if (!itemContained) {
+ if (itemIndex >= 0)
+ grabber->ignoreList().remove(itemIndex);
+
+ if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape)
+ return false;
}
QDragEnterEvent enterEvent(
@@ -2247,7 +2304,7 @@ bool QQuickDeliveryAgentPrivate::deliverDragEvent(
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
// Check children in front of this item first
- for (int ii = children.count() - 1; ii >= 0; --ii) {
+ for (int ii = children.size() - 1; ii >= 0; --ii) {
if (children.at(ii)->z() < 0)
continue;
if (deliverDragEvent(grabber, children.at(ii), &enterEvent, currentGrabItems, formerTarget))
@@ -2264,15 +2321,19 @@ bool QQuickDeliveryAgentPrivate::deliverDragEvent(
}
if (event->type() == QEvent::DragMove || itemPrivate->flags & QQuickItem::ItemAcceptsDrops) {
- if (event->type() == QEvent::DragEnter && formerTarget) {
- QQuickItem *formerTargetItem = qobject_cast<QQuickItem *>(formerTarget);
- if (formerTargetItem && currentGrabItems) {
- QDragLeaveEvent leaveEvent;
- QCoreApplication::sendEvent(formerTarget, &leaveEvent);
-
- // Remove the item from the currentGrabItems so a leave event won't be generated
- // later on
- currentGrabItems->removeAll(formerTarget);
+ if (event->type() == QEvent::DragEnter) {
+ if (formerTarget) {
+ QQuickItem *formerTargetItem = qobject_cast<QQuickItem *>(formerTarget);
+ if (formerTargetItem && currentGrabItems) {
+ QDragLeaveEvent leaveEvent;
+ QCoreApplication::sendEvent(formerTarget, &leaveEvent);
+
+ // Remove the item from the currentGrabItems so a leave event won't be generated
+ // later on
+ currentGrabItems->removeAll(formerTarget);
+ }
+ } else if (itemIndex >= 0) {
+ return false;
}
}
@@ -2288,6 +2349,8 @@ bool QQuickDeliveryAgentPrivate::deliverDragEvent(
grabber->grab(item);
grabber->setTarget(item);
return true;
+ } else if (itemIndex < 0) {
+ grabber->ignoreList().append(item);
}
} else {
return true;
@@ -2296,7 +2359,7 @@ bool QQuickDeliveryAgentPrivate::deliverDragEvent(
}
// Check children behind this item if this item or any higher children have not accepted
- for (int ii = children.count() - 1; ii >= 0; --ii) {
+ for (int ii = children.size() - 1; ii >= 0; --ii) {
if (children.at(ii)->z() >= 0)
continue;
if (deliverDragEvent(grabber, children.at(ii), &enterEvent, currentGrabItems, formerTarget))
@@ -2363,8 +2426,11 @@ bool QQuickDeliveryAgentPrivate::sendFilteredPointerEventImpl(QPointerEvent *eve
if (filteringParent->childMouseEventFilter(receiver, &filteringParentTouchEvent)) {
qCDebug(lcTouch) << "touch event intercepted by childMouseEventFilter of " << filteringParent;
skipDelivery.append(filteringParent);
- for (auto point : filteringParentTouchEvent.points())
- event->setExclusiveGrabber(point, filteringParent);
+ for (auto point : filteringParentTouchEvent.points()) {
+ const QQuickItem *exclusiveGrabber = qobject_cast<const QQuickItem *>(event->exclusiveGrabber(point));
+ if (!exclusiveGrabber || !exclusiveGrabber->keepTouchGrab())
+ event->setExclusiveGrabber(point, filteringParent);
+ }
return true;
} else if (Q_LIKELY(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)) &&
!filteringParent->acceptTouchEvents()) {
diff --git a/src/quick/util/qquickdeliveryagent_p_p.h b/src/quick/util/qquickdeliveryagent_p_p.h
index 66249f69c8..66db4bc88c 100644
--- a/src/quick/util/qquickdeliveryagent_p_p.h
+++ b/src/quick/util/qquickdeliveryagent_p_p.h
@@ -139,10 +139,12 @@ public:
static bool anyPointGrabbed(const QPointerEvent *ev);
static bool allPointsGrabbed(const QPointerEvent *ev);
static bool isMouseEvent(const QPointerEvent *ev);
+ static bool isMouseOrWheelEvent(const QPointerEvent *ev);
static bool isHoverEvent(const QPointerEvent *ev);
static bool isTouchEvent(const QPointerEvent *ev);
static bool isTabletEvent(const QPointerEvent *ev);
static bool isEventFromMouseOrTouchpad(const QPointerEvent *ev);
+ static bool isSynthMouse(const QPointerEvent *ev);
static QQuickPointingDeviceExtra *deviceExtra(const QInputDevice *device);
// delivery of pointer events:
diff --git a/src/quick/util/qquickframeanimation.cpp b/src/quick/util/qquickframeanimation.cpp
index 61e7e43875..bbdd0e79e0 100644
--- a/src/quick/util/qquickframeanimation.cpp
+++ b/src/quick/util/qquickframeanimation.cpp
@@ -263,10 +263,11 @@ int QQuickFrameAnimation::currentFrame() const
\code
Rectangle {
id: rect
- property real speed: 360
+ property real speed: 90
width: 100
height: 100
color: "red"
+ anchors.centerIn: parent
}
FrameAnimation {
@@ -274,7 +275,7 @@ int QQuickFrameAnimation::currentFrame() const
running: true
onTriggered: {
// Rotate the item speed-degrees / second.
- rect.rotation = rect.speed * frameTime
+ rect.rotation += rect.speed * frameTime
}
}
\endcode
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 1e9a419cfb..5b6ed25692 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -72,7 +72,7 @@ void QQmlQtQuick2DebugStatesDelegate::buildStatesList(bool cleanList,
m_allStates.clear();
//only root context has all instances
- for (int ii = 0; ii < instances.count(); ++ii) {
+ for (int ii = 0; ii < instances.size(); ++ii) {
buildStatesList(instances.at(ii));
}
}
@@ -84,7 +84,7 @@ void QQmlQtQuick2DebugStatesDelegate::buildStatesList(QObject *obj)
}
QObjectList children = obj->children();
- for (int ii = 0; ii < children.count(); ++ii) {
+ for (int ii = 0; ii < children.size(); ++ii) {
buildStatesList(children.at(ii));
}
}
@@ -99,7 +99,7 @@ void QQmlQtQuick2DebugStatesDelegate::updateBinding(QQmlContext *context,
typedef QPointer<QQuickState> QuickStatePointer;
QObject *object = property.object();
QString propertyName = property.name();
- for (const QuickStatePointer& statePointer : qAsConst(m_allStates)) {
+ for (const QuickStatePointer& statePointer : std::as_const(m_allStates)) {
if (QQuickState *state = statePointer.data()) {
// here we assume that the revert list on itself defines the base state
if (state->isStateActive() && state->containsPropertyInRevertList(object, propertyName)) {
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index ee2414432d..e3b96ddad4 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -433,7 +433,7 @@ QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSi
\class QQuickAsyncImageProvider
\since 5.6
\inmodule QtQuick
- \brief The QQuickAsyncImageProvider class provides an interface for for asynchronous control of QML image requests.
+ \brief The QQuickAsyncImageProvider class provides an interface for asynchronous control of QML image requests.
See the \l {imageresponseprovider}{Image Response Provider Example} for a complete implementation.
diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp
index b8aaf4e7ae..a38de75753 100644
--- a/src/quick/util/qquickpath.cpp
+++ b/src/quick/util/qquickpath.cpp
@@ -271,7 +271,7 @@ qsizetype QQuickPath::pathElements_count(QQmlListProperty<QQuickPathElement> *pr
{
QQuickPathPrivate *d = privatePath(property->object);
- return d->_pathElements.count();
+ return d->_pathElements.size();
}
void QQuickPath::pathElements_clear(QQmlListProperty<QQuickPathElement> *property)
@@ -327,10 +327,10 @@ void QQuickPath::endpoint(const QString &name)
Q_D(QQuickPath);
const AttributePoint &first = d->_attributePoints.first();
qreal val = first.values.value(name);
- for (int ii = d->_attributePoints.count() - 1; ii >= 0; ii--) {
+ for (int ii = d->_attributePoints.size() - 1; ii >= 0; ii--) {
const AttributePoint &point = d->_attributePoints.at(ii);
if (point.values.contains(name)) {
- for (int jj = ii + 1; jj < d->_attributePoints.count(); ++jj) {
+ for (int jj = ii + 1; jj < d->_attributePoints.size(); ++jj) {
AttributePoint &setPoint = d->_attributePoints[jj];
setPoint.values.insert(name, val);
}
@@ -343,10 +343,10 @@ void QQuickPath::endpoint(QList<AttributePoint> &attributePoints, const QString
{
const AttributePoint &first = attributePoints.first();
qreal val = first.values.value(name);
- for (int ii = attributePoints.count() - 1; ii >= 0; ii--) {
+ for (int ii = attributePoints.size() - 1; ii >= 0; ii--) {
const AttributePoint &point = attributePoints.at(ii);
if (point.values.contains(name)) {
- for (int jj = ii + 1; jj < attributePoints.count(); ++jj) {
+ for (int jj = ii + 1; jj < attributePoints.size(); ++jj) {
AttributePoint &setPoint = attributePoints[jj];
setPoint.values.insert(name, val);
}
@@ -401,7 +401,7 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en
QPainterPath path;
AttributePoint first;
- for (int ii = 0; ii < attributes.count(); ++ii)
+ for (int ii = 0; ii < attributes.size(); ++ii)
first.values[attributes.at(ii)] = 0;
attributePoints << first;
@@ -413,7 +413,7 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en
bool usesPercent = false;
int index = 0;
- for (QQuickPathElement *pathElement : qAsConst(d->_pathElements)) {
+ for (QQuickPathElement *pathElement : std::as_const(d->_pathElements)) {
if (QQuickCurve *curve = qobject_cast<QQuickCurve *>(pathElement)) {
QQuickPathData data;
data.index = index;
@@ -427,11 +427,11 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en
} else if (QQuickPathAttribute *attribute = qobject_cast<QQuickPathAttribute *>(pathElement)) {
AttributePoint &point = attributePoints.last();
point.values[attribute->name()] = attribute->value();
- interpolate(attributePoints, attributePoints.count() - 1, attribute->name(), attribute->value());
+ interpolate(attributePoints, attributePoints.size() - 1, attribute->name(), attribute->value());
} else if (QQuickPathPercent *percent = qobject_cast<QQuickPathPercent *>(pathElement)) {
AttributePoint &point = attributePoints.last();
point.values[percentString] = percent->value();
- interpolate(attributePoints, attributePoints.count() - 1, percentString, percent->value());
+ interpolate(attributePoints, attributePoints.size() - 1, percentString, percent->value());
usesPercent = true;
} else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement)) {
text->addToPath(path);
@@ -440,13 +440,13 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en
// Fixup end points
const AttributePoint &last = attributePoints.constLast();
- for (int ii = 0; ii < attributes.count(); ++ii) {
+ for (int ii = 0; ii < attributes.size(); ++ii) {
if (!last.values.contains(attributes.at(ii)))
endpoint(attributePoints, attributes.at(ii));
}
if (usesPercent && !last.values.contains(percentString)) {
d->_attributePoints.last().values[percentString] = 1;
- interpolate(d->_attributePoints.count() - 1, percentString, 1);
+ interpolate(d->_attributePoints.size() - 1, percentString, 1);
}
scalePath(path, d->scale);
@@ -454,7 +454,7 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en
qreal length = path.length();
qreal prevpercent = 0;
qreal prevorigpercent = 0;
- for (int ii = 0; ii < attributePoints.count(); ++ii) {
+ for (int ii = 0; ii < attributePoints.size(); ++ii) {
const AttributePoint &point = attributePoints.at(ii);
if (point.values.contains(percentString)) { //special string for QQuickPathPercent
if ( ii > 0) {
@@ -495,7 +495,7 @@ QPainterPath QQuickPath::createShapePath(const QPointF &startPoint, const QPoint
path.moveTo(startX, startY);
int index = 0;
- for (QQuickCurve *curve : qAsConst(d->_pathCurves)) {
+ for (QQuickCurve *curve : std::as_const(d->_pathCurves)) {
QQuickPathData data;
data.index = index;
data.endPoint = endPoint;
@@ -504,7 +504,7 @@ QPainterPath QQuickPath::createShapePath(const QPointF &startPoint, const QPoint
++index;
}
- for (QQuickPathText *text : qAsConst(d->_pathTexts))
+ for (QQuickPathText *text : std::as_const(d->_pathTexts))
text->addToPath(path);
if (closed) {
@@ -550,7 +550,7 @@ void QQuickPath::gatherAttributes()
QSet<QString> attributes;
// First gather up all the attributes
- for (QQuickPathElement *pathElement : qAsConst(d->_pathElements)) {
+ for (QQuickPathElement *pathElement : std::as_const(d->_pathElements)) {
if (QQuickCurve *curve = qobject_cast<QQuickCurve *>(pathElement))
d->_pathCurves.append(curve);
else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement))
@@ -676,10 +676,10 @@ void QQuickPath::createPointCache() const
//find which set we are in
qreal prevPercent = 0;
qreal prevOrigPercent = 0;
- for (int ii = 0; ii < d->_attributePoints.count(); ++ii) {
+ for (int ii = 0; ii < d->_attributePoints.size(); ++ii) {
qreal percent = qreal(i)/segments;
const AttributePoint &point = d->_attributePoints.at(ii);
- if (percent < point.percent || ii == d->_attributePoints.count() - 1) { //### || is special case for very last item
+ if (percent < point.percent || ii == d->_attributePoints.size() - 1) { //### || is special case for very last item
qreal elementPercent = (percent - prevPercent);
qreal spc = prevOrigPercent + elementPercent * point.scale;
@@ -773,10 +773,10 @@ QPointF QQuickPath::forwardsPointAt(const QPainterPath &path, const qreal &pathL
//find which set we are in
qreal prevPercent = 0;
qreal prevOrigPercent = 0;
- for (int ii = 0; ii < attributePoints.count(); ++ii) {
+ for (int ii = 0; ii < attributePoints.size(); ++ii) {
qreal percent = p;
const AttributePoint &point = attributePoints.at(ii);
- if (percent < point.percent || ii == attributePoints.count() - 1) {
+ if (percent < point.percent || ii == attributePoints.size() - 1) {
qreal elementPercent = (percent - prevPercent);
qreal spc = prevOrigPercent + elementPercent * point.scale;
@@ -827,7 +827,7 @@ QPointF QQuickPath::backwardsPointAt(const QPainterPath &path, const qreal &path
qreal prevLength = currLength - bezLength;
qreal epc = prevLength / pathLength;
- for (int ii = attributePoints.count() - 1; ii > 0; --ii) {
+ for (int ii = attributePoints.size() - 1; ii > 0; --ii) {
qreal percent = p;
const AttributePoint &point = attributePoints.at(ii);
const AttributePoint &prevPoint = attributePoints.at(ii-1);
@@ -928,7 +928,7 @@ qreal QQuickPath::attributeAt(const QString &name, qreal percent) const
if (percent < 0 || percent > 1)
return 0;
- for (int ii = 0; ii < d->_attributePoints.count(); ++ii) {
+ for (int ii = 0; ii < d->_attributePoints.size(); ++ii) {
const AttributePoint &point = d->_attributePoints.at(ii);
if (point.percent == percent) {
@@ -1711,17 +1711,17 @@ void QQuickPathCatmullRomCurve::addToPath(QPainterPath &path, const QQuickPathDa
} else {
prev = path.currentPosition();
bool prevFarSet = false;
- if (index == -1 && data.curves.count() > 1) {
- if (qobject_cast<QQuickPathCatmullRomCurve*>(data.curves.at(data.curves.count()-1))) {
+ if (index == -1 && data.curves.size() > 1) {
+ if (qobject_cast<QQuickPathCatmullRomCurve*>(data.curves.at(data.curves.size()-1))) {
//TODO: profile and optimize
QPointF pos = prev;
QQuickPathData loopData;
loopData.endPoint = data.endPoint;
loopData.curves = data.curves;
- for (int i = data.index; i < data.curves.count(); ++i) {
+ for (int i = data.index; i < data.curves.size(); ++i) {
loopData.index = i;
pos = positionForCurve(loopData, pos);
- if (i == data.curves.count()-2)
+ if (i == data.curves.size()-2)
prevFar = pos;
}
if (pos == QPointF(path.elementAt(0))) {
@@ -1740,7 +1740,7 @@ void QQuickPathCatmullRomCurve::addToPath(QPainterPath &path, const QQuickPathDa
//get next point
index = data.index + 1;
- if (index < data.curves.count() && qobject_cast<QQuickPathCatmullRomCurve*>(data.curves.at(index))) {
+ if (index < data.curves.size() && qobject_cast<QQuickPathCatmullRomCurve*>(data.curves.at(index))) {
QQuickPathData nextData;
nextData.index = index;
nextData.endPoint = data.endPoint;
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 51be6f8e51..7644ab4447 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -466,7 +466,7 @@ static QString existingImageFileForPath(const QString &localFile)
return localFile;
QString tryFile = localFile + QStringLiteral(".xxxx");
- const int suffixIdx = localFile.length() + 1;
+ const int suffixIdx = localFile.size() + 1;
for (const QString &suffix : backendSupport()->fileSuffixes) {
tryFile.replace(suffixIdx, 10, suffix);
if (QFileInfo::exists(tryFile))
@@ -499,7 +499,7 @@ QQuickPixmapReader::~QQuickPixmapReader()
mutex.lock();
// manually cancel all outstanding jobs.
- for (QQuickPixmapReply *reply : qAsConst(jobs)) {
+ for (QQuickPixmapReply *reply : std::as_const(jobs)) {
if (reply->data && reply->data->reply == reply)
reply->data->reply = nullptr;
delete reply;
@@ -514,10 +514,10 @@ QQuickPixmapReader::~QQuickPixmapReader()
}
};
- for (auto *reply : qAsConst(networkJobs))
+ for (auto *reply : std::as_const(networkJobs))
cancelJob(reply);
- for (auto *reply : qAsConst(asyncResponses))
+ for (auto *reply : std::as_const(asyncResponses))
cancelJob(reply);
#endif
if (threadObject) threadObject->processJobs();
@@ -660,7 +660,7 @@ void QQuickPixmapReader::processJobs()
// Clean cancelled jobs
if (!cancelled.isEmpty()) {
- for (int i = 0; i < cancelled.count(); ++i) {
+ for (int i = 0; i < cancelled.size(); ++i) {
QQuickPixmapReply *job = cancelled.at(i);
#if QT_CONFIG(qml_network)
QNetworkReply *reply = networkJobs.key(job, 0);
@@ -688,7 +688,7 @@ void QQuickPixmapReader::processJobs()
if (!jobs.isEmpty()) {
// Find a job we can use
bool usableJob = false;
- for (int i = jobs.count() - 1; !usableJob && i >= 0; i--) {
+ for (int i = jobs.size() - 1; !usableJob && i >= 0; i--) {
QQuickPixmapReply *job = jobs.at(i);
const QUrl url = job->url;
QString localFile;
@@ -706,7 +706,7 @@ void QQuickPixmapReader::processJobs()
localFile = QQmlFile::urlToLocalFileOrQrc(url);
usableJob = !localFile.isEmpty()
#if QT_CONFIG(qml_network)
- || networkJobs.count() < IMAGEREQUEST_MAX_NETWORK_REQUEST_COUNT
+ || networkJobs.size() < IMAGEREQUEST_MAX_NETWORK_REQUEST_COUNT
#endif
;
}
@@ -1301,7 +1301,7 @@ void QQuickPixmapData::addToCache()
pixmapStore()->m_cache.insert(key, this);
inCache = true;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
- url, pixmapStore()->m_cache.count()));
+ url, pixmapStore()->m_cache.size()));
}
}
@@ -1315,7 +1315,7 @@ void QQuickPixmapData::removeFromCache(QQuickPixmapStore *store)
store->m_cache.remove(key);
inCache = false;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
- url, store->m_cache.count()));
+ url, store->m_cache.size()));
}
}
@@ -1747,8 +1747,7 @@ void QQuickPixmap::loadImageFromDevice(QQmlEngine *engine, QIODevice *device, co
QQuickPixmapReader::readerMutex.lock();
d->reply = QQuickPixmapReader::instance(engine)->getImage(d);
if (oldD) {
- QObject::connect(d->reply, &QQuickPixmapReply::finished, [oldD, this]() {
- oldD->declarativePixmaps.remove(this);
+ QObject::connect(d->reply, &QQuickPixmapReply::finished, [oldD]() {
oldD->release();
});
}
diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp
index efa6b1dfa0..fcb6e71e17 100644
--- a/src/quick/util/qquickpropertychanges.cpp
+++ b/src/quick/util/qquickpropertychanges.cpp
@@ -238,7 +238,7 @@ void QQuickPropertyChangesPrivate::decode()
if (decoded)
return;
- for (const QV4::CompiledData::Binding *binding : qAsConst(bindings))
+ for (const QV4::CompiledData::Binding *binding : std::as_const(bindings))
decodeBinding(QString(), compilationUnit, binding);
bindings.clear();
@@ -333,7 +333,7 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix,
void QQuickPropertyChangesParser::verifyBindings(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &props)
{
- for (int ii = 0; ii < props.count(); ++ii)
+ for (int ii = 0; ii < props.size(); ++ii)
verifyList(compilationUnit, props.at(ii));
}
@@ -358,7 +358,7 @@ QQuickPropertyChanges::QQuickPropertyChanges()
QQuickPropertyChanges::~QQuickPropertyChanges()
{
Q_D(QQuickPropertyChanges);
- for(int ii = 0; ii < d->signalReplacements.count(); ++ii)
+ for(int ii = 0; ii < d->signalReplacements.size(); ++ii)
delete d->signalReplacements.at(ii);
}
@@ -427,7 +427,7 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions()
ActionList list;
- for (int ii = 0; ii < d->properties.count(); ++ii) {
+ for (int ii = 0; ii < d->properties.size(); ++ii) {
QQmlProperty prop = d->property(d->properties.at(ii).first);
QQuickStateAction a(d->object, prop, d->properties.at(ii).first,
@@ -439,7 +439,7 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions()
}
}
- for (int ii = 0; ii < d->signalReplacements.count(); ++ii) {
+ for (int ii = 0; ii < d->signalReplacements.size(); ++ii) {
QQuickReplaceSignalHandler *handler = d->signalReplacements.at(ii);
if (handler->property.isValid()) {
@@ -449,7 +449,7 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions()
}
}
- for (int ii = 0; ii < d->expressions.count(); ++ii) {
+ for (int ii = 0; ii < d->expressions.size(); ++ii) {
QQuickPropertyChangesPrivate::ExpressionChange e = d->expressions.at(ii);
const QString &property = e.name;
diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp
index 7b93936cfe..51de063090 100644
--- a/src/quick/util/qquickshortcut.cpp
+++ b/src/quick/util/qquickshortcut.cpp
@@ -209,7 +209,7 @@ void QQuickShortcut::setSequences(const QVariantList &values)
// if nothing has changed, just return:
if (m_shortcuts.size() == requestedShortcuts.size()) {
bool changed = false;
- for (int i = 0; i < requestedShortcuts.count(); ++i) {
+ for (int i = 0; i < requestedShortcuts.size(); ++i) {
const Shortcut &requestedShortcut = requestedShortcuts[i];
const Shortcut &shortcut = m_shortcuts[i];
if (!(requestedShortcut.userValue == shortcut.userValue
@@ -373,7 +373,7 @@ bool QQuickShortcut::event(QEvent *event)
QShortcutEvent *se = static_cast<QShortcutEvent *>(event);
bool match = m_shortcut.matches(se);
int i = 0;
- while (!match && i < m_shortcuts.count())
+ while (!match && i < m_shortcuts.size())
match |= m_shortcuts.at(i++).matches(se);
if (match) {
if (se->isAmbiguous())
diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h
index f303043008..baa884b6f0 100644
--- a/src/quick/util/qquickshortcut_p.h
+++ b/src/quick/util/qquickshortcut_p.h
@@ -22,12 +22,13 @@
#include <QtQml/qqmlparserstatus.h>
#include <QtQml/qqml.h>
#include <QtCore/private/qglobal_p.h>
+#include <QtQuick/private/qtquickglobal_p.h>
QT_BEGIN_NAMESPACE
class QShortcutEvent;
-class QQuickShortcut : public QObject, public QQmlParserStatus
+class Q_QUICK_PRIVATE_EXPORT QQuickShortcut : public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
diff --git a/src/quick/util/qquicksmoothedanimation.cpp b/src/quick/util/qquicksmoothedanimation.cpp
index 5e05da302d..4681d5919e 100644
--- a/src/quick/util/qquicksmoothedanimation.cpp
+++ b/src/quick/util/qquicksmoothedanimation.cpp
@@ -351,7 +351,7 @@ QQuickSmoothedAnimationPrivate::~QQuickSmoothedAnimationPrivate()
void QQuickSmoothedAnimationPrivate::updateRunningAnimations()
{
- for (QSmoothedAnimation *ease : qAsConst(activeAnimations)) {
+ for (QSmoothedAnimation *ease : std::as_const(activeAnimations)) {
ease->maximumEasingTime = anim->maximumEasingTime;
ease->reversingMode = anim->reversingMode;
ease->velocity = anim->velocity;
diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp
index 09eaf60819..51bc9852f4 100644
--- a/src/quick/util/qquickstate.cpp
+++ b/src/quick/util/qquickstate.cpp
@@ -243,7 +243,7 @@ QQmlListProperty<QQuickStateOperation> QQuickState::changes()
int QQuickState::operationCount() const
{
Q_D(const QQuickState);
- return d->operations.count();
+ return d->operations.size();
}
QQuickStateOperation *QQuickState::operationAt(int index) const
@@ -263,8 +263,8 @@ void QQuickStatePrivate::complete()
{
Q_Q(QQuickState);
- for (int ii = 0; ii < reverting.count(); ++ii) {
- for (int jj = 0; jj < revertList.count(); ++jj) {
+ for (int ii = 0; ii < reverting.size(); ++ii) {
+ for (int jj = 0; jj < revertList.size(); ++jj) {
const QQuickRevertAction &revert = reverting.at(ii);
const QQuickSimpleAction &simple = revertList.at(jj);
if ((revert.event && simple.event() == revert.event) ||
@@ -295,7 +295,7 @@ QQuickStatePrivate::generateActionList() const
if (!extends.isEmpty()) {
QList<QQuickState *> states = group ? group->states() : QList<QQuickState *>();
- for (int ii = 0; ii < states.count(); ++ii)
+ for (int ii = 0; ii < states.size(); ++ii)
if (states.at(ii)->name() == extends) {
qmlExecuteDeferred(states.at(ii));
applyList = static_cast<QQuickStatePrivate*>(states.at(ii)->d_func())->generateActionList();
@@ -447,7 +447,7 @@ void QQuickState::addEntriesToRevertList(const QList<QQuickStateAction> &actionL
Q_D(QQuickState);
if (isStateActive()) {
QList<QQuickSimpleAction> simpleActionList;
- simpleActionList.reserve(actionList.count());
+ simpleActionList.reserve(actionList.size());
for (const QQuickStateAction &action : actionList) {
QQuickSimpleAction simpleAction(action);
@@ -520,14 +520,14 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
// List of actions that need to be reverted to roll back (just) this state
QQuickStatePrivate::SimpleActionList additionalReverts;
// First add the reverse of all the applyList actions
- for (int ii = 0; ii < applyList.count(); ++ii) {
+ for (int ii = 0; ii < applyList.size(); ++ii) {
QQuickStateAction &action = applyList[ii];
if (action.event) {
if (!action.event->isReversable())
continue;
bool found = false;
- for (int jj = 0; jj < d->revertList.count(); ++jj) {
+ for (int jj = 0; jj < d->revertList.size(); ++jj) {
QQuickStateActionEvent *event = d->revertList.at(jj).event();
if (event && event->type() == action.event->type()) {
if (action.event->mayOverride(event)) {
@@ -558,7 +558,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
bool found = false;
action.fromBinding = QQmlAnyBinding::ofProperty(action.property);
- for (int jj = 0; jj < d->revertList.count(); ++jj) {
+ for (int jj = 0; jj < d->revertList.size(); ++jj) {
if (d->revertList.at(jj).property() == action.property) {
found = true;
if (d->revertList.at(jj).binding() != action.fromBinding) {
@@ -583,13 +583,13 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
// Any reverts from a previous state that aren't carried forth
// into this state need to be translated into apply actions
- for (int ii = 0; ii < d->revertList.count(); ++ii) {
+ for (int ii = 0; ii < d->revertList.size(); ++ii) {
bool found = false;
if (d->revertList.at(ii).event()) {
QQuickStateActionEvent *event = d->revertList.at(ii).event();
if (!event->isReversable())
continue;
- for (int jj = 0; !found && jj < applyList.count(); ++jj) {
+ for (int jj = 0; !found && jj < applyList.size(); ++jj) {
const QQuickStateAction &action = applyList.at(jj);
if (action.event && action.event->type() == event->type()) {
if (action.event->mayOverride(event))
@@ -597,7 +597,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
}
}
} else {
- for (int jj = 0; !found && jj < applyList.count(); ++jj) {
+ for (int jj = 0; !found && jj < applyList.size(); ++jj) {
const QQuickStateAction &action = applyList.at(jj);
if (action.property == d->revertList.at(ii).property())
found = true;
@@ -636,7 +636,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
d->revertList << additionalReverts;
if (lcStates().isDebugEnabled()) {
- for (const QQuickStateAction &action : qAsConst(applyList)) {
+ for (const QQuickStateAction &action : std::as_const(applyList)) {
if (action.event)
qCDebug(lcStates) << "QQuickStateAction event:" << action.event->type();
else
diff --git a/src/quick/util/qquickstate_p_p.h b/src/quick/util/qquickstate_p_p.h
index 528682a5ba..cd7c1be5aa 100644
--- a/src/quick/util/qquickstate_p_p.h
+++ b/src/quick/util/qquickstate_p_p.h
@@ -206,7 +206,7 @@ public:
}
static qsizetype operations_count(QQmlListProperty<QQuickStateOperation> *prop) {
QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
- return list->count();
+ return list->size();
}
static QQuickStateOperation *operations_at(QQmlListProperty<QQuickStateOperation> *prop, qsizetype index) {
QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp
index 2812b5824a..b4be946dc3 100644
--- a/src/quick/util/qquickstategroup.cpp
+++ b/src/quick/util/qquickstategroup.cpp
@@ -96,7 +96,7 @@ QQuickStateGroup::QQuickStateGroup(QObject *parent)
QQuickStateGroup::~QQuickStateGroup()
{
Q_D(const QQuickStateGroup);
- for (int i = 0; i < d->states.count(); ++i)
+ for (int i = 0; i < d->states.size(); ++i)
d->states.at(i)->setStateGroup(nullptr);
if (d->nullState)
d->nullState->setStateGroup(nullptr);
@@ -153,7 +153,7 @@ void QQuickStateGroupPrivate::append_state(QQmlListProperty<QQuickState> *list,
qsizetype QQuickStateGroupPrivate::count_state(QQmlListProperty<QQuickState> *list)
{
QQuickStateGroup *_this = static_cast<QQuickStateGroup *>(list->object);
- return _this->d_func()->states.count();
+ return _this->d_func()->states.size();
}
QQuickState *QQuickStateGroupPrivate::at_state(QQmlListProperty<QQuickState> *list, qsizetype index)
@@ -166,7 +166,7 @@ void QQuickStateGroupPrivate::clear_states(QQmlListProperty<QQuickState> *list)
{
QQuickStateGroup *_this = static_cast<QQuickStateGroup *>(list->object);
_this->d_func()->setCurrentStateInternal(QString(), true);
- for (qsizetype i = 0; i < _this->d_func()->states.count(); ++i) {
+ for (qsizetype i = 0; i < _this->d_func()->states.size(); ++i) {
_this->d_func()->states.at(i)->setStateGroup(nullptr);
}
_this->d_func()->states.clear();
@@ -190,7 +190,7 @@ void QQuickStateGroupPrivate::removeLast_states(QQmlListProperty<QQuickState> *l
{
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->setCurrentStateInternal(d->states.size() > 1 ? d->states.first()->name() : QString(), true);
d->states.last()->setStateGroup(nullptr);
d->states.removeLast();
}
@@ -234,7 +234,7 @@ void QQuickStateGroupPrivate::append_transition(QQmlListProperty<QQuickTransitio
qsizetype QQuickStateGroupPrivate::count_transitions(QQmlListProperty<QQuickTransition> *list)
{
QQuickStateGroup *_this = static_cast<QQuickStateGroup *>(list->object);
- return _this->d_func()->transitions.count();
+ return _this->d_func()->transitions.size();
}
QQuickTransition *QQuickStateGroupPrivate::at_transition(QQmlListProperty<QQuickTransition> *list, qsizetype index)
@@ -257,14 +257,14 @@ void QQuickStateGroupPrivate::clear_transitions(QQmlListProperty<QQuickTransitio
This property is often used in scripts to change between states. For
example:
- \js
+ \qml
function toggle() {
if (button.state == 'On')
button.state = 'Off';
else
button.state = 'On';
}
- \endjs
+ \endqml
If the state group is in its base state (i.e. no explicit state has been
set), \c state will be a blank string. Likewise, you can return a
@@ -299,8 +299,8 @@ void QQuickStateGroup::componentComplete()
d->componentComplete = true;
QVarLengthArray<QString, 4> names;
- names.reserve(d->states.count());
- for (int ii = 0; ii < d->states.count(); ++ii) {
+ names.reserve(d->states.size());
+ for (int ii = 0; ii < d->states.size(); ++ii) {
QQuickState *state = d->states.at(ii);
if (!state->isNamed())
state->setName(QLatin1String("anonymousState") + QString::number(++d->unnamedCount));
@@ -338,7 +338,7 @@ bool QQuickStateGroupPrivate::updateAutoState()
return false;
bool revert = false;
- for (int ii = 0; ii < states.count(); ++ii) {
+ for (int ii = 0; ii < states.size(); ++ii) {
QQuickState *state = states.at(ii);
if (state->isWhenKnown()) {
if (state->isNamed()) {
@@ -353,11 +353,10 @@ bool QQuickStateGroupPrivate::updateAutoState()
if (abstractBinding && abstractBinding->kind() == QQmlAbstractBinding::QmlBinding) {
QQmlBinding *binding = static_cast<QQmlBinding *>(abstractBinding);
if (binding->hasValidContext()) {
- QVariant evalResult = binding->evaluate();
- if (evalResult.metaType() == QMetaType::fromType<QJSValue>())
- whenValue = evalResult.value<QJSValue>().toBool();
- else
- whenValue = evalResult.toBool();
+ const auto boolType = QMetaType::fromType<bool>();
+ const bool isUndefined = !binding->evaluate(&whenValue, boolType);
+ if (isUndefined)
+ whenValue = false;
}
}
@@ -391,7 +390,7 @@ QQuickTransition *QQuickStateGroupPrivate::findTransition(const QString &from, c
bool reversed = false;
bool done = false;
- for (int ii = 0; !done && ii < transitions.count(); ++ii) {
+ for (int ii = 0; !done && ii < transitions.size(); ++ii) {
QQuickTransition *t = transitions.at(ii);
if (!t->enabled())
continue;
@@ -405,10 +404,10 @@ QQuickTransition *QQuickStateGroupPrivate::findTransition(const QString &from, c
const QString toStateStr = t->toState();
auto fromState = QStringView{fromStateStr}.split(QLatin1Char(','));
- for (int jj = 0; jj < fromState.count(); ++jj)
+ for (int jj = 0; jj < fromState.size(); ++jj)
fromState[jj] = fromState.at(jj).trimmed();
auto toState = QStringView{toStateStr}.split(QLatin1Char(','));
- for (int jj = 0; jj < toState.count(); ++jj)
+ for (int jj = 0; jj < toState.size(); ++jj)
toState[jj] = toState.at(jj).trimmed();
if (ii == 1)
qSwap(fromState, toState);
@@ -476,7 +475,7 @@ void QQuickStateGroupPrivate::setCurrentStateInternal(const QString &state,
QQuickState *oldState = nullptr;
if (!currentState.isEmpty()) {
- for (int ii = 0; ii < states.count(); ++ii) {
+ for (int ii = 0; ii < states.size(); ++ii) {
if (states.at(ii)->name() == currentState) {
oldState = states.at(ii);
break;
@@ -488,7 +487,7 @@ void QQuickStateGroupPrivate::setCurrentStateInternal(const QString &state,
emit q->stateChanged(currentState);
QQuickState *newState = nullptr;
- for (int ii = 0; ii < states.count(); ++ii) {
+ for (int ii = 0; ii < states.size(); ++ii) {
if (states.at(ii)->name() == currentState) {
newState = states.at(ii);
break;
@@ -512,7 +511,7 @@ void QQuickStateGroupPrivate::setCurrentStateInternal(const QString &state,
QQuickState *QQuickStateGroup::findState(const QString &name) const
{
Q_D(const QQuickStateGroup);
- for (int i = 0; i < d->states.count(); ++i) {
+ for (int i = 0; i < d->states.size(); ++i) {
QQuickState *state = d->states.at(i);
if (state->name() == name)
return state;
diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp
index b542869913..1bee09a421 100644
--- a/src/quick/util/qquickstyledtext.cpp
+++ b/src/quick/util/qquickstyledtext.cpp
@@ -127,6 +127,13 @@ const QChar QQuickStyledTextPrivate::square(0x25a1);
const QChar QQuickStyledTextPrivate::lineFeed(QLatin1Char('\n'));
const QChar QQuickStyledTextPrivate::space(QLatin1Char(' '));
+namespace {
+bool is_equal_ignoring_case(QStringView s1, QLatin1StringView s2) noexcept
+{
+ return s1.compare(s2, Qt::CaseInsensitive) == 0;
+}
+}
+
QQuickStyledText::QQuickStyledText(const QString &string, QTextLayout &layout,
QList<QQuickStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
@@ -181,31 +188,31 @@ void QQuickStyledTextPrivate::parse()
hasSpace = true;
}
- if (rangeStart != drawText.length() && formatStack.count()) {
+ if (rangeStart != drawText.size() && formatStack.size()) {
if (formatChanged) {
QTextLayout::FormatRange formatRange;
formatRange.format = formatStack.top();
formatRange.start = rangeStart;
- formatRange.length = drawText.length() - rangeStart;
+ formatRange.length = drawText.size() - rangeStart;
ranges.append(formatRange);
formatChanged = false;
- } else if (ranges.count()) {
- ranges.last().length += drawText.length() - rangeStart;
+ } else if (ranges.size()) {
+ ranges.last().length += drawText.size() - rangeStart;
}
}
- rangeStart = drawText.length();
+ rangeStart = drawText.size();
++ch;
if (*ch == slash) {
++ch;
if (parseCloseTag(ch, text, drawText)) {
- if (formatStack.count()) {
+ if (formatStack.size()) {
formatChanged = true;
formatStack.pop();
}
}
} else {
QTextCharFormat format;
- if (formatStack.count())
+ if (formatStack.size())
format = formatStack.top();
if (parseTag(ch, text, drawText, format)) {
formatChanged = true;
@@ -245,15 +252,15 @@ void QQuickStyledTextPrivate::parse()
}
if (textLength)
appendText(text, textStart, textLength, drawText);
- if (rangeStart != drawText.length() && formatStack.count()) {
+ if (rangeStart != drawText.size() && formatStack.size()) {
if (formatChanged) {
QTextLayout::FormatRange formatRange;
formatRange.format = formatStack.top();
formatRange.start = rangeStart;
- formatRange.length = drawText.length() - rangeStart;
+ formatRange.length = drawText.size() - rangeStart;
ranges.append(formatRange);
- } else if (ranges.count()) {
- ranges.last().length += drawText.length() - rangeStart;
+ } else if (ranges.size()) {
+ ranges.last().length += drawText.size() - rangeStart;
}
}
@@ -296,12 +303,12 @@ bool QQuickStyledTextPrivate::parseTag(const QChar *&ch, const QString &textIn,
if (tagLength == 0)
return false;
auto tag = QStringView(textIn).mid(tagStart, tagLength);
- const QChar char0 = tag.at(0);
+ const QChar char0 = tag.at(0).toLower();
if (char0 == QLatin1Char('b')) {
if (tagLength == 1) {
format.setFontWeight(QFont::Bold);
return true;
- } else if (tagLength == 2 && tag.at(1) == QLatin1Char('r')) {
+ } else if (tagLength == 2 && tag.at(1).toLower() == QLatin1Char('r')) {
textOut.append(QChar(QChar::LineSeparator));
hasSpace = true;
prependSpace = false;
@@ -318,7 +325,7 @@ bool QQuickStyledTextPrivate::parseTag(const QChar *&ch, const QString &textIn,
textOut.append(QChar::LineSeparator);
hasSpace = true;
prependSpace = false;
- } else if (tag == QLatin1String("pre")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("pre"))) {
preFormat = true;
if (!hasNewLine)
textOut.append(QChar::LineSeparator);
@@ -330,7 +337,7 @@ bool QQuickStyledTextPrivate::parseTag(const QChar *&ch, const QString &textIn,
if (tagLength == 1) {
format.setFontUnderline(true);
return true;
- } else if (tag == QLatin1String("ul")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("ul"))) {
List listItem;
listItem.level = 0;
listItem.type = Unordered;
@@ -352,20 +359,20 @@ bool QQuickStyledTextPrivate::parseTag(const QChar *&ch, const QString &textIn,
if (tagLength == 1) {
format.setFontStrikeOut(true);
return true;
- } else if (tag == QLatin1String("strong")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("strong"))) {
format.setFontWeight(QFont::Bold);
return true;
}
- } else if (tag == QLatin1String("del")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("del"))) {
format.setFontStrikeOut(true);
return true;
- } else if (tag == QLatin1String("ol")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("ol"))) {
List listItem;
listItem.level = 0;
listItem.type = Ordered;
listItem.format = Decimal;
listStack.push(listItem);
- } else if (tag == QLatin1String("li")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("li"))) {
if (!hasNewLine)
textOut.append(QChar(QChar::LineSeparator));
if (!listStack.isEmpty()) {
@@ -405,20 +412,20 @@ bool QQuickStyledTextPrivate::parseTag(const QChar *&ch, const QString &textIn,
} else if (ch->isSpace()) {
// may have params.
auto tag = QStringView(textIn).mid(tagStart, tagLength);
- if (tag == QLatin1String("font"))
+ if (is_equal_ignoring_case(tag, QLatin1String("font")))
return parseFontAttributes(ch, textIn, format);
- if (tag == QLatin1String("ol")) {
+ if (is_equal_ignoring_case(tag, QLatin1String("ol"))) {
parseOrderedListAttributes(ch, textIn);
return false; // doesn't modify format
}
- if (tag == QLatin1String("ul")) {
+ if (is_equal_ignoring_case(tag, QLatin1String("ul"))) {
parseUnorderedListAttributes(ch, textIn);
return false; // doesn't modify format
}
- if (tag == QLatin1String("a")) {
+ if (is_equal_ignoring_case(tag, QLatin1String("a"))) {
return parseAnchorAttributes(ch, textIn, format);
}
- if (tag == QLatin1String("img")) {
+ if (is_equal_ignoring_case(tag, QLatin1String("img"))) {
parseImageAttributes(ch, textIn, textOut);
return false;
}
@@ -443,12 +450,12 @@ bool QQuickStyledTextPrivate::parseCloseTag(const QChar *&ch, const QString &tex
if (tagLength == 0)
return false;
auto tag = QStringView(textIn).mid(tagStart, tagLength);
- const QChar char0 = tag.at(0);
+ const QChar char0 = tag.at(0).toLower();
hasNewLine = false;
if (char0 == QLatin1Char('b')) {
if (tagLength == 1)
return true;
- else if (tag.at(1) == QLatin1Char('r') && tagLength == 2)
+ else if (tag.at(1).toLower() == QLatin1Char('r') && tagLength == 2)
return false;
} else if (char0 == QLatin1Char('i')) {
if (tagLength == 1)
@@ -462,7 +469,7 @@ bool QQuickStyledTextPrivate::parseCloseTag(const QChar *&ch, const QString &tex
hasNewLine = true;
hasSpace = true;
return false;
- } else if (tag == QLatin1String("pre")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("pre"))) {
preFormat = false;
if (!hasNewLine)
textOut.append(QChar::LineSeparator);
@@ -473,10 +480,10 @@ bool QQuickStyledTextPrivate::parseCloseTag(const QChar *&ch, const QString &tex
} else if (char0 == QLatin1Char('u')) {
if (tagLength == 1)
return true;
- else if (tag == QLatin1String("ul")) {
+ else if (is_equal_ignoring_case(tag, QLatin1String("ul"))) {
if (!listStack.isEmpty()) {
listStack.pop();
- if (!listStack.count())
+ if (!listStack.size())
textOut.append(QChar::LineSeparator);
}
return false;
@@ -486,24 +493,24 @@ bool QQuickStyledTextPrivate::parseCloseTag(const QChar *&ch, const QString &tex
hasNewLine = true;
hasSpace = true;
return true;
- } else if (tag == QLatin1String("font")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("font"))) {
return true;
} else if (char0 == QLatin1Char('s')) {
if (tagLength == 1) {
return true;
- } else if (tag == QLatin1String("strong")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("strong"))) {
return true;
}
- } else if (tag == QLatin1String("del")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("del"))) {
return true;
- } else if (tag == QLatin1String("ol")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("ol"))) {
if (!listStack.isEmpty()) {
listStack.pop();
- if (!listStack.count())
+ if (!listStack.size())
textOut.append(QChar::LineSeparator);
}
return false;
- } else if (tag == QLatin1String("li")) {
+ } else if (is_equal_ignoring_case(tag, QLatin1String("li"))) {
return false;
}
return false;
@@ -545,10 +552,10 @@ bool QQuickStyledTextPrivate::parseFontAttributes(const QChar *&ch, const QStrin
QPair<QStringView,QStringView> attr;
do {
attr = parseAttribute(ch, textIn);
- if (attr.first == QLatin1String("color")) {
+ if (is_equal_ignoring_case(attr.first, QLatin1String("color"))) {
valid = true;
format.setForeground(QColor::fromString(attr.second));
- } else if (attr.first == QLatin1String("size")) {
+ } else if (is_equal_ignoring_case(attr.first, QLatin1String("size"))) {
valid = true;
int size = attr.second.toInt();
if (attr.second.at(0) == QLatin1Char('-') || attr.second.at(0) == QLatin1Char('+'))
@@ -573,7 +580,7 @@ bool QQuickStyledTextPrivate::parseOrderedListAttributes(const QChar *&ch, const
QPair<QStringView,QStringView> attr;
do {
attr = parseAttribute(ch, textIn);
- if (attr.first == QLatin1String("type")) {
+ if (is_equal_ignoring_case(attr.first, QLatin1String("type"))) {
valid = true;
if (attr.second == QLatin1String("a"))
listItem.format = LowerAlpha;
@@ -602,11 +609,11 @@ bool QQuickStyledTextPrivate::parseUnorderedListAttributes(const QChar *&ch, con
QPair<QStringView,QStringView> attr;
do {
attr = parseAttribute(ch, textIn);
- if (attr.first == QLatin1String("type")) {
+ if (is_equal_ignoring_case(attr.first, QLatin1String("type"))) {
valid = true;
- if (attr.second == QLatin1String("disc"))
+ if (is_equal_ignoring_case(attr.second, QLatin1String("disc")))
listItem.format = Disc;
- else if (attr.second == QLatin1String("square"))
+ else if (is_equal_ignoring_case(attr.second, QLatin1String("square")))
listItem.format = Square;
}
} while (!ch->isNull() && !attr.first.isEmpty());
@@ -622,7 +629,7 @@ bool QQuickStyledTextPrivate::parseAnchorAttributes(const QChar *&ch, const QStr
QPair<QStringView,QStringView> attr;
do {
attr = parseAttribute(ch, textIn);
- if (attr.first == QLatin1String("href")) {
+ if (is_equal_ignoring_case(attr.first, QLatin1String("href"))) {
format.setAnchorHref(attr.second.toString());
format.setAnchor(true);
format.setFontUnderline(true);
@@ -642,21 +649,21 @@ void QQuickStyledTextPrivate::parseImageAttributes(const QChar *&ch, const QStri
if (!updateImagePositions) {
QQuickStyledTextImgTag *image = new QQuickStyledTextImgTag;
- image->position = textOut.length() + (trailingSpace ? 0 : 1);
+ image->position = textOut.size() + (trailingSpace ? 0 : 1);
QPair<QStringView,QStringView> attr;
do {
attr = parseAttribute(ch, textIn);
- if (attr.first == QLatin1String("src")) {
+ if (is_equal_ignoring_case(attr.first, QLatin1String("src"))) {
image->url = QUrl(attr.second.toString());
- } else if (attr.first == QLatin1String("width")) {
+ } else if (is_equal_ignoring_case(attr.first, QLatin1String("width"))) {
image->size.setWidth(attr.second.toString().toInt());
- } else if (attr.first == QLatin1String("height")) {
+ } else if (is_equal_ignoring_case(attr.first, QLatin1String("height"))) {
image->size.setHeight(attr.second.toString().toInt());
- } else if (attr.first == QLatin1String("align")) {
- if (attr.second.toString() == QLatin1String("top")) {
+ } else if (is_equal_ignoring_case(attr.first, QLatin1String("align"))) {
+ if (is_equal_ignoring_case(attr.second, QLatin1String("top"))) {
image->align = QQuickStyledTextImgTag::Top;
- } else if (attr.second.toString() == QLatin1String("middle")) {
+ } else if (is_equal_ignoring_case(attr.second, QLatin1String("middle"))) {
image->align = QQuickStyledTextImgTag::Middle;
}
}
@@ -686,7 +693,7 @@ void QQuickStyledTextPrivate::parseImageAttributes(const QChar *&ch, const QStri
// if we already have a list of img tags for this text
// we only want to update the positions of these tags.
QQuickStyledTextImgTag *image = imgTags->value(nbImages);
- image->position = textOut.length() + (trailingSpace ? 0 : 1);
+ image->position = textOut.size() + (trailingSpace ? 0 : 1);
imgWidth = image->size.width();
image->offset = -std::fmod(imgWidth, spaceWidth) / 2.0;
QPair<QStringView,QStringView> attr;
diff --git a/src/quick/util/qquicksvgparser.cpp b/src/quick/util/qquicksvgparser.cpp
index a4f1ac8e80..5f88805ef7 100644
--- a/src/quick/util/qquicksvgparser.cpp
+++ b/src/quick/util/qquicksvgparser.cpp
@@ -249,7 +249,7 @@ bool QQuickSvgParser::parsePathDataFast(const QString &dataStr, QPainterPath &pa
if (pathElem == QLatin1Char('z') || pathElem == QLatin1Char('Z'))
arg.append(0);//dummy
const qreal *num = arg.constData();
- int count = arg.count();
+ int count = arg.size();
while (count > 0) {
qreal offsetX = x; // correction offsets
qreal offsetY = y; // for relative commands
diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp
index ab59969ce5..e53dbe0fd9 100644
--- a/src/quick/util/qquicktimeline.cpp
+++ b/src/quick/util/qquicktimeline.cpp
@@ -786,7 +786,7 @@ int QQuickTimeLinePrivate::advance(int t)
std::sort(updates.begin(), updates.end());
updateQueue = &updates;
- for (int ii = 0; ii < updates.count(); ++ii) {
+ for (int ii = 0; ii < updates.size(); ++ii) {
const Update &v = updates.at(ii).second;
if (v.g) {
v.g->setValue(v.v);
@@ -836,7 +836,7 @@ void QQuickTimeLine::remove(QQuickTimeLineObject *v)
}
if (d->updateQueue) {
- for (int ii = 0; ii < d->updateQueue->count(); ++ii) {
+ for (int ii = 0; ii < d->updateQueue->size(); ++ii) {
if (d->updateQueue->at(ii).second.g == v ||
d->updateQueue->at(ii).second.e.callbackObject() == v) {
d->updateQueue->removeAt(ii);
diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp
index 1d2c9e2f41..062e6e2656 100644
--- a/src/quick/util/qquicktransition.cpp
+++ b/src/quick/util/qquicktransition.cpp
@@ -115,7 +115,7 @@ void QQuickTransitionPrivate::append_animation(QQmlListProperty<QQuickAbstractAn
qsizetype QQuickTransitionPrivate::animation_count(QQmlListProperty<QQuickAbstractAnimation> *list)
{
QQuickTransition *q = static_cast<QQuickTransition *>(list->object);
- return q->d_func()->animations.count();
+ return q->d_func()->animations.size();
}
QQuickAbstractAnimation* QQuickTransitionPrivate::animation_at(QQmlListProperty<QQuickAbstractAnimation> *list, qsizetype pos)
@@ -127,7 +127,7 @@ QQuickAbstractAnimation* QQuickTransitionPrivate::animation_at(QQmlListProperty<
void QQuickTransitionPrivate::clear_animations(QQmlListProperty<QQuickAbstractAnimation> *list)
{
QQuickTransition *q = static_cast<QQuickTransition *>(list->object);
- while (q->d_func()->animations.count()) {
+ while (q->d_func()->animations.size()) {
QQuickAbstractAnimation *firstAnim = q->d_func()->animations.at(0);
q->d_func()->animations.removeAll(firstAnim);
}
@@ -232,8 +232,8 @@ QQuickTransitionInstance *QQuickTransition::prepare(QQuickStateOperation::Action
group->manager = manager;
QQuickAbstractAnimation::TransitionDirection direction = d->reversed ? QQuickAbstractAnimation::Backward : QQuickAbstractAnimation::Forward;
- int start = d->reversed ? d->animations.count() - 1 : 0;
- int end = d->reversed ? -1 : d->animations.count();
+ int start = d->reversed ? d->animations.size() - 1 : 0;
+ int end = d->reversed ? -1 : d->animations.size();
QAbstractAnimationJob *anim = nullptr;
for (int i = start; i != end;) {
diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp
index 53aa6608aa..efaa01c305 100644
--- a/src/quick/util/qquicktransitionmanager.cpp
+++ b/src/quick/util/qquicktransitionmanager.cpp
@@ -59,7 +59,7 @@ void QQuickTransitionManager::complete()
// Explicitly take a copy in case the write action triggers a script that modifies the list.
QQuickTransitionManagerPrivate::SimpleActionList completeListCopy = d->completeList;
- for (const QQuickSimpleAction &action : qAsConst(completeListCopy))
+ for (const QQuickSimpleAction &action : std::as_const(completeListCopy))
action.property().write(action.value());
d->completeList.clear();
@@ -72,7 +72,7 @@ void QQuickTransitionManager::complete()
void QQuickTransitionManagerPrivate::applyBindings()
{
- for (const QQuickStateAction &action : qAsConst(bindingsList)) {
+ for (const QQuickStateAction &action : std::as_const(bindingsList)) {
if (auto binding = action.toBinding; binding) {
binding.installOn(action.property, QQmlAnyBinding::RespectInterceptors);
} else if (action.event) {
@@ -101,11 +101,13 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
QQuickStateOperation::ActionList applyList = list;
// Determine which actions are binding changes and disable any current bindings
- for (const QQuickStateAction &action : qAsConst(applyList)) {
+ for (const QQuickStateAction &action : std::as_const(applyList)) {
if (action.toBinding)
d->bindingsList << action;
- if (action.fromBinding)
- QQmlPropertyPrivate::removeBinding(action.property); // Disable current binding
+ if (action.fromBinding) {
+ auto property = action.property;
+ QQmlAnyBinding::removeBindingFrom(property); // Disable current binding
+ }
if (action.event && action.event->changesBindings()) { //### assume isReversable()?
d->bindingsList << action;
action.event->clearBindings();
@@ -123,7 +125,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
if (transition && !d->bindingsList.isEmpty()) {
// Apply all the property and binding changes
- for (const QQuickStateAction &action : qAsConst(applyList)) {
+ for (const QQuickStateAction &action : std::as_const(applyList)) {
if (auto binding = action.toBinding; binding) {
binding.installOn(action.property);
} else if (!action.event) {
@@ -148,7 +150,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
}
// Revert back to the original values
- for (const QQuickStateAction &action : qAsConst(applyList)) {
+ for (const QQuickStateAction &action : std::as_const(applyList)) {
if (action.event) {
if (action.event->isReversable()) {
action.event->clearBindings();
@@ -158,8 +160,10 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
continue;
}
- if (action.toBinding)
- QQmlPropertyPrivate::removeBinding(action.property); // Make sure this is disabled during the transition
+ if (action.toBinding) {
+ auto property = action.property;
+ QQmlAnyBinding::removeBindingFrom(property); // Make sure this is disabled during the transition
+ }
QQmlPropertyPrivate::write(action.property, action.fromValue, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding);
}
@@ -194,7 +198,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
// be applied immediately. We skip applying bindings, as they are all
// applied at the end in applyBindings() to avoid any nastiness mid
// transition
- for (const QQuickStateAction &action : qAsConst(applyList)) {
+ for (const QQuickStateAction &action : std::as_const(applyList)) {
if (action.event && !action.event->changesBindings()) {
if (action.event->isReversable() && action.reverseEvent)
action.event->reverse();
@@ -205,7 +209,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
}
}
if (lcStates().isDebugEnabled()) {
- for (const QQuickStateAction &action : qAsConst(applyList)) {
+ for (const QQuickStateAction &action : std::as_const(applyList)) {
if (action.event)
qCDebug(lcStates) << "no transition for event:" << action.event->type();
else
@@ -224,9 +228,10 @@ void QQuickTransitionManager::cancel()
if (d->transitionInstance && d->transitionInstance->isRunning())
RETURN_IF_DELETED(d->transitionInstance->stop());
- for (const QQuickStateAction &action : qAsConst(d->bindingsList)) {
+ for (const QQuickStateAction &action : std::as_const(d->bindingsList)) {
if (action.toBinding && action.deletableToBinding) {
- QQmlPropertyPrivate::removeBinding(action.property);
+ auto property = action.property;
+ QQmlAnyBinding::removeBindingFrom(property);
} else if (action.event) {
//### what do we do here?
}
diff --git a/src/quickcontrols2/basic/HorizontalHeaderView.qml b/src/quickcontrols2/basic/HorizontalHeaderView.qml
index 140c9f3ae8..bad08d947d 100644
--- a/src/quickcontrols2/basic/HorizontalHeaderView.qml
+++ b/src/quickcontrols2/basic/HorizontalHeaderView.qml
@@ -19,7 +19,7 @@ T.HorizontalHeaderView {
color: "#f6f6f6"
border.color: "#e4e4e4"
- Text {
+ Label {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
diff --git a/src/quickcontrols2/basic/TreeViewDelegate.qml b/src/quickcontrols2/basic/TreeViewDelegate.qml
index 9f6eecd62b..fc9a072c43 100644
--- a/src/quickcontrols2/basic/TreeViewDelegate.qml
+++ b/src/quickcontrols2/basic/TreeViewDelegate.qml
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 The Qt Company Lt.
+// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
@@ -34,8 +34,8 @@ T.TreeViewDelegate {
readonly property real __indicatorIndent: control.leftMargin + (control.depth * control.indentation)
x: !control.mirrored ? __indicatorIndent : control.width - __indicatorIndent - width
y: (control.height - height) / 2
- width: 16
- height: 16
+ implicitWidth: 20
+ implicitHeight: 40 // same as Button.qml
ColorImage {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
@@ -43,11 +43,11 @@ T.TreeViewDelegate {
source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/arrow-indicator.png"
color: control.palette.windowText
defaultColor: "#353637"
- scale: 0.5
}
}
background: Rectangle {
+ implicitHeight: 40 // same as Button.qml
color: control.highlighted
? control.palette.highlight
: (control.treeView.alternatingRows && control.row % 2 !== 0
diff --git a/src/quickcontrols2/basic/VerticalHeaderView.qml b/src/quickcontrols2/basic/VerticalHeaderView.qml
index a59e228d20..cb942c978f 100644
--- a/src/quickcontrols2/basic/VerticalHeaderView.qml
+++ b/src/quickcontrols2/basic/VerticalHeaderView.qml
@@ -19,7 +19,7 @@ T.VerticalHeaderView {
color: "#f6f6f6"
border.color: "#e4e4e4"
- Text {
+ Label {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
diff --git a/src/quickcontrols2/designer/qtquickcontrols2.metainfo b/src/quickcontrols2/designer/qtquickcontrols2.metainfo
index 1075cec62e..0cd3959cf8 100644
--- a/src/quickcontrols2/designer/qtquickcontrols2.metainfo
+++ b/src/quickcontrols2/designer/qtquickcontrols2.metainfo
@@ -9,6 +9,7 @@ MetaInfo {
libraryIcon: "images/busyindicator-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("Indicates activity while, for example, content is being loaded.")
}
}
@@ -22,6 +23,7 @@ MetaInfo {
libraryIcon: "images/button-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A button with text.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Button\")" }
}
@@ -37,6 +39,7 @@ MetaInfo {
libraryIcon: "images/checkbox-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A checkbox with a text label.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Check Box\")" }
}
@@ -52,6 +55,7 @@ MetaInfo {
libraryIcon: "images/checkbox-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("Presents items from a model as checkboxes.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Check Delegate\")" }
}
@@ -67,6 +71,7 @@ MetaInfo {
libraryIcon: "images/combobox-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("An editable drop-down list.")
}
}
@@ -80,6 +85,7 @@ MetaInfo {
libraryIcon: "images/control-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("An abstract base type for UI controls.")
}
}
@@ -93,6 +99,7 @@ MetaInfo {
libraryIcon: "images/delaybutton-icon.png"
version: "2.2"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A button with a delay preventing accidental presses.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Delay Button\")" }
}
@@ -108,6 +115,8 @@ MetaInfo {
libraryIcon: "images/dial-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+
+ toolTip: qsTr("A circular dial that is rotated to set a value.")
}
}
@@ -121,6 +130,7 @@ MetaInfo {
libraryIcon: "images/frame-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("An untitled container for a group of controls.")
Property { name: "width"; type: "int"; value: 200 }
Property { name: "height"; type: "int"; value: 200 }
@@ -137,6 +147,7 @@ MetaInfo {
libraryIcon: "images/groupbox-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A titled container for a group of controls.")
Property { name: "width"; type: "int"; value: 200 }
Property { name: "height"; type: "int"; value: 200 }
@@ -154,6 +165,7 @@ MetaInfo {
libraryIcon: "images/itemdelegate-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("Presents a standard view item. It can be used as a delegate in various views and controls, such as ListView and ComboBox.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Item Delegate\")" }
}
@@ -169,6 +181,7 @@ MetaInfo {
libraryIcon: "images/label-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A text label.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Label\")" }
}
@@ -184,6 +197,7 @@ MetaInfo {
libraryIcon: "images/page-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A page with header and footer.")
Property { name: "width"; type: "int"; value: 200 }
Property { name: "height"; type: "int"; value: 200 }
@@ -200,6 +214,7 @@ MetaInfo {
libraryIcon: "images/pageindicator-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("Indicates the currently active page.")
Property { name: "count"; type: "int"; value: 3 }
}
@@ -215,6 +230,7 @@ MetaInfo {
libraryIcon: "images/pane-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("Provides a background matching the application style and theme.")
Property { name: "width"; type: "int"; value: 200 }
Property { name: "height"; type: "int"; value: 200 }
@@ -231,6 +247,7 @@ MetaInfo {
libraryIcon: "images/progressbar-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A bar indicating the progress of an operation.")
Property { name: "value"; type: "real"; value: 0.5 }
}
@@ -246,6 +263,7 @@ MetaInfo {
libraryIcon: "images/radiobutton-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("An option button that you can toggle on or off.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Radio Button\")" }
}
@@ -261,6 +279,7 @@ MetaInfo {
libraryIcon: "images/radiobutton-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("Presents items from a model as radio buttons.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Radio Delegate\")" }
}
@@ -276,6 +295,7 @@ MetaInfo {
libraryIcon: "images/rangeslider-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A bar with adjustable start and end points.")
Property { name: "first.value"; type: "real"; value: 0.25 }
Property { name: "second.value"; type: "real"; value: 0.75 }
@@ -292,6 +312,8 @@ MetaInfo {
libraryIcon: "images/roundbutton-icon.png"
version: "2.1"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A round button with text.")
+
Property { name: "text"; type: "string"; value: "+" }
}
}
@@ -306,6 +328,7 @@ MetaInfo {
libraryIcon: "images/slider-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("An adjustable slider.")
Property { name: "value"; type: "real"; value: 0.5 }
}
@@ -321,6 +344,7 @@ MetaInfo {
libraryIcon: "images/spinbox-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A box with an adjustable number.")
}
}
@@ -334,6 +358,7 @@ MetaInfo {
libraryIcon: "images/scrollview-icon.png"
version: "2.2"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A scrollable area.")
Property { name: "width"; type: "int"; value: 200 }
Property { name: "height"; type: "int"; value: 200 }
@@ -350,6 +375,7 @@ MetaInfo {
libraryIcon: "images/stackview-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("Provides a stack-based navigation for a set of pages.")
Property { name: "width"; type: "int"; value: 200 }
Property { name: "height"; type: "int"; value: 200 }
@@ -366,6 +392,7 @@ MetaInfo {
libraryIcon: "images/itemdelegate-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("Presents items from a model as items that you can swipe to expose more options.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Swipe Delegate\")" }
}
@@ -381,6 +408,7 @@ MetaInfo {
libraryIcon: "images/swipeview-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("Provides a view where you can navigate pages by swiping.")
Property { name: "width"; type: "int"; value: 200 }
Property { name: "height"; type: "int"; value: 200 }
@@ -397,6 +425,7 @@ MetaInfo {
libraryIcon: "images/switch-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A button that you can toggle on and off.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Switch\")" }
}
@@ -412,6 +441,7 @@ MetaInfo {
libraryIcon: "images/switch-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("Presents items from a model as toggle switches.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Switch Delegate\")" }
}
@@ -427,6 +457,8 @@ MetaInfo {
libraryIcon: "images/toolbar-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A tab-based navigation model.")
+
Property { name: "width"; type: "int"; value: 240 }
}
}
@@ -441,6 +473,8 @@ MetaInfo {
libraryIcon: "images/toolbutton-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A button suitable for a tab bar.")
+
Property { name: "text"; type: "binding"; value: "qsTr(\"Tab Button\")" }
}
}
@@ -455,6 +489,7 @@ MetaInfo {
libraryIcon: "images/textarea-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A multi-line text box.")
Property { name: "placeholderText"; type: "binding"; value: "qsTr(\"Text Area\")" }
}
@@ -470,6 +505,7 @@ MetaInfo {
libraryIcon: "images/textfield-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A single-line text box.")
Property { name: "placeholderText"; type: "binding"; value: "qsTr(\"Text Field\")" }
}
@@ -485,6 +521,7 @@ MetaInfo {
libraryIcon: "images/toolbar-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A row that can hold actions and buttons.")
Property { name: "width"; type: "int"; value: 360 }
}
@@ -500,6 +537,7 @@ MetaInfo {
libraryIcon: "images/toolbutton-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A button suitable for a tool bar.")
Property { name: "text"; type: "binding"; value: "qsTr(\"Tool Button\")" }
}
@@ -515,6 +553,7 @@ MetaInfo {
libraryIcon: "images/toolseparator-icon.png"
version: "2.1"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A line to separate sections in a tool bar.")
}
}
@@ -528,6 +567,7 @@ MetaInfo {
libraryIcon: "images/tumbler-icon.png"
version: "2.0"
requiredImport: "QtQuick.Controls"
+ toolTip: qsTr("A spinnable wheel of selectable items.")
Property { name: "model"; type: "int"; value: "10" }
}
diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate.qml
index fb2df4f6d3..9f6ec74537 100644
--- a/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate.qml
+++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate.qml
@@ -21,6 +21,7 @@ ListView {
required property string sender
required property string title
+ required property int index
ListView.onRemove: SequentialAnimation {
PropertyAction {
@@ -52,8 +53,6 @@ ListView {
SwipeDelegate.onClicked: listView.model.remove(index)
- required property int index
-
background: Rectangle {
color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
}
diff --git a/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc b/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc
index f6fe5a970a..411c6c1088 100644
--- a/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc
+++ b/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc
@@ -53,5 +53,8 @@
\note Due to a technical limitation, the path should not be named
\e "imagine" if it is relative to the \c qtquickcontrols2.conf file.
+ \li \c QT_QUICK_CONTROLS_IMAGINE_SMOOTH
+ \li Set to \c 1 to enable smooth scaling for 9-patch images.
+ This environment variable was added in Qt 6.5.
\endtable
//! [env]
diff --git a/src/quickcontrols2/doc/src/includes/qquicktooltip.qdocinc b/src/quickcontrols2/doc/src/includes/qquicktooltip.qdocinc
new file mode 100644
index 0000000000..0046a2d8b0
--- /dev/null
+++ b/src/quickcontrols2/doc/src/includes/qquicktooltip.qdocinc
@@ -0,0 +1,6 @@
+//! [customize-note]
+\note to customize the \l {Attached Tool Tips}{attached ToolTip}, it
+must be provided as part of
+\l {Creating a Custom Style}{your own style}. To do a one-off
+customization of a \c ToolTip, see \l {Custom Tool Tips}.
+//! [customize-note]
diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-customize.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-customize.qdoc
index bd362270fc..e30d393771 100644
--- a/src/quickcontrols2/doc/src/qtquickcontrols2-customize.qdoc
+++ b/src/quickcontrols2/doc/src/qtquickcontrols2-customize.qdoc
@@ -85,6 +85,12 @@
An added benefit of these three methods is that it's not necessary to
implement the template from scratch.
+ \note the three approaches mentioned here do not work for customizing the
+ attached \l ToolTip, as that is a shared item created internally. To do
+ a one-off customization of a \c ToolTip, see \l {Custom Tool Tips}. To
+ customize the attached \c ToolTip, it must be provided as part of
+ \l {Creating a Custom Style}{your own style}.
+
\section1 Creating a Custom Style
There are several ways to go about creating your own styles. Below, we'll
@@ -518,7 +524,7 @@
\l {ApplicationWindow::background}{background}.
\code
- import
+ import QtQuick
import QtQuick.Controls
ApplicationWindow {
@@ -1003,6 +1009,7 @@
\printuntil }
\printuntil }
+ \include qquicktooltip.qdocinc customize-note
\section2 Customizing Tumbler
diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-delegates.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-delegates.qdoc
index a5ccb95bc3..5d498ced1f 100644
--- a/src/quickcontrols2/doc/src/qtquickcontrols2-delegates.qdoc
+++ b/src/quickcontrols2/doc/src/qtquickcontrols2-delegates.qdoc
@@ -62,10 +62,10 @@
\image qtquickcontrols2-treeviewdelegate.png
- \l A TreeViewDelegate is a delegate that can be assigned to the delegate property
+ A \l TreeViewDelegate is a delegate that can be assigned to the delegate property
of a TreeView.
- \b {See also} \l {TreeView Control}.
+ \b {See also} \l {TreeView}.
\section1 Related Information
\list
diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-ios.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-ios.qdoc
index e81fb468f8..1ef9a1dccf 100644
--- a/src/quickcontrols2/doc/src/qtquickcontrols2-ios.qdoc
+++ b/src/quickcontrols2/doc/src/qtquickcontrols2-ios.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
- \page qtquickcontrols2-iOS.html
+ \page qtquickcontrols2-ios.html
\title iOS Style
The iOS Style is a native-looking style for iOS based on image assets.
@@ -51,9 +51,6 @@
\section2 Customization
- The iOS style allows customizing the \l {ios-theme-attached-prop}{theme} attribute.
- By default it follows the system's theme.
-
\section3 Palette
The iOS style supports palette customization via the \l {Item::}{palette}
diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-macos.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-macos.qdoc
index befa0d59c8..911baf6c20 100644
--- a/src/quickcontrols2/doc/src/qtquickcontrols2-macos.qdoc
+++ b/src/quickcontrols2/doc/src/qtquickcontrols2-macos.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
- \page qtquickcontrols2-macOS.html
+ \page qtquickcontrols2-macos.html
\title macOS Style
The macOS style is a style that looks native on macOS.
diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-windows.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-windows.qdoc
index 3bacc3f4ec..e068f3c86d 100644
--- a/src/quickcontrols2/doc/src/qtquickcontrols2-windows.qdoc
+++ b/src/quickcontrols2/doc/src/qtquickcontrols2-windows.qdoc
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
- \page qtquickcontrols2-Windows.html
+ \page qtquickcontrols2-windows.html
\title Windows Style
The Windows style is a style that looks native on Windows.
diff --git a/src/quickcontrols2/fusion/CMakeLists.txt b/src/quickcontrols2/fusion/CMakeLists.txt
index 86a389822c..49bd660a65 100644
--- a/src/quickcontrols2/fusion/CMakeLists.txt
+++ b/src/quickcontrols2/fusion/CMakeLists.txt
@@ -51,6 +51,7 @@ set(qml_files
"ToolButton.qml"
"ToolSeparator.qml"
"ToolTip.qml"
+ "TreeViewDelegate.qml"
"Tumbler.qml"
"VerticalHeaderView.qml"
)
diff --git a/src/quickcontrols2/fusion/HorizontalHeaderView.qml b/src/quickcontrols2/fusion/HorizontalHeaderView.qml
index aafe0fb2fd..77a39cc5a5 100644
--- a/src/quickcontrols2/fusion/HorizontalHeaderView.qml
+++ b/src/quickcontrols2/fusion/HorizontalHeaderView.qml
@@ -3,6 +3,8 @@
import QtQuick
import QtQuick.Templates as T
+import QtQuick.Controls.Fusion
+import QtQuick.Controls.Fusion.impl
T.HorizontalHeaderView {
id: control
@@ -16,20 +18,19 @@ T.HorizontalHeaderView {
implicitWidth: text.implicitWidth + (cellPadding * 2)
implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2))
- border.color: "#cacaca"
gradient: Gradient {
GradientStop {
position: 0
- color: "#fbfbfb"
+ color: Fusion.gradientStart(control.palette.button)
}
GradientStop {
position: 1
- color: "#e0dfe0"
+ color: Fusion.gradientStop(control.palette.button)
}
}
- Text {
+ Label {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
@@ -38,7 +39,6 @@ T.HorizontalHeaderView {
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
- color: "#ff26282a"
}
}
}
diff --git a/src/quickcontrols2/fusion/TreeViewDelegate.qml b/src/quickcontrols2/fusion/TreeViewDelegate.qml
new file mode 100644
index 0000000000..5223361872
--- /dev/null
+++ b/src/quickcontrols2/fusion/TreeViewDelegate.qml
@@ -0,0 +1,62 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Templates as T
+import QtQuick.Controls.impl
+import QtQuick.Controls.Fusion
+
+T.TreeViewDelegate {
+ id: control
+
+ implicitWidth: leftMargin + __contentIndent + implicitContentWidth + rightPadding + rightMargin
+ implicitHeight: Math.max(implicitBackgroundHeight, implicitContentHeight, implicitIndicatorHeight)
+
+ indentation: indicator ? indicator.width : 12
+ leftMargin: 5
+ rightMargin: 5
+ spacing: 5
+
+ topPadding: contentItem ? (height - contentItem.implicitHeight) / 2 : 0
+ leftPadding: !mirrored ? leftMargin + __contentIndent : width - leftMargin - __contentIndent - implicitContentWidth
+
+ highlighted: control.selected || control.current
+ || ((control.treeView.selectionBehavior === TableView.SelectRows
+ || control.treeView.selectionBehavior === TableView.SelectionDisabled)
+ && control.row === control.treeView.currentRow)
+
+ required property int row
+ required property var model
+ readonly property real __contentIndent: !isTreeNode ? 0 : (depth * indentation) + (indicator ? indicator.width + spacing : 0)
+
+ indicator: Item {
+ readonly property real __indicatorIndent: control.leftMargin + (control.depth * control.indentation)
+ x: !control.mirrored ? __indicatorIndent : control.width - __indicatorIndent - width
+ y: (control.height - height) / 2
+ implicitWidth: Math.max(arrow.implicitWidth, 20)
+ implicitHeight: 24 // same as Button.qml
+
+ property ColorImage arrow : ColorImage {
+ parent: control.indicator
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ rotation: control.expanded ? 0 : (control.mirrored ? 90 : -90)
+ source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/arrow.png"
+ color: control.palette.windowText
+ defaultColor: "#353637"
+ }
+ }
+
+ background: Rectangle {
+ implicitHeight: 24 // same as Button.qml
+ color: control.highlighted
+ ? control.palette.highlight
+ : (control.treeView.alternatingRows && control.row % 2 !== 0
+ ? control.palette.alternateBase : control.palette.base)
+ }
+
+ contentItem: Label {
+ text: control.model.display
+ elide: Text.ElideRight
+ }
+}
diff --git a/src/quickcontrols2/fusion/VerticalHeaderView.qml b/src/quickcontrols2/fusion/VerticalHeaderView.qml
index 7ae2fcdd62..a6072c0930 100644
--- a/src/quickcontrols2/fusion/VerticalHeaderView.qml
+++ b/src/quickcontrols2/fusion/VerticalHeaderView.qml
@@ -3,6 +3,8 @@
import QtQuick
import QtQuick.Templates as T
+import QtQuick.Controls.Fusion
+import QtQuick.Controls.Fusion.impl
T.VerticalHeaderView {
id: control
@@ -16,20 +18,19 @@ T.VerticalHeaderView {
implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2))
implicitHeight: text.implicitHeight + (cellPadding * 2)
- border.color: "#cacaca"
gradient: Gradient {
GradientStop {
position: 0
- color: "#fbfbfb"
+ color: Fusion.gradientStart(control.palette.button)
}
GradientStop {
position: 1
- color: "#e0dfe0"
+ color: Fusion.gradientStop(control.palette.button)
}
}
- Text {
+ Label {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
@@ -38,7 +39,6 @@ T.VerticalHeaderView {
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
- color: "#ff26282a"
}
}
}
diff --git a/src/quickcontrols2/fusion/qquickfusiontheme.cpp b/src/quickcontrols2/fusion/qquickfusiontheme.cpp
index bef0628125..335d3be73f 100644
--- a/src/quickcontrols2/fusion/qquickfusiontheme.cpp
+++ b/src/quickcontrols2/fusion/qquickfusiontheme.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 The Qt Company Ltd.
+// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickfusiontheme_p.h"
@@ -8,17 +8,11 @@
QT_BEGIN_NAMESPACE
+extern QPalette qt_fusionPalette();
+
void QQuickFusionTheme::initialize(QQuickTheme *theme)
{
- const bool isDarkSystemTheme = QQuickStylePrivate::isDarkSystemTheme();
- QPalette systemPalette;
- systemPalette.setColor(QPalette::Active, QPalette::ButtonText,
- isDarkSystemTheme ? QColor::fromRgb(0xe7e7e7) : QColor::fromRgb(0x252525));
- systemPalette.setColor(QPalette::Inactive, QPalette::ButtonText,
- isDarkSystemTheme ? QColor::fromRgb(0xe7e7e7) : QColor::fromRgb(0x252525));
- systemPalette.setColor(QPalette::Disabled, QPalette::ButtonText,
- isDarkSystemTheme ? QColor::fromRgb(0x777777) : QColor::fromRgb(0xb6b6b6));
- theme->setPalette(QQuickTheme::System, systemPalette);
+ theme->setPalette(QQuickTheme::System, qt_fusionPalette());
}
QT_END_NAMESPACE
diff --git a/src/quickcontrols2/fusion/qquickfusiontheme_p.h b/src/quickcontrols2/fusion/qquickfusiontheme_p.h
index 7ab953c5f5..a41c9d7315 100644
--- a/src/quickcontrols2/fusion/qquickfusiontheme_p.h
+++ b/src/quickcontrols2/fusion/qquickfusiontheme_p.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKFUSIONTHEME_P_H
diff --git a/src/quickcontrols2/imagine/ComboBox.qml b/src/quickcontrols2/imagine/ComboBox.qml
index 960d58334a..254313454c 100644
--- a/src/quickcontrols2/imagine/ComboBox.qml
+++ b/src/quickcontrols2/imagine/ComboBox.qml
@@ -11,10 +11,10 @@ T.ComboBox {
id: control
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
- contentItem.implicitWidth + background ? (background.leftPadding + background.rightPadding) : 0)
+ implicitContentWidth + (background ? background.leftPadding + background.rightPadding : 0))
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
Math.max(implicitContentHeight,
- implicitIndicatorHeight) + background ? (background.topPadding + background.bottomPadding) : 0)
+ implicitIndicatorHeight) + (background ? background.topPadding + background.bottomPadding : 0))
leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
diff --git a/src/quickcontrols2/imagine/HorizontalHeaderView.qml b/src/quickcontrols2/imagine/HorizontalHeaderView.qml
index 140c9f3ae8..bad08d947d 100644
--- a/src/quickcontrols2/imagine/HorizontalHeaderView.qml
+++ b/src/quickcontrols2/imagine/HorizontalHeaderView.qml
@@ -19,7 +19,7 @@ T.HorizontalHeaderView {
color: "#f6f6f6"
border.color: "#e4e4e4"
- Text {
+ Label {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
diff --git a/src/quickcontrols2/imagine/VerticalHeaderView.qml b/src/quickcontrols2/imagine/VerticalHeaderView.qml
index a59e228d20..cb942c978f 100644
--- a/src/quickcontrols2/imagine/VerticalHeaderView.qml
+++ b/src/quickcontrols2/imagine/VerticalHeaderView.qml
@@ -19,7 +19,7 @@ T.VerticalHeaderView {
color: "#f6f6f6"
border.color: "#e4e4e4"
- Text {
+ Label {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
diff --git a/src/quickcontrols2/imagine/impl/shaders/OpacityMask.frag b/src/quickcontrols2/imagine/impl/shaders/OpacityMask.frag
index 84f9bc3ee6..e3b17752a7 100644
--- a/src/quickcontrols2/imagine/impl/shaders/OpacityMask.frag
+++ b/src/quickcontrols2/imagine/impl/shaders/OpacityMask.frag
@@ -1,3 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
diff --git a/src/quickcontrols2/ios/CMakeLists.txt b/src/quickcontrols2/ios/CMakeLists.txt
index 8168d0d89b..7d8557fd0b 100644
--- a/src/quickcontrols2/ios/CMakeLists.txt
+++ b/src/quickcontrols2/ios/CMakeLists.txt
@@ -35,6 +35,9 @@ set(qml_files
"MenuBar.qml"
"Drawer.qml"
"Popup.qml"
+ "Menu.qml"
+ "MenuItem.qml"
+ "MenuSeparator.qml"
)
set_source_files_properties(Slider.qml PROPERTIES
@@ -70,7 +73,7 @@ qt_internal_add_qml_module(qtquickcontrols2iosstyleplugin
Qt::QuickControls2ImplPrivate
)
-qt_internal_extend_target(Core CONDITION APPLE AND IOS
+qt_internal_extend_target(qtquickcontrols2iosstyleplugin CONDITION APPLE AND IOS
LIBRARIES
${FWUIKit}
)
diff --git a/src/quickcontrols2/ios/Menu.qml b/src/quickcontrols2/ios/Menu.qml
new file mode 100644
index 0000000000..db142868a9
--- /dev/null
+++ b/src/quickcontrols2/ios/Menu.qml
@@ -0,0 +1,71 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Templates as T
+import QtQuick.Controls.impl
+import QtQuick.Controls.iOS
+
+T.Menu {
+ id: control
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ contentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ contentHeight + topPadding + bottomPadding)
+
+ delegate: MenuItem {}
+
+ margins: 0
+ cascade: true
+ dim: modal || control.parent && control.parent.menu
+ overlap: control.width
+
+ enter: Transition {
+ NumberAnimation { property: "scale"; from: 0.2; to: 1.0; easing.type: Easing.OutQuint; duration: 220 }
+ NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 }
+ }
+
+ exit: Transition {
+ NumberAnimation { property: "scale"; from: 1.0; to: 0.0; easing.type: Easing.OutQuint; duration: 220 }
+ NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 }
+ }
+
+ contentItem: ListView {
+ implicitHeight: contentHeight
+ model: control.contentModel
+ interactive: Window.window
+ ? contentHeight + control.topPadding + control.bottomPadding > Window.window.height
+ : false
+ clip: true
+ currentIndex: control.currentIndex
+
+ T.ScrollIndicator.vertical: ScrollIndicator { }
+ }
+
+ background: Item {
+ implicitHeight: 44
+ implicitWidth: 250
+ NinePatchImage {
+ width: parent.width
+ height: parent.height
+ source: control.IOS.url + "menu-background"
+ NinePatchImageSelector on source {
+ states: [
+ {"light": control.IOS.theme === IOS.Light},
+ {"dark": control.IOS.theme === IOS.Dark}
+ ]
+ }
+ }
+ }
+
+ T.Overlay.modal: Rectangle {
+ color: Color.transparent("black", 0.5)
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
+
+ T.Overlay.modeless: Rectangle {
+ color: Color.transparent("black", 0.5)
+ Behavior on opacity { NumberAnimation { duration: 150 } }
+ }
+}
diff --git a/src/quickcontrols2/ios/MenuItem.qml b/src/quickcontrols2/ios/MenuItem.qml
new file mode 100644
index 0000000000..8b05c33d45
--- /dev/null
+++ b/src/quickcontrols2/ios/MenuItem.qml
@@ -0,0 +1,104 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Templates as T
+import QtQuick.Controls.impl
+import QtQuick.Controls.iOS
+
+T.MenuItem {
+ id: control
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding,
+ implicitIndicatorHeight + topPadding + bottomPadding)
+
+ leftPadding: 12
+ rightPadding: 18
+ spacing: 9
+
+ icon.width: 19
+ icon.height: 19
+ icon.color: control.palette.windowText
+
+ property bool isSingleItem: control.menu && control.menu.count === 1
+ property bool isFirstItem: !isSingleItem && control.menu && control.menu.itemAt(0) === control ? true : false
+ property bool isLastItem: !isSingleItem && control.menu && control.menu.itemAt(control.menu.count - 1) === control ? true : false
+ property real indicatorWidth: 12
+
+ contentItem: IconLabel {
+ readonly property real padding: control.indicatorWidth + control.spacing
+ leftPadding: !control.mirrored ? padding : 0
+ rightPadding: control.mirrored ? padding : 0
+
+ spacing: control.spacing
+ mirrored: control.mirrored
+ display: control.display
+ alignment: Qt.AlignLeft
+
+ icon: control.icon
+ text: control.text
+ font: control.font
+ color: control.palette.windowText
+ }
+
+ arrow: ColorImage {
+ x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding
+ y: control.topPadding + (control.availableHeight - height) / 2
+ width: 7
+ height: 12
+ rotation: control.subMenu && (control.down || control.subMenu.visible) ? 90 : 0
+
+ visible: control.subMenu
+ opacity: control.enabled ? 1 : 0.5
+ mirror: control.mirrored
+ color: control.palette.windowText
+ source: control.subMenu ? "qrc:/qt-project.org/imports/QtQuick/Controls/iOS/images/arrow-indicator-light.png" : ""
+
+ Behavior on rotation { RotationAnimation { duration: 100 } }
+ }
+
+ indicator: ColorImage {
+ x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding
+ y: control.topPadding + (control.availableHeight - height) / 2
+ width: control.indicatorWidth
+ height: control.indicatorWidth
+
+ visible: control.checked
+ source: control.checkable ? "qrc:/qt-project.org/imports/QtQuick/Controls/iOS/images/radiodelegate-indicator-light.png" : ""
+ color: control.palette.windowText
+ }
+
+ background: Item {
+ implicitHeight: 44
+ implicitWidth: 250
+ NinePatchImage {
+ y: control.isLastItem ? -1 : 0
+ width: parent.width
+ height: control.isLastItem ? parent.height + 1 : parent.height
+ rotation: control.isLastItem ? 180 : 0
+ visible: !(isSingleItem && !control.down)
+ source: control.IOS.url + "menuitem-background"
+ NinePatchImageSelector on source {
+ states: [
+ {"edge": control.isFirstItem || control.isLastItem},
+ {"single": control.isSingleItem},
+ {"light": control.IOS.theme === IOS.Light},
+ {"dark": control.IOS.theme === IOS.Dark},
+ {"pressed": control.down}
+ ]
+ }
+ }
+ }
+
+ states: [
+ State {
+ name: "submenu-opened"
+ when: control.subMenu && control.subMenu.visible
+ PropertyChanges { target: control.menu; scale: 0.9 }
+ }
+ ]
+}
+
diff --git a/src/quickcontrols2/ios/MenuSeparator.qml b/src/quickcontrols2/ios/MenuSeparator.qml
new file mode 100644
index 0000000000..5d64365219
--- /dev/null
+++ b/src/quickcontrols2/ios/MenuSeparator.qml
@@ -0,0 +1,26 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Templates as T
+import QtQuick.Controls.impl
+import QtQuick.Controls.iOS
+
+T.MenuSeparator {
+ id: control
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding)
+
+ contentItem: NinePatchImage {
+ source: control.IOS.url + "menuseparator-separator"
+ NinePatchImageSelector on source {
+ states: [
+ {"light": control.IOS.theme === IOS.Light},
+ {"dark": control.IOS.theme === IOS.Dark}
+ ]
+ }
+ }
+}
diff --git a/src/quickcontrols2/ios/ProgressBar.qml b/src/quickcontrols2/ios/ProgressBar.qml
index 439ba5a309..b487d13528 100644
--- a/src/quickcontrols2/ios/ProgressBar.qml
+++ b/src/quickcontrols2/ios/ProgressBar.qml
@@ -24,7 +24,7 @@ T.ProgressBar {
readonly property NinePatchImage progress: NinePatchImage {
parent: control.contentItem
- visible: control.value
+ visible: control.indeterminate || control.value
y: (parent.height - height) / 2
width: control.indeterminate ? control.width * 0.4 : control.position * parent.width
@@ -44,8 +44,14 @@ T.ProgressBar {
easing.type: Easing.Linear
loops: Animation.Infinite
// TODO: workaround for QTBUG-38932; remove once that is fixed
- onFromChanged: restart()
- onToChanged: restart()
+ onFromChanged: {
+ if (control.indeterminate)
+ restart()
+ }
+ onToChanged: {
+ if (control.indeterminate)
+ restart()
+ }
}
}
}
diff --git a/src/quickcontrols2/ios/TreeViewDelegate.qml b/src/quickcontrols2/ios/TreeViewDelegate.qml
index 7f7099ecfb..571fcd4a29 100644
--- a/src/quickcontrols2/ios/TreeViewDelegate.qml
+++ b/src/quickcontrols2/ios/TreeViewDelegate.qml
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 The Qt Company Lt.
+// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
@@ -20,6 +20,11 @@ T.TreeViewDelegate {
topPadding: contentItem ? (height - contentItem.implicitHeight) / 2 : 0
leftPadding: !mirrored ? leftMargin + __contentIndent : width - leftMargin - __contentIndent - implicitContentWidth
+ highlighted: control.selected || control.current
+ || ((control.treeView.selectionBehavior === TableView.SelectRows
+ || control.treeView.selectionBehavior === TableView.SelectionDisabled)
+ && control.row === control.treeView.currentRow)
+
required property int row
required property var model
readonly property real __contentIndent: !isTreeNode ? 0 : (depth * indentation) + (indicator ? indicator.width + spacing : 0)
@@ -54,7 +59,7 @@ T.TreeViewDelegate {
NinePatchImage {
height: parent.height
width: parent.width
- source: control.IOS.url + "itemdelegate-background"
+ source: control.IOS.url + (control.highlighted ? "itemdelegate-background-pressed" : "itemdelegate-background")
NinePatchImageSelector on source {
states: [
{"light": control.IOS.theme === IOS.Light},
diff --git a/src/quickcontrols2/ios/images/menu-background-dark.9.png b/src/quickcontrols2/ios/images/menu-background-dark.9.png
new file mode 100644
index 0000000000..863a3c1759
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menu-background-dark.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menu-background-dark@2x.9.png b/src/quickcontrols2/ios/images/menu-background-dark@2x.9.png
new file mode 100644
index 0000000000..ddddaa3532
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menu-background-dark@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menu-background-dark@3x.9.png b/src/quickcontrols2/ios/images/menu-background-dark@3x.9.png
new file mode 100644
index 0000000000..a640f6fe06
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menu-background-dark@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menu-background-light.9.png b/src/quickcontrols2/ios/images/menu-background-light.9.png
new file mode 100644
index 0000000000..410abed278
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menu-background-light.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menu-background-light@2x.9.png b/src/quickcontrols2/ios/images/menu-background-light@2x.9.png
new file mode 100644
index 0000000000..82d99af518
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menu-background-light@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menu-background-light@3x.9.png b/src/quickcontrols2/ios/images/menu-background-light@3x.9.png
new file mode 100644
index 0000000000..48f3f7ed4e
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menu-background-light@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-dark.9.png b/src/quickcontrols2/ios/images/menuitem-background-dark.9.png
new file mode 100644
index 0000000000..463def221b
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-dark.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-dark@2x.9.png b/src/quickcontrols2/ios/images/menuitem-background-dark@2x.9.png
new file mode 100644
index 0000000000..53fdaa7c35
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-dark@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-dark@3x.9.png b/src/quickcontrols2/ios/images/menuitem-background-dark@3x.9.png
new file mode 100644
index 0000000000..a514f80071
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-dark@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-dark.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-dark.9.png
new file mode 100644
index 0000000000..514c0901e6
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-dark.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-dark@2x.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-dark@2x.9.png
new file mode 100644
index 0000000000..1ca1ee8d9e
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-dark@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-dark@3x.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-dark@3x.9.png
new file mode 100644
index 0000000000..6a4277a7c3
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-dark@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-light.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-light.9.png
new file mode 100644
index 0000000000..262c12d7b7
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-light.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-light@2x.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-light@2x.9.png
new file mode 100644
index 0000000000..4838abb511
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-light@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-light@3x.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-light@3x.9.png
new file mode 100644
index 0000000000..0e17b608da
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-light@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark.9.png
new file mode 100644
index 0000000000..290101b99b
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark@2x.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark@2x.9.png
new file mode 100644
index 0000000000..a738f20650
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark@3x.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark@3x.9.png
new file mode 100644
index 0000000000..ef05342d0b
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-dark@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light.9.png
new file mode 100644
index 0000000000..706f642552
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light@2x.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light@2x.9.png
new file mode 100644
index 0000000000..e196a71bbe
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light@3x.9.png b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light@3x.9.png
new file mode 100644
index 0000000000..4f5a71ff86
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-edge-pressed-light@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-light.9.png b/src/quickcontrols2/ios/images/menuitem-background-light.9.png
new file mode 100644
index 0000000000..644f207a26
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-light.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-light@2x.9.png b/src/quickcontrols2/ios/images/menuitem-background-light@2x.9.png
new file mode 100644
index 0000000000..d7c78cb5dc
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-light@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-light@3x.9.png b/src/quickcontrols2/ios/images/menuitem-background-light@3x.9.png
new file mode 100644
index 0000000000..70ce76a961
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-light@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-pressed-dark.9.png b/src/quickcontrols2/ios/images/menuitem-background-pressed-dark.9.png
new file mode 100644
index 0000000000..4f1fdfc82c
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-pressed-dark.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-pressed-dark@2x.9.png b/src/quickcontrols2/ios/images/menuitem-background-pressed-dark@2x.9.png
new file mode 100644
index 0000000000..f72729f45d
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-pressed-dark@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-pressed-dark@3x.9.png b/src/quickcontrols2/ios/images/menuitem-background-pressed-dark@3x.9.png
new file mode 100644
index 0000000000..eaa574174b
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-pressed-dark@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-pressed-light.9.png b/src/quickcontrols2/ios/images/menuitem-background-pressed-light.9.png
new file mode 100644
index 0000000000..5141095a95
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-pressed-light.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-pressed-light@2x.9.png b/src/quickcontrols2/ios/images/menuitem-background-pressed-light@2x.9.png
new file mode 100644
index 0000000000..b8fb91997f
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-pressed-light@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-pressed-light@3x.9.png b/src/quickcontrols2/ios/images/menuitem-background-pressed-light@3x.9.png
new file mode 100644
index 0000000000..250247d322
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-pressed-light@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark.9.png b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark.9.png
new file mode 100644
index 0000000000..708285fe39
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark@2x.9.png b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark@2x.9.png
new file mode 100644
index 0000000000..0cb6f175ff
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark@3x.9.png b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark@3x.9.png
new file mode 100644
index 0000000000..cb7c1f210c
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-dark@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-single-pressed-light.9.png b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-light.9.png
new file mode 100644
index 0000000000..5a71309c91
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-light.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-single-pressed-light@2x.9.png b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-light@2x.9.png
new file mode 100644
index 0000000000..7798409aa3
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-light@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuitem-background-single-pressed-light@3x.9.png b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-light@3x.9.png
new file mode 100644
index 0000000000..77a69bd247
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuitem-background-single-pressed-light@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuseparator-separator-dark.9.png b/src/quickcontrols2/ios/images/menuseparator-separator-dark.9.png
new file mode 100644
index 0000000000..819e465354
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuseparator-separator-dark.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuseparator-separator-dark@2x.9.png b/src/quickcontrols2/ios/images/menuseparator-separator-dark@2x.9.png
new file mode 100644
index 0000000000..81e3cdd391
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuseparator-separator-dark@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuseparator-separator-dark@3x.9.png b/src/quickcontrols2/ios/images/menuseparator-separator-dark@3x.9.png
new file mode 100644
index 0000000000..95d88ee659
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuseparator-separator-dark@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuseparator-separator-light.9.png b/src/quickcontrols2/ios/images/menuseparator-separator-light.9.png
new file mode 100644
index 0000000000..46276666e2
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuseparator-separator-light.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuseparator-separator-light@2x.9.png b/src/quickcontrols2/ios/images/menuseparator-separator-light@2x.9.png
new file mode 100644
index 0000000000..0e2b9986a9
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuseparator-separator-light@2x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/images/menuseparator-separator-light@3x.9.png b/src/quickcontrols2/ios/images/menuseparator-separator-light@3x.9.png
new file mode 100644
index 0000000000..d3eb183bf3
--- /dev/null
+++ b/src/quickcontrols2/ios/images/menuseparator-separator-light@3x.9.png
Binary files differ
diff --git a/src/quickcontrols2/ios/qquickiosstyle.cpp b/src/quickcontrols2/ios/qquickiosstyle.cpp
index cc629d88e2..f773833f00 100644
--- a/src/quickcontrols2/ios/qquickiosstyle.cpp
+++ b/src/quickcontrols2/ios/qquickiosstyle.cpp
@@ -21,6 +21,7 @@ QQuickIOSStyle::QQuickIOSStyle(QObject *parent)
: QQuickAttachedObject(parent)
{
init();
+ m_theme = qquickios_effective_theme();
}
QQuickIOSStyle *QQuickIOSStyle::qmlAttachedProperties(QObject *object)
@@ -41,7 +42,6 @@ void QQuickIOSStyle::init()
// globalsInitialized = true;
// }
QQuickAttachedObject::init(); // TODO: lazy init?
- setTheme(qquickios_effective_theme());
}
QQuickIOSStyle::Theme QQuickIOSStyle::theme() const
@@ -49,13 +49,4 @@ QQuickIOSStyle::Theme QQuickIOSStyle::theme() const
return m_theme;
}
-void QQuickIOSStyle::setTheme(Theme theme)
-{
- if (m_theme == theme)
- return;
- m_theme = theme;
-
- themeChanged();
-}
-
QT_END_NAMESPACE
diff --git a/src/quickcontrols2/ios/qquickiosstyle_p.h b/src/quickcontrols2/ios/qquickiosstyle_p.h
index 2134440377..f24b435190 100644
--- a/src/quickcontrols2/ios/qquickiosstyle_p.h
+++ b/src/quickcontrols2/ios/qquickiosstyle_p.h
@@ -25,7 +25,7 @@ class QQuickIOSStyle : public QQuickAttachedObject
{
Q_OBJECT
Q_PROPERTY(QUrl url READ url CONSTANT)
- Q_PROPERTY(Theme theme READ theme WRITE setTheme NOTIFY themeChanged FINAL)
+ Q_PROPERTY(Theme theme READ theme NOTIFY themeChanged FINAL)
QML_NAMED_ELEMENT(IOS)
QML_ATTACHED(QQuickIOSStyle)
QML_UNCREATABLE("")
@@ -43,7 +43,6 @@ public:
static QQuickIOSStyle *qmlAttachedProperties(QObject *object);
Theme theme() const;
- void setTheme(Theme theme);
QUrl url() const;
diff --git a/src/quickcontrols2/macos/TreeViewDelegate.qml b/src/quickcontrols2/macos/TreeViewDelegate.qml
index c357f97a89..43930cc7a9 100644
--- a/src/quickcontrols2/macos/TreeViewDelegate.qml
+++ b/src/quickcontrols2/macos/TreeViewDelegate.qml
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 The Qt Company Lt.
+// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
diff --git a/src/quickcontrols2/material/CMakeLists.txt b/src/quickcontrols2/material/CMakeLists.txt
index 19c68ebff9..2ca69fcad9 100644
--- a/src/quickcontrols2/material/CMakeLists.txt
+++ b/src/quickcontrols2/material/CMakeLists.txt
@@ -53,6 +53,7 @@ set(qml_files
"ToolButton.qml"
"ToolSeparator.qml"
"ToolTip.qml"
+ "TreeViewDelegate.qml"
"Tumbler.qml"
"VerticalHeaderView.qml"
)
diff --git a/src/quickcontrols2/material/HorizontalHeaderView.qml b/src/quickcontrols2/material/HorizontalHeaderView.qml
index 671728c004..430508cbdc 100644
--- a/src/quickcontrols2/material/HorizontalHeaderView.qml
+++ b/src/quickcontrols2/material/HorizontalHeaderView.qml
@@ -20,7 +20,7 @@ T.HorizontalHeaderView {
implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2))
color: control.Material.backgroundColor
- Text {
+ Label {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
diff --git a/src/quickcontrols2/material/TreeViewDelegate.qml b/src/quickcontrols2/material/TreeViewDelegate.qml
new file mode 100644
index 0000000000..a7be36a555
--- /dev/null
+++ b/src/quickcontrols2/material/TreeViewDelegate.qml
@@ -0,0 +1,62 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Templates as T
+import QtQuick.Controls.impl
+import QtQuick.Controls.Material
+
+T.TreeViewDelegate {
+ id: control
+
+ implicitWidth: leftMargin + __contentIndent + implicitContentWidth + rightPadding + rightMargin
+ implicitHeight: Math.max(implicitBackgroundHeight, implicitContentHeight, implicitIndicatorHeight)
+
+ indentation: indicator ? indicator.width : 12
+ leftMargin: 16
+ rightMargin: 16
+ spacing: 14
+
+ topPadding: contentItem ? (height - contentItem.implicitHeight) / 2 : 0
+ leftPadding: !mirrored ? leftMargin + __contentIndent : width - leftMargin - __contentIndent - implicitContentWidth
+
+ highlighted: control.selected || control.current
+ || ((control.treeView.selectionBehavior === TableView.SelectRows
+ || control.treeView.selectionBehavior === TableView.SelectionDisabled)
+ && control.row === control.treeView.currentRow)
+
+ required property int row
+ required property var model
+ readonly property real __contentIndent: !isTreeNode ? 0 : (depth * indentation) + (indicator ? indicator.width + spacing : 0)
+
+ indicator: Item {
+ readonly property real __indicatorIndent: control.leftMargin + (control.depth * control.indentation)
+ x: !control.mirrored ? __indicatorIndent : control.width - __indicatorIndent - width
+ y: (control.height - height) / 2
+ implicitWidth: Math.max(arrow.implicitWidth, 20)
+ implicitHeight: control.Material.buttonHeight
+
+ property ColorImage arrow : ColorImage {
+ parent: control.indicator
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ rotation: control.expanded ? 90 : (control.mirrored ? 180 : 0)
+ source: "qrc:/qt-project.org/imports/QtQuick/Controls/Material/images/arrow-indicator.png"
+ color: control.palette.windowText
+ defaultColor: "#353637"
+ }
+ }
+
+ background: Rectangle {
+ implicitHeight: control.Material.buttonHeight
+ color: control.highlighted
+ ? control.palette.highlight
+ : (control.treeView.alternatingRows && control.row % 2 !== 0
+ ? control.palette.alternateBase : control.palette.base)
+ }
+
+ contentItem: Label {
+ text: control.model.display
+ elide: Text.ElideRight
+ }
+}
diff --git a/src/quickcontrols2/material/VerticalHeaderView.qml b/src/quickcontrols2/material/VerticalHeaderView.qml
index e497d4a84c..322df3e593 100644
--- a/src/quickcontrols2/material/VerticalHeaderView.qml
+++ b/src/quickcontrols2/material/VerticalHeaderView.qml
@@ -20,7 +20,7 @@ T.VerticalHeaderView {
implicitHeight: text.implicitHeight + (cellPadding * 2)
color: control.Material.backgroundColor
- Text {
+ Label {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
diff --git a/src/quickcontrols2/material/qt_attribution.json b/src/quickcontrols2/material/qt_attribution.json
index 85fdadf9e0..9d53b8b014 100644
--- a/src/quickcontrols2/material/qt_attribution.json
+++ b/src/quickcontrols2/material/qt_attribution.json
@@ -2,8 +2,8 @@
"Id": "shadow_angular_material",
"Name": "Shadow values from Angular Material",
"QDocModule": "qtquickcontrols",
- "QtUsage": "Used in the Material Style of Qt Quick Controls 2.",
- "Files": "ElevationEffect.qml",
+ "QtUsage": "Used in the Material Style of Qt Quick Controls.",
+ "Files": "impl/ElevationEffect.qml",
"Description": "Shadow values for the elevation effect.",
"Homepage": "https://angularjs.org/",
"License": "MIT License",
diff --git a/src/quickcontrols2/universal/HorizontalHeaderView.qml b/src/quickcontrols2/universal/HorizontalHeaderView.qml
index 878fb1e10e..f1112bb8f8 100644
--- a/src/quickcontrols2/universal/HorizontalHeaderView.qml
+++ b/src/quickcontrols2/universal/HorizontalHeaderView.qml
@@ -21,7 +21,7 @@ T.HorizontalHeaderView {
implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2))
color: control.Universal.background
- Text {
+ Label {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
diff --git a/src/quickcontrols2/universal/VerticalHeaderView.qml b/src/quickcontrols2/universal/VerticalHeaderView.qml
index 189bed0906..c8fb52a58f 100644
--- a/src/quickcontrols2/universal/VerticalHeaderView.qml
+++ b/src/quickcontrols2/universal/VerticalHeaderView.qml
@@ -21,7 +21,7 @@ T.VerticalHeaderView {
implicitHeight: text.implicitHeight + (cellPadding * 2)
color: control.Universal.background
- Text {
+ Label {
id: text
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole]
: model[control.textRole])
diff --git a/src/quickcontrols2/windows/SpinBox.qml b/src/quickcontrols2/windows/SpinBox.qml
index 2d07b92d1f..0d54e1a4c5 100644
--- a/src/quickcontrols2/windows/SpinBox.qml
+++ b/src/quickcontrols2/windows/SpinBox.qml
@@ -8,12 +8,9 @@ import QtQuick.NativeStyle as NativeStyle
T.SpinBox {
id: control
- property bool __nativeBackground: background instanceof NativeStyle.StyleItem
property bool nativeIndicators: up.indicator.hasOwnProperty("_qt_default")
&& down.indicator.hasOwnProperty("_qt_default")
- font.pixelSize: __nativeBackground ? background.styleFont(control).pixelSize : undefined
-
implicitWidth: Math.max(contentItem.implicitWidth + leftInset + rightInset,
90 /* minimum */ )
implicitHeight: Math.max(contentItem.implicitHeight, up.implicitIndicatorHeight + down.implicitIndicatorHeight)
@@ -21,10 +18,10 @@ T.SpinBox {
spacing: 2
- leftPadding: __nativeBackground ? background.contentPadding.left: 0
- topPadding: __nativeBackground ? background.contentPadding.top: 0
- rightPadding: (__nativeBackground ? background.contentPadding.right : 0) + rightInset
- bottomPadding: __nativeBackground ? background.contentPadding.bottom: 0
+ leftPadding: 0
+ topPadding: 0
+ rightPadding: rightInset
+ bottomPadding: 0
validator: IntValidator {
locale: control.locale.name
diff --git a/src/quickcontrols2impl/qquickimageselector.cpp b/src/quickcontrols2impl/qquickimageselector.cpp
index a7c431ba7a..35f6555684 100644
--- a/src/quickcontrols2impl/qquickimageselector.cpp
+++ b/src/quickcontrols2impl/qquickimageselector.cpp
@@ -30,14 +30,14 @@ static inline int cacheSize()
static QList<QStringList> permutations(const QStringList &input, int count = -1)
{
if (count == -1)
- count = input.count();
+ count = input.size();
QList<QStringList> output;
- for (int i = 0; i < input.count(); ++i) {
+ for (int i = 0; i < input.size(); ++i) {
QStringList sub = input.mid(i, count);
if (count > 1) {
- if (i + count > input.count())
+ if (i + count > input.size())
sub += input.mid(0, count - i + 1);
std::sort(sub.begin(), sub.end());
@@ -49,7 +49,7 @@ static QList<QStringList> permutations(const QStringList &input, int count = -1)
output += sub;
}
- if (count == input.count())
+ if (count == input.size())
break;
}
@@ -256,7 +256,7 @@ void QQuickImageSelector::setUrl(const QUrl &url)
bool QQuickImageSelector::updateActiveStates()
{
QStringList active;
- for (const QVariant &v : qAsConst(m_allStates)) {
+ for (const QVariant &v : std::as_const(m_allStates)) {
const QVariantMap state = v.toMap();
if (state.isEmpty())
continue;
@@ -275,8 +275,8 @@ bool QQuickImageSelector::updateActiveStates()
int QQuickImageSelector::calculateScore(const QStringList &states) const
{
int score = 0;
- for (int i = 0; i < states.count(); ++i)
- score += (m_activeStates.count() - m_activeStates.indexOf(states.at(i))) << 1;
+ for (int i = 0; i < states.size(); ++i)
+ score += (m_activeStates.size() - m_activeStates.indexOf(states.at(i))) << 1;
return score;
}
diff --git a/src/quickcontrols2impl/qquickmnemoniclabel.cpp b/src/quickcontrols2impl/qquickmnemoniclabel.cpp
index c88f0994c9..982ffeeb66 100644
--- a/src/quickcontrols2impl/qquickmnemoniclabel.cpp
+++ b/src/quickcontrols2impl/qquickmnemoniclabel.cpp
@@ -58,7 +58,7 @@ void QQuickMnemonicLabel::updateMnemonic()
QString text(m_fullText.size(), QChar::Null);
int idx = 0;
int pos = 0;
- int len = m_fullText.length();
+ int len = m_fullText.size();
QList<QTextLayout::FormatRange> formats;
while (len) {
if (m_fullText.at(pos) == QLatin1Char('&') && (len == 1 || m_fullText.at(pos + 1) != QLatin1Char('&'))) {
diff --git a/src/quickcontrols2impl/qquickninepatchimage.cpp b/src/quickcontrols2impl/qquickninepatchimage.cpp
index cdd4708e30..cc3869ded9 100644
--- a/src/quickcontrols2impl/qquickninepatchimage.cpp
+++ b/src/quickcontrols2impl/qquickninepatchimage.cpp
@@ -54,6 +54,9 @@ QList<qreal> QQuickNinePatchData::coordsForSize(qreal size) const
return coords;
}
+/*
+ Adds the 0 index coordinate if appropriate, and the one at "size".
+*/
void QQuickNinePatchData::fill(const QList<qreal> &coords, qreal size)
{
data.clear();
@@ -174,6 +177,31 @@ public:
QQuickNinePatchData yDivs;
};
+/*
+ Examines each pixel in a horizontal or vertical (if offset is equal to the image's width)
+ line, storing the start and end index ("coordinate") of each 9-patch line.
+
+ For instance, in the 7x3 (9x5 actual size) 9-patch image below, which has no horizontal
+ stretchable area, it would return {}:
+
+ +-----+
+ | |
+ +-----+
+
+ If indices 3 to 5 were marked, it would return {2, 5}:
+
+ xxx
+ +-----+
+ | |
+ +-----+
+
+ If indices 3 and 5 were marked, it would store {0, 2, 3, 4, 5, 7}:
+
+ x x
+ +-----+
+ | |
+ +-----+
+*/
static QList<qreal> readCoords(const QRgb *data, int from, int count, int offset, QRgb color)
{
int p1 = -1;
@@ -182,12 +210,16 @@ static QList<qreal> readCoords(const QRgb *data, int from, int count, int offset
int p2 = from + i * offset;
if (data[p2] == color) {
// colored pixel
- if (p1 == -1)
+ if (p1 == -1) {
+ // This is the start of a 9-patch line.
p1 = i;
+ }
} else {
// empty pixel
if (p1 != -1) {
+ // This is the end of a 9-patch line; add the start and end indices as coordinates...
coords << p1 << i;
+ // ... and reset p1 so that we can search for the next one.
p1 = -1;
}
}
@@ -195,6 +227,12 @@ static QList<qreal> readCoords(const QRgb *data, int from, int count, int offset
return coords;
}
+/*
+ Called whenever a 9-patch image is set as the image's source.
+
+ Reads the 9-patch lines from the source image and sets the
+ inset and padding properties accordingly.
+*/
void QQuickNinePatchImagePrivate::updatePatches()
{
if (ninePatch.isNull())
@@ -228,7 +266,7 @@ void QQuickNinePatchImagePrivate::updatePaddings(const QSizeF &size, const QList
qreal oldRightPadding = rightPadding;
qreal oldBottomPadding = bottomPadding;
- if (horizontal.count() >= 2) {
+ if (horizontal.size() >= 2) {
leftPadding = horizontal.first();
rightPadding = size.width() - horizontal.last() - 2;
} else {
@@ -236,7 +274,7 @@ void QQuickNinePatchImagePrivate::updatePaddings(const QSizeF &size, const QList
rightPadding = 0;
}
- if (vertical.count() >= 2) {
+ if (vertical.size() >= 2) {
topPadding = vertical.first();
bottomPadding = size.height() - vertical.last() - 2;
} else {
@@ -262,26 +300,26 @@ void QQuickNinePatchImagePrivate::updateInsets(const QList<qreal> &horizontal, c
qreal oldRightInset = rightInset;
qreal oldBottomInset = bottomInset;
- if (horizontal.count() >= 2 && horizontal.first() == 0)
+ if (horizontal.size() >= 2 && horizontal.first() == 0)
leftInset = horizontal.at(1);
else
leftInset = 0;
- if (horizontal.count() == 2 && horizontal.first() > 0)
+ if (horizontal.size() == 2 && horizontal.first() > 0)
rightInset = horizontal.last() - horizontal.first();
- else if (horizontal.count() == 4)
+ else if (horizontal.size() == 4)
rightInset = horizontal.last() - horizontal.at(2);
else
rightInset = 0;
- if (vertical.count() >= 2 && vertical.first() == 0)
+ if (vertical.size() >= 2 && vertical.first() == 0)
topInset = vertical.at(1);
else
topInset = 0;
- if (vertical.count() == 2 && vertical.first() > 0)
+ if (vertical.size() == 2 && vertical.first() > 0)
bottomInset = vertical.last() - vertical.first();
- else if (vertical.count() == 4)
+ else if (vertical.size() == 4)
bottomInset = vertical.last() - vertical.at(2);
else
bottomInset = 0;
@@ -299,6 +337,8 @@ void QQuickNinePatchImagePrivate::updateInsets(const QList<qreal> &horizontal, c
QQuickNinePatchImage::QQuickNinePatchImage(QQuickItem *parent)
: QQuickImage(*(new QQuickNinePatchImagePrivate), parent)
{
+ Q_D(QQuickNinePatchImage);
+ d->smooth = qEnvironmentVariableIntValue("QT_QUICK_CONTROLS_IMAGINE_SMOOTH");
}
qreal QQuickNinePatchImage::topPadding() const
@@ -403,6 +443,9 @@ QSGNode *QQuickNinePatchImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNode
d->resetNode = false;
}
+ if (d->ninePatch.isNull())
+ return QQuickImage::updatePaintNode(oldNode, data);
+
QSizeF sz = size();
QImage image = d->pix.image();
if (!sz.isValid() || image.isNull()) {
@@ -412,9 +455,6 @@ QSGNode *QQuickNinePatchImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNode
return nullptr;
}
- if (d->ninePatch.isNull())
- return QQuickImage::updatePaintNode(oldNode, data);
-
QQuickNinePatchNode *patchNode = static_cast<QQuickNinePatchNode *>(oldNode);
if (!patchNode)
patchNode = new QQuickNinePatchNode;
@@ -432,6 +472,8 @@ QSGNode *QQuickNinePatchImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNode
QSGTexture *texture = window()->createTextureFromImage(image);
patchNode->initialize(texture, sz * d->devicePixelRatio, image.size(), d->xDivs, d->yDivs, d->devicePixelRatio);
+ auto patchNodeMaterial = static_cast<QSGTextureMaterial *>(patchNode->material());
+ patchNodeMaterial->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
return patchNode;
}
diff --git a/src/quickcontrolstestutils/CMakeLists.txt b/src/quickcontrolstestutils/CMakeLists.txt
index 3cb27c71e7..268dc4198d 100644
--- a/src/quickcontrolstestutils/CMakeLists.txt
+++ b/src/quickcontrolstestutils/CMakeLists.txt
@@ -23,3 +23,11 @@ qt_internal_add_module(QuickControlsTestUtilsPrivate
Qt::QuickTemplates2Private
Qt::QuickTestUtilsPrivate
)
+
+# This is used by both C++ and QML tests, so we need it to be a library and a QML plugin,
+# hence qt_internal_add_qml_module. We use it in addition to qt_internal_add_module,
+# because otherwise syncqt complains that there is no "QtQuickControlsTestUtilsPrivate" module.
+qt_internal_add_qml_module(QuickControlsTestUtilsPrivate
+ URI "Qt.test.controls"
+ VERSION "${PROJECT_VERSION}"
+)
diff --git a/src/quickcontrolstestutils/controlstestutils.cpp b/src/quickcontrolstestutils/controlstestutils.cpp
index df65c3234b..f565751c0d 100644
--- a/src/quickcontrolstestutils/controlstestutils.cpp
+++ b/src/quickcontrolstestutils/controlstestutils.cpp
@@ -4,6 +4,7 @@
#include "controlstestutils_p.h"
#include <QtTest/qsignalspy.h>
+#include <QtQml/qqmlcomponent.h>
#include <QtQuickControls2/qquickstyle.h>
#include <QtQuickTemplates2/private/qquickabstractbutton_p.h>
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
@@ -16,11 +17,19 @@ QQuickControlsTestUtils::QQuickControlsApplicationHelper::QQuickControlsApplicat
appWindow = qobject_cast<QQuickApplicationWindow*>(cleanup.data());
}
+/*!
+ \internal
+
+ If \a style is different from the current style, this function will
+ recreate the QML engine, clear type registrations and set the new style.
+
+ Returns \c true if successful or if \c style is already set.
+*/
bool QQuickControlsTestUtils::QQuickStyleHelper::updateStyle(const QString &style)
{
// If it's not the first time a style has been set and the new style is not different, do nothing.
if (!currentStyle.isEmpty() && style == currentStyle)
- return false;
+ return true;
engine.reset();
currentStyle = style;
@@ -30,8 +39,9 @@ bool QQuickControlsTestUtils::QQuickStyleHelper::updateStyle(const QString &styl
QQmlComponent component(engine.data());
component.setData(QString::fromUtf8("import QtQuick\nimport QtQuick.Controls\n Control { }").toUtf8(), QUrl());
-
- return true;
+ if (!component.isReady())
+ qWarning() << "Failed to load component:" << component.errorString();
+ return component.isReady();
}
void QQuickControlsTestUtils::forEachControl(QQmlEngine *engine, const QString &qqc2ImportPath,
@@ -127,7 +137,7 @@ bool QQuickControlsTestUtils::clickButton(QQuickAbstractButton *button)
const QPoint buttonCenter = button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint();
QTest::mouseClick(button->window(), Qt::LeftButton, Qt::NoModifier, buttonCenter);
- if (spy.count() != 1) {
+ if (spy.size() != 1) {
qWarning() << "clicked signal of button" << button << "was not emitted after clicking";
return false;
}
@@ -148,10 +158,23 @@ bool QQuickControlsTestUtils::doubleClickButton(QQuickAbstractButton *button)
const QPoint buttonCenter = button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint();
QTest::mouseDClick(button->window(), Qt::LeftButton, Qt::NoModifier, buttonCenter);
- if (spy.count() != 1) {
+ if (spy.size() != 1) {
qWarning() << "doubleClicked signal of button" << button << "was not emitted after double-clicking";
return false;
}
return true;
}
+
+/*!
+ Allows creating QQmlComponents in C++, which is useful for tests that need
+ to check if items created from the component have the correct QML context.
+*/
+Q_INVOKABLE QQmlComponent *QQuickControlsTestUtils::ComponentCreator::createComponent(const QByteArray &data)
+{
+ std::unique_ptr<QQmlComponent> component(new QQmlComponent(qmlEngine(this)));
+ component->setData(data, QUrl());
+ if (component->isError())
+ qmlWarning(this) << "Failed to create component from the following data:\n" << data;
+ return component.release();
+}
diff --git a/src/quickcontrolstestutils/controlstestutils_p.h b/src/quickcontrolstestutils/controlstestutils_p.h
index 4d79d4af52..487d3b79fe 100644
--- a/src/quickcontrolstestutils/controlstestutils_p.h
+++ b/src/quickcontrolstestutils/controlstestutils_p.h
@@ -19,6 +19,7 @@
QT_BEGIN_NAMESPACE
+class QQmlComponent;
class QQmlEngine;
class QQuickApplicationWindow;
class QQuickAbstractButton;
@@ -53,6 +54,17 @@ namespace QQuickControlsTestUtils
[[nodiscard]] bool verifyButtonClickable(QQuickAbstractButton *button);
[[nodiscard]] bool clickButton(QQuickAbstractButton *button);
[[nodiscard]] bool doubleClickButton(QQuickAbstractButton *button);
+
+ class ComponentCreator : public QObject
+ {
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ Q_MOC_INCLUDE(<QtQml/qqmlcomponent.h>)
+
+ public:
+ Q_INVOKABLE QQmlComponent *createComponent(const QByteArray &data);
+ };
}
QT_END_NAMESPACE
diff --git a/src/quickcontrolstestutils/dialogstestutils.cpp b/src/quickcontrolstestutils/dialogstestutils.cpp
index 972ef63f21..71622fabb0 100644
--- a/src/quickcontrolstestutils/dialogstestutils.cpp
+++ b/src/quickcontrolstestutils/dialogstestutils.cpp
@@ -40,9 +40,17 @@ bool QQuickDialogTestUtils::verifyFileDialogDelegates(QQuickListView *fileDialog
}
if (actualFiles != expectedFiles) {
+ QString expectedFilesStr = QDebug::toString(expectedFiles);
+ QString actualFilesStr = QDebug::toString(actualFiles);
failureMessage = QString::fromLatin1("Mismatch in actual vs expected "
- "delegates in fileDialogListView:\n expected: %1\n actual: %2")
- .arg(QDebug::toString(expectedFiles), QDebug::toString(actualFiles));
+ "delegates in fileDialogListView:\n expected: %1\n actual: %2");
+ if (failureMessage.size() + expectedFilesStr.size() + actualFilesStr.size() > 1024) {
+ // If we've exceeded QTest's character limit for failure messages,
+ // just show the number of files.
+ expectedFilesStr = QString::number(expectedFiles.size());
+ actualFilesStr = QString::number(actualFiles.size());
+ }
+ failureMessage = failureMessage.arg(expectedFilesStr, actualFilesStr);
return false;
}
diff --git a/src/quickcontrolstestutils/qtest_quickcontrols_p.h b/src/quickcontrolstestutils/qtest_quickcontrols_p.h
index bd86e4a18b..1294781114 100644
--- a/src/quickcontrolstestutils/qtest_quickcontrols_p.h
+++ b/src/quickcontrolstestutils/qtest_quickcontrols_p.h
@@ -22,7 +22,7 @@
#include <QtQuickControls2/qquickstyle.h>
#include <QtQuickControls2/private/qquickstyle_p.h>
-static QStringList testStyles()
+inline QStringList testStyles()
{
// It's not enough to check if the name is empty, because since Qt 6
// we set an appropriate style for the platform if no style was specified.
@@ -33,7 +33,7 @@ static QStringList testStyles()
return QStringList(QQuickStyle::name());
}
-static int runTests(QObject *testObject, int argc, char *argv[])
+inline int runTests(QObject *testObject, int argc, char *argv[])
{
int res = 0;
QTest::qInit(testObject, argc, argv);
diff --git a/src/quickdialogs2/quickdialogs2/doc/qtquickdialogs.qdocconf b/src/quickdialogs2/quickdialogs2/doc/qtquickdialogs.qdocconf
index 6d59f69817..d4f7595f0f 100644
--- a/src/quickdialogs2/quickdialogs2/doc/qtquickdialogs.qdocconf
+++ b/src/quickdialogs2/quickdialogs2/doc/qtquickdialogs.qdocconf
@@ -24,6 +24,8 @@ depends = qtcore qtqmlcore qtgui qtdoc qtqml qtquick qtquickcontrols qtlabsplatf
# This module has no documented C++ types, clear the module header
moduleheader =
+exampledirs += snippets
+
headerdirs += ..
sourcedirs += .. \
src
diff --git a/src/quickdialogs2/quickdialogs2/doc/snippets/qtquickdialogs-filedialog.qml b/src/quickdialogs2/quickdialogs2/doc/snippets/qtquickdialogs-filedialog.qml
new file mode 100644
index 0000000000..ab3f33f910
--- /dev/null
+++ b/src/quickdialogs2/quickdialogs2/doc/snippets/qtquickdialogs-filedialog.qml
@@ -0,0 +1,34 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+//! [file]
+import QtCore
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Dialogs
+
+ApplicationWindow {
+ width: 640
+ height: 480
+ visible: true
+
+ header: ToolBar {
+ Button {
+ text: qsTr("Choose Image...")
+ onClicked: fileDialog.open()
+ }
+ }
+
+ Image {
+ id: image
+ anchors.fill: parent
+ fillMode: Image.PreserveAspectFit
+ }
+
+ FileDialog {
+ id: fileDialog
+ currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
+ onAccepted: image.source = selectedFile
+ }
+}
+//! [file]
diff --git a/src/quickdialogs2/quickdialogs2/qquickfiledialog.cpp b/src/quickdialogs2/quickdialogs2/qquickfiledialog.cpp
index 4caaec96cf..6b1cdb860c 100644
--- a/src/quickdialogs2/quickdialogs2/qquickfiledialog.cpp
+++ b/src/quickdialogs2/quickdialogs2/qquickfiledialog.cpp
@@ -36,23 +36,7 @@ Q_LOGGING_CATEGORY(lcFileDialog, "qt.quick.dialogs.filedialog")
properties are updated only after the final selection has been made by
accepting the dialog.
- \code
- MenuItem {
- text: "Open..."
- onTriggered: fileDialog.open()
- }
-
- FileDialog {
- id: fileDialog
- currentFile: document.source
- folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
- }
-
- MyDocument {
- id: document
- source: fileDialog.file
- }
- \endcode
+ \snippet qtquickdialogs-filedialog.qml file
\section2 Availability
@@ -179,7 +163,7 @@ void QQuickFileDialog::setSelectedFiles(const QList<QUrl> &selectedFiles)
if (m_fileMode != SaveFile) {
for (const auto &selectedFile : selectedFiles) {
- const QString selectedFilePath = selectedFile.toLocalFile();
+ const QString selectedFilePath = QQmlFile::urlToLocalFileOrQrc(selectedFile);
if (!QFileInfo::exists(selectedFilePath)) {
qmlWarning(this) << "Cannot set " << selectedFilePath
<< " as a selected file because it doesn't exist";
@@ -342,7 +326,7 @@ void QQuickFileDialog::setNameFilters(const QStringList &filters)
m_options->setNameFilters(filters);
if (m_selectedNameFilter) {
int index = m_selectedNameFilter->index();
- if (index < 0 || index >= filters.count())
+ if (index < 0 || index >= filters.size())
index = 0;
m_selectedNameFilter->update(filters.value(index));
}
diff --git a/src/quickdialogs2/quickdialogs2/qquickfolderdialog.cpp b/src/quickdialogs2/quickdialogs2/qquickfolderdialog.cpp
index a2c3a45ba6..692a68c7a6 100644
--- a/src/quickdialogs2/quickdialogs2/qquickfolderdialog.cpp
+++ b/src/quickdialogs2/quickdialogs2/qquickfolderdialog.cpp
@@ -30,19 +30,19 @@ Q_DECLARE_LOGGING_CATEGORY(lcDialogs)
\code
MenuItem {
- text: "Open..."
+ text: qsTr("Open...")
onTriggered: folderDialog.open()
}
FolderDialog {
id: folderDialog
- currentFolder: viewer.folder
- folder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
+ currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
+ selectedFolder: viewer.folder
}
MyViewer {
id: viewer
- folder: folderDialog.folder
+ folder: folderDialog.selectedFolder
}
\endcode
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt b/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt
index abbee6dfd2..6feb99f204 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt
+++ b/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt
@@ -67,6 +67,10 @@ qt_internal_add_qml_module(QuickDialogs2QuickImpl
qquickcolordialogimpl.cpp
qquickcolordialogimpl_p.h
qquickcolordialogimpl_p_p.h
+ qquickcolordialogutils_p.h
+ qquickcolordialogutils.cpp
+ qquickcolorinputs.cpp
+ qquickcolorinputs_p.h
qquickdialogimplfactory.cpp
qquickdialogimplfactory_p.h
qquickfiledialogdelegate.cpp
@@ -204,4 +208,5 @@ qt_internal_add_shaders(QuickDialogs2QuickImpl "QuickDialogs2QuickImplShaders"
"/qt-project.org/imports/QtQuick/Dialogs/quickimpl"
FILES
"shaders/SaturationLightness.frag"
+ SILENT
)
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/ColorDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/ColorDialog.qml
index 441e032fa4..3ad3c80369 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/ColorDialog.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/ColorDialog.qml
@@ -33,6 +33,7 @@ ColorDialogImpl {
ColorDialogImpl.eyeDropperButton: eyeDropperButton
ColorDialogImpl.buttonBox: buttonBox
ColorDialogImpl.colorPicker: colorPicker
+ ColorDialogImpl.colorInputs: inputs
ColorDialogImpl.alphaSlider: alphaSlider
background: Rectangle {
@@ -132,7 +133,6 @@ ColorDialogImpl {
Slider {
id: alphaSlider
objectName: "alphaSlider"
- visible: control.showAlpha
orientation: Qt.Horizontal
value: control.alpha
implicitHeight: 20
@@ -187,28 +187,8 @@ ColorDialogImpl {
ColorInputs {
id: inputs
- spacing: 12
- currentColor: control.color
- red: control.red
- green: control.green
- blue: control.blue
- hue: control.hue
- saturation: control.saturation
- value: control.value
- lightness: control.lightness
- alpha: control.alpha
- showAlpha: control.showAlpha
- onEmitHex: function (hex) { control.color = hex; }
- onEmitRed: function (r) { control.red = r; }
- onEmitGreen: function (g) { control.green = g; }
- onEmitBlue: function (b) { control.blue = b; }
- onEmitHue: function (h) { control.hue = h; }
- onEmitSaturation: function (s) { control.saturation = s; }
- onEmitValue: function(v) { control.value = v; }
- onEmitLightness: function (l) { control.lightness = l; }
- onEmitAlpha: function (a) { control.alpha = a; }
+ color: control.color
- Layout.fillWidth: true
Layout.leftMargin: 12
Layout.rightMargin: 12
Layout.bottomMargin: 12
@@ -246,6 +226,12 @@ ColorDialogImpl {
Layout.bottomMargin: 6
}
+ Item {
+ Layout.fillWidth: true
+ Layout.topMargin: 6
+ Layout.bottomMargin: 6
+ }
+
DialogButtonBox {
id: buttonBox
standardButtons: control.standardButtons
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml
index 26b6bec534..a928a4b0cc 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml
@@ -43,6 +43,8 @@ FileDialogImpl {
FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox
FileDialogImpl.fileDialogListView: fileDialogListView
FileDialogImpl.breadcrumbBar: breadcrumbBar
+ FileDialogImpl.fileNameLabel: fileNameLabel
+ FileDialogImpl.fileNameTextField: fileNameTextField
background: Rectangle {
implicitWidth: 600
@@ -127,16 +129,40 @@ FileDialogImpl {
}
}
- footer: RowLayout {
- id: rowLayout
- spacing: 12
+ footer: GridLayout {
+ columnSpacing: 12
+ columns: 3
+
+ Label {
+ id: fileNameLabel
+ text: qsTr("File name")
+ Layout.leftMargin: 12
+ visible: false
+ }
+
+ TextField {
+ id: fileNameTextField
+ objectName: "fileNameTextField"
+ text: control.fileName
+ visible: false
+
+ Layout.fillWidth: true
+ }
+
+ Label {
+ text: qsTr("Filter")
+ Layout.column: 0
+ Layout.row: 1
+ Layout.leftMargin: 12
+ Layout.bottomMargin: 12
+ }
+
ComboBox {
// OK to use IDs here, since users shouldn't be overriding this stuff.
id: nameFiltersComboBox
model: control.nameFilters
- Layout.leftMargin: 12
Layout.fillWidth: true
Layout.bottomMargin: 12
}
@@ -149,6 +175,10 @@ FileDialogImpl {
verticalPadding: 0
background: null
+ // TODO: make the orientation vertical
+ Layout.row: 1
+ Layout.column: 2
+ Layout.columnSpan: 1
Layout.rightMargin: 12
Layout.bottomMargin: 12
}
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/ColorDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/ColorDialog.qml
index b4713cbb76..f0150c8fdd 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/ColorDialog.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/ColorDialog.qml
@@ -43,6 +43,7 @@ ColorDialogImpl {
ColorDialogImpl.buttonBox: buttonBox
ColorDialogImpl.colorPicker: colorPicker
ColorDialogImpl.alphaSlider: alphaSlider
+ ColorDialogImpl.colorInputs: inputs
background: NinePatchImage {
source: Imagine.url + "dialog-background"
@@ -136,7 +137,6 @@ ColorDialogImpl {
Slider {
id: alphaSlider
objectName: "alphaSlider"
- visible: control.showAlpha
orientation: Qt.Horizontal
value: control.alpha
implicitHeight: 20
@@ -194,28 +194,8 @@ ColorDialogImpl {
ColorInputs {
id: inputs
- spacing: 20
- currentColor: control.color
- red: control.red
- green: control.green
- blue: control.blue
- hue: control.hue
- saturation: control.saturation
- value: control.value
- lightness: control.lightness
- alpha: control.alpha
- showAlpha: control.showAlpha
- onEmitHex: function (hex) { control.color = hex; }
- onEmitRed: function (r) { control.red = r; }
- onEmitGreen: function (g) { control.green = g; }
- onEmitBlue: function (b) { control.blue = b; }
- onEmitHue: function (h) { control.hue = h; }
- onEmitSaturation: function (s) { control.saturation = s; }
- onEmitValue: function(v) { control.value = v; }
- onEmitLightness: function (l) { control.lightness = l; }
- onEmitAlpha: function (a) { control.alpha = a; }
+ color: control.color
- Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.bottomMargin: 16
@@ -255,6 +235,11 @@ ColorDialogImpl {
Layout.bottomMargin: 16
}
+ Item {
+ // empty filler
+ Layout.fillWidth: true
+ }
+
DialogButtonBox {
id: buttonBox
standardButtons: control.standardButtons
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml
index 762cf8c5cc..664965e571 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml
@@ -43,6 +43,8 @@ FileDialogImpl {
FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox
FileDialogImpl.fileDialogListView: fileDialogListView
FileDialogImpl.breadcrumbBar: breadcrumbBar
+ FileDialogImpl.fileNameLabel: fileNameLabel
+ FileDialogImpl.fileNameTextField: fileNameTextField
background: NinePatchImage {
source: Imagine.url + "dialog-background"
@@ -116,17 +118,42 @@ FileDialogImpl {
}
}
- footer: RowLayout {
- id: rowLayout
- spacing: 20
+ footer: GridLayout {
+ columnSpacing: 20
+ columns: 3
+
+ Label {
+ id: fileNameLabel
+ text: qsTr("File name")
+ visible: false
+
+ Layout.leftMargin: 16
+ }
+
+ TextField {
+ id: fileNameTextField
+ objectName: "fileNameTextField"
+ text: control.fileName
+ visible: false
+
+ Layout.fillWidth: true
+ }
+
+ Label {
+ text: qsTr("Filter")
+
+ Layout.column: 0
+ Layout.row: 1
+ Layout.leftMargin: 16
+ Layout.bottomMargin: 16
+ }
ComboBox {
id: nameFiltersComboBox
model: control.nameFilters
- Layout.leftMargin: 16
- Layout.bottomMargin: 16
Layout.fillWidth: true
+ Layout.bottomMargin: 16
}
DialogButtonBox {
@@ -134,6 +161,9 @@ FileDialogImpl {
standardButtons: control.standardButtons
spacing: 12
+ Layout.row: 1
+ Layout.column: 2
+ Layout.columnSpan: 1
Layout.bottomMargin: 16
Layout.rightMargin: 16
}
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/ColorDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/ColorDialog.qml
index 718f5e6730..9f07f9fd3e 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/ColorDialog.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/ColorDialog.qml
@@ -33,6 +33,7 @@ ColorDialogImpl {
ColorDialogImpl.buttonBox: buttonBox
ColorDialogImpl.colorPicker: colorPicker
ColorDialogImpl.alphaSlider: alphaSlider
+ ColorDialogImpl.colorInputs: inputs
Material.elevation: 24
@@ -127,7 +128,6 @@ ColorDialogImpl {
Slider {
id: alphaSlider
objectName: "alphaSlider"
- visible: control.showAlpha
orientation: Qt.Horizontal
value: control.alpha
implicitHeight: 20
@@ -185,28 +185,8 @@ ColorDialogImpl {
ColorInputs {
id: inputs
- spacing: 12
- currentColor: control.color
- red: control.red
- green: control.green
- blue: control.blue
- hue: control.hue
- saturation: control.saturation
- value: control.value
- lightness: control.lightness
- alpha: control.alpha
- showAlpha: control.showAlpha
- onEmitHex: function (hex) { control.color = hex; }
- onEmitRed: function (r) { control.red = r; }
- onEmitGreen: function (g) { control.green = g; }
- onEmitBlue: function (b) { control.blue = b; }
- onEmitHue: function (h) { control.hue = h; }
- onEmitSaturation: function (s) { control.saturation = s; }
- onEmitValue: function(v) { control.value = v; }
- onEmitLightness: function (l) { control.lightness = l; }
- onEmitAlpha: function (a) { control.alpha = a; }
+ color: control.color
- Layout.fillWidth: true
Layout.leftMargin: 12
Layout.rightMargin: 12
Layout.bottomMargin: 12
@@ -243,6 +223,10 @@ ColorDialogImpl {
}
}
+ Item {
+ Layout.fillWidth: true
+ }
+
DialogButtonBox {
id: buttonBox
standardButtons: control.standardButtons
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml
index 73c9cea704..cd2c513c2e 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml
@@ -36,6 +36,8 @@ FileDialogImpl {
FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox
FileDialogImpl.fileDialogListView: fileDialogListView
FileDialogImpl.breadcrumbBar: breadcrumbBar
+ FileDialogImpl.fileNameLabel: fileNameLabel
+ FileDialogImpl.fileNameTextField: fileNameTextField
background: Rectangle {
implicitWidth: 600
@@ -98,15 +100,46 @@ FileDialogImpl {
}
}
- footer: RowLayout {
- id: rowLayout
- spacing: 20
+ footer: GridLayout {
+ columnSpacing: 20
+ columns: 3
+
+ Label {
+ id: fileNameLabel
+ text: qsTr("File name")
+ visible: false
+
+ Layout.topMargin: 12
+ Layout.leftMargin: 20
+ }
+
+ TextField {
+ id: fileNameTextField
+ objectName: "fileNameTextField"
+ text: control.fileName
+ visible: false
+
+ Layout.topMargin: 12
+ Layout.fillWidth: true
+ }
+
+ Label {
+ text: qsTr("Filter")
+
+ Layout.row: 1
+ Layout.topMargin: fileNameTextField.visible ? 0 : 12
+ Layout.leftMargin: 20
+ }
ComboBox {
id: nameFiltersComboBox
model: control.nameFilters
+ flat: true
- Layout.leftMargin: 20
+ verticalPadding: 0
+ topInset: 0
+ bottomInset: 0
+ Layout.topMargin: fileNameTextField.visible ? 0 : 12
Layout.fillWidth: true
}
@@ -114,9 +147,13 @@ FileDialogImpl {
id: buttonBox
standardButtons: control.standardButtons
spacing: 12
- horizontalPadding: 0
- verticalPadding: 20
+ padding: 0
+ topInset: 0
+ bottomInset: 0
+ Layout.row: 1
+ Layout.column: 2
+ Layout.topMargin: fileNameTextField.visible ? 0 : 12
Layout.rightMargin: 20
}
}
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/ColorDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/ColorDialog.qml
index 932c0baadc..f3ef9fe2e5 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/ColorDialog.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/ColorDialog.qml
@@ -33,6 +33,7 @@ ColorDialogImpl {
ColorDialogImpl.buttonBox: buttonBox
ColorDialogImpl.colorPicker: colorPicker
ColorDialogImpl.alphaSlider: alphaSlider
+ ColorDialogImpl.colorInputs: inputs
background: Rectangle {
implicitWidth: 200
@@ -130,7 +131,6 @@ ColorDialogImpl {
Slider {
id: alphaSlider
objectName: "alphaSlider"
- visible: control.showAlpha
orientation: Qt.Horizontal
value: control.alpha
implicitHeight: 20
@@ -188,28 +188,8 @@ ColorDialogImpl {
ColorInputs {
id: inputs
- spacing: 12
- currentColor: control.color
- red: control.red
- green: control.green
- blue: control.blue
- hue: control.hue
- saturation: control.saturation
- value: control.value
- lightness: control.lightness
- alpha: control.alpha
- showAlpha: control.showAlpha
- onEmitHex: function (hex) { control.color = hex; }
- onEmitRed: function (r) { control.red = r; }
- onEmitGreen: function (g) { control.green = g; }
- onEmitBlue: function (b) { control.blue = b; }
- onEmitHue: function (h) { control.hue = h; }
- onEmitSaturation: function (s) { control.saturation = s; }
- onEmitValue: function(v) { control.value = v; }
- onEmitLightness: function (l) { control.lightness = l; }
- onEmitAlpha: function (a) { control.alpha = a; }
+ color: control.color
- Layout.fillWidth: true
Layout.leftMargin: 12
Layout.rightMargin: 12
Layout.bottomMargin: 12
@@ -251,6 +231,10 @@ ColorDialogImpl {
Layout.bottomMargin: 24
}
+ Item {
+ Layout.fillWidth: true
+ }
+
DialogButtonBox {
id: buttonBox
standardButtons: control.standardButtons
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml
index a22d7884e6..c029b06293 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml
@@ -34,6 +34,8 @@ FileDialogImpl {
FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox
FileDialogImpl.fileDialogListView: fileDialogListView
FileDialogImpl.breadcrumbBar: breadcrumbBar
+ FileDialogImpl.fileNameLabel: fileNameLabel
+ FileDialogImpl.fileNameTextField: fileNameTextField
background: Rectangle {
implicitWidth: 600
@@ -100,15 +102,40 @@ FileDialogImpl {
}
}
- footer: RowLayout {
- id: rowLayout
- spacing: 24
+ footer: GridLayout {
+ columnSpacing: 24
+ columns: 3
+
+ Label {
+ id: fileNameLabel
+ text: qsTr("File name")
+ visible: false
+
+ Layout.leftMargin: 24
+ }
+
+ TextField {
+ id: fileNameTextField
+ objectName: "fileNameTextField"
+ text: control.fileName
+ visible: false
+
+ Layout.fillWidth: true
+ }
+
+ Label {
+ text: qsTr("Filter")
+
+ Layout.row: 1
+ Layout.column: 0
+ Layout.leftMargin: 24
+ Layout.bottomMargin: 24
+ }
ComboBox {
id: nameFiltersComboBox
model: control.nameFilters
- Layout.leftMargin: 24
Layout.fillWidth: true
Layout.topMargin: 6
Layout.bottomMargin: 24
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/ColorDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/ColorDialog.qml
index 24b75b0add..c8395bacd0 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/ColorDialog.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/ColorDialog.qml
@@ -37,6 +37,7 @@ ColorDialogImpl {
ColorDialogImpl.eyeDropperButton: eyeDropperButton
ColorDialogImpl.buttonBox: buttonBox
ColorDialogImpl.colorPicker: colorPicker
+ ColorDialogImpl.colorInputs: inputs
ColorDialogImpl.alphaSlider: alphaSlider
background: Rectangle {
@@ -128,7 +129,6 @@ ColorDialogImpl {
Slider {
id: alphaSlider
objectName: "alphaSlider"
- visible: control.showAlpha
orientation: Qt.Horizontal
value: control.alpha
implicitHeight: 20
@@ -186,26 +186,7 @@ ColorDialogImpl {
ColorInputs {
id: inputs
- spacing: 12
- currentColor: control.color
- red: control.red
- green: control.green
- blue: control.blue
- hue: control.hue
- saturation: control.saturation
- value: control.value
- lightness: control.lightness
- alpha: control.alpha
- showAlpha: control.showAlpha
- onEmitHex: function (hex) { control.color = hex; }
- onEmitRed: function (r) { control.red = r; }
- onEmitGreen: function (g) { control.green = g; }
- onEmitBlue: function (b) { control.blue = b; }
- onEmitHue: function (h) { control.hue = h; }
- onEmitSaturation: function (s) { control.saturation = s; }
- onEmitValue: function(v) { control.value = v; }
- onEmitLightness: function (l) { control.lightness = l; }
- onEmitAlpha: function (a) { control.alpha = a; }
+ color: control.color
Layout.fillWidth: true
Layout.leftMargin: 12
@@ -252,6 +233,11 @@ ColorDialogImpl {
}
}
+ Item {
+ // empty space filler
+ Layout.fillWidth: true
+ }
+
DialogButtonBox {
id: buttonBox
standardButtons: control.standardButtons
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/ColorInputs.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/ColorInputs.qml
index 1fc4d90e2d..42086629ff 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/ColorInputs.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/ColorInputs.qml
@@ -4,269 +4,221 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
+import QtQuick.Dialogs.quickimpl
-RowLayout {
+ColorInputsImpl {
id: root
- required property color currentColor
- required property real red
- required property real green
- required property real blue
- required property real hue
- required property real saturation
- required property real value
- required property real lightness
- required property real alpha
- property bool showAlpha
- property alias currentIndex: colorSystemComboBox.currentIndex
- signal emitHex(string hex)
- signal emitRed(int r)
- signal emitGreen(int g)
- signal emitBlue(int b)
- signal emitHue(real h)
- signal emitSaturation(real s)
- signal emitValue(real v)
- signal emitLightness(real l)
- signal emitAlpha(real a)
- ComboBox {
- id: colorSystemComboBox
- objectName: "colorSystemComboBox"
- editable: false
- flat: true
- background.implicitWidth: 0
- implicitContentWidthPolicy: ComboBox.WidestText
- model: ListModel {
- ListElement {
- name: qsTr("Hex")
- }
- ListElement {
- name: qsTr("RGB")
- }
- ListElement {
- name: qsTr("HSV")
- }
- ListElement {
- name: qsTr("HSL")
- }
- }
+ hexInput: hex
+ redInput: rgbRed
+ greenInput: rgbGreen
+ blueInput: rgbBlue
+ rgbAlphaInput: rgbAlpha
+ hsvHueInput: hsvHue
+ hsvSaturationInput: hsvSaturation
+ valueInput: hsvValue
+ hsvAlphaInput: hsvAlpha
+ hslHueInput: hslHue
+ hslSaturationInput: hslSaturation
+ lightnessInput: hslLightness
+ hslAlphaInput: hslAlpha
+
+ implicitWidth: content.implicitWidth
+ implicitHeight: content.implicitHeight
+
+ TextMetrics {
+ id: fourM
+ text: "MMMM"
+ font: colorSystemComboBox.font
}
- StackLayout {
- objectName: "colorParameters"
- currentIndex: colorSystemComboBox.currentIndex
-
- Layout.fillWidth: true
- Layout.fillHeight: false
- TextField {
- horizontalAlignment: Qt.AlignHCenter
- text: root.currentColor
- selectByMouse: true
- maximumLength: 9
- validator: RegularExpressionValidator {
- regularExpression: /^#[0-9A-f]{6}(?:[0-9A-f]{2})?$/
- }
- onEditingFinished: function() {
- root.emitHex(text)
- }
- }
+ RowLayout {
+ id: content
+ anchors.fill: parent
+ spacing: 12
- RowLayout {
- Layout.fillWidth: true
-
- TextField {
- horizontalAlignment: Qt.AlignHCenter
- text: root.red
- maximumLength: 3
- validator: IntValidator {
- bottom: 0
- top: 999
+ ComboBox {
+ id: colorSystemComboBox
+ objectName: "colorSystemComboBox"
+ editable: false
+ flat: true
+ background.implicitWidth: 0
+ implicitContentWidthPolicy: ComboBox.WidestTextWhenCompleted
+ implicitWidth: implicitContentWidth + leftPadding + rightPadding // Workaround QTBUG-106098
+ model: ListModel {
+ ListElement {
+ name: qsTr("Hex")
}
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitRed(Math.max(Math.min(parseInt(text), 255), 0))
+ ListElement {
+ name: qsTr("RGB")
}
- }
- TextField {
- horizontalAlignment: Qt.AlignHCenter
- text: root.green
- maximumLength: 3
- validator: IntValidator {
- bottom: 0
- top: 999
+ ListElement {
+ name: qsTr("HSV")
}
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitGreen(Math.max(Math.min(parseInt(text), 255), 0))
- }
- }
- TextField {
- horizontalAlignment: Qt.AlignHCenter
- text: root.blue
- maximumLength: 3
- validator: IntValidator {
- bottom: 0
- top: 999
- }
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitBlue(Math.max(Math.min(parseInt(text), 255), 0))
- }
- }
- TextField {
- visible: root.showAlpha
- horizontalAlignment: Qt.AlignHCenter
- text: Math.round(root.alpha * 100).toString() + "%"
- maximumLength: 4
- validator: RegularExpressionValidator {
- regularExpression: /^[0-9]{0,3}%?$/
- }
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitAlpha(Math.max(Math.min(text.match(/^(\d+)%?$/)[1], 100), 0) / 100.0)
+ ListElement {
+ name: qsTr("HSL")
}
}
}
- RowLayout {
- Layout.fillWidth: true
-
- TextField {
- horizontalAlignment: Qt.AlignHCenter
- text: Math.round(root.hue === -1.0 ? 0 : control.hue * 360).toString() + "°"
- maximumLength: 4
- validator: RegularExpressionValidator {
- regularExpression: /^[0-9]{0,3}°?$/
- }
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitHue(Math.max(Math.min(text.match(/^(\d+)°?$/)[1], 360), 0) / 360.0)
- }
- }
- TextField {
- horizontalAlignment: Qt.AlignHCenter
- text: Math.round(root.saturation * 100).toString() + "%"
- maximumLength: 4
- validator: RegularExpressionValidator {
- regularExpression: /^[0-9]{0,3}%?$/
- }
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitSaturation(Math.max(Math.min(text.match(/^(\d+)%?$/)[1], 100), 0) / 100.0)
- }
- }
- TextField {
- horizontalAlignment: Qt.AlignHCenter
- text: Math.round(root.value * 100).toString() + "%"
- maximumLength: 4
- validator: RegularExpressionValidator {
- regularExpression: /^[0-9]{0,3}%?$/
- }
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitValue(Math.max(Math.min(text.match(/^(\d+)%?$/)[1], 100), 0) / 100.0)
- }
- }
- TextField {
- visible: root.showAlpha
- horizontalAlignment: Qt.AlignHCenter
- text: Math.round(root.alpha * 100).toString() + "%"
- maximumLength: 4
- validator: RegularExpressionValidator {
- regularExpression: /^[0-9]{0,3}%?$/
- }
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitAlpha(Math.max(Math.min(text.match(/^(\d+)%?$/)[1], 100), 0) / 100.0)
- }
- }
- }
+ StackLayout {
+ objectName: "colorParameters"
+ currentIndex: colorSystemComboBox.currentIndex
- RowLayout {
Layout.fillWidth: true
TextField {
- horizontalAlignment: Qt.AlignHCenter
- text: Math.round(root.hue === -1.0 ? 0 : control.hue * 360).toString() + "°"
- maximumLength: 4
+ id: hex
+ horizontalAlignment: Qt.AlignLeft
+ text: root.color
+ maximumLength: 9
validator: RegularExpressionValidator {
- regularExpression: /^[0-9]{0,3}°?$/
+ regularExpression: root.showAlpha ? /^#[0-9A-f]{6}(?:[0-9A-f]{2})?$/ : /^#[0-9A-f]{6}$/
}
-
- Layout.preferredWidth: 1
Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitHue(Math.max(Math.min(text.match(/^(\d+)°?$/)[1], 360), 0) / 360.0)
- }
- }
- TextField {
- horizontalAlignment: Qt.AlignHCenter
- text: Math.round(root.saturation * 100).toString() + "%"
- maximumLength: 4
- validator: RegularExpressionValidator {
- regularExpression: /^[0-9]{0,3}%?$/
- }
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitSaturation(Math.max(Math.min(text.match(/^(\d+)%?$/)[1], 100), 0) / 100.0)
- }
}
- TextField {
- horizontalAlignment: Qt.AlignHCenter
- text: Math.round(root.lightness * 100).toString() + "%"
- maximumLength: 4
- validator: RegularExpressionValidator {
- regularExpression: /^[0-9]{0,3}%?$/
- }
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
-
- onEditingFinished: function() {
- root.emitLightness(Math.max(Math.min(text.match(/^(\d+)%?$/)[1], 100), 0) / 100.0)
- }
- }
- TextField {
- visible: root.showAlpha
- horizontalAlignment: Qt.AlignHCenter
- text: Math.round(root.alpha * 100).toString() + "%"
- maximumLength: 4
- validator: RegularExpressionValidator {
- regularExpression: /^[0-9]{0,3}%?$/
- }
-
- Layout.preferredWidth: 1
- Layout.fillWidth: true
- onEditingFinished: function() {
- root.emitAlpha(Math.max(Math.min(text.match(/^(\d+)%?$/)[1], 100), 0) / 100.0)
+ RowLayout {
+ TextField {
+ id: rgbRed
+ horizontalAlignment: Qt.AlignHCenter
+ text: root.red
+ maximumLength: 3
+ validator: IntValidator {
+ bottom: 0
+ top: 999
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ TextField {
+ id: rgbGreen
+ horizontalAlignment: Qt.AlignHCenter
+ text: root.green
+ maximumLength: 3
+ validator: IntValidator {
+ bottom: 0
+ top: 999
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ TextField {
+ id: rgbBlue
+ horizontalAlignment: Qt.AlignHCenter
+ text: root.blue
+ maximumLength: 3
+ validator: IntValidator {
+ bottom: 0
+ top: 999
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ TextField {
+ id: rgbAlpha
+ horizontalAlignment: Qt.AlignHCenter
+ text: Math.round(root.alpha * 100).toString() + "%"
+ maximumLength: 4
+ validator: RegularExpressionValidator {
+ regularExpression: /^[0-9]{0,3}%?$/
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ }
+
+ RowLayout {
+ TextField {
+ id: hsvHue
+ horizontalAlignment: Qt.AlignHCenter
+ text: Math.round(root.hue * 360).toString() + "°"
+ maximumLength: 4
+ validator: RegularExpressionValidator {
+ regularExpression: /^[0-9]{0,3}°?$/
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ TextField {
+ id: hsvSaturation
+ horizontalAlignment: Qt.AlignHCenter
+ text: Math.round(root.hsvSaturation * 100).toString() + "%"
+ maximumLength: 4
+ validator: RegularExpressionValidator {
+ regularExpression: /^[0-9]{0,3}%?$/
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ TextField {
+ id: hsvValue
+ horizontalAlignment: Qt.AlignHCenter
+ text: Math.round(root.value * 100).toString() + "%"
+ maximumLength: 4
+ validator: RegularExpressionValidator {
+ regularExpression: /^[0-9]{0,3}%?$/
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ TextField {
+ id: hsvAlpha
+ horizontalAlignment: Qt.AlignHCenter
+ text: Math.round(root.alpha * 100).toString() + "%"
+ maximumLength: 4
+ validator: RegularExpressionValidator {
+ regularExpression: /^[0-9]{0,3}%?$/
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ }
+
+ RowLayout {
+ TextField {
+ id: hslHue
+ horizontalAlignment: Qt.AlignHCenter
+ text: Math.round(root.hue * 360).toString() + "°"
+ maximumLength: 4
+ validator: RegularExpressionValidator {
+ regularExpression: /^[0-9]{0,3}°?$/
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ TextField {
+ id: hslSaturation
+ horizontalAlignment: Qt.AlignHCenter
+ text: Math.round(root.hslSaturation * 100).toString() + "%"
+ maximumLength: 4
+ validator: RegularExpressionValidator {
+ regularExpression: /^[0-9]{0,3}%?$/
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ TextField {
+ id: hslLightness
+ horizontalAlignment: Qt.AlignHCenter
+ text: Math.round(root.lightness * 100).toString() + "%"
+ maximumLength: 4
+ validator: RegularExpressionValidator {
+ regularExpression: /^[0-9]{0,3}%?$/
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
+ }
+ TextField {
+ id: hslAlpha
+ horizontalAlignment: Qt.AlignHCenter
+ text: Math.round(root.alpha * 100).toString() + "%"
+ maximumLength: 4
+ validator: RegularExpressionValidator {
+ regularExpression: /^[0-9]{0,3}%?$/
+ }
+ implicitWidth: fourM.width + leftPadding + rightPadding
+ Layout.fillWidth: true
}
}
}
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml
index 75aaa10b74..0f25dee35b 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml
@@ -46,6 +46,8 @@ FileDialogImpl {
FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox
FileDialogImpl.fileDialogListView: fileDialogListView
FileDialogImpl.breadcrumbBar: breadcrumbBar
+ FileDialogImpl.fileNameLabel: fileNameLabel
+ FileDialogImpl.fileNameTextField: fileNameTextField
background: Rectangle {
implicitWidth: 600
@@ -110,21 +112,48 @@ FileDialogImpl {
footer: Rectangle {
color: control.palette.light
- implicitWidth: rowLayout.implicitWidth
- implicitHeight: rowLayout.implicitHeight
+ implicitWidth: gridLayout.implicitWidth
+ implicitHeight: gridLayout.implicitHeight + 12
+
+ GridLayout {
+ // OK to use IDs here, since users shouldn't be overriding this stuff.
+ id: gridLayout
+ anchors.fill: parent
+ anchors.topMargin: 6
+ anchors.bottomMargin: 6
+ columnSpacing: 20
+ columns: 3
- RowLayout {
- id: rowLayout
- width: parent.width
- height: parent.height
- spacing: 20
+ Label {
+ id: fileNameLabel
+ text: qsTr("File name")
+ visible: false
+
+ Layout.leftMargin: 20
+ }
+
+ TextField {
+ id: fileNameTextField
+ objectName: "fileNameTextField"
+ text: control.fileName
+ visible: false
+
+ Layout.fillWidth: true
+ }
+
+ Label {
+ text: qsTr("Filter")
+
+ Layout.row: 1
+ Layout.column: 0
+ Layout.leftMargin: 20
+ }
ComboBox {
- // OK to use IDs here, since users shouldn't be overriding this stuff.
id: nameFiltersComboBox
model: control.nameFilters
+ verticalPadding: 0
- Layout.leftMargin: 20
Layout.fillWidth: true
}
@@ -133,9 +162,10 @@ FileDialogImpl {
standardButtons: control.standardButtons
palette.window: control.palette.light
spacing: 12
- horizontalPadding: 0
- verticalPadding: 20
+ padding: 0
+ Layout.row: 1
+ Layout.column: 2
Layout.rightMargin: 20
}
}
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker.cpp
index 96742b9ce8..4606c00502 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker.cpp
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker.cpp
@@ -3,16 +3,15 @@
#include "qquickabstractcolorpicker_p_p.h"
+#include "qquickcolordialogutils_p.h"
+
#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>
#include <QtQuickTemplates2/private/qquickdeferredexecute_p_p.h>
#include <qpa/qplatformintegration.h>
#include <private/qguiapplication_p.h>
-QQuickAbstractColorPickerPrivate::QQuickAbstractColorPickerPrivate()
- : m_pressed(false), m_hsl(false)
-{
-}
+QQuickAbstractColorPickerPrivate::QQuickAbstractColorPickerPrivate() = default;
static inline QString handleName()
{
@@ -25,7 +24,6 @@ bool QQuickAbstractColorPickerPrivate::handlePress(const QPointF &point, ulong t
QQuickControlPrivate::handlePress(point, timestamp);
m_pressPoint = point;
q->setPressed(true);
-
q->updateColor(point);
return true;
}
@@ -111,6 +109,13 @@ QColor QQuickAbstractColorPicker::color() const
void QQuickAbstractColorPicker::setColor(const QColor &c)
{
Q_D(QQuickAbstractColorPicker);
+ // QColor represents a theoretical color, rather than simply an rgba value.
+ // Therefore, two QColor objects can be different,
+ // and yet translate to the same rgba value.
+ // Since the color picker can reuse the same rgba value for multiple pixels,
+ // we should not return early if the rgba() values are equal,
+ // but only if the QColor objects are exactly the same.
+
if (color() == c)
return;
@@ -352,24 +357,3 @@ void QQuickAbstractColorPicker::updateColor(const QPointF &pos)
emit colorPicked(c);
}
-
-std::pair<qreal, qreal> QQuickAbstractColorPicker::getSaturationAndValue(qreal saturation,
- qreal lightness)
-{
- const qreal v = lightness + saturation * qMin(lightness, 1 - lightness);
- if (v == .0)
- return { .0, .0 };
-
- const qreal s = 2 * (1 - lightness / v);
- return { s, v };
-}
-std::pair<qreal, qreal> QQuickAbstractColorPicker::getSaturationAndLightness(qreal saturation,
- qreal value)
-{
- const qreal l = value * (1 - saturation / 2);
- if (l == .0)
- return { .0, .0 };
-
- const qreal s = (value - l) / qMin(l, 1 - l);
- return { s, l };
-}
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker_p.h
index 6138581d4e..b29e488b3a 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker_p.h
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker_p.h
@@ -87,8 +87,6 @@ protected:
private:
void updateColor(const QPointF &pos);
- static std::pair<qreal, qreal> getSaturationAndValue(qreal saturation, qreal lightness);
- static std::pair<qreal, qreal> getSaturationAndLightness(qreal saturation, qreal value);
Q_DISABLE_COPY(QQuickAbstractColorPicker)
Q_DECLARE_PRIVATE(QQuickAbstractColorPicker)
};
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker_p_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker_p_p.h
index eb93cbab07..73878a1cc0 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker_p_p.h
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickabstractcolorpicker_p_p.h
@@ -19,6 +19,7 @@
#include <QtQuickTemplates2/private/qquickdeferredexecute_p_p.h>
#include "qquickabstractcolorpicker_p.h"
+#include "qquickcolordialogutils_p.h"
QT_BEGIN_NAMESPACE
@@ -45,22 +46,13 @@ public:
void itemImplicitWidthChanged(QQuickItem *item) override;
void itemImplicitHeightChanged(QQuickItem *item) override;
- struct
- {
- qreal h = .0;
- qreal s = .0;
- union {
- qreal v = 1.0;
- qreal l;
- };
- qreal a = 1.0;
- } m_hsva;
+ HSVA m_hsva;
QPointF m_pressPoint;
QQuickDeferredPointer<QQuickItem> m_handle;
- bool m_pressed : 1;
+ bool m_pressed = false;
protected:
- bool m_hsl : 1; // Use hsv by default.
+ bool m_hsl = false; // Use hsv by default.
};
QT_END_NAMESPACE
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl.cpp
index f26b90570c..6f13403766 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl.cpp
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl.cpp
@@ -4,6 +4,8 @@
#include "qquickcolordialogimpl_p.h"
#include "qquickcolordialogimpl_p_p.h"
+#include "qquickcolordialogutils_p.h"
+
#include <QtQuickTemplates2/private/qquickslider_p.h>
#include <qpa/qplatformintegration.h>
@@ -58,8 +60,7 @@ bool QQuickEyeDropperEventFilter::eventFilter(QObject *obj, QEvent *event)
}
}
-QQuickColorDialogImplPrivate::QQuickColorDialogImplPrivate()
-{}
+QQuickColorDialogImplPrivate::QQuickColorDialogImplPrivate() = default;
QQuickColorDialogImplPrivate::~QQuickColorDialogImplPrivate()
{
@@ -178,13 +179,38 @@ QColor QQuickColorDialogImpl::color() const
void QQuickColorDialogImpl::setColor(const QColor &c)
{
Q_D(QQuickColorDialogImpl);
-
if (color().rgba() == c.rgba())
return;
- d->m_hsva.h = d->m_hsl ? c.hslHueF() : c.hsvHueF();
- d->m_hsva.s = d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF();
- d->m_hsva.v = d->m_hsl ? c.lightnessF() : c.valueF();
+ // If we get a QColor from an Hsv or Hsl color system,
+ // we want to get the raw values without the risk of QColor converting them,
+ // and possible deleting relevant information for achromatic cases.
+ if (c.spec() == QColor::Spec::Hsv) {
+ d->m_hsva.h = qBound(.0, c.hsvHueF(), 1.0);
+ if (d->m_hsl) {
+ const auto sl = getSaturationAndLightness(c.hsvSaturationF(), c.valueF());
+ d->m_hsva.s = qBound(.0, sl.first, 1.0);
+ d->m_hsva.l = qBound(.0, sl.second, 1.0);
+ } else {
+ d->m_hsva.s = qBound(.0, c.hsvSaturationF(), 1.0);
+ d->m_hsva.v = qBound(.0, c.valueF(), 1.0);
+ }
+ } else if (c.spec() == QColor::Spec::Hsl) {
+ d->m_hsva.h = qBound(.0, c.hslHueF(), 1.0);
+ if (d->m_hsl) {
+ d->m_hsva.s = qBound(.0, c.hslSaturationF(), 1.0);
+ d->m_hsva.l = qBound(.0, c.lightnessF(), 1.0);
+ } else {
+ const auto sv = getSaturationAndValue(c.hslSaturationF(), c.lightnessF());
+ d->m_hsva.s = qBound(.0, sv.first, 1.0);
+ d->m_hsva.v = qBound(.0, sv.second, 1.0);
+ }
+ } else {
+ d->m_hsva.h = qBound(.0, d->m_hsl ? c.hslHueF() : c.hsvHueF(), 1.0);
+ d->m_hsva.s = qBound(.0, d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF(), 1.0);
+ d->m_hsva.v = qBound(.0, d->m_hsl ? c.lightnessF() : c.valueF(), 1.0);
+ }
+
d->m_hsva.a = c.alphaF();
emit colorChanged(color());
@@ -379,12 +405,6 @@ void QQuickColorDialogImpl::setHsl(bool hsl)
emit specChanged();
}
-bool QQuickColorDialogImpl::showAlpha()
-{
- Q_D(const QQuickColorDialogImpl);
- return d->m_showAlpha;
-}
-
QSharedPointer<QColorDialogOptions> QQuickColorDialogImpl::options() const
{
Q_D(const QQuickColorDialogImpl);
@@ -406,14 +426,10 @@ void QQuickColorDialogImpl::setOptions(const QSharedPointer<QColorDialogOptions>
if (d->options) {
attached->buttonBox()->setVisible(
!(d->options->options() & QColorDialogOptions::NoButtons));
- }
- }
- if (d->options) {
- const bool showAlpha = d->options->options() & QColorDialogOptions::ShowAlphaChannel;
- if (showAlpha != d->m_showAlpha) {
- d->m_showAlpha = showAlpha;
- emit showAlphaChanged();
+ const bool showAlpha = d->options->options() & QColorDialogOptions::ShowAlphaChannel;
+ attached->alphaSlider()->setVisible(showAlpha);
+ attached->colorInputs()->setShowAlpha(showAlpha);
}
}
}
@@ -424,25 +440,6 @@ void QQuickColorDialogImpl::invokeEyeDropper()
d->eyeDropperEnter();
}
-std::pair<qreal, qreal> QQuickColorDialogImpl::getSaturationAndValue(qreal saturation,
- qreal lightness)
-{
- const qreal v = lightness + saturation * qMin(lightness, 1 - lightness);
- if (v == .0)
- return { .0, .0 };
- const qreal s = 2 * (1 - lightness / v);
- return { s, v };
-}
-std::pair<qreal, qreal> QQuickColorDialogImpl::getSaturationAndLightness(qreal saturation,
- qreal value)
-{
- const qreal l = value * (1 - saturation / 2);
- if (l == .0)
- return { .0, .0 };
- const qreal s = (value - l) / qMin(l, 1 - l);
- return { s, l };
-}
-
QQuickColorDialogImplAttached::QQuickColorDialogImplAttached(QObject *parent)
: QObject(*(new QQuickColorDialogImplAttachedPrivate), parent)
{
@@ -581,4 +578,36 @@ void QQuickColorDialogImplAttached::setAlphaSlider(QQuickSlider *alphaSlider)
emit alphaSliderChanged();
}
+QQuickColorInputs *QQuickColorDialogImplAttached::colorInputs() const
+{
+ Q_D(const QQuickColorDialogImplAttached);
+ return d->colorInputs;
+}
+
+void QQuickColorDialogImplAttached::setColorInputs(QQuickColorInputs *colorInputs)
+{
+ Q_D(QQuickColorDialogImplAttached);
+
+ if (d->colorInputs == colorInputs)
+ return;
+
+ if (d->colorInputs) {
+ QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
+ if (colorDialogImpl)
+ QObject::disconnect(d->colorInputs, &QQuickColorInputs::colorModified,
+ colorDialogImpl, &QQuickColorDialogImpl::setColor);
+ }
+
+ d->colorInputs = colorInputs;
+
+ if (d->colorInputs) {
+ QQuickColorDialogImpl *colorDialogImpl = qobject_cast<QQuickColorDialogImpl *>(parent());
+ if (colorDialogImpl)
+ QObject::connect(d->colorInputs, &QQuickColorInputs::colorModified,
+ colorDialogImpl, &QQuickColorDialogImpl::setColor);
+ }
+
+ emit colorInputsChanged();
+}
+
QT_END_NAMESPACE
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl_p.h
index d5c81372ba..110298b5f2 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl_p.h
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl_p.h
@@ -23,6 +23,7 @@ QT_BEGIN_NAMESPACE
class QQuickDialogButtonBox;
class QQuickAbstractColorPicker;
+class QQuickColorInputs;
class QQuickSlider;
class QQuickColorDialogImplAttached;
@@ -42,7 +43,6 @@ class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickColorDialogImpl : public QQu
Q_PROPERTY(int green READ green WRITE setGreen NOTIFY colorChanged FINAL)
Q_PROPERTY(int blue READ blue WRITE setBlue NOTIFY colorChanged FINAL)
Q_PROPERTY(bool isHsl READ isHsl WRITE setHsl NOTIFY specChanged FINAL)
- Q_PROPERTY(bool showAlpha READ showAlpha NOTIFY showAlphaChanged)
QML_NAMED_ELEMENT(ColorDialogImpl)
QML_ATTACHED(QQuickColorDialogImplAttached)
QML_ADDED_IN_VERSION(6, 4)
@@ -85,18 +85,13 @@ public:
bool isHsl() const;
void setHsl(bool hsl);
- bool showAlpha();
-
Q_INVOKABLE void invokeEyeDropper();
Q_SIGNALS:
void colorChanged(const QColor &color);
void specChanged();
- void showAlphaChanged();
private:
- static std::pair<qreal, qreal> getSaturationAndValue(qreal saturation, qreal lightness);
- static std::pair<qreal, qreal> getSaturationAndLightness(qreal saturation, qreal value);
Q_DISABLE_COPY(QQuickColorDialogImpl)
Q_DECLARE_PRIVATE(QQuickColorDialogImpl)
};
@@ -106,12 +101,17 @@ class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickColorDialogImplAttached : pu
Q_OBJECT
Q_PROPERTY(QQuickDialogButtonBox *buttonBox READ buttonBox WRITE setButtonBox NOTIFY buttonBoxChanged FINAL)
Q_PROPERTY(QQuickAbstractButton *eyeDropperButton READ eyeDropperButton WRITE setEyeDropperButton NOTIFY eyeDropperButtonChanged FINAL)
- Q_PROPERTY(QQuickAbstractColorPicker *colorPicker READ colorPicker WRITE setColorPicker NOTIFY colorPickerChanged)
- Q_PROPERTY(QQuickSlider *alphaSlider READ alphaSlider WRITE setAlphaSlider NOTIFY alphaSliderChanged)
+ Q_PROPERTY(QQuickAbstractColorPicker *colorPicker READ colorPicker WRITE setColorPicker NOTIFY
+ colorPickerChanged FINAL)
+ Q_PROPERTY(QQuickColorInputs *colorInputs READ colorInputs WRITE setColorInputs NOTIFY
+ colorInputsChanged FINAL)
+ Q_PROPERTY(QQuickSlider *alphaSlider READ alphaSlider WRITE setAlphaSlider NOTIFY
+ alphaSliderChanged FINAL)
Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquickdialogbuttonbox_p.h>)
Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquickabstractbutton_p.h>)
Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquickslider_p.h>)
Q_MOC_INCLUDE("qquickabstractcolorpicker_p.h")
+ Q_MOC_INCLUDE("qquickcolorinputs_p.h")
public:
explicit QQuickColorDialogImplAttached(QObject *parent = nullptr);
@@ -125,6 +125,9 @@ public:
QQuickAbstractColorPicker *colorPicker() const;
void setColorPicker(QQuickAbstractColorPicker *colorPicker);
+ QQuickColorInputs *colorInputs() const;
+ void setColorInputs(QQuickColorInputs *colorInputs);
+
QQuickSlider *alphaSlider() const;
void setAlphaSlider(QQuickSlider *alphaSlider);
@@ -132,6 +135,7 @@ Q_SIGNALS:
void buttonBoxChanged();
void eyeDropperButtonChanged();
void colorPickerChanged();
+ void colorInputsChanged();
void alphaSliderChanged();
private:
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl_p_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl_p_p.h
index 5349fb7da4..b7c4dc8e2c 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl_p_p.h
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogimpl_p_p.h
@@ -17,6 +17,7 @@
#include "qquickcolordialogimpl_p.h"
#include "qquickabstractcolorpicker_p.h"
+#include "qquickcolorinputs_p.h"
#include <QtQuickTemplates2/private/qquickdialog_p_p.h>
#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h>
@@ -69,16 +70,7 @@ public:
void alphaSliderMoved();
QSharedPointer<QColorDialogOptions> options;
- struct
- {
- qreal h = .0;
- qreal s = .0;
- union {
- qreal v = 1.0;
- qreal l;
- };
- qreal a = 1.0;
- } m_hsva;
+ HSVA m_hsva;
std::unique_ptr<QQuickEyeDropperEventFilter> eyeDropperEventFilter;
QPointer<QQuickWindow> m_eyeDropperWindow;
QColor m_eyeDropperPreviousColor;
@@ -92,6 +84,7 @@ class QQuickColorDialogImplAttachedPrivate : public QObjectPrivate
public:
QPointer<QQuickDialogButtonBox> buttonBox;
QPointer<QQuickAbstractButton> eyeDropperButton;
+ QPointer<QQuickColorInputs> colorInputs;
QPointer<QQuickAbstractColorPicker> colorPicker;
QPointer<QQuickSlider> alphaSlider;
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogutils.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogutils.cpp
new file mode 100644
index 0000000000..0a123f84a6
--- /dev/null
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogutils.cpp
@@ -0,0 +1,24 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickcolordialogutils_p.h"
+
+std::pair<qreal, qreal> getSaturationAndValue(qreal saturation, qreal lightness)
+{
+ const qreal v = lightness + saturation * qMin(lightness, 1 - lightness);
+ if (v == .0)
+ return { .0, .0 };
+ const qreal s = 2 * (1 - lightness / v);
+ return { s, v };
+}
+
+std::pair<qreal, qreal> getSaturationAndLightness(qreal saturation, qreal value)
+{
+ const qreal l = value * (1 - saturation / 2);
+ if (l == .0)
+ return { .0, .0 };
+ if (l == 1 && value == 1)
+ return { saturation, l };
+ const qreal s = (value - l) / qMin(l, 1 - l);
+ return { s, l };
+}
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogutils_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogutils_p.h
new file mode 100644
index 0000000000..6b5c2e026c
--- /dev/null
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolordialogutils_p.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQUICKCOLORDIALOGUTILS_P_H
+#define QQUICKCOLORDIALOGUTILS_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/QtGlobal>
+
+std::pair<qreal, qreal> getSaturationAndValue(qreal saturation, qreal lightness);
+
+std::pair<qreal, qreal> getSaturationAndLightness(qreal saturation, qreal value);
+
+struct HSVA
+{
+ qreal h = .0;
+ qreal s = .0;
+ union {
+ qreal v = 1.0;
+ qreal l;
+ };
+ qreal a = 1.0;
+};
+
+#endif // QQUICKCOLORDIALOGUTILS_P_H
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickcolorinputs.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolorinputs.cpp
new file mode 100644
index 0000000000..cc3743c494
--- /dev/null
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolorinputs.cpp
@@ -0,0 +1,509 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickcolorinputs_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QQuickColorInputs::QQuickColorInputs() = default;
+
+QColor QQuickColorInputs::color() const
+{
+ return QColor::fromHsvF(m_hsva.h, m_hsva.s, m_hsva.v, m_hsva.a);
+}
+
+void QQuickColorInputs::setColor(const QColor &c)
+{
+ if (color().rgba() == c.rgba())
+ return;
+
+ // If we get a QColor from an Hsv or Hsl color system,
+ // we want to get the raw values without the risk of QColor converting them,
+ // and possible deleting relevant information for achromatic cases.
+ if (c.spec() == QColor::Spec::Hsl) {
+ const auto sv = getSaturationAndValue(c.hslSaturationF(), c.lightnessF());
+ m_hsva.h = qBound(.0, c.hslHueF(), 1.0);
+ m_hsva.s = qBound(.0, sv.first, 1.0);
+ m_hsva.v = qBound(.0, sv.second, 1.0);
+ } else {
+ m_hsva.h = qBound(.0, c.hsvHueF(), 1.0);
+ m_hsva.s = qBound(.0, c.hsvSaturationF(), 1.0);
+ m_hsva.v = qBound(.0, c.valueF(), 1.0);
+ }
+
+ m_hsva.a = c.alphaF();
+
+ emit colorChanged(color());
+}
+
+int QQuickColorInputs::red() const
+{
+ return color().red();
+}
+
+int QQuickColorInputs::green() const
+{
+ return color().green();
+}
+
+int QQuickColorInputs::blue() const
+{
+ return color().blue();
+}
+
+qreal QQuickColorInputs::alpha() const
+{
+ return m_hsva.a;
+}
+
+qreal QQuickColorInputs::hue() const
+{
+ return m_hsva.h;
+}
+
+qreal QQuickColorInputs::hslSaturation() const
+{
+ return getSaturationAndLightness(m_hsva.s, m_hsva.v).first;
+}
+
+qreal QQuickColorInputs::hsvSaturation() const
+{
+ return m_hsva.s;
+}
+
+qreal QQuickColorInputs::value() const
+{
+ return m_hsva.v;
+}
+
+qreal QQuickColorInputs::lightness() const
+{
+ return getSaturationAndLightness(m_hsva.s, m_hsva.v).second;
+}
+
+bool QQuickColorInputs::showAlpha() const
+{
+ return m_showAlpha;
+}
+
+void QQuickColorInputs::setShowAlpha(bool showAlpha)
+{
+ if (m_showAlpha == showAlpha)
+ return;
+
+ m_showAlpha = showAlpha;
+ emit showAlphaChanged(m_showAlpha);
+}
+
+QQuickTextInput *QQuickColorInputs::hexInput() const
+{
+ return m_hexInput;
+}
+
+void QQuickColorInputs::setHexInput(QQuickTextInput *hexInput)
+{
+ if (m_hexInput == hexInput)
+ return;
+
+ if (m_hexInput)
+ disconnect(m_hexInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHexChanged);
+
+ m_hexInput = hexInput;
+
+ if (m_hexInput)
+ connect(m_hexInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHexChanged);
+
+ emit hexInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::redInput() const
+{
+ return m_redInput;
+}
+
+void QQuickColorInputs::setRedInput(QQuickTextInput *redInput)
+{
+ if (m_redInput == redInput)
+ return;
+
+ if (m_redInput)
+ disconnect(m_redInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleRedChanged);
+
+ m_redInput = redInput;
+
+ if (m_redInput)
+ connect(m_redInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleRedChanged);
+
+ emit redInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::greenInput() const
+{
+ return m_greenInput;
+}
+
+void QQuickColorInputs::setGreenInput(QQuickTextInput *greenInput)
+{
+ if (m_greenInput == greenInput)
+ return;
+
+ if (m_greenInput)
+ disconnect(m_greenInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleGreenChanged);
+
+ m_greenInput = greenInput;
+
+ if (m_greenInput)
+ connect(m_greenInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleGreenChanged);
+
+ emit greenInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::blueInput() const
+{
+ return m_blueInput;
+}
+
+void QQuickColorInputs::setBlueInput(QQuickTextInput *blueInput)
+{
+ if (m_blueInput == blueInput)
+ return;
+
+ if (m_blueInput)
+ disconnect(m_blueInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleBlueChanged);
+
+ m_blueInput = blueInput;
+
+ if (m_blueInput)
+ connect(m_blueInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleBlueChanged);
+
+ emit blueInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::hsvHueInput() const
+{
+ return m_hsvHueInput;
+}
+
+void QQuickColorInputs::setHsvHueInput(QQuickTextInput *hsvHueInput)
+{
+ if (m_hsvHueInput == hsvHueInput)
+ return;
+
+ if (m_hsvHueInput)
+ disconnect(m_hsvHueInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHsvHueChanged);
+
+ m_hsvHueInput = hsvHueInput;
+
+ if (m_hsvHueInput)
+ connect(m_hsvHueInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHsvHueChanged);
+
+ emit hsvHueInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::hslHueInput() const
+{
+ return m_hslHueInput;
+}
+
+void QQuickColorInputs::setHslHueInput(QQuickTextInput *hslHueInput)
+{
+ if (m_hslHueInput == hslHueInput)
+ return;
+
+ if (m_hslHueInput)
+ disconnect(m_hslHueInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHslHueChanged);
+
+ m_hslHueInput = hslHueInput;
+
+ if (m_hslHueInput)
+ connect(m_hslHueInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHslHueChanged);
+
+ emit hslHueInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::hsvSaturationInput() const
+{
+ return m_hsvSaturationInput;
+}
+
+void QQuickColorInputs::setHsvSaturationInput(QQuickTextInput *hsvSaturationInput)
+{
+ if (m_hsvSaturationInput == hsvSaturationInput)
+ return;
+
+ if (m_hsvSaturationInput)
+ disconnect(m_hsvSaturationInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHsvSaturationChanged);
+
+ m_hsvSaturationInput = hsvSaturationInput;
+
+ if (m_hsvSaturationInput)
+ connect(m_hsvSaturationInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHsvSaturationChanged);
+
+ emit hsvSaturationInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::hslSaturationInput() const
+{
+ return m_hslSaturationInput;
+}
+
+void QQuickColorInputs::setHslSaturationInput(QQuickTextInput *hslSaturationInput)
+{
+ if (m_hslSaturationInput == hslSaturationInput)
+ return;
+
+ if (m_hslSaturationInput)
+ disconnect(m_hslSaturationInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHslSaturationChanged);
+
+ m_hslSaturationInput = hslSaturationInput;
+
+ if (m_hslSaturationInput)
+ connect(m_hslSaturationInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHslSaturationChanged);
+
+ emit hslSaturationInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::valueInput() const
+{
+ return m_valueInput;
+}
+
+void QQuickColorInputs::setValueInput(QQuickTextInput *valueInput)
+{
+ if (m_valueInput == valueInput)
+ return;
+
+ if (m_valueInput)
+ disconnect(m_valueInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleValueChanged);
+
+ m_valueInput = valueInput;
+
+ if (m_valueInput)
+ connect(m_valueInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleValueChanged);
+
+ emit valueInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::lightnessInput() const
+{
+ return m_lightnessInput;
+}
+
+void QQuickColorInputs::setLightnessInput(QQuickTextInput *lightnessInput)
+{
+ if (m_lightnessInput == lightnessInput)
+ return;
+
+ if (m_lightnessInput)
+ disconnect(m_lightnessInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleLightnessChanged);
+
+ m_lightnessInput = lightnessInput;
+
+ if (m_lightnessInput)
+ connect(m_lightnessInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleLightnessChanged);
+
+ emit lightnessInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::rgbAlphaInput() const
+{
+ return m_rgbAlphaInput;
+}
+
+void QQuickColorInputs::setRgbAlphaInput(QQuickTextInput *alphaInput)
+{
+ if (alphaInput == m_rgbAlphaInput)
+ return;
+
+ if (m_rgbAlphaInput) {
+ disconnect(m_rgbAlphaInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleRgbAlphaChanged);
+ disconnect(this, &QQuickColorInputs::showAlphaChanged, m_rgbAlphaInput, &QQuickTextInput::setVisible);
+ }
+
+ m_rgbAlphaInput = alphaInput;
+
+ if (m_rgbAlphaInput) {
+ connect(m_rgbAlphaInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleRgbAlphaChanged);
+ connect(this, &QQuickColorInputs::showAlphaChanged, m_rgbAlphaInput, &QQuickTextInput::setVisible);
+ m_rgbAlphaInput->setVisible(showAlpha());
+ }
+
+ emit rgbAlphaInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::hsvAlphaInput() const
+{
+ return m_hsvAlphaInput;
+}
+
+void QQuickColorInputs::setHsvAlphaInput(QQuickTextInput *alphaInput)
+{
+ if (alphaInput == m_hsvAlphaInput)
+ return;
+
+ if (m_hsvAlphaInput) {
+ disconnect(m_hsvAlphaInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHsvAlphaChanged);
+ disconnect(this, &QQuickColorInputs::showAlphaChanged, m_hsvAlphaInput, &QQuickTextInput::setVisible);
+ }
+
+ m_hsvAlphaInput = alphaInput;
+
+ if (m_hsvAlphaInput) {
+ connect(m_hsvAlphaInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHsvAlphaChanged);
+ connect(this, &QQuickColorInputs::showAlphaChanged, m_hsvAlphaInput, &QQuickTextInput::setVisible);
+ m_hsvAlphaInput->setVisible(showAlpha());
+ }
+
+ emit hsvAlphaInputChanged();
+}
+
+QQuickTextInput *QQuickColorInputs::hslAlphaInput() const
+{
+ return m_hslAlphaInput;
+}
+
+void QQuickColorInputs::setHslAlphaInput(QQuickTextInput *alphaInput)
+{
+ if (alphaInput == m_hslAlphaInput)
+ return;
+
+ if (m_hslAlphaInput) {
+ disconnect(m_hslAlphaInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHslAlphaChanged);
+ disconnect(this, &QQuickColorInputs::showAlphaChanged, m_hslAlphaInput, &QQuickTextInput::setVisible);
+ }
+
+ m_hslAlphaInput = alphaInput;
+
+ if (m_hslAlphaInput) {
+ connect(m_hslAlphaInput, &QQuickTextInput::editingFinished, this, &QQuickColorInputs::handleHslAlphaChanged);
+ connect(this, &QQuickColorInputs::showAlphaChanged, m_hslAlphaInput, &QQuickTextInput::setVisible);
+ m_hslAlphaInput->setVisible(showAlpha());
+ }
+
+ emit hslAlphaInputChanged();
+}
+
+void QQuickColorInputs::handleHexChanged()
+{
+ emit colorModified(QColor::fromString(m_hexInput->text()));
+}
+
+void QQuickColorInputs::handleRedChanged()
+{
+ QColor c = color();
+ c.setRed(qBound(0, m_redInput->text().toInt(), 255));
+ emit colorModified(c);
+}
+
+void QQuickColorInputs::handleGreenChanged()
+{
+ QColor c = color();
+ c.setGreen(qBound(0, m_greenInput->text().toInt(), 255));
+ emit colorModified(c);
+}
+
+void QQuickColorInputs::handleBlueChanged()
+{
+ QColor c = color();
+ c.setBlue(qBound(0, m_blueInput->text().toInt(), 255));
+ emit colorModified(c);
+}
+
+static QString s_percentage_pattern = QString::fromUtf8("^(\\d+)%?$");
+static QString s_degree_pattern = QString::fromUtf8("(\\d+)°?$");
+
+void QQuickColorInputs::handleHsvHueChanged()
+{
+ const QRegularExpression pattern(s_degree_pattern);
+ const auto match = pattern.match(m_hsvHueInput->text());
+ if (match.hasMatch()) {
+ const auto substr = match.captured(1);
+ const qreal input = static_cast<qreal>(qBound(0, substr.toInt(), 360)) / static_cast<qreal>(360);
+ emit colorModified(QColor::fromHsvF(input, hsvSaturation(), value(), alpha()));
+ }
+}
+
+void QQuickColorInputs::handleHslHueChanged()
+{
+ const QRegularExpression pattern(s_degree_pattern);
+ const auto match = pattern.match(m_hslHueInput->text());
+ if (match.hasMatch()) {
+ const auto substr = match.captured(1);
+ const qreal input = static_cast<qreal>(qBound(0, substr.toInt(), 360)) / static_cast<qreal>(360);
+ emit colorModified(QColor::fromHslF(input, hslSaturation(), lightness(), alpha()));
+ }
+}
+
+void QQuickColorInputs::handleHsvSaturationChanged()
+{
+ const QRegularExpression pattern(s_percentage_pattern);
+ const auto match = pattern.match(m_hsvSaturationInput->text());
+ if (match.hasMatch()) {
+ const auto substr = match.captured(1);
+ const qreal input = static_cast<qreal>(qBound(0, substr.toInt(), 100)) / static_cast<qreal>(100);
+ emit colorModified(QColor::fromHsvF(hue(), input, value(), alpha()));
+ }
+}
+
+void QQuickColorInputs::handleHslSaturationChanged()
+{
+ const QRegularExpression pattern(s_percentage_pattern);
+ const auto match = pattern.match(m_hslSaturationInput->text());
+ if (match.hasMatch()) {
+ const auto substr = match.captured(1);
+ const qreal input = static_cast<qreal>(qBound(0, substr.toInt(), 100)) / static_cast<qreal>(100);
+ emit colorModified(QColor::fromHslF(hue(), input, lightness(), alpha()));
+ }
+}
+
+void QQuickColorInputs::handleValueChanged()
+{
+ const QRegularExpression pattern(s_percentage_pattern);
+ const auto match = pattern.match(m_valueInput->text());
+ if (match.hasMatch()) {
+ const auto substr = match.captured(1);
+ const qreal input = static_cast<qreal>(qBound(0, substr.toInt(), 100)) / static_cast<qreal>(100);
+ emit colorModified(QColor::fromHsvF(hue(), hsvSaturation(), input, alpha()));
+ }
+}
+
+void QQuickColorInputs::handleLightnessChanged()
+{
+ const QRegularExpression pattern(s_percentage_pattern);
+ const auto match = pattern.match(m_lightnessInput->text());
+ if (match.hasMatch()) {
+ const auto substr = match.captured(1);
+ const qreal input = static_cast<qreal>(qBound(0, substr.toInt(), 100)) / static_cast<qreal>(100);
+ emit colorModified(QColor::fromHslF(hue(), hslSaturation(), input, alpha()));
+ }
+}
+
+void QQuickColorInputs::handleRgbAlphaChanged()
+{
+ handleAlphaChanged(m_rgbAlphaInput->text());
+}
+
+void QQuickColorInputs::handleHsvAlphaChanged()
+{
+ handleAlphaChanged(m_hsvAlphaInput->text());
+}
+
+void QQuickColorInputs::handleHslAlphaChanged()
+{
+ handleAlphaChanged(m_hslAlphaInput->text());
+}
+
+void QQuickColorInputs::handleAlphaChanged(const QString &input)
+{
+ const QRegularExpression pattern(s_percentage_pattern);
+ const auto match = pattern.match(input);
+ if (match.hasMatch()) {
+ QColor c = color();
+ const auto substr = match.captured(1);
+ const qreal input = static_cast<qreal>(qBound(0, substr.toInt(), 100)) / static_cast<qreal>(100);
+ c.setAlphaF(input);
+ emit colorModified(c);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickcolorinputs_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolorinputs_p.h
new file mode 100644
index 0000000000..4827627d6f
--- /dev/null
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickcolorinputs_p.h
@@ -0,0 +1,171 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQUICKCOLORINPUTS_P_H
+#define QQUICKCOLORINPUTS_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 <QtGui/qcolor.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuickTemplates2/private/qquickcombobox_p.h>
+#include <QtQuickTemplates2/private/qquicktextfield_p.h>
+
+#include "qtquickdialogs2quickimplglobal_p.h"
+
+#include "qquickcolordialogutils_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickColorInputs : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+ Q_PROPERTY(int red READ red NOTIFY colorChanged)
+ Q_PROPERTY(int green READ green NOTIFY colorChanged)
+ Q_PROPERTY(int blue READ blue NOTIFY colorChanged)
+ Q_PROPERTY(qreal hue READ hue NOTIFY colorChanged)
+ Q_PROPERTY(qreal hslSaturation READ hslSaturation NOTIFY colorChanged)
+ Q_PROPERTY(qreal hsvSaturation READ hsvSaturation NOTIFY colorChanged)
+ Q_PROPERTY(qreal value READ value NOTIFY colorChanged)
+ Q_PROPERTY(qreal lightness READ lightness NOTIFY colorChanged)
+ Q_PROPERTY(qreal alpha READ alpha NOTIFY colorChanged)
+ Q_PROPERTY(bool showAlpha READ showAlpha WRITE setShowAlpha NOTIFY showAlphaChanged)
+ Q_PROPERTY(QQuickTextInput *hexInput READ hexInput WRITE setHexInput NOTIFY hexInputChanged)
+ Q_PROPERTY(QQuickTextInput *redInput READ redInput WRITE setRedInput NOTIFY redInputChanged)
+ Q_PROPERTY(QQuickTextInput *greenInput READ greenInput WRITE setGreenInput NOTIFY greenInputChanged)
+ Q_PROPERTY(QQuickTextInput *blueInput READ blueInput WRITE setBlueInput NOTIFY blueInputChanged)
+ Q_PROPERTY(QQuickTextInput *hsvHueInput READ hsvHueInput WRITE setHsvHueInput NOTIFY hsvHueInputChanged)
+ Q_PROPERTY(QQuickTextInput *hslHueInput READ hslHueInput WRITE setHslHueInput NOTIFY hslHueInputChanged)
+ Q_PROPERTY(QQuickTextInput *hsvSaturationInput READ hsvSaturationInput WRITE setHsvSaturationInput NOTIFY hsvSaturationInputChanged)
+ Q_PROPERTY(QQuickTextInput *hslSaturationInput READ hslSaturationInput WRITE setHslSaturationInput NOTIFY hslSaturationInputChanged)
+ Q_PROPERTY(QQuickTextInput *valueInput READ valueInput WRITE setValueInput NOTIFY valueInputChanged)
+ Q_PROPERTY(QQuickTextInput *lightnessInput READ lightnessInput WRITE setLightnessInput NOTIFY lightnessInputChanged)
+ Q_PROPERTY(QQuickTextInput *rgbAlphaInput READ rgbAlphaInput WRITE setRgbAlphaInput NOTIFY rgbAlphaInputChanged)
+ Q_PROPERTY(QQuickTextInput *hsvAlphaInput READ hsvAlphaInput WRITE setHsvAlphaInput NOTIFY hsvAlphaInputChanged)
+ Q_PROPERTY(QQuickTextInput *hslAlphaInput READ hslAlphaInput WRITE setHslAlphaInput NOTIFY hslAlphaInputChanged)
+ QML_NAMED_ELEMENT(ColorInputsImpl)
+
+public:
+ explicit QQuickColorInputs();
+
+ QColor color() const;
+ void setColor(const QColor &c);
+ int red() const;
+ int green() const;
+ int blue() const;
+ qreal alpha() const;
+ qreal hue() const;
+ qreal hslSaturation() const;
+ qreal hsvSaturation() const;
+ qreal value() const;
+ qreal lightness() const;
+
+ bool showAlpha() const;
+ void setShowAlpha(bool showAlpha);
+
+ QQuickTextInput *hexInput() const;
+ void setHexInput(QQuickTextInput *hexInput);
+
+ QQuickTextInput *redInput() const;
+ void setRedInput(QQuickTextInput *redInput);
+
+ QQuickTextInput *greenInput() const;
+ void setGreenInput(QQuickTextInput *greenInput);
+
+ QQuickTextInput *blueInput() const;
+ void setBlueInput(QQuickTextInput *blueInput);
+
+ QQuickTextInput *hsvHueInput() const;
+ void setHsvHueInput(QQuickTextInput *hsvHueInput);
+
+ QQuickTextInput *hslHueInput() const;
+ void setHslHueInput(QQuickTextInput *hslHueInput);
+
+ QQuickTextInput *hsvSaturationInput() const;
+ void setHsvSaturationInput(QQuickTextInput *hsvSaturationInput);
+
+ QQuickTextInput *hslSaturationInput() const;
+ void setHslSaturationInput(QQuickTextInput *hslSaturationInput);
+
+ QQuickTextInput *valueInput() const;
+ void setValueInput(QQuickTextInput *valueInput);
+
+ QQuickTextInput *lightnessInput() const;
+ void setLightnessInput(QQuickTextInput *lightnessInput);
+
+ QQuickTextInput *rgbAlphaInput() const;
+ void setRgbAlphaInput(QQuickTextInput *alphaInput);
+
+ QQuickTextInput *hsvAlphaInput() const;
+ void setHsvAlphaInput(QQuickTextInput *alphaInput);
+
+ QQuickTextInput *hslAlphaInput() const;
+ void setHslAlphaInput(QQuickTextInput *alphaInput);
+
+Q_SIGNALS:
+ void colorChanged(const QColor &c);
+ void colorModified(const QColor &c);
+ void hslChanged();
+ void showAlphaChanged(bool);
+ void hexInputChanged();
+ void redInputChanged();
+ void greenInputChanged();
+ void blueInputChanged();
+ void hsvHueInputChanged();
+ void hslHueInputChanged();
+ void hsvSaturationInputChanged();
+ void hslSaturationInputChanged();
+ void valueInputChanged();
+ void lightnessInputChanged();
+ void rgbAlphaInputChanged();
+ void hsvAlphaInputChanged();
+ void hslAlphaInputChanged();
+
+private:
+ void handleHexChanged();
+ void handleRedChanged();
+ void handleGreenChanged();
+ void handleBlueChanged();
+ void handleHsvHueChanged();
+ void handleHslHueChanged();
+ void handleHueChanged(const QString &input);
+ void handleHsvSaturationChanged();
+ void handleHslSaturationChanged();
+ void handleSaturationChanged(const QString &input);
+ void handleValueChanged();
+ void handleLightnessChanged();
+ void handleRgbAlphaChanged();
+ void handleHsvAlphaChanged();
+ void handleHslAlphaChanged();
+ void handleAlphaChanged(const QString &input);
+
+ QPointer<QQuickTextInput> m_hexInput;
+ QPointer<QQuickTextInput> m_redInput;
+ QPointer<QQuickTextInput> m_greenInput;
+ QPointer<QQuickTextInput> m_blueInput;
+ QPointer<QQuickTextInput> m_hsvHueInput;
+ QPointer<QQuickTextInput> m_hslHueInput;
+ QPointer<QQuickTextInput> m_hsvSaturationInput;
+ QPointer<QQuickTextInput> m_hslSaturationInput;
+ QPointer<QQuickTextInput> m_valueInput;
+ QPointer<QQuickTextInput> m_lightnessInput;
+ QPointer<QQuickTextInput> m_rgbAlphaInput;
+ QPointer<QQuickTextInput> m_hsvAlphaInput;
+ QPointer<QQuickTextInput> m_hslAlphaInput;
+ HSVA m_hsva;
+ bool m_showAlpha = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKCOLORINPUTS_P_H
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp
index 72c4ca8336..a490ba1ebc 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp
@@ -366,6 +366,12 @@ void QQuickFileDialogImpl::setOptions(const QSharedPointer<QFileDialogOptions> &
if (d->options) {
d->selectedNameFilter->setOptions(options);
d->setNameFilters(options->nameFilters());
+
+ if (auto attached = d->attachedOrWarn()) {
+ const bool isSaveMode = d->options->fileMode() == QFileDialogOptions::AnyFile;
+ attached->fileNameLabel()->setVisible(isSaveMode);
+ attached->fileNameTextField()->setVisible(isSaveMode);
+ }
}
}
@@ -451,6 +457,19 @@ void QQuickFileDialogImpl::selectNameFilter(const QString &filter)
emit filterSelected(filter);
}
+QString QQuickFileDialogImpl::fileName() const
+{
+ return selectedFile().fileName();
+}
+void QQuickFileDialogImpl::setFileName(const QString &fileName)
+{
+ const QString previous = selectedFile().fileName();
+ if (previous == fileName)
+ return;
+
+ setSelectedFile(QUrl(currentFolder().path() + u'/' + fileName));
+}
+
void QQuickFileDialogImpl::componentComplete()
{
Q_D(QQuickFileDialogImpl);
@@ -554,6 +573,15 @@ void QQuickFileDialogImplAttachedPrivate::fileDialogListViewCurrentIndexChanged(
}
}
+void QQuickFileDialogImplAttachedPrivate::fileNameChangedByUser()
+{
+ auto fileDialogImpl = qobject_cast<QQuickFileDialogImpl *>(parent);
+ if (!fileDialogImpl)
+ return;
+
+ fileDialogImpl->setFileName(fileNameTextField->text());
+}
+
QQuickFileDialogImplAttached::QQuickFileDialogImplAttached(QObject *parent)
: QObject(*(new QQuickFileDialogImplAttachedPrivate), parent)
{
@@ -683,6 +711,48 @@ void QQuickFileDialogImplAttached::setBreadcrumbBar(QQuickFolderBreadcrumbBar *b
emit breadcrumbBarChanged();
}
+QQuickLabel *QQuickFileDialogImplAttached::fileNameLabel() const
+{
+ Q_D(const QQuickFileDialogImplAttached);
+ return d->fileNameLabel;
+}
+
+void QQuickFileDialogImplAttached::setFileNameLabel(QQuickLabel *fileNameLabel)
+{
+ Q_D(QQuickFileDialogImplAttached);
+ if (fileNameLabel == d->fileNameLabel)
+ return;
+
+ d->fileNameLabel = fileNameLabel;
+
+ emit fileNameLabelChanged();
+}
+
+QQuickTextField *QQuickFileDialogImplAttached::fileNameTextField() const
+{
+ Q_D(const QQuickFileDialogImplAttached);
+ return d->fileNameTextField;
+}
+
+void QQuickFileDialogImplAttached::setFileNameTextField(QQuickTextField *fileNameTextField)
+{
+ Q_D(QQuickFileDialogImplAttached);
+ if (fileNameTextField == d->fileNameTextField)
+ return;
+
+ if (d->fileNameTextField)
+ QObjectPrivate::disconnect(d->fileNameTextField, &QQuickTextField::editingFinished,
+ d, &QQuickFileDialogImplAttachedPrivate::fileNameChangedByUser);
+
+ d->fileNameTextField = fileNameTextField;
+
+ if (d->fileNameTextField)
+ QObjectPrivate::connect(d->fileNameTextField, &QQuickTextField::editingFinished,
+ d, &QQuickFileDialogImplAttachedPrivate::fileNameChangedByUser);
+
+ emit fileNameTextFieldChanged();
+}
+
QT_END_NAMESPACE
#include "moc_qquickfiledialogimpl_p.cpp"
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h
index dca4450de1..4c64c5e4dd 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h
@@ -24,6 +24,8 @@ QT_BEGIN_NAMESPACE
class QQuickComboBox;
class QQuickDialogButtonBox;
+class QQuickTextField;
+class QQuickLabel;
class QQuickFileDialogImplAttached;
class QQuickFileDialogImplAttachedPrivate;
@@ -38,6 +40,7 @@ class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFileDialogImpl : public QQui
Q_PROPERTY(QUrl selectedFile READ selectedFile WRITE setSelectedFile NOTIFY selectedFileChanged FINAL)
Q_PROPERTY(QStringList nameFilters READ nameFilters NOTIFY nameFiltersChanged FINAL)
Q_PROPERTY(QQuickFileNameFilter *selectedNameFilter READ selectedNameFilter CONSTANT)
+ Q_PROPERTY(QString fileName READ fileName WRITE setFileName NOTIFY selectedFileChanged FINAL)
QML_NAMED_ELEMENT(FileDialogImpl)
QML_ATTACHED(QQuickFileDialogImplAttached)
QML_ADDED_IN_VERSION(6, 2)
@@ -74,6 +77,9 @@ public:
void setAcceptLabel(const QString &label);
void setRejectLabel(const QString &label);
+ QString fileName() const;
+ void setFileName(const QString &fileName);
+
public Q_SLOTS:
void selectNameFilter(const QString &filter);
@@ -99,8 +105,12 @@ class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFileDialogImplAttached : pub
Q_PROPERTY(QQuickComboBox *nameFiltersComboBox READ nameFiltersComboBox WRITE setNameFiltersComboBox NOTIFY nameFiltersComboBoxChanged)
Q_PROPERTY(QQuickListView *fileDialogListView READ fileDialogListView WRITE setFileDialogListView NOTIFY fileDialogListViewChanged)
Q_PROPERTY(QQuickFolderBreadcrumbBar *breadcrumbBar READ breadcrumbBar WRITE setBreadcrumbBar NOTIFY breadcrumbBarChanged)
+ Q_PROPERTY(QQuickLabel *fileNameLabel READ fileNameLabel WRITE setFileNameLabel NOTIFY fileNameLabelChanged FINAL)
+ Q_PROPERTY(QQuickTextField *fileNameTextField READ fileNameTextField WRITE setFileNameTextField NOTIFY fileNameTextFieldChanged FINAL)
Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquickdialogbuttonbox_p.h>)
Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquickcombobox_p.h>)
+ Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquicktextfield_p.h>)
+ Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquicklabel_p.h>)
public:
explicit QQuickFileDialogImplAttached(QObject *parent = nullptr);
@@ -120,11 +130,19 @@ public:
QQuickFolderBreadcrumbBar *breadcrumbBar() const;
void setBreadcrumbBar(QQuickFolderBreadcrumbBar *breadcrumbBar);
+ QQuickLabel *fileNameLabel() const;
+ void setFileNameLabel(QQuickLabel *fileNameLabel);
+
+ QQuickTextField *fileNameTextField() const;
+ void setFileNameTextField(QQuickTextField *fileNameTextField);
+
Q_SIGNALS:
void buttonBoxChanged();
void nameFiltersComboBoxChanged();
void fileDialogListViewChanged();
void breadcrumbBarChanged();
+ void fileNameLabelChanged();
+ void fileNameTextFieldChanged();
private:
Q_DISABLE_COPY(QQuickFileDialogImplAttached)
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h
index 82bef2e8ba..6f3cc55e86 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h
@@ -18,6 +18,8 @@
#include <QtQuickTemplates2/private/qquickcombobox_p.h>
#include <QtQuickTemplates2/private/qquickdialog_p_p.h>
#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h>
+#include <QtQuickTemplates2/private/qquicklabel_p.h>
+#include <QtQuickTemplates2/private/qquicktextfield_p.h>
#include "qquickfiledialogimpl_p.h"
@@ -68,6 +70,7 @@ class QQuickFileDialogImplAttachedPrivate : public QObjectPrivate
{
void nameFiltersComboBoxItemActivated(int index);
void fileDialogListViewCurrentIndexChanged();
+ void fileNameChangedByUser();
public:
Q_DECLARE_PUBLIC(QQuickFileDialogImplAttached)
@@ -76,6 +79,8 @@ public:
QPointer<QQuickComboBox> nameFiltersComboBox;
QPointer<QQuickListView> fileDialogListView;
QPointer<QQuickFolderBreadcrumbBar> breadcrumbBar;
+ QPointer<QQuickLabel> fileNameLabel;
+ QPointer<QQuickTextField> fileNameTextField;
};
QT_END_NAMESPACE
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp
index 8fb117b167..a78833f470 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp
@@ -35,13 +35,19 @@ QQuickItem *QQuickFolderBreadcrumbBarPrivate::createDelegateItem(QQmlComponent *
Q_Q(QQuickFolderBreadcrumbBar);
// If we don't use the correct context, it won't be possible to refer to
// the control's id from within the delegates.
- QQmlContext *creationContext = component->creationContext();
+ QQmlContext *context = component->creationContext();
// The component might not have been created in QML, in which case
// the creation context will be null and we have to create it ourselves.
- if (!creationContext)
- creationContext = qmlContext(q);
- QQmlContext *context = new QQmlContext(creationContext, q);
- context->setContextObject(q);
+ if (!context)
+ context = qmlContext(q);
+
+ // If we have initial properties we assume that all necessary information is passed via
+ // initial properties.
+ if (!component->isBound() && initialProperties.isEmpty()) {
+ context = new QQmlContext(context, q);
+ context->setContextObject(q);
+ }
+
QQuickItem *item = qobject_cast<QQuickItem*>(component->createWithInitialProperties(initialProperties, context));
if (item)
QQml_setParent_noEvent(item, q);
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp
index 1f5f060620..5dcde5a81e 100644
--- a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp
+++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp
@@ -532,7 +532,7 @@ static int findStyleInModel(const QString &selectedStyle, const QStringList &mod
auto styleClass = classifyStyleFallback(selectedStyle);
if (styleClass != StyleClass::Unknown)
- for (int i = 0; i < model.count(); ++i)
+ for (int i = 0; i < model.size(); ++i)
if (classifyStyleFallback(model.at(i)) == styleClass)
return i;
}
@@ -707,7 +707,7 @@ void QQuickFontDialogImplAttached::searchListView(const QString &s, QQuickListVi
do {
m_search.append(s);
- for (int i = 0; i < model.count(); ++i) {
+ for (int i = 0; i < model.size(); ++i) {
if (model.at(i).startsWith(m_search, Qt::CaseInsensitive)) {
listView->setCurrentIndex(i);
return;
@@ -774,7 +774,7 @@ void QQuickFontDialogImplAttached::_q_sizeEdited()
auto model = sizeListView()->model().toStringList();
int i;
- for (i = 0; i < model.count() - 1; ++i) {
+ for (i = 0; i < model.size() - 1; ++i) {
if (model.at(i).toInt() >= size)
break;
}
diff --git a/src/quicklayouts/qquickgridlayoutengine.cpp b/src/quicklayouts/qquickgridlayoutengine.cpp
index 9b4d877127..daec5151dc 100644
--- a/src/quicklayouts/qquickgridlayoutengine.cpp
+++ b/src/quicklayouts/qquickgridlayoutengine.cpp
@@ -15,11 +15,4 @@ void QQuickGridLayoutEngine::setAlignment(QQuickItem *quickItem, Qt::Alignment a
}
}
-Qt::Alignment QQuickGridLayoutEngine::alignment(QQuickItem *quickItem) const
-{
- if (QGridLayoutItem *item = findLayoutItem(quickItem))
- return item->alignment();
- return {};
-}
-
QT_END_NAMESPACE
diff --git a/src/quicklayouts/qquickgridlayoutengine_p.h b/src/quicklayouts/qquickgridlayoutengine_p.h
index 0fb503d5cc..412e56b29a 100644
--- a/src/quicklayouts/qquickgridlayoutengine_p.h
+++ b/src/quicklayouts/qquickgridlayoutengine_p.h
@@ -109,7 +109,7 @@ public:
QQuickGridLayoutItem *findLayoutItem(QQuickItem *layoutItem) const
{
- for (int i = q_items.count() - 1; i >= 0; --i) {
+ for (int i = q_items.size() - 1; i >= 0; --i) {
QQuickGridLayoutItem *item = static_cast<QQuickGridLayoutItem*>(q_items.at(i));
if (item->layoutItem() == layoutItem)
return item;
@@ -118,7 +118,6 @@ public:
}
void setAlignment(QQuickItem *quickItem, Qt::Alignment alignment);
- Qt::Alignment alignment(QQuickItem *quickItem) const;
};
diff --git a/src/quicklayouts/qquicklayout.cpp b/src/quicklayouts/qquicklayout.cpp
index 7d99c0c37e..74167db3e7 100644
--- a/src/quicklayouts/qquicklayout.cpp
+++ b/src/quicklayouts/qquicklayout.cpp
@@ -730,6 +730,18 @@ void QQuickLayout::componentComplete()
d->m_isReady = true;
}
+void QQuickLayout::maybeSubscribeToBaseLineOffsetChanges(QQuickItem *item)
+{
+ QQuickLayoutAttached *info = attachedLayoutObject(item, false);
+ if (info) {
+ if (info->alignment() == Qt::AlignBaseline && static_cast<QQuickLayout*>(item->parentItem()) == this) {
+ qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem()));
+ } else {
+ qmlobject_disconnect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem()));
+ }
+ }
+}
+
void QQuickLayout::invalidate(QQuickItem * /*childItem*/)
{
Q_D(QQuickLayout);
@@ -811,7 +823,7 @@ void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value)
if (change == ItemChildAddedChange) {
Q_D(QQuickLayout);
QQuickItem *item = value.item;
- qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem()));
+ maybeSubscribeToBaseLineOffsetChanges(item);
QQuickItemPrivate::get(item)->addItemChangeListener(this, changeTypes);
d->m_hasItemChangeListeners = true;
qCDebug(lcQuickLayouts) << "ChildAdded" << item;
@@ -819,7 +831,7 @@ void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value)
invalidate();
} else if (change == ItemChildRemovedChange) {
QQuickItem *item = value.item;
- qmlobject_disconnect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem()));
+ maybeSubscribeToBaseLineOffsetChanges(item);
QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes);
qCDebug(lcQuickLayouts) << "ChildRemoved" << item;
if (isReady())
diff --git a/src/quicklayouts/qquicklayout_p.h b/src/quicklayouts/qquicklayout_p.h
index 6c72e31216..40ee74614a 100644
--- a/src/quicklayouts/qquicklayout_p.h
+++ b/src/quicklayouts/qquicklayout_p.h
@@ -95,6 +95,8 @@ public:
void itemDestroyed(QQuickItem *item) override;
void itemVisibilityChanged(QQuickItem *item) override;
+ void maybeSubscribeToBaseLineOffsetChanges(QQuickItem *item);
+
Q_INVOKABLE void _q_dumpLayoutTree() const;
void dumpLayoutTreeRecursive(int level, QString &buf) const;
@@ -149,7 +151,6 @@ protected:
unsigned m_isReady : 1;
unsigned m_disableRearrange : 1;
unsigned m_hasItemChangeListeners : 1; // if false, we don't need to remove its item change listeners...
- mutable QSet<QQuickItem *> m_ignoredItems;
};
diff --git a/src/quicklayouts/qquicklinearlayout.cpp b/src/quicklayouts/qquicklinearlayout.cpp
index 1ca3499bd9..8cb3ecfcf1 100644
--- a/src/quicklayouts/qquicklinearlayout.cpp
+++ b/src/quicklayouts/qquicklinearlayout.cpp
@@ -281,6 +281,7 @@ void QQuickGridLayoutBase::setAlignment(QQuickItem *item, Qt::Alignment alignmen
{
Q_D(QQuickGridLayoutBase);
d->engine.setAlignment(item, alignment);
+ maybeSubscribeToBaseLineOffsetChanges(item);
}
QQuickGridLayoutBase::~QQuickGridLayoutBase()
@@ -470,7 +471,7 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size)
d->engine.setGeometries(QRectF(QPointF(0,0), size), d->styleInfo);
d->m_rearranging = false;
- for (QQuickItem *invalid : qAsConst(d->m_invalidateAfterRearrange))
+ for (QQuickItem *invalid : std::as_const(d->m_invalidateAfterRearrange))
invalidate(invalid);
d->m_invalidateAfterRearrange.clear();
}
diff --git a/src/quicklayouts/qquicklinearlayout_p.h b/src/quicklayouts/qquicklinearlayout_p.h
index 26810d5684..15ce953ead 100644
--- a/src/quicklayouts/qquicklinearlayout_p.h
+++ b/src/quicklayouts/qquicklinearlayout_p.h
@@ -169,7 +169,7 @@ public:
**
**/
class QQuickLinearLayoutPrivate;
-class QQuickLinearLayout : public QQuickGridLayoutBase
+class Q_QUICKLAYOUTS_PRIVATE_EXPORT QQuickLinearLayout : public QQuickGridLayoutBase
{
Q_OBJECT
Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
diff --git a/src/quicklayouts/qquickstacklayout.cpp b/src/quicklayouts/qquickstacklayout.cpp
index 1e6ba4d27d..2b06473154 100644
--- a/src/quicklayouts/qquickstacklayout.cpp
+++ b/src/quicklayouts/qquickstacklayout.cpp
@@ -168,6 +168,7 @@ void QQuickStackLayout::itemChange(QQuickItem::ItemChange change, const QQuickIt
stackLayoutAttached->setIndex(-1);
stackLayoutAttached->setIsCurrentItem(false);
}
+ m_cachedItemSizeHints.remove(item);
childItemsChanged();
invalidate();
} else if (change == ItemChildAddedChange) {
@@ -190,10 +191,8 @@ QSizeF QQuickStackLayout::sizeHint(Qt::SizeHint whichSizeHint) const
maxS = QSizeF(std::numeric_limits<qreal>::infinity(), std::numeric_limits<qreal>::infinity());
const int count = itemCount();
- m_cachedItemSizeHints.resize(count);
for (int i = 0; i < count; ++i) {
- SizeHints &hints = m_cachedItemSizeHints[i];
- QQuickStackLayout::collectItemSizeHints(itemAt(i), hints.array);
+ SizeHints &hints = cachedItemSizeHints(i);
minS = minS.expandedTo(hints.min());
prefS = prefS.expandedTo(hints.pref());
//maxS = maxS.boundedTo(hints.max()); // Can be resized to be larger than any of its items.
@@ -258,11 +257,11 @@ void QQuickStackLayout::setAlignment(QQuickItem * /*item*/, Qt::Alignment /*alig
void QQuickStackLayout::invalidate(QQuickItem *childItem)
{
- const int indexOfChild = indexOf(childItem);
- if (indexOfChild >= 0 && indexOfChild < m_cachedItemSizeHints.count()) {
- m_cachedItemSizeHints[indexOfChild].min() = QSizeF();
- m_cachedItemSizeHints[indexOfChild].pref() = QSizeF();
- m_cachedItemSizeHints[indexOfChild].max() = QSizeF();
+ if (childItem) {
+ SizeHints &hints = m_cachedItemSizeHints[childItem];
+ hints.min() = QSizeF();
+ hints.pref() = QSizeF();
+ hints.max() = QSizeF();
}
for (int i = 0; i < Qt::NSizeHints; ++i)
@@ -276,7 +275,6 @@ void QQuickStackLayout::invalidate(QQuickItem *childItem)
void QQuickStackLayout::childItemsChanged()
{
Q_D(QQuickStackLayout);
- d->m_ignoredItems.clear();
const int count = itemCount();
const int oldIndex = d->currentIndex;
if (!d->explicitCurrentIndex)
@@ -303,6 +301,17 @@ void QQuickStackLayout::childItemsChanged()
}
}
+QQuickStackLayout::SizeHints &QQuickStackLayout::cachedItemSizeHints(int index) const
+{
+ QQuickItem *item = itemAt(index);
+ Q_ASSERT(item);
+ SizeHints &hints = m_cachedItemSizeHints[item]; // will create an entry if it doesn't exist
+ if (!hints.min().isValid())
+ QQuickStackLayout::collectItemSizeHints(item, hints.array);
+ return hints;
+}
+
+
void QQuickStackLayout::rearrange(const QSizeF &newSize)
{
Q_D(QQuickStackLayout);
@@ -311,9 +320,9 @@ void QQuickStackLayout::rearrange(const QSizeF &newSize)
qCDebug(lcQuickLayouts) << "QQuickStackLayout::rearrange";
- if (d->currentIndex == -1 || d->currentIndex >= m_cachedItemSizeHints.count())
+ if (d->currentIndex == -1 || d->currentIndex >= m_cachedItemSizeHints.size())
return;
- QQuickStackLayout::SizeHints &hints = m_cachedItemSizeHints[d->currentIndex];
+ QQuickStackLayout::SizeHints &hints = cachedItemSizeHints(d->currentIndex);
QQuickItem *item = itemAt(d->currentIndex);
Q_ASSERT(item);
item->setPosition(QPointF(0,0)); // ### respect alignment?
@@ -346,10 +355,7 @@ void QQuickStackLayout::collectItemSizeHints(QQuickItem *item, QSizeF *sizeHints
bool QQuickStackLayout::shouldIgnoreItem(QQuickItem *item) const
{
- const bool ignored = QQuickItemPrivate::get(item)->isTransparentForPositioner();
- if (ignored)
- d_func()->m_ignoredItems << item;
- return ignored;
+ return QQuickItemPrivate::get(item)->isTransparentForPositioner();
}
QQuickStackLayoutAttached::QQuickStackLayoutAttached(QObject *object)
@@ -377,6 +383,11 @@ QQuickStackLayoutAttached::QQuickStackLayoutAttached(QObject *object)
setLayout(stackLayout);
setIndex(index);
setIsCurrentItem(stackLayout->currentIndex() == index);
+
+ // In case of lazy loading in loader, attachedProperties are created and updated for the
+ // object after adding the child object to the stack layout, which leads to entries with
+ // same index. Triggering childItemsChanged() resets to right index in the stack layout.
+ stackLayout->childItemsChanged();
}
/*!
diff --git a/src/quicklayouts/qquickstacklayout_p.h b/src/quicklayouts/qquickstacklayout_p.h
index c7c174450e..a27f7f6f7a 100644
--- a/src/quicklayouts/qquickstacklayout_p.h
+++ b/src/quicklayouts/qquickstacklayout_p.h
@@ -74,8 +74,9 @@ private:
QSizeF array[Qt::NSizeHints];
};
- mutable QVector<SizeHints> m_cachedItemSizeHints;
+ mutable QHash<QQuickItem*, SizeHints> m_cachedItemSizeHints;
mutable QSizeF m_cachedSizeHints[Qt::NSizeHints];
+ SizeHints &cachedItemSizeHints(int index) const;
};
class QQuickStackLayoutPrivate : public QQuickLayoutPrivate
diff --git a/src/quicknativestyle/controls/DefaultTreeViewDelegate.qml b/src/quicknativestyle/controls/DefaultTreeViewDelegate.qml
index a55e56d911..57e51d9639 100644
--- a/src/quicknativestyle/controls/DefaultTreeViewDelegate.qml
+++ b/src/quicknativestyle/controls/DefaultTreeViewDelegate.qml
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 The Qt Company Lt.
+// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
diff --git a/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm b/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm
index 43983b9fd9..eb777ea9f2 100644
--- a/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm
+++ b/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm
@@ -361,7 +361,11 @@ static bool setupSlider(NSSlider *slider, const QStyleOptionSlider *sl)
if (sl->minimum >= sl->maximum)
return false;
- slider.frame = sl->rect.toCGRect();
+ // NSSlider seems to cache values based on tracking and the last layout of the
+ // NSView, resulting in incorrect knob rects that break the interaction with
+ // multiple sliders. So completely reinitialize the slider.
+ [slider initWithFrame:sl->rect.toCGRect()];
+
slider.minValue = sl->minimum;
slider.maxValue = sl->maximum;
slider.intValue = sl->sliderPosition;
@@ -391,6 +395,14 @@ static bool setupSlider(NSSlider *slider, const QStyleOptionSlider *sl)
// the cell for its metrics and to draw itself.
[slider layoutSubtreeIfNeeded];
+ if (sl->state & QStyle::State_Sunken) {
+ const CGRect knobRect = [slider.cell knobRectFlipped:slider.isFlipped];
+ CGPoint pressPoint;
+ pressPoint.x = CGRectGetMidX(knobRect);
+ pressPoint.y = CGRectGetMidY(knobRect);
+ [slider.cell startTrackingAt:pressPoint inView:slider];
+ }
+
return true;
}
@@ -2759,7 +2771,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
[triangleCell setState:(opt->state & State_Open) ? NSControlStateValueOn : NSControlStateValueOff];
// bool viewHasFocus = (w && w->hasFocus()) || (opt->state & State_HasFocus);
bool viewHasFocus = false;
- [triangleCell setBackgroundStyle:((opt->state & State_Selected) && viewHasFocus) ? NSBackgroundStyleDark : NSBackgroundStyleLight];
+ [triangleCell setBackgroundStyle:((opt->state & State_Selected) && viewHasFocus) ? NSBackgroundStyleEmphasized : NSBackgroundStyleNormal];
d->setupNSGraphicsContext(cg, NO);
diff --git a/src/quicknativestyle/qstyle/qquickcommonstyle.cpp b/src/quicknativestyle/qstyle/qquickcommonstyle.cpp
index 5c54a3bc1e..d8cac57486 100644
--- a/src/quicknativestyle/qstyle/qquickcommonstyle.cpp
+++ b/src/quicknativestyle/qstyle/qquickcommonstyle.cpp
@@ -4475,12 +4475,13 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt) const
QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &csz) const
{
Q_D(const QCommonStyle);
- QSize sz(csz);
+ QSize sz(!csz.isEmpty() ? csz : QSize(0,0));
+
switch (ct) {
case CT_PushButton:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- int w = csz.width(),
- h = csz.height(),
+ int w = sz.width(),
+ h = sz.height(),
bm = proxy()->pixelMetric(PM_ButtonMargin, btn),
fw = proxy()->pixelMetric(PM_DefaultFrameWidth, btn) * 2;
w += bm + fw;
diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp
index f19c4e637b..6ec5c566d0 100644
--- a/src/quickshapes/qquickshape.cpp
+++ b/src/quickshapes/qquickshape.cpp
@@ -903,7 +903,7 @@ void QQuickShape::itemChange(ItemChange change, const ItemChangeData &data)
if (change == ItemVisibleHasChanged && data.boolValue)
d->_q_shapePathChanged();
else if (change == QQuickItem::ItemSceneChange) {
- for (int i = 0; i < d->sp.count(); ++i)
+ for (int i = 0; i < d->sp.size(); ++i)
QQuickShapePathPrivate::get(d->sp[i])->dirty = QQuickShapePathPrivate::DirtyAll;
d->_q_shapePathChanged();
}
@@ -1002,7 +1002,7 @@ void QQuickShapePrivate::sync()
renderer->setAsyncCallback(asyncShapeReady, this);
}
- const int count = sp.count();
+ const int count = sp.size();
bool countChanged = false;
renderer->beginSync(count, &countChanged);
@@ -1440,6 +1440,7 @@ static void generateGradientColorTable(const QQuickShapeGradientCacheKey &gradie
{
int pos = 0;
const QGradientStops &s = gradient.stops;
+ Q_ASSERT(!s.isEmpty());
const bool colorInterpolation = true;
uint alpha = qRound(opacity * 256);
@@ -1477,8 +1478,6 @@ static void generateGradientColorTable(const QQuickShapeGradientCacheKey &gradie
current_color = next_color;
}
- Q_ASSERT(s.size() > 0);
-
uint last_color = ARGB2RGBA(qPremultiply(ARGB_COMBINE_ALPHA(s[sLast].second.rgba(), alpha)));
for ( ; pos < size; ++pos)
colorTable[pos] = last_color;
@@ -1513,7 +1512,10 @@ QSGTexture *QQuickShapeGradientCache::get(const QQuickShapeGradientCacheKey &gra
if (!tx) {
static const int W = 1024; // texture size is 1024x1
QImage gradTab(W, 1, QImage::Format_RGBA8888_Premultiplied);
- generateGradientColorTable(grad, reinterpret_cast<uint *>(gradTab.bits()), W, 1.0f);
+ if (!grad.stops.isEmpty())
+ generateGradientColorTable(grad, reinterpret_cast<uint *>(gradTab.bits()), W, 1.0f);
+ else
+ gradTab.fill(Qt::black);
tx = new QSGPlainTexture;
tx->setImage(gradTab);
switch (grad.spread) {
diff --git a/src/quickshapes/qquickshape_p_p.h b/src/quickshapes/qquickshape_p_p.h
index 593a5d8d73..20bc07da0f 100644
--- a/src/quickshapes/qquickshape_p_p.h
+++ b/src/quickshapes/qquickshape_p_p.h
@@ -167,7 +167,7 @@ struct QQuickShapeGradientCacheKey
inline size_t qHash(const QQuickShapeGradientCacheKey &v, size_t seed = 0)
{
size_t h = seed + v.spread;
- for (int i = 0; i < 3 && i < v.stops.count(); ++i)
+ for (int i = 0; i < 3 && i < v.stops.size(); ++i)
h += v.stops[i].second.rgba();
return h;
}
diff --git a/src/quickshapes/qquickshapegenericrenderer.cpp b/src/quickshapes/qquickshapegenericrenderer.cpp
index 470e5e9641..4fabcd1056 100644
--- a/src/quickshapes/qquickshapegenericrenderer.cpp
+++ b/src/quickshapes/qquickshapegenericrenderer.cpp
@@ -90,7 +90,7 @@ QQuickShapeGenericRenderer::~QQuickShapeGenericRenderer()
void QQuickShapeGenericRenderer::beginSync(int totalCount, bool *countChanged)
{
- if (m_sp.count() != totalCount) {
+ if (m_sp.size() != totalCount) {
m_sp.resize(totalCount);
m_accDirty |= DirtyList;
*countChanged = true;
@@ -111,8 +111,12 @@ void QQuickShapeGenericRenderer::setPath(int index, const QQuickPath *path)
void QQuickShapeGenericRenderer::setStrokeColor(int index, const QColor &color)
{
ShapePathData &d(m_sp[index]);
+ const bool wasTransparent = d.strokeColor.a == 0;
d.strokeColor = colorToColor4ub(color);
+ const bool isTransparent = d.strokeColor.a == 0;
d.syncDirty |= DirtyColor;
+ if (wasTransparent && !isTransparent)
+ d.syncDirty |= DirtyStrokeGeom;
}
void QQuickShapeGenericRenderer::setStrokeWidth(int index, qreal w)
@@ -236,7 +240,7 @@ void QQuickShapeGenericRenderer::endSync(bool async)
bool didKickOffAsync = false;
- for (int i = 0; i < m_sp.count(); ++i) {
+ for (int i = 0; i < m_sp.size(); ++i) {
ShapePathData &d(m_sp[i]);
if (!d.syncDirty)
continue;
@@ -291,7 +295,7 @@ void QQuickShapeGenericRenderer::endSync(bool async)
QObject::connect(r, &QQuickShapeFillRunnable::done, qApp, [this, i](QQuickShapeFillRunnable *r) {
// Bail out when orphaned (meaning either another run was
// started after this one, or the renderer got destroyed).
- if (!r->orphaned && i < m_sp.count()) {
+ if (!r->orphaned && i < m_sp.size()) {
ShapePathData &d(m_sp[i]);
d.fillVertices = r->fillVertices;
d.fillIndices = r->fillIndices;
@@ -326,7 +330,7 @@ void QQuickShapeGenericRenderer::endSync(bool async)
r->strokeColor = d.strokeColor;
r->clipSize = QSize(m_item->width(), m_item->height());
QObject::connect(r, &QQuickShapeStrokeRunnable::done, qApp, [this, i](QQuickShapeStrokeRunnable *r) {
- if (!r->orphaned && i < m_sp.count()) {
+ if (!r->orphaned && i < m_sp.size()) {
ShapePathData &d(m_sp[i]);
d.strokeVertices = r->strokeVertices;
d.pendingStroke = nullptr;
@@ -355,7 +359,7 @@ void QQuickShapeGenericRenderer::endSync(bool async)
void QQuickShapeGenericRenderer::maybeUpdateAsyncItem()
{
- for (const ShapePathData &d : qAsConst(m_sp)) {
+ for (const ShapePathData &d : std::as_const(m_sp)) {
if (d.pendingFill || d.pendingStroke)
return;
}
@@ -377,7 +381,7 @@ void QQuickShapeGenericRenderer::triangulateFill(const QPainterPath &path,
const QVectorPath &vp = qtVectorPathForPath(path);
QTriangleSet ts = qTriangulate(vp, QTransform::fromScale(TRI_SCALE, TRI_SCALE), 1, supportsElementIndexUint);
- const int vertexCount = ts.vertices.count() / 2; // just a qreal vector with x,y hence the / 2
+ const int vertexCount = ts.vertices.size() / 2; // just a qreal vector with x,y hence the / 2
fillVertices->resize(vertexCount);
ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(fillVertices->data());
const qreal *vsrc = ts.vertices.constData();
@@ -588,13 +592,13 @@ void QQuickShapeGenericRenderer::updateFillNode(ShapePathData *d, QQuickShapeGen
}
const int indexCount = d->indexType == QSGGeometry::UnsignedShortType
- ? d->fillIndices.count() * 2 : d->fillIndices.count();
+ ? d->fillIndices.size() * 2 : d->fillIndices.size();
if (g->indexType() != d->indexType) {
g = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(),
- d->fillVertices.count(), indexCount, d->indexType);
+ d->fillVertices.size(), indexCount, d->indexType);
n->setGeometry(g);
} else {
- g->allocate(d->fillVertices.count(), indexCount);
+ g->allocate(d->fillVertices.size(), indexCount);
}
g->setDrawingMode(QSGGeometry::DrawTriangles);
memcpy(g->vertexData(), d->fillVertices.constData(), g->vertexCount() * g->sizeOfVertex());
@@ -635,7 +639,7 @@ void QQuickShapeGenericRenderer::updateStrokeNode(ShapePathData *d, QQuickShapeG
return;
}
- g->allocate(d->strokeVertices.count(), 0);
+ g->allocate(d->strokeVertices.size(), 0);
g->setDrawingMode(QSGGeometry::DrawTriangleStrip);
memcpy(g->vertexData(), d->strokeVertices.constData(), g->vertexCount() * g->sizeOfVertex());
}
@@ -778,10 +782,10 @@ int QQuickShapeLinearGradientMaterial::compare(const QSGMaterial *other) const
if (int d = ga->b.y() - gb->b.y())
return d;
- if (int d = ga->stops.count() - gb->stops.count())
+ if (int d = ga->stops.size() - gb->stops.size())
return d;
- for (int i = 0; i < ga->stops.count(); ++i) {
+ for (int i = 0; i < ga->stops.size(); ++i) {
if (int d = ga->stops[i].first - gb->stops[i].first)
return d;
if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
@@ -807,7 +811,7 @@ bool QQuickShapeRadialGradientRhiShader::updateUniformData(RenderState &state,
QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
{
Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type());
- QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial);
+ QQuickShapeRadialGradientMaterial *m = static_cast<QQuickShapeRadialGradientMaterial *>(newMaterial);
bool changed = false;
QByteArray *buf = state.uniformData();
Q_ASSERT(buf->size() >= 92);
@@ -867,7 +871,7 @@ void QQuickShapeRadialGradientRhiShader::updateSampledImage(RenderState &state,
if (binding != 1)
return;
- QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial);
+ QQuickShapeRadialGradientMaterial *m = static_cast<QQuickShapeRadialGradientMaterial *>(newMaterial);
QQuickShapeGenericStrokeFillNode *node = m->node();
const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread);
QSGTexture *t = QQuickShapeGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
@@ -912,10 +916,10 @@ int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const
if (int d = ga->v1 - gb->v1)
return d;
- if (int d = ga->stops.count() - gb->stops.count())
+ if (int d = ga->stops.size() - gb->stops.size())
return d;
- for (int i = 0; i < ga->stops.count(); ++i) {
+ for (int i = 0; i < ga->stops.size(); ++i) {
if (int d = ga->stops[i].first - gb->stops[i].first)
return d;
if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
@@ -941,7 +945,7 @@ bool QQuickShapeConicalGradientRhiShader::updateUniformData(RenderState &state,
QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
{
Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type());
- QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial);
+ QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(newMaterial);
bool changed = false;
QByteArray *buf = state.uniformData();
Q_ASSERT(buf->size() >= 80);
@@ -985,7 +989,7 @@ void QQuickShapeConicalGradientRhiShader::updateSampledImage(RenderState &state,
if (binding != 1)
return;
- QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial);
+ QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(newMaterial);
QQuickShapeGenericStrokeFillNode *node = m->node();
const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread);
QSGTexture *t = QQuickShapeGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
@@ -1021,10 +1025,10 @@ int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const
if (int d = ga->v0 - gb->v0)
return d;
- if (int d = ga->stops.count() - gb->stops.count())
+ if (int d = ga->stops.size() - gb->stops.size())
return d;
- for (int i = 0; i < ga->stops.count(); ++i) {
+ for (int i = 0; i < ga->stops.size(); ++i) {
if (int d = ga->stops[i].first - gb->stops[i].first)
return d;
if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
diff --git a/src/quickshapes/qquickshapesoftwarerenderer.cpp b/src/quickshapes/qquickshapesoftwarerenderer.cpp
index 21327d12e0..60efcf1db9 100644
--- a/src/quickshapes/qquickshapesoftwarerenderer.cpp
+++ b/src/quickshapes/qquickshapesoftwarerenderer.cpp
@@ -8,7 +8,7 @@ QT_BEGIN_NAMESPACE
void QQuickShapeSoftwareRenderer::beginSync(int totalCount, bool *countChanged)
{
- if (m_sp.count() != totalCount) {
+ if (m_sp.size() != totalCount) {
m_sp.resize(totalCount);
m_accDirty |= DirtyList;
*countChanged = true;
@@ -144,10 +144,8 @@ void QQuickShapeSoftwareRenderer::endSync(bool)
void QQuickShapeSoftwareRenderer::setNode(QQuickShapeSoftwareRenderNode *node)
{
- if (m_node != node) {
- m_node = node;
- m_accDirty |= DirtyList;
- }
+ m_node = node;
+ m_accDirty |= DirtyList;
}
void QQuickShapeSoftwareRenderer::updateNode()
@@ -155,7 +153,7 @@ void QQuickShapeSoftwareRenderer::updateNode()
if (!m_accDirty)
return;
- const int count = m_sp.count();
+ const int count = m_sp.size();
const bool listChanged = m_accDirty & DirtyList;
if (listChanged)
m_node->m_sp.resize(count);
@@ -224,7 +222,7 @@ void QQuickShapeSoftwareRenderNode::render(const RenderState *state)
p->setTransform(matrix()->toTransform());
p->setOpacity(inheritedOpacity());
- for (const ShapePathRenderData &d : qAsConst(m_sp)) {
+ for (const ShapePathRenderData &d : std::as_const(m_sp)) {
p->setPen(d.strokeWidth >= 0.0f && d.pen.color() != Qt::transparent ? d.pen : Qt::NoPen);
p->setBrush(d.brush.color() != Qt::transparent ? d.brush : Qt::NoBrush);
p->drawPath(d.path);
diff --git a/src/quicktemplates2/accessible/qaccessiblequickpage.cpp b/src/quicktemplates2/accessible/qaccessiblequickpage.cpp
index d291648bab..6a15f3a3b3 100644
--- a/src/quicktemplates2/accessible/qaccessiblequickpage.cpp
+++ b/src/quicktemplates2/accessible/qaccessiblequickpage.cpp
@@ -35,7 +35,7 @@ QList<QQuickItem *> QAccessibleQuickPage::orderedChildItems() const
kids.move(hidx, 0);
const qsizetype fidx = kids.indexOf(p->footer());
if (fidx != -1)
- kids.move(fidx, kids.count() - 1);
+ kids.move(fidx, kids.size() - 1);
return kids;
}
diff --git a/src/quicktemplates2/qquickaction.cpp b/src/quicktemplates2/qquickaction.cpp
index 2cf1006845..2ff5fd4a48 100644
--- a/src/quicktemplates2/qquickaction.cpp
+++ b/src/quicktemplates2/qquickaction.cpp
@@ -151,14 +151,14 @@ void QQuickActionPrivate::setShortcut(const QVariant &var)
return;
defaultShortcutEntry->ungrab();
- for (QQuickActionPrivate::ShortcutEntry *entry : qAsConst(shortcutEntries))
+ for (QQuickActionPrivate::ShortcutEntry *entry : std::as_const(shortcutEntries))
entry->ungrab();
vshortcut = var;
keySequence = variantToKeySequence(var);
defaultShortcutEntry->grab(keySequence, enabled);
- for (QQuickActionPrivate::ShortcutEntry *entry : qAsConst(shortcutEntries))
+ for (QQuickActionPrivate::ShortcutEntry *entry : std::as_const(shortcutEntries))
entry->grab(keySequence, enabled);
emit q->shortcutChanged(keySequence);
@@ -175,7 +175,7 @@ void QQuickActionPrivate::setEnabled(bool enable)
#if QT_CONFIG(shortcut)
defaultShortcutEntry->setEnabled(enable);
- for (QQuickActionPrivate::ShortcutEntry *entry : qAsConst(shortcutEntries))
+ for (QQuickActionPrivate::ShortcutEntry *entry : std::as_const(shortcutEntries))
entry->setEnabled(enable);
#endif
@@ -288,7 +288,7 @@ QQuickActionPrivate::ShortcutEntry *QQuickActionPrivate::findShortcutEntry(QObje
void QQuickActionPrivate::updateDefaultShortcutEntry()
{
bool hasActiveShortcutEntries = false;
- for (QQuickActionPrivate::ShortcutEntry *entry : qAsConst(shortcutEntries)) {
+ for (QQuickActionPrivate::ShortcutEntry *entry : std::as_const(shortcutEntries)) {
if (entry->shortcutId()) {
hasActiveShortcutEntries = true;
break;
@@ -318,7 +318,7 @@ QQuickAction::~QQuickAction()
d->group->removeAction(this);
#if QT_CONFIG(shortcut)
- for (QQuickActionPrivate::ShortcutEntry *entry : qAsConst(d->shortcutEntries))
+ for (QQuickActionPrivate::ShortcutEntry *entry : std::as_const(d->shortcutEntries))
d->unwatchItem(qobject_cast<QQuickItem *>(entry->target()));
qDeleteAll(d->shortcutEntries);
diff --git a/src/quicktemplates2/qquickactiongroup.cpp b/src/quicktemplates2/qquickactiongroup.cpp
index 9caf5f67f8..5e088f3924 100644
--- a/src/quicktemplates2/qquickactiongroup.cpp
+++ b/src/quicktemplates2/qquickactiongroup.cpp
@@ -128,7 +128,7 @@ public:
void QQuickActionGroupPrivate::clear()
{
- for (QQuickAction *action : qAsConst(actions)) {
+ for (QQuickAction *action : std::as_const(actions)) {
QQuickActionPrivate::get(action)->group = nullptr;
QObjectPrivate::disconnect(action, &QQuickAction::triggered, this, &QQuickActionGroupPrivate::actionTriggered);
QObjectPrivate::disconnect(action, &QQuickAction::checkedChanged, this, &QQuickActionGroupPrivate::_q_updateCurrent);
@@ -170,7 +170,7 @@ void QQuickActionGroupPrivate::actions_append(QQmlListProperty<QQuickAction> *pr
qsizetype QQuickActionGroupPrivate::actions_count(QQmlListProperty<QQuickAction> *prop)
{
QQuickActionGroupPrivate *p = static_cast<QQuickActionGroupPrivate *>(prop->data);
- return p->actions.count();
+ return p->actions.size();
}
QQuickAction *QQuickActionGroupPrivate::actions_at(QQmlListProperty<QQuickAction> *prop, qsizetype index)
@@ -307,7 +307,7 @@ void QQuickActionGroup::setEnabled(bool enabled)
if (d->enabled == enabled)
return;
- for (QQuickAction *action : qAsConst(d->actions)) {
+ for (QQuickAction *action : std::as_const(d->actions)) {
if (d->changeEnabled(action, enabled))
emit action->enabledChanged(enabled);
}
diff --git a/src/quicktemplates2/qquickbuttongroup.cpp b/src/quicktemplates2/qquickbuttongroup.cpp
index b5a7ea00aa..89a64720dc 100644
--- a/src/quicktemplates2/qquickbuttongroup.cpp
+++ b/src/quicktemplates2/qquickbuttongroup.cpp
@@ -142,7 +142,7 @@ public:
void QQuickButtonGroupPrivate::clear()
{
- for (QQuickAbstractButton *button : qAsConst(buttons)) {
+ for (QQuickAbstractButton *button : std::as_const(buttons)) {
QQuickAbstractButtonPrivate::get(button)->group = nullptr;
QObjectPrivate::disconnect(button, &QQuickAbstractButton::clicked, this, &QQuickButtonGroupPrivate::buttonClicked);
QObjectPrivate::disconnect(button, &QQuickAbstractButton::checkedChanged, this, &QQuickButtonGroupPrivate::_q_updateCurrent);
@@ -178,7 +178,7 @@ void QQuickButtonGroupPrivate::updateCheckState()
bool anyChecked = false;
bool allChecked = !buttons.isEmpty();
- for (QQuickAbstractButton *button : qAsConst(buttons)) {
+ for (QQuickAbstractButton *button : std::as_const(buttons)) {
const bool isChecked = button->isChecked();
anyChecked |= isChecked;
allChecked &= isChecked;
@@ -205,7 +205,7 @@ void QQuickButtonGroupPrivate::buttons_append(QQmlListProperty<QQuickAbstractBut
qsizetype QQuickButtonGroupPrivate::buttons_count(QQmlListProperty<QQuickAbstractButton> *prop)
{
QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data);
- return p->buttons.count();
+ return p->buttons.size();
}
QQuickAbstractButton *QQuickButtonGroupPrivate::buttons_at(QQmlListProperty<QQuickAbstractButton> *prop, qsizetype index)
@@ -376,7 +376,7 @@ void QQuickButtonGroup::setCheckState(Qt::CheckState state)
if (d->checkedButton && state == Qt::Unchecked)
setCheckedButton(nullptr);
} else {
- for (QQuickAbstractButton *button : qAsConst(d->buttons))
+ for (QQuickAbstractButton *button : std::as_const(d->buttons))
button->setChecked(state == Qt::Checked);
}
d->settingCheckState = false;
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index 6311981645..f90cf0254f 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -190,7 +190,7 @@ QVariant QQuickComboBoxDelegateModel::variantValue(int index, const QString &rol
const QVariant object = model.toList().value(index);
if (object.metaType() == QMetaType::fromType<QVariantMap>()) {
const QVariantMap data = object.toMap();
- if (data.count() == 1)
+ if (data.size() == 1)
return data.first();
}
}
@@ -441,10 +441,10 @@ void QQuickComboBoxPrivate::updateEditText()
if (extra.isAllocated() && extra->allowComplete && !text.isEmpty()) {
const QString completed = tryComplete(text);
- if (completed.length() > text.length()) {
+ if (completed.size() > text.size()) {
input->setText(completed);
// This will select the text backwards.
- input->select(completed.length(), text.length());
+ input->select(completed.size(), text.size());
return;
}
}
@@ -548,14 +548,14 @@ QString QQuickComboBoxPrivate::tryComplete(const QString &input)
continue;
// either the first or the shortest match
- if (match.isEmpty() || text.length() < match.length())
+ if (match.isEmpty() || text.size() < match.size())
match = text;
}
if (match.isEmpty())
return input;
- return input + match.mid(input.length());
+ return input + match.mid(input.size());
}
void QQuickComboBoxPrivate::setCurrentIndex(int index, Activation activate)
diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp
index 85a1308604..45bdfcc5b3 100644
--- a/src/quicktemplates2/qquickcontainer.cpp
+++ b/src/quicktemplates2/qquickcontainer.cpp
@@ -296,7 +296,7 @@ void QQuickContainerPrivate::reorderItems()
QList<QQuickItem *> siblings = effectiveContentItem(contentItem)->childItems();
int to = 0;
- for (int i = 0; i < siblings.count(); ++i) {
+ for (int i = 0; i < siblings.size(); ++i) {
QQuickItem* sibling = siblings.at(i);
if (QQuickItemPrivate::get(sibling)->isTransparentForPositioner())
continue;
@@ -362,7 +362,7 @@ void QQuickContainerPrivate::contentData_append(QQmlListProperty<QObject> *prop,
qsizetype QQuickContainerPrivate::contentData_count(QQmlListProperty<QObject> *prop)
{
QQuickContainer *q = static_cast<QQuickContainer *>(prop->object);
- return QQuickContainerPrivate::get(q)->contentData.count();
+ return QQuickContainerPrivate::get(q)->contentData.size();
}
QObject *QQuickContainerPrivate::contentData_at(QQmlListProperty<QObject> *prop, qsizetype index)
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index e0d2740519..0f6d02ccbd 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -735,6 +735,13 @@ void QQuickControlPrivate::executeBackground(bool complete)
quickCompleteDeferred(q, backgroundName(), background);
}
+/*
+ \internal
+
+ Hides an item that was replaced by a newer one, rather than
+ deleting it, as the item is typically created in QML and hence
+ we don't own it.
+*/
void QQuickControlPrivate::hideOldItem(QQuickItem *item)
{
if (!item)
@@ -753,6 +760,29 @@ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
#endif
}
+/*
+ \internal
+
+ Named "unhide" because it's used for cases where an item
+ that was previously hidden by \l hideOldItem() wants to be
+ shown by a control again, such as a ScrollBar in ScrollView.
+*/
+void QQuickControlPrivate::unhideOldItem(QQuickControl *control, QQuickItem *item)
+{
+ Q_ASSERT(item);
+ qCDebug(lcItemManagement) << "unhiding old item" << item;
+
+ item->setVisible(true);
+ item->setParentItem(control);
+
+#if QT_CONFIG(accessibility)
+ // Add the item back in to the accessibility tree.
+ QQuickAccessibleAttached *accessible = accessibleAttached(item);
+ if (accessible)
+ accessible->setIgnored(false);
+#endif
+}
+
void QQuickControlPrivate::updateBaselineOffset()
{
Q_Q(QQuickControl);
diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h
index 736841ecbc..1832427a67 100644
--- a/src/quicktemplates2/qquickcontrol_p_p.h
+++ b/src/quicktemplates2/qquickcontrol_p_p.h
@@ -129,6 +129,7 @@ public:
virtual void executeBackground(bool complete = false);
static void hideOldItem(QQuickItem *item);
+ static void unhideOldItem(QQuickControl *control, QQuickItem *item);
void updateBaselineOffset();
diff --git a/src/quicktemplates2/qquickdialog.cpp b/src/quicktemplates2/qquickdialog.cpp
index 7ed05e2516..94e35d2fb1 100644
--- a/src/quicktemplates2/qquickdialog.cpp
+++ b/src/quicktemplates2/qquickdialog.cpp
@@ -25,7 +25,7 @@ QT_BEGIN_NAMESPACE
\image qtquickcontrols2-page-wireframe.png
- By default, Dialogs have \l focus.
+ By default, Dialogs have \l {QQuickItem::}{focus}.
\section1 Dialog Title and Buttons
diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp
index f06bb147c9..abcd56c98a 100644
--- a/src/quicktemplates2/qquickdialogbuttonbox.cpp
+++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp
@@ -282,7 +282,7 @@ void QQuickDialogButtonBoxPrivate::updateLayout()
std::stable_sort(buttons.begin(), buttons.end(), ButtonLayout(static_cast<QPlatformDialogHelper::ButtonLayout>(buttonLayout)));
- for (int i = 0; i < buttons.count() - 1; ++i)
+ for (int i = 0; i < buttons.size() - 1; ++i)
q->insertItem(i, buttons.at(i));
}
@@ -383,10 +383,8 @@ QQuickAbstractButton *QQuickDialogButtonBoxPrivate::createStandardButton(QPlatfo
QQmlContext *creationContext = delegate->creationContext();
if (!creationContext)
creationContext = qmlContext(q);
- QQmlContext *context = new QQmlContext(creationContext, q);
- context->setContextObject(q);
- QObject *object = delegate->beginCreate(context);
+ QObject *object = delegate->beginCreate(creationContext);
QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(object);
if (button) {
QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, true));
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp
index caef208545..fca910138a 100644
--- a/src/quicktemplates2/qquickdrawer.cpp
+++ b/src/quicktemplates2/qquickdrawer.cpp
@@ -473,6 +473,12 @@ bool QQuickDrawerPrivate::handleMove(QQuickItem *item, const QPointF &point, ulo
bool QQuickDrawerPrivate::handleRelease(QQuickItem *item, const QPointF &point, ulong timestamp)
{
+ auto cleanup = qScopeGuard([this] {
+ popupItem->setKeepMouseGrab(false);
+ popupItem->setKeepTouchGrab(false);
+ pressPoint = QPointF();
+ touchId = -1;
+ });
if (pressPoint.isNull())
return false;
if (!popupItem->keepMouseGrab() && !popupItem->keepTouchGrab()) {
@@ -532,14 +538,8 @@ bool QQuickDrawerPrivate::handleRelease(QQuickItem *item, const QPointF &point,
}
}
- bool wasGrabbed = popupItem->keepMouseGrab() || popupItem->keepTouchGrab();
- popupItem->setKeepMouseGrab(false);
- popupItem->setKeepTouchGrab(false);
-
- pressPoint = QPointF();
- touchId = -1;
-
- return wasGrabbed;
+ // the cleanup() lambda will run before return
+ return popupItem->keepMouseGrab() || popupItem->keepTouchGrab();
}
void QQuickDrawerPrivate::handleUngrab()
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp
index 20280824c0..f5c59ed4e0 100644
--- a/src/quicktemplates2/qquickmenu.cpp
+++ b/src/quicktemplates2/qquickmenu.cpp
@@ -254,11 +254,9 @@ QQuickItem *QQuickMenuPrivate::beginCreateItem()
if (!delegate)
return nullptr;
- QQmlContext *creationContext = delegate->creationContext();
- if (!creationContext)
- creationContext = qmlContext(q);
- QQmlContext *context = new QQmlContext(creationContext, q);
- context->setContextObject(q);
+ QQmlContext *context = delegate->creationContext();
+ if (!context)
+ context = qmlContext(q);
QObject *object = delegate->beginCreate(context);
QQuickItem *item = qobject_cast<QQuickItem *>(object);
diff --git a/src/quicktemplates2/qquickmenubar.cpp b/src/quicktemplates2/qquickmenubar.cpp
index f638320286..3f7fd853d4 100644
--- a/src/quicktemplates2/qquickmenubar.cpp
+++ b/src/quicktemplates2/qquickmenubar.cpp
@@ -49,17 +49,14 @@ QQuickItem *QQuickMenuBarPrivate::beginCreateItem(QQuickMenu *menu)
if (!delegate)
return nullptr;
- QQmlContext *creationContext = delegate->creationContext();
- if (!creationContext)
- creationContext = qmlContext(q);
- QQmlContext *context = new QQmlContext(creationContext, q);
- context->setContextObject(q);
+ QQmlContext *context = delegate->creationContext();
+ if (!context)
+ context = qmlContext(q);
QObject *object = delegate->beginCreate(context);
QQuickItem *item = qobject_cast<QQuickItem *>(object);
if (!item) {
delete object;
- delete context;
return nullptr;
}
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
index 8cf6e40f66..cdb40e2e8b 100644
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ b/src/quicktemplates2/qquickoverlay.cpp
@@ -41,7 +41,7 @@ QList<QQuickPopup *> QQuickOverlayPrivate::stackingOrderPopups() const
const QList<QQuickItem *> children = paintOrderChildItems();
QList<QQuickPopup *> popups;
- popups.reserve(children.count());
+ popups.reserve(children.size());
for (auto it = children.crbegin(), end = children.crend(); it != end; ++it) {
QQuickPopup *popup = qobject_cast<QQuickPopup *>((*it)->parent());
@@ -52,10 +52,10 @@ QList<QQuickPopup *> QQuickOverlayPrivate::stackingOrderPopups() const
return popups;
}
-QList<QQuickDrawer *> QQuickOverlayPrivate::stackingOrderDrawers() const
+QList<QQuickPopup *> QQuickOverlayPrivate::stackingOrderDrawers() const
{
- QList<QQuickDrawer *> sorted(allDrawers);
- std::sort(sorted.begin(), sorted.end(), [](const QQuickDrawer *one, const QQuickDrawer *another) {
+ QList<QQuickPopup *> sorted(allDrawers);
+ std::sort(sorted.begin(), sorted.end(), [](const QQuickPopup *one, const QQuickPopup *another) {
return one->z() > another->z();
});
return sorted;
@@ -83,8 +83,10 @@ bool QQuickOverlayPrivate::startDrag(QEvent *event, const QPointF &pos)
}
}
- const QList<QQuickDrawer *> drawers = stackingOrderDrawers();
- for (QQuickDrawer *drawer : drawers) {
+ const QList<QQuickPopup *> drawers = stackingOrderDrawers();
+ for (QQuickPopup *popup : drawers) {
+ QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(popup);
+ Q_ASSERT(drawer);
QQuickDrawerPrivate *p = QQuickDrawerPrivate::get(drawer);
if (p->startDrag(event)) {
setMouseGrabberPopup(drawer);
@@ -240,7 +242,7 @@ void QQuickOverlayPrivate::removePopup(QQuickPopup *popup)
{
Q_Q(QQuickOverlay);
allPopups.removeOne(popup);
- if (allDrawers.removeOne(qobject_cast<QQuickDrawer *>(popup)))
+ if (allDrawers.removeOne(popup))
q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty());
}
@@ -389,7 +391,7 @@ void QQuickOverlay::geometryChange(const QRectF &newGeometry, const QRectF &oldG
{
Q_D(QQuickOverlay);
QQuickItem::geometryChange(newGeometry, oldGeometry);
- for (QQuickPopup *popup : qAsConst(d->allPopups))
+ for (QQuickPopup *popup : std::as_const(d->allPopups))
QQuickPopupPrivate::get(popup)->resizeOverlay();
}
@@ -554,6 +556,34 @@ bool QQuickOverlay::eventFilter(QObject *object, QEvent *event)
d->handleRelease(d->window->contentItem(), event, nullptr);
break;
+ case QEvent::Wheel: {
+ // If the top item in the drawing-order is blocked by a modal popup, then
+ // eat the event. There is no scenario where the top most item is blocked
+ // by a popup, but an item further down in the drawing order is not.
+ QWheelEvent *we = static_cast<QWheelEvent *>(event);
+ const QVector<QQuickItem *> targetItems = d->deliveryAgentPrivate()->pointerTargets(
+ d->window->contentItem(), we, we->point(0), false, false);
+ if (targetItems.isEmpty())
+ break;
+
+ QQuickItem * const topItem = targetItems.first();
+ const auto popups = d->stackingOrderPopups();
+ // Eat the event if receiver topItem is not a child of a popup before
+ // the first modal popup.
+ for (const auto &popup : popups) {
+ const QQuickItem *popupItem = popup->popupItem();
+ if (!popupItem)
+ continue;
+ // if we reach a popup that contains the item, deliver the event
+ if (popupItem->isAncestorOf(topItem))
+ break;
+ // if the popup doesn't contain the item but is modal, eat the event
+ if (popup->overlayEvent(topItem, we))
+ return true;
+ }
+ break;
+ }
+
default:
break;
}
diff --git a/src/quicktemplates2/qquickoverlay_p_p.h b/src/quicktemplates2/qquickoverlay_p_p.h
index ba2ea3cdbb..38c214804f 100644
--- a/src/quicktemplates2/qquickoverlay_p_p.h
+++ b/src/quicktemplates2/qquickoverlay_p_p.h
@@ -23,9 +23,9 @@
QT_BEGIN_NAMESPACE
class QQuickPopup;
-class QQuickDrawer;
-class QQuickOverlayPrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+class Q_AUTOTEST_EXPORT QQuickOverlayPrivate : public QQuickItemPrivate,
+ public QQuickItemChangeListener
{
public:
Q_DECLARE_PUBLIC(QQuickOverlay)
@@ -51,7 +51,7 @@ public:
void setMouseGrabberPopup(QQuickPopup *popup);
QList<QQuickPopup *> stackingOrderPopups() const;
- QList<QQuickDrawer *> stackingOrderDrawers() const;
+ QList<QQuickPopup *> stackingOrderDrawers() const;
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override;
@@ -60,7 +60,9 @@ public:
QQmlComponent *modal = nullptr;
QQmlComponent *modeless = nullptr;
QList<QQuickPopup *> allPopups;
- QList<QQuickDrawer *> allDrawers;
+ // Store drawers as QQuickPopup instead of QQuickDrawer because they're no longer
+ // QQuickDrawer by the time removePopup is called.
+ QList<QQuickPopup *> allDrawers;
QPointer<QQuickPopup> mouseGrabberPopup;
};
diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp
index 46d943c2bb..05e5c90883 100644
--- a/src/quicktemplates2/qquickpane.cpp
+++ b/src/quicktemplates2/qquickpane.cpp
@@ -165,7 +165,7 @@ qreal QQuickPanePrivate::getContentWidth() const
return cw;
const auto contentChildren = contentChildItems();
- if (contentChildren.count() == 1)
+ if (contentChildren.size() == 1)
return contentChildren.first()->implicitWidth();
return 0;
@@ -181,7 +181,7 @@ qreal QQuickPanePrivate::getContentHeight() const
return ch;
const auto contentChildren = contentChildItems();
- if (contentChildren.count() == 1)
+ if (contentChildren.size() == 1)
return contentChildren.first()->implicitHeight();
return 0;
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 05ce9175a4..f523d22d8f 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -283,6 +283,7 @@ void QQuickPopupPrivate::closeOrReject()
dialog->reject();
else
q->close();
+ touchId = -1;
}
bool QQuickPopupPrivate::tryClose(const QPointF &pos, QQuickPopup::ClosePolicy flags)
@@ -329,6 +330,12 @@ bool QQuickPopupPrivate::acceptTouch(const QTouchEvent::TouchPoint &point)
bool QQuickPopupPrivate::blockInput(QQuickItem *item, const QPointF &point) const
{
+ // don't propagate events within the popup beyond the overlay
+ if (popupItem->contains(popupItem->mapFromScene(point))
+ && item == QQuickOverlay::overlay(window)) {
+ return true;
+ }
+
// don't block presses and releases
// a) outside a non-modal popup,
// b) to popup children/content, or
@@ -413,7 +420,7 @@ bool QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event)
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
for (const QTouchEvent::TouchPoint &point : event->points()) {
- if (!acceptTouch(point))
+ if (event->type() != QEvent::TouchEnd && !acceptTouch(point))
return blockInput(item, point.position());
switch (point.state()) {
@@ -715,11 +722,9 @@ static QQuickItem *createDimmer(QQmlComponent *component, QQuickPopup *popup, QQ
{
QQuickItem *item = nullptr;
if (component) {
- QQmlContext *creationContext = component->creationContext();
- if (!creationContext)
- creationContext = qmlContext(popup);
- QQmlContext *context = new QQmlContext(creationContext, popup);
- context->setContextObject(popup);
+ QQmlContext *context = component->creationContext();
+ if (!context)
+ context = qmlContext(popup);
item = qobject_cast<QQuickItem*>(component->beginCreate(context));
}
@@ -2495,7 +2500,12 @@ void QQuickPopup::keyPressEvent(QKeyEvent *event)
return;
#if QT_CONFIG(shortcut)
- if (d->closePolicy.testFlag(QQuickPopup::CloseOnEscape) && event->matches(QKeySequence::Cancel)) {
+ if (d->closePolicy.testFlag(QQuickPopup::CloseOnEscape)
+ && (event->matches(QKeySequence::Cancel)
+#if defined(Q_OS_ANDROID)
+ || event->key() == Qt::Key_Back
+#endif
+ )) {
event->accept();
if (d->interactive)
d->closeOrReject();
diff --git a/src/quicktemplates2/qquickpopuppositioner.cpp b/src/quicktemplates2/qquickpopuppositioner.cpp
index 0e05e189c9..aecbc7373c 100644
--- a/src/quicktemplates2/qquickpopuppositioner.cpp
+++ b/src/quicktemplates2/qquickpopuppositioner.cpp
@@ -129,14 +129,18 @@ void QQuickPopupPositioner::reposition()
// if the popup doesn't fit horizontally inside the window, try flipping it around (left <-> right)
if (p->allowHorizontalFlip && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
- const QRectF flipped(m_parentItem->mapToScene(QPointF(m_parentItem->width() - p->x - rect.width(), p->y)), rect.size());
+ const QPointF newTopLeft(m_parentItem->width() - p->x - rect.width(), p->y);
+ const QRectF flipped(m_parentItem->mapToItem(popupItem->parentItem(), newTopLeft),
+ rect.size());
if (flipped.intersected(bounds).width() > rect.intersected(bounds).width())
rect.moveLeft(flipped.left());
}
// if the popup doesn't fit vertically inside the window, try flipping it around (above <-> below)
if (p->allowVerticalFlip && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
- const QRectF flipped(m_parentItem->mapToScene(QPointF(p->x, m_parentItem->height() - p->y - rect.height())), rect.size());
+ const QPointF newTopLeft(p->x, m_parentItem->height() - p->y - rect.height());
+ const QRectF flipped(m_parentItem->mapToItem(popupItem->parentItem(), newTopLeft),
+ rect.size());
if (flipped.intersected(bounds).height() > rect.intersected(bounds).height())
rect.moveTop(flipped.top());
}
diff --git a/src/quicktemplates2/qquickpresshandler.cpp b/src/quicktemplates2/qquickpresshandler.cpp
index b1c2208e99..d752bb36f1 100644
--- a/src/quicktemplates2/qquickpresshandler.cpp
+++ b/src/quicktemplates2/qquickpresshandler.cpp
@@ -20,7 +20,7 @@ void QQuickPressHandler::mousePressEvent(QMouseEvent *event)
if (Qt::LeftButton == (event->buttons() & Qt::LeftButton)) {
timer.start(QGuiApplication::styleHints()->mousePressAndHoldInterval(), control);
delayedMousePressEvent = new QMouseEvent(event->type(), event->position().toPoint(), event->globalPosition().toPoint(),
- event->button(), event->buttons(), event->modifiers());
+ event->button(), event->buttons(), event->modifiers(), event->pointingDevice());
} else {
timer.stop();
}
diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp
index 4b4660b0a5..c17f3e773e 100644
--- a/src/quicktemplates2/qquickscrollbar.cpp
+++ b/src/quicktemplates2/qquickscrollbar.cpp
@@ -903,6 +903,7 @@ void QQuickScrollBarAttachedPrivate::setFlickable(QQuickFlickable *item)
// The latter doesn't remove the listener but only resets its types. Thus, it leaves behind a dangling
// pointer on destruction.
QQuickItemPrivate::get(flickable)->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
+ QQuickItemPrivate::get(flickable)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed);
if (horizontal)
cleanupHorizontal();
if (vertical)
@@ -912,7 +913,10 @@ void QQuickScrollBarAttachedPrivate::setFlickable(QQuickFlickable *item)
flickable = item;
if (item) {
+ // Don't know how to combine these calls into one, and as long as they're separate calls,
+ // the remove* calls above need to be separate too, otherwise they will have no effect.
QQuickItemPrivate::get(item)->updateOrAddGeometryChangeListener(this, QQuickGeometryChange::Size);
+ QQuickItemPrivate::get(item)->updateOrAddItemChangeListener(this, QQuickItemPrivate::Destroyed);
if (horizontal)
initHorizontal();
if (vertical)
@@ -936,6 +940,14 @@ void QQuickScrollBarAttachedPrivate::initHorizontal()
if (parent && parent == flickable->parentItem())
horizontal->stackAfter(flickable);
+ // If a scroll bar was previously hidden (due to e.g. setting a new contentItem
+ // on a ScrollView), we need to make sure that we un-hide it.
+ // We don't bother checking if the item is actually the old one, because
+ // if it's not, all of the things the function does (setting parent, visibility, etc.)
+ // should be no-ops anyway.
+ if (auto control = qobject_cast<QQuickControl*>(q_func()->parent()))
+ QQuickControlPrivate::unhideOldItem(control, horizontal);
+
layoutHorizontal();
horizontal->setSize(area->property("widthRatio").toReal());
horizontal->setPosition(area->property("xPosition").toReal());
@@ -957,6 +969,9 @@ void QQuickScrollBarAttachedPrivate::initVertical()
if (parent && parent == flickable->parentItem())
vertical->stackAfter(flickable);
+ if (auto control = qobject_cast<QQuickControl*>(q_func()->parent()))
+ QQuickControlPrivate::unhideOldItem(control, vertical);
+
layoutVertical();
vertical->setSize(area->property("heightRatio").toReal());
vertical->setPosition(area->property("yPosition").toReal());
@@ -1115,6 +1130,8 @@ void QQuickScrollBarAttachedPrivate::itemImplicitHeightChanged(QQuickItem *item)
void QQuickScrollBarAttachedPrivate::itemDestroyed(QQuickItem *item)
{
+ if (item == flickable)
+ flickable = nullptr;
if (item == horizontal)
horizontal = nullptr;
if (item == vertical)
diff --git a/src/quicktemplates2/qquickshortcutcontext.cpp b/src/quicktemplates2/qquickshortcutcontext.cpp
index 6905f39e01..2d07eb44f9 100644
--- a/src/quicktemplates2/qquickshortcutcontext.cpp
+++ b/src/quicktemplates2/qquickshortcutcontext.cpp
@@ -8,11 +8,14 @@
#include "qquickmenu_p_p.h"
#include "qquickpopup_p.h"
+#include <QtCore/qloggingcategory.h>
#include <QtGui/qguiapplication.h>
#include <QtQuick/qquickrendercontrol.h>
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcContextMatcher, "qt.quick.controls.shortcutcontext.matcher")
+
static bool isBlockedByPopup(QQuickItem *item)
{
if (!item || !item->window())
@@ -64,6 +67,8 @@ bool QQuickShortcutContext::matcher(QObject *obj, Qt::ShortcutContext context)
}
if (QWindow *renderWindow = QQuickRenderControl::renderWindowFor(qobject_cast<QQuickWindow *>(obj)))
obj = renderWindow;
+ qCDebug(lcContextMatcher) << "obj" << obj << "focusWindow" << QGuiApplication::focusWindow()
+ << "!isBlockedByPopup(item)" << !isBlockedByPopup(item);
return obj && obj == QGuiApplication::focusWindow() && !isBlockedByPopup(item);
default:
return false;
diff --git a/src/quicktemplates2/qquicksplitview.cpp b/src/quicktemplates2/qquicksplitview.cpp
index c0f894ffa5..af405c8564 100644
--- a/src/quicktemplates2/qquicksplitview.cpp
+++ b/src/quicktemplates2/qquicksplitview.cpp
@@ -222,7 +222,7 @@ QT_BEGIN_NAMESPACE
*/
Q_LOGGING_CATEGORY(qlcQQuickSplitView, "qt.quick.controls.splitview")
-Q_LOGGING_CATEGORY(qlcQQuickSplitViewMouse, "qt.quick.controls.splitview.mouse")
+Q_LOGGING_CATEGORY(qlcQQuickSplitViewPointer, "qt.quick.controls.splitview.pointer")
Q_LOGGING_CATEGORY(qlcQQuickSplitViewState, "qt.quick.controls.splitview.state")
void QQuickSplitViewPrivate::updateFillIndex()
@@ -700,13 +700,11 @@ void QQuickSplitViewPrivate::createHandleItem(int index)
// If we don't use the correct context, it won't be possible to refer to
// the control's id from within the delegate.
- QQmlContext *creationContext = m_handle->creationContext();
+ QQmlContext *context = m_handle->creationContext();
// The component might not have been created in QML, in which case
// the creation context will be null and we have to create it ourselves.
- if (!creationContext)
- creationContext = qmlContext(q);
- QQmlContext *context = new QQmlContext(creationContext, q);
- context->setContextObject(q);
+ if (!context)
+ context = qmlContext(q);
QQuickItem *handleItem = qobject_cast<QQuickItem*>(m_handle->beginCreate(context));
if (handleItem) {
handleItem->setParent(q);
@@ -898,7 +896,7 @@ void QQuickSplitViewPrivate::updateHandleVisibilities()
void QQuickSplitViewPrivate::updateHoveredHandle(QQuickItem *hoveredItem)
{
- qCDebug(qlcQQuickSplitViewMouse) << "updating hovered handle after" << hoveredItem << "was hovered";
+ qCDebug(qlcQQuickSplitViewPointer) << "updating hovered handle after" << hoveredItem << "was hovered";
const int oldHoveredHandleIndex = m_hoveredHandleIndex;
m_hoveredHandleIndex = m_handleItems.indexOf(hoveredItem);
@@ -911,16 +909,16 @@ void QQuickSplitViewPrivate::updateHoveredHandle(QQuickItem *hoveredItem)
QQuickSplitHandleAttached *oldHoveredHandleAttached = qobject_cast<QQuickSplitHandleAttached*>(
qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(oldHoveredHandle, true));
QQuickSplitHandleAttachedPrivate::get(oldHoveredHandleAttached)->setHovered(false);
- qCDebug(qlcQQuickSplitViewMouse) << "handle item at index" << oldHoveredHandleIndex << "is no longer hovered";
+ qCDebug(qlcQQuickSplitViewPointer) << "handle item at index" << oldHoveredHandleIndex << "is no longer hovered";
}
if (m_hoveredHandleIndex != -1) {
QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>(
qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(hoveredItem, true));
QQuickSplitHandleAttachedPrivate::get(handleAttached)->setHovered(true);
- qCDebug(qlcQQuickSplitViewMouse) << "handle item at index" << m_hoveredHandleIndex << "is now hovered";
+ qCDebug(qlcQQuickSplitViewPointer) << "handle item at index" << m_hoveredHandleIndex << "is now hovered";
} else {
- qCDebug(qlcQQuickSplitViewMouse) << "either there is no hovered item or" << hoveredItem << "is not a handle";
+ qCDebug(qlcQQuickSplitViewPointer) << "either there is no hovered item or" << hoveredItem << "is not a handle";
}
}
@@ -989,7 +987,7 @@ bool QQuickSplitViewPrivate::handlePress(const QPointF &point, ulong timestamp)
setResizing(true);
- qCDebug(qlcQQuickSplitViewMouse).nospace() << "handled press -"
+ qCDebug(qlcQQuickSplitViewPointer).nospace() << "handled press -"
<< " left/top index=" << m_pressedHandleIndex << ","
<< " size before press=" << m_leftOrTopItemSizeBeforePress << ","
<< " item=" << leftOrTopItem
@@ -1382,27 +1380,51 @@ void QQuickSplitView::hoverLeaveEvent(QHoverEvent *event)
bool QQuickSplitView::childMouseEventFilter(QQuickItem *item, QEvent *event)
{
Q_D(QQuickSplitView);
- qCDebug(qlcQQuickSplitViewMouse) << "childMouseEventFilter called with" << item << event;
-
- if (event->type() == QEvent::MouseButtonPress) {
- QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
- const QPointF point = mapFromItem(item, mouseEvent->position());
- d->handlePress(point, mouseEvent->timestamp());
-
- // Keep the mouse grab if this item belongs to the handle,
- // otherwise this event can be stolen e.g. Flickable if we're inside it.
- if (d->m_pressedHandleIndex != -1)
- item->setKeepMouseGrab(true);
- }
- else if (event->type() == QEvent::MouseButtonRelease) {
- QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
- const QPointF point = mapFromItem(item, mouseEvent->position());
- d->handleRelease(point, mouseEvent->timestamp());
- }
- else if (event->type() == QEvent::MouseMove) {
- QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
- const QPointF point = mapFromItem(item, mouseEvent->position());
- d->handleMove(point, mouseEvent->timestamp());
+ qCDebug(qlcQQuickSplitViewPointer) << "childMouseEventFilter called with" << item << event;
+
+ if (Q_LIKELY(event->isPointerEvent())) {
+ auto *pointerEvent = static_cast<QPointerEvent *>(event);
+ const auto &eventPoint = pointerEvent->points().first();
+ const QPointF point = mapFromItem(item, eventPoint.position());
+ const auto timestamp = pointerEvent->timestamp();
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ d->handlePress(point, timestamp);
+ // Keep the mouse grab if this item belongs to the handle,
+ // otherwise this event can be stolen e.g. Flickable if we're inside it.
+ if (d->m_pressedHandleIndex != -1)
+ item->setKeepMouseGrab(true);
+ break;
+ case QEvent::MouseButtonRelease:
+ d->handleRelease(point, timestamp);
+ break;
+ case QEvent::MouseMove:
+ d->handleMove(point, timestamp);
+ break;
+ case QEvent::TouchBegin:
+ if (pointerEvent->pointCount() == 1) {
+ d->handlePress(point, timestamp);
+ // We filter the event on behalf of item, but we want the item
+ // to be the exclusive grabber so that we can continue to filter
+ // touch events for it.
+ if (d->m_pressedHandleIndex != -1) {
+ item->setKeepTouchGrab(true);
+ pointerEvent->setExclusiveGrabber(eventPoint, item);
+ }
+ }
+ break;
+ case QEvent::TouchEnd:
+ if (pointerEvent->pointCount() == 1)
+ d->handleRelease(point, timestamp);
+ break;
+ case QEvent::TouchUpdate:
+ if (pointerEvent->pointCount() == 1)
+ d->handleMove(point, timestamp);
+ break;
+ default:
+ break;
+ }
}
// If this event belongs to the handle, filter it. (d->m_pressedHandleIndex != -1) means that
diff --git a/src/quicktemplates2/qquickstackelement.cpp b/src/quicktemplates2/qquickstackelement.cpp
index 09790d4f93..e165a780bb 100644
--- a/src/quicktemplates2/qquickstackelement.cpp
+++ b/src/quicktemplates2/qquickstackelement.cpp
@@ -79,8 +79,6 @@ QQuickStackElement::~QQuickStackElement()
if (attached)
emit attached->removed();
-
- delete context;
}
QQuickStackElement *QQuickStackElement::fromString(const QString &str, QQuickStackView *view, QString *error)
@@ -134,11 +132,9 @@ bool QQuickStackElement::load(QQuickStackView *parent)
return true;
}
- QQmlContext *creationContext = component->creationContext();
- if (!creationContext)
- creationContext = qmlContext(parent);
- context = new QQmlContext(creationContext, parent);
- context->setContextObject(parent);
+ QQmlContext *context = component->creationContext();
+ if (!context)
+ context = qmlContext(parent);
QQuickStackIncubator incubator(this);
component->create(incubator, context);
diff --git a/src/quicktemplates2/qquickstackelement_p_p.h b/src/quicktemplates2/qquickstackelement_p_p.h
index 2e38e42c47..f591e8fd5d 100644
--- a/src/quicktemplates2/qquickstackelement_p_p.h
+++ b/src/quicktemplates2/qquickstackelement_p_p.h
@@ -61,7 +61,6 @@ public:
bool ownComponent = false;
bool widthValid = false;
bool heightValid = false;
- QQmlContext *context = nullptr;
QQmlComponent *component = nullptr;
QQuickStackView *view = nullptr;
QPointer<QQuickItem> originalParent;
diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp
index e65a2f18ad..1b16c6e581 100644
--- a/src/quicktemplates2/qquickstackview.cpp
+++ b/src/quicktemplates2/qquickstackview.cpp
@@ -387,7 +387,7 @@ bool QQuickStackView::isBusy() const
int QQuickStackView::depth() const
{
Q_D(const QQuickStackView);
- return d->elements.count();
+ return d->elements.size();
}
/*!
@@ -448,7 +448,7 @@ QQuickItem *QQuickStackView::find(const QJSValue &callback, LoadBehavior behavio
if (!engine || !func.isCallable()) // TODO: warning?
return nullptr;
- for (int i = d->elements.count() - 1; i >= 0; --i) {
+ for (int i = d->elements.size() - 1; i >= 0; --i) {
QQuickStackElement *element = d->elements.at(i);
if (behavior == ForceLoad)
element->load(this);
@@ -561,7 +561,7 @@ void QQuickStackView::push(QQmlV4Function *args)
if (!errors.isEmpty() || elements.isEmpty()) {
if (!errors.isEmpty()) {
- for (const QString &error : qAsConst(errors))
+ for (const QString &error : std::as_const(errors))
d->warn(error);
} else {
d->warn(QStringLiteral("nothing to push"));
@@ -574,9 +574,9 @@ void QQuickStackView::push(QQmlV4Function *args)
if (!d->elements.isEmpty())
exit = d->elements.top();
- int oldDepth = d->elements.count();
+ int oldDepth = d->elements.size();
if (d->pushElements(elements)) {
- d->depthChange(d->elements.count(), oldDepth);
+ d->depthChange(d->elements.size(), oldDepth);
QQuickStackElement *enter = d->elements.top();
d->startTransition(QQuickStackTransition::pushEnter(operation, enter, this),
QQuickStackTransition::pushExit(operation, exit, this),
@@ -640,14 +640,14 @@ void QQuickStackView::pop(QQmlV4Function *args)
QScopedValueRollback<bool> modifyingElements(d->modifyingElements, true);
QScopedValueRollback<QString> operationNameRollback(d->operation, operationName);
int argc = args->length();
- if (d->elements.count() <= 1 || argc > 2) {
+ if (d->elements.size() <= 1 || argc > 2) {
if (argc > 2)
d->warn(QStringLiteral("too many arguments"));
args->setReturnValue(QV4::Encode::null());
return;
}
- int oldDepth = d->elements.count();
+ int oldDepth = d->elements.size();
QQuickStackElement *exit = d->elements.pop();
QQuickStackElement *enter = d->elements.top();
@@ -686,7 +686,7 @@ void QQuickStackView::pop(QQmlV4Function *args)
d->removing.insert(exit);
previousItem = exit->item;
}
- d->depthChange(d->elements.count(), oldDepth);
+ d->depthChange(d->elements.size(), oldDepth);
d->startTransition(QQuickStackTransition::popExit(operation, exit, this),
QQuickStackTransition::popEnter(operation, enter, this),
operation == Immediate);
@@ -828,7 +828,7 @@ void QQuickStackView::replace(QQmlV4Function *args)
QList<QQuickStackElement *> elements = d->parseElements(target ? 1 : 0, args, &errors);
if (!errors.isEmpty() || elements.isEmpty()) {
if (!errors.isEmpty()) {
- for (const QString &error : qAsConst(errors))
+ for (const QString &error : std::as_const(errors))
d->warn(error);
} else {
d->warn(QStringLiteral("nothing to push"));
@@ -837,13 +837,13 @@ void QQuickStackView::replace(QQmlV4Function *args)
return;
}
- int oldDepth = d->elements.count();
+ int oldDepth = d->elements.size();
QQuickStackElement* exit = nullptr;
if (!d->elements.isEmpty())
exit = d->elements.pop();
if (exit != target ? d->replaceElements(target, elements) : d->pushElements(elements)) {
- d->depthChange(d->elements.count(), oldDepth);
+ d->depthChange(d->elements.size(), oldDepth);
if (exit) {
exit->removal = true;
d->removing.insert(exit);
@@ -914,7 +914,7 @@ void QQuickStackView::clear(Operation operation)
QQuickStackTransition::popEnter(operation, nullptr, this), false);
}
- int oldDepth = d->elements.count();
+ int oldDepth = d->elements.size();
d->setCurrentItem(nullptr);
qDeleteAll(d->elements);
d->elements.clear();
@@ -1115,7 +1115,7 @@ void QQuickStackView::componentComplete()
QScopedValueRollback<QString> operationNameRollback(d->operation, QStringLiteral("initialItem"));
QQuickStackElement *element = nullptr;
QString error;
- int oldDepth = d->elements.count();
+ int oldDepth = d->elements.size();
if (QObject *o = d->initialItem.toQObject())
element = QQuickStackElement::fromObject(o, this, &error);
else if (d->initialItem.isString())
@@ -1124,7 +1124,7 @@ void QQuickStackView::componentComplete()
d->warn(error);
delete element;
} else if (d->pushElement(element)) {
- d->depthChange(d->elements.count(), oldDepth);
+ d->depthChange(d->elements.size(), oldDepth);
d->setCurrentItem(element);
element->setStatus(QQuickStackView::Active);
}
@@ -1135,7 +1135,7 @@ void QQuickStackView::geometryChange(const QRectF &newGeometry, const QRectF &ol
QQuickControl::geometryChange(newGeometry, oldGeometry);
Q_D(QQuickStackView);
- for (QQuickStackElement *element : qAsConst(d->elements)) {
+ for (QQuickStackElement *element : std::as_const(d->elements)) {
if (element->item) {
if (!element->widthValid)
element->item->setWidth(newGeometry.width());
diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp
index 23cdf0c41e..c867c55dcc 100644
--- a/src/quicktemplates2/qquickstackview_p.cpp
+++ b/src/quicktemplates2/qquickstackview_p.cpp
@@ -109,7 +109,7 @@ QList<QQuickStackElement *> QQuickStackViewPrivate::parseElements(int from, QQml
QQuickStackElement *QQuickStackViewPrivate::findElement(QQuickItem *item) const
{
if (item) {
- for (QQuickStackElement *e : qAsConst(elements)) {
+ for (QQuickStackElement *e : std::as_const(elements)) {
if (e->item == item)
return e;
}
@@ -165,7 +165,7 @@ bool QQuickStackViewPrivate::pushElements(const QList<QQuickStackElement *> &ele
Q_Q(QQuickStackView);
if (!elems.isEmpty()) {
for (QQuickStackElement *e : elems) {
- e->setIndex(elements.count());
+ e->setIndex(elements.size());
elements += e;
}
return elements.top()->load(q);
@@ -183,7 +183,7 @@ bool QQuickStackViewPrivate::pushElement(QQuickStackElement *element)
bool QQuickStackViewPrivate::popElements(QQuickStackElement *element)
{
Q_Q(QQuickStackView);
- while (elements.count() > 1 && elements.top() != element) {
+ while (elements.size() > 1 && elements.top() != element) {
delete elements.pop();
if (!element)
break;
@@ -287,7 +287,7 @@ void QQuickStackViewPrivate::viewItemTransitionFinished(QQuickItemViewTransition
QList<QQuickStackElement*> removedElements = removed;
removed.clear();
- for (QQuickStackElement *removedElement : qAsConst(removedElements)) {
+ for (QQuickStackElement *removedElement : std::as_const(removedElements)) {
// If an element with the same item is found in the active stack list,
// forget about the item so that we don't hide it.
if (removedElement->item && findElement(removedElement->item)) {
diff --git a/src/quicktemplates2/qquickswipedelegate.cpp b/src/quicktemplates2/qquickswipedelegate.cpp
index f3c57fe8fa..42343d1072 100644
--- a/src/quicktemplates2/qquickswipedelegate.cpp
+++ b/src/quicktemplates2/qquickswipedelegate.cpp
@@ -185,13 +185,11 @@ QQuickItem *QQuickSwipePrivate::createDelegateItem(QQmlComponent *component)
{
// If we don't use the correct context, it won't be possible to refer to
// the control's id from within the delegates.
- QQmlContext *creationContext = component->creationContext();
+ QQmlContext *context = component->creationContext();
// The component might not have been created in QML, in which case
// the creation context will be null and we have to create it ourselves.
- if (!creationContext)
- creationContext = qmlContext(control);
- QQmlContext *context = new QQmlContext(creationContext, control);
- context->setContextObject(control);
+ if (!context)
+ context = qmlContext(control);
QQuickItem *item = qobject_cast<QQuickItem*>(component->beginCreate(context));
if (item) {
item->setParentItem(control);
@@ -943,7 +941,7 @@ bool QQuickSwipeDelegatePrivate::attachedObjectsSetPressed(QQuickItem *item, QPo
bool found = false;
QVarLengthArray<QQuickItem *, 16> itemAndChildren;
itemAndChildren.append(item);
- for (int i = 0; i < itemAndChildren.count(); ++i) {
+ for (int i = 0; i < itemAndChildren.size(); ++i) {
auto item = itemAndChildren.at(i);
auto posInItem = item->mapFromScene(scenePos);
if (item->contains(posInItem)) {
diff --git a/src/quicktemplates2/qquicktabbar.cpp b/src/quicktemplates2/qquicktabbar.cpp
index 1421f0155d..a1dfc9068c 100644
--- a/src/quicktemplates2/qquicktabbar.cpp
+++ b/src/quicktemplates2/qquicktabbar.cpp
@@ -147,7 +147,7 @@ void QQuickTabBarPrivate::updateLayout()
const qreal itemWidth = (contentItem->width() - reservedWidth - totalSpacing) / qMax(1, resizableCount);
updatingLayout = true;
- for (QQuickItem *item : qAsConst(allItems)) {
+ for (QQuickItem *item : std::as_const(allItems)) {
QQuickItemPrivate *p = QQuickItemPrivate::get(item);
if (!p->widthValid()) {
item->setWidth(itemWidth);
diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp
index 48bdcddb64..0572746d14 100644
--- a/src/quicktemplates2/qquicktextarea.cpp
+++ b/src/quicktemplates2/qquicktextarea.cpp
@@ -19,6 +19,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
/*!
\qmltype TextArea
\inherits TextEdit
@@ -509,6 +511,10 @@ QQuickTextArea::QQuickTextArea(QQuickItem *parent)
QObjectPrivate::connect(this, &QQuickTextEdit::readOnlyChanged,
d, &QQuickTextAreaPrivate::readOnlyChanged);
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+ if (qEnvironmentVariable("QT_QUICK_CONTROLS_TEXT_SELECTION_BEHAVIOR") == u"old"_s)
+ QQuickTextEdit::setOldSelectionDefault();
+#endif
}
QQuickTextArea::~QQuickTextArea()
diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp
index 99f9b757c1..3e6d2a48a7 100644
--- a/src/quicktemplates2/qquicktextfield.cpp
+++ b/src/quicktemplates2/qquicktextfield.cpp
@@ -17,6 +17,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
/*!
\qmltype TextField
\inherits TextInput
@@ -377,6 +379,10 @@ QQuickTextField::QQuickTextField(QQuickItem *parent)
#endif
QObjectPrivate::connect(this, &QQuickTextInput::readOnlyChanged, d, &QQuickTextFieldPrivate::readOnlyChanged);
QObjectPrivate::connect(this, &QQuickTextInput::echoModeChanged, d, &QQuickTextFieldPrivate::echoModeChanged);
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+ if (qEnvironmentVariable("QT_QUICK_CONTROLS_TEXT_SELECTION_BEHAVIOR") == u"old"_s)
+ QQuickTextInput::setOldSelectionDefault();
+#endif
}
QQuickTextField::~QQuickTextField()
@@ -880,9 +886,12 @@ void QQuickTextField::mouseMoveEvent(QMouseEvent *event)
QQuickTextInput::mousePressEvent(d->pressHandler.delayedMousePressEvent);
d->pressHandler.clearDelayedMouseEvent();
}
- const auto devType = event->device()->type();
- if (event->buttons() != Qt::RightButton &&
- (devType == QInputDevice::DeviceType::Mouse || devType == QInputDevice::DeviceType::TouchPad))
+ const bool isMouse = QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(event)
+ #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+ || d->selectByTouchDrag
+ #endif
+ ;
+ if (event->buttons() != Qt::RightButton && isMouse)
QQuickTextInput::mouseMoveEvent(event);
}
}
diff --git a/src/quicktemplates2/qquicktooltip.cpp b/src/quicktemplates2/qquicktooltip.cpp
index 5ec4e00964..7703d57b53 100644
--- a/src/quicktemplates2/qquicktooltip.cpp
+++ b/src/quicktemplates2/qquicktooltip.cpp
@@ -47,6 +47,8 @@ QT_BEGIN_NAMESPACE
shown for the last item that made it visible. The position of the shared tool
tip is determined by the framework.
+ \include qquicktooltip.qdocinc customize-note
+
\section2 Delay and Timeout
Tool tips are typically transient in a sense that they are shown as a
diff --git a/src/quicktemplates2/qquicktreeviewdelegate.cpp b/src/quicktemplates2/qquicktreeviewdelegate.cpp
index 022d1ebf5c..f21b215dfe 100644
--- a/src/quicktemplates2/qquicktreeviewdelegate.cpp
+++ b/src/quicktemplates2/qquicktreeviewdelegate.cpp
@@ -68,34 +68,39 @@ QT_BEGIN_NAMESPACE
such as \l {AbstractButton::clicked()}{clicked} when the user clicks on the delegate.
If needed, you could connect to that signal to implement application specific
functionality, in addition to the default expand/collapse behavior (and even set \l
- {QQuickTableView::pointerNavigationEnabled}{pointerNavigationEnabled} to \c false, to
+ {TableView::pointerNavigationEnabled}{pointerNavigationEnabled} to \c false, to
disable the default behavior as well).
But the ItemDelegate API does not give you information about the position of the
click, or which modifiers are being held. If this is needed, a better approach would
- be to use pointer handlers. To ensure that they don't interfere with the
- existing logic in TreeViewDelegate, install them on a child item, e.g:
+ be to use pointer handlers, for example:
\code
TreeView {
id: treeView
delegate: TreeViewDelegate {
- Item {
- anchors.fill: parent
- TapHandler {
- acceptedModifiers: Qt.ControlModifier
- onTapped: {
- if (treeView.isExpanded(row))
- treeView.collapseRecursively(row)
- else
- treeView.expandRecursively(row)
- }
+ TapHandler {
+ acceptedButtons: Qt.RightButton
+ onTapped: someContextMenu.open()
+ }
+
+ TapHandler {
+ acceptedModifiers: Qt.ControlModifier
+ onTapped: {
+ if (treeView.isExpanded(row))
+ treeView.collapseRecursively(row)
+ else
+ treeView.expandRecursively(row)
}
}
}
}
\endcode
+ \note If you want to disable the default behavior that occurs when the
+ user clicks on the delegate (like changing the current index), you can set
+ {QQuickTableView::pointerNavigationEnabled}{pointerNavigationEnabled} to \c false.
+
\sa TreeView
*/
@@ -145,7 +150,7 @@ QT_BEGIN_NAMESPACE
This property holds if the delegate represent the
\l {QItemSelectionModel::currentIndex()}{current index}
- in the \l {QQuickTableView::selectionModel()}{selection model}.
+ in the \l {TableView::selectionModel}{selection model}.
*/
/*!
@@ -153,7 +158,7 @@ QT_BEGIN_NAMESPACE
This property holds if the delegate represent a
\l {QItemSelectionModel::selection()}{selected index}
- in the \l {QQuickTableView::selectionModel()}{selection model}.
+ in the \l {TableView::selectionModel}{selection model}.
*/
/*!
@@ -183,19 +188,21 @@ QT_BEGIN_NAMESPACE
\sa leftMargin, indentation, {QQuickControl::}{spacing}
*/
+using namespace Qt::Literals::StringLiterals;
+
class QQuickTreeViewDelegatePrivate : public QQuickItemDelegatePrivate
{
public:
Q_DECLARE_PUBLIC(QQuickTreeViewDelegate)
void updateIndicatorVisibility();
+ void updateIndicatorPointerHandlers();
+ void toggleExpanded();
QPalette defaultPalette() const override;
- bool posOnTopOfIndicator(const QPointF &pos);
- void handleClickOnIndicator(QMouseEvent *event, bool isPress);
- void setCurrentIndex(const QPointF pos);
public:
QPointer<QQuickTreeView> m_treeView;
+ QPointer<QQuickTapHandler> m_tapHandlerOnIndicator;
qreal m_indentation = 18;
qreal m_leftMargin = 0;
qreal m_rightMargin = 0;
@@ -208,86 +215,86 @@ public:
int m_depth = 0;
};
-void QQuickTreeViewDelegatePrivate::updateIndicatorVisibility()
-{
- Q_Q(QQuickTreeViewDelegate);
-
- if (auto indicator = q_func()->indicator()) {
- const bool insideDelegateBounds = indicator->x() + indicator->width() < q->width();
- indicator->setVisible(m_isTreeNode && m_hasChildren && insideDelegateBounds);
- }
-}
-
-bool QQuickTreeViewDelegatePrivate::posOnTopOfIndicator(const QPointF &pos)
-{
- Q_Q(QQuickTreeViewDelegate);
-
- const auto indicator = q->indicator();
- if (!indicator || !indicator->isVisible())
- return false;
-
- const auto posInIndicator = q->mapToItem(indicator, pos);
- if (!indicator->contains(posInIndicator))
- return false;
-
- return true;
-}
-
-void QQuickTreeViewDelegatePrivate::handleClickOnIndicator(QMouseEvent *event, bool isPress)
+void QQuickTreeViewDelegatePrivate::toggleExpanded()
{
Q_Q(QQuickTreeViewDelegate);
- event->accept();
-
- // To not interfere with flicking, we only toggle expanded on press
- // if the flickable is not interactive. Otherwise we do it on release.
- const bool interactOnRelease = q->treeView()->isInteractive();
- if (isPress == interactOnRelease)
- return;
-
auto view = q->treeView();
if (!view)
return;
+ if (!view->pointerNavigationEnabled())
+ return;
- const int row = qmlContext(q)->contextProperty(QStringLiteral("row")).toInt();
+ const int row = qmlContext(q)->contextProperty(u"row"_s).toInt();
view->toggleExpanded(row);
}
-void QQuickTreeViewDelegatePrivate::setCurrentIndex(const QPointF pos)
+void QQuickTreeViewDelegatePrivate::updateIndicatorPointerHandlers()
{
Q_Q(QQuickTreeViewDelegate);
- auto view = q->treeView();
- if (!view)
- return;
+ // Remove the tap handler that was installed
+ // on the previous indicator
+ delete m_tapHandlerOnIndicator.data();
- if (!view->pointerNavigationEnabled())
+ auto indicator = q->indicator();
+ if (!indicator)
return;
- const auto posOnContentItem = q->mapToItem(view->contentItem(), pos);
- const QPoint cell = view->cellAtPosition(posOnContentItem);
- if (cell.x() == -1 && cell.y() == -1)
- return;
+ m_tapHandlerOnIndicator = new QQuickTapHandler(indicator);
+ m_tapHandlerOnIndicator->setAcceptedModifiers(Qt::NoModifier);
+ // Work-around to block taps from passing through to TreeView.
+ m_tapHandlerOnIndicator->setGesturePolicy(QQuickTapHandler::ReleaseWithinBounds);
+ connect(m_tapHandlerOnIndicator, &QQuickTapHandler::tapped, this, &QQuickTreeViewDelegatePrivate::toggleExpanded);
+}
- QItemSelectionModel *model = view->selectionModel();
- if (!model)
- return;
+void QQuickTreeViewDelegatePrivate::updateIndicatorVisibility()
+{
+ Q_Q(QQuickTreeViewDelegate);
- model->setCurrentIndex(view->modelIndex(cell), QItemSelectionModel::NoUpdate);
- view->positionViewAtCell(cell, QQuickTableView::Contain);
- view->forceActiveFocus();
+ if (auto indicator = q_func()->indicator()) {
+ const bool insideDelegateBounds = indicator->x() + indicator->width() < q->width();
+ indicator->setVisible(m_isTreeNode && m_hasChildren && insideDelegateBounds);
+ }
}
QQuickTreeViewDelegate::QQuickTreeViewDelegate(QQuickItem *parent)
: QQuickItemDelegate(*(new QQuickTreeViewDelegatePrivate), parent)
{
+ Q_D(QQuickTreeViewDelegate);
+
+ auto tapHandler = new QQuickTapHandler(this);
+ tapHandler->setAcceptedModifiers(Qt::NoModifier);
+ QObjectPrivate::connect(tapHandler, &QQuickTapHandler::doubleTapped, d_func(), &QQuickTreeViewDelegatePrivate::toggleExpanded);
+ QObjectPrivate::connect(this, &QQuickAbstractButton::indicatorChanged, d, &QQuickTreeViewDelegatePrivate::updateIndicatorPointerHandlers);
+
+ // Since we override mousePressEvent to avoid QQuickAbstractButton from blocking
+ // pointer handlers, we inform the button about its pressed state from the tap
+ // handler instead. This will ensure that we emit button signals like
+ // pressed, clicked, and doubleClicked.
+ connect(tapHandler, &QQuickTapHandler::pressedChanged, [this, d, tapHandler] {
+ auto view = treeView();
+ if (view && !view->pointerNavigationEnabled())
+ return;
+
+ const QQuickHandlerPoint p = tapHandler->point();
+ if (tapHandler->isPressed())
+ d->handlePress(p.position(), 0);
+ else if (tapHandler->tapCount() > 0)
+ d->handleRelease(p.position(), 0);
+ else
+ d->handleUngrab();
+
+ if (tapHandler->tapCount() > 1 && !tapHandler->isPressed())
+ emit doubleClicked();
+ });
}
void QQuickTreeViewDelegate::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickTreeViewDelegate);
- QQuickAbstractButton::geometryChange(newGeometry, oldGeometry);
+ QQuickItemDelegate::geometryChange(newGeometry, oldGeometry);
d->updateIndicatorVisibility();
}
@@ -295,67 +302,17 @@ void QQuickTreeViewDelegate::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickTreeViewDelegate);
- if (d->m_treeView && !d->m_treeView->pointerNavigationEnabled()) {
- QQuickAbstractButton::mousePressEvent(event);
- return;
- }
-
- d->m_pressOnTopOfIndicator = d->posOnTopOfIndicator(event->position());
- if (d->m_pressOnTopOfIndicator) {
- d->handleClickOnIndicator(event, true);
- return;
- }
-
- const bool interactOnPress = !treeView()->isInteractive();
- if (interactOnPress && contains(event->position())) {
- d->setCurrentIndex(event->position());
- if (d->m_treeView && d->m_treeView->selectionModel())
- d->m_treeView->selectionModel()->clearSelection();
- }
-
- QQuickAbstractButton::mousePressEvent(event);
-}
-
-void QQuickTreeViewDelegate::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_D(QQuickTreeViewDelegate);
-
- if (d->m_pressOnTopOfIndicator) {
- if (d->posOnTopOfIndicator(event->position()))
- d->handleClickOnIndicator(event, false);
- return;
- }
-
- const bool interactOnRelease = treeView()->isInteractive();
- if (interactOnRelease && contains(event->position())) {
- d->setCurrentIndex(event->position());
- if (d->m_treeView && d->m_treeView->selectionModel())
- d->m_treeView->selectionModel()->clearSelection();
- }
-
- QQuickAbstractButton::mouseReleaseEvent(event);
-}
-
-void QQuickTreeViewDelegate::mouseDoubleClickEvent(QMouseEvent *event)
-{
- Q_D(QQuickTreeViewDelegate);
-
- if (d->m_treeView && !d->m_treeView->pointerNavigationEnabled()) {
- QQuickAbstractButton::mouseDoubleClickEvent(event);
+ const auto view = d->m_treeView;
+ if (view && view->pointerNavigationEnabled()) {
+ // Ignore mouse events so that we don't block our own pointer handlers, or
+ // pointer handlers in e.g TreeView, TableView, or SelectionRectangle. Instead
+ // we call out to the needed mouse handling functions in QAbstractButton directly
+ // from our pointer handlers, to ensure that continue to work as a button.
+ event->ignore();
return;
}
- event->accept();
-
- if (d->posOnTopOfIndicator(event->position()))
- return;
-
- if (auto view = treeView()) {
- const int row = qmlContext(this)->contextProperty(QStringLiteral("row")).toInt();
- view->toggleExpanded(row);
- }
-
- QQuickAbstractButton::mouseDoubleClickEvent(event);
+ QQuickItemDelegate::mousePressEvent(event);
}
QPalette QQuickTreeViewDelegatePrivate::defaultPalette() const
@@ -492,8 +449,10 @@ void QQuickTreeViewDelegate::setTreeView(QQuickTreeView *treeView)
void QQuickTreeViewDelegate::componentComplete()
{
- QQuickAbstractButton::componentComplete();
- d_func()->updateIndicatorVisibility();
+ Q_D(QQuickTreeViewDelegate);
+ QQuickItemDelegate::componentComplete();
+ d->updateIndicatorVisibility();
+ d->updateIndicatorPointerHandlers();
}
qreal QQuickTreeViewDelegate::leftMargin() const
diff --git a/src/quicktemplates2/qquicktreeviewdelegate_p.h b/src/quicktemplates2/qquicktreeviewdelegate_p.h
index 60acb7f221..de85f7c2cd 100644
--- a/src/quicktemplates2/qquicktreeviewdelegate_p.h
+++ b/src/quicktemplates2/qquicktreeviewdelegate_p.h
@@ -94,8 +94,6 @@ protected:
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void componentComplete() override;
void mousePressEvent(QMouseEvent *event) override;
- void mouseReleaseEvent(QMouseEvent *event) override;
- void mouseDoubleClickEvent(QMouseEvent *event) override;
private:
Q_DISABLE_COPY(QQuickTreeViewDelegate)
diff --git a/src/quicktestutils/qml/testhttpserver.cpp b/src/quicktestutils/qml/testhttpserver.cpp
index 5a9cb6a1cd..9873cd1827 100644
--- a/src/quicktestutils/qml/testhttpserver.cpp
+++ b/src/quicktestutils/qml/testhttpserver.cpp
@@ -165,7 +165,7 @@ bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &bod
if (headers_done) {
m_waitData.body.append(line);
} else if (line.endsWith("{{Ignore}}\n")) {
- m_waitData.headerPrefixes.append(line.left(line.length() - strlen("{{Ignore}}\n")));
+ m_waitData.headerPrefixes.append(line.left(line.size() - strlen("{{Ignore}}\n")));
} else {
line.replace("{{ServerHostUrl}}", serverHostUrl);
m_waitData.headerExactMatches.append(line);
@@ -177,7 +177,7 @@ bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &bod
if (!m_replyData.endsWith('\n'))
m_replyData.append('\n');
m_replyData.append("Content-length: ");
- m_replyData.append(QByteArray::number(m_bodyData.length()));
+ m_replyData.append(QByteArray::number(m_bodyData.size()));
m_replyData.append("\n\n");
for (int ii = 0; ii < m_replyData.size(); ++ii) {
@@ -216,7 +216,7 @@ void TestHTTPServer::disconnected()
return;
m_dataCache.remove(socket);
- for (int ii = 0; ii < m_toSend.count(); ++ii) {
+ for (int ii = 0; ii < m_toSend.size(); ++ii) {
if (m_toSend.at(ii).first == socket) {
m_toSend.removeAt(ii);
--ii;
@@ -237,7 +237,7 @@ void TestHTTPServer::readyRead()
return;
}
- if (m_state == Failed || (m_waitData.body.isEmpty() && m_waitData.headerExactMatches.count() == 0)) {
+ if (m_state == Failed || (m_waitData.body.isEmpty() && m_waitData.headerExactMatches.size() == 0)) {
qWarning() << "TestHTTPServer: Unexpected data" << socket->readAll();
return;
}
@@ -301,7 +301,7 @@ bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileNameIn)
return true;
}
- for (int ii = 0; ii < m_directories.count(); ++ii) {
+ for (int ii = 0; ii < m_directories.size(); ++ii) {
const QString &dir = m_directories.at(ii).first;
const Mode mode = m_directories.at(ii).second;
diff --git a/src/quicktestutils/quick/viewtestutils.cpp b/src/quicktestutils/quick/viewtestutils.cpp
index 9249f4bfad..19e29928bb 100644
--- a/src/quicktestutils/quick/viewtestutils.cpp
+++ b/src/quicktestutils/quick/viewtestutils.cpp
@@ -7,6 +7,7 @@
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickView>
#include <QtGui/QScreen>
+#include <QtGui/qpa/qwindowsysteminterface.h>
#include <QtTest/QTest>
@@ -78,7 +79,7 @@ void QQuickViewTestUtils::flick(QQuickView *window, const QPoint &from, const QP
QList<int> QQuickViewTestUtils::adjustIndexesForAddDisplaced(const QList<int> &indexes, int index, int count)
{
QList<int> result;
- for (int i=0; i<indexes.count(); i++) {
+ for (int i=0; i<indexes.size(); i++) {
int num = indexes[i];
if (num >= index) {
num += count;
@@ -91,7 +92,7 @@ QList<int> QQuickViewTestUtils::adjustIndexesForAddDisplaced(const QList<int> &i
QList<int> QQuickViewTestUtils::adjustIndexesForMove(const QList<int> &indexes, int from, int to, int count)
{
QList<int> result;
- for (int i=0; i<indexes.count(); i++) {
+ for (int i=0; i<indexes.size(); i++) {
int num = indexes[i];
if (from < to) {
if (num >= from && num < from + count)
@@ -112,7 +113,7 @@ QList<int> QQuickViewTestUtils::adjustIndexesForMove(const QList<int> &indexes,
QList<int> QQuickViewTestUtils::adjustIndexesForRemoveDisplaced(const QList<int> &indexes, int index, int count)
{
QList<int> result;
- for (int i=0; i<indexes.count(); i++) {
+ for (int i=0; i<indexes.size(); i++) {
int num = indexes[i];
if (num >= index)
num -= count;
@@ -129,7 +130,7 @@ QQuickViewTestUtils::QaimModel::QaimModel(QObject *parent)
int QQuickViewTestUtils::QaimModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
- return list.count();
+ return list.size();
}
int QQuickViewTestUtils::QaimModel::columnCount(const QModelIndex &parent) const
@@ -174,15 +175,15 @@ QString QQuickViewTestUtils::QaimModel::number(int index) const
void QQuickViewTestUtils::QaimModel::addItem(const QString &name, const QString &number)
{
- emit beginInsertRows(QModelIndex(), list.count(), list.count());
+ emit beginInsertRows(QModelIndex(), list.size(), list.size());
list.append(QPair<QString,QString>(name, number));
emit endInsertRows();
}
void QQuickViewTestUtils::QaimModel::addItems(const QList<QPair<QString, QString> > &items)
{
- emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1);
- for (int i=0; i<items.count(); i++)
+ emit beginInsertRows(QModelIndex(), list.size(), list.size()+items.size()-1);
+ for (int i=0; i<items.size(); i++)
list.append(QPair<QString,QString>(items[i].first, items[i].second));
emit endInsertRows();
}
@@ -196,8 +197,8 @@ void QQuickViewTestUtils::QaimModel::insertItem(int index, const QString &name,
void QQuickViewTestUtils::QaimModel::insertItems(int index, const QList<QPair<QString, QString> > &items)
{
- emit beginInsertRows(QModelIndex(), index, index+items.count()-1);
- for (int i=0; i<items.count(); i++)
+ emit beginInsertRows(QModelIndex(), index, index+items.size()-1);
+ for (int i=0; i<items.size(); i++)
list.insert(index + i, QPair<QString,QString>(items[i].first, items[i].second));
emit endInsertRows();
}
@@ -239,7 +240,7 @@ void QQuickViewTestUtils::QaimModel::modifyItem(int idx, const QString &name, co
void QQuickViewTestUtils::QaimModel::clear()
{
- int count = list.count();
+ int count = list.size();
if (count > 0) {
beginRemoveRows(QModelIndex(), 0, count-1);
list.clear();
@@ -275,11 +276,11 @@ private:
};
void QQuickViewTestUtils::QaimModel::matchAgainst(const QList<QPair<QString, QString> > &other, const QString &error1, const QString &error2) {
- for (int i=0; i<other.count(); i++) {
+ for (int i=0; i<other.size(); i++) {
QVERIFY2(list.contains(other[i]),
ScopedPrintable(other[i].first + QLatin1Char(' ') + other[i].second + QLatin1Char(' ') + error1));
}
- for (int i=0; i<list.count(); i++) {
+ for (int i=0; i<list.size(); i++) {
QVERIFY2(other.contains(list[i]),
ScopedPrintable(list[i].first + QLatin1Char(' ') + list[i].second + QLatin1Char(' ') + error2));
}
@@ -336,7 +337,7 @@ bool QQuickViewTestUtils::ListRange::isValid() const
int QQuickViewTestUtils::ListRange::count() const
{
- return indexes.count();
+ return indexes.size();
}
QList<QPair<QString,QString> > QQuickViewTestUtils::ListRange::getModelDataValues(const QaimModel &model)
@@ -344,7 +345,7 @@ QList<QPair<QString,QString> > QQuickViewTestUtils::ListRange::getModelDataValue
QList<QPair<QString,QString> > data;
if (!valid)
return data;
- for (int i=0; i<indexes.count(); i++)
+ for (int i=0; i<indexes.size(); i++)
data.append(qMakePair(model.name(indexes[i]), model.number(indexes[i])));
return data;
}
@@ -395,7 +396,7 @@ bool QQuickViewTestUtils::testVisibleItems(const QQuickItemViewPrivate *priv, bo
QHash<QQuickItem*, int> uniqueItems;
int skip = 0;
- for (int i = 0; i < priv->visibleItems.count(); ++i) {
+ for (int i = 0; i < priv->visibleItems.size(); ++i) {
FxViewItem *item = priv->visibleItems.at(i);
if (!item) {
*failItem = nullptr;
@@ -446,6 +447,10 @@ namespace QQuickTouchUtils {
}
+namespace QTest {
+ int Q_TESTLIB_EXPORT defaultMouseDelay();
+}
+
namespace QQuickTest {
/*! \internal
@@ -503,6 +508,88 @@ namespace QQuickTest {
return false;
return true;
}
+
+ // TODO maybe move the generic pointerPress/Move/Release functions to QTestLib later on
+
+ static Qt::MouseButton pressedTabletButton = Qt::NoButton;
+ static Qt::KeyboardModifiers pressedTabletModifiers = Qt::NoModifier;
+
+ void pointerPress(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p,
+ Qt::MouseButton button, Qt::KeyboardModifiers modifiers)
+ {
+ switch (dev->type()) {
+ case QPointingDevice::DeviceType::Mouse:
+ case QPointingDevice::DeviceType::TouchPad:
+ QTest::mousePress(window, button, modifiers, p);
+ break;
+ case QPointingDevice::DeviceType::TouchScreen:
+ QTest::touchEvent(window, const_cast<QPointingDevice *>(dev)).press(pointId, p, window);
+ QQuickTouchUtils::flush(window);
+ break;
+ case QPointingDevice::DeviceType::Puck:
+ case QPointingDevice::DeviceType::Stylus:
+ case QPointingDevice::DeviceType::Airbrush:
+ QTest::lastMouseTimestamp += QTest::defaultMouseDelay();
+ pressedTabletButton = button;
+ pressedTabletModifiers = modifiers;
+ QWindowSystemInterface::handleTabletEvent(window, QTest::lastMouseTimestamp, dev, p, window->mapToGlobal(p),
+ button, 0.8, 0, 0, 0, 0, 0, modifiers);
+ break;
+ default:
+ qWarning() << "can't send a press event from" << dev;
+ break;
+ }
+ }
+
+ void pointerMove(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p)
+ {
+ switch (dev->type()) {
+ case QPointingDevice::DeviceType::Mouse:
+ case QPointingDevice::DeviceType::TouchPad:
+ QTest::mouseMove(window, p);
+ break;
+ case QPointingDevice::DeviceType::TouchScreen:
+ QTest::touchEvent(window, const_cast<QPointingDevice *>(dev)).move(pointId, p, window);
+ QQuickTouchUtils::flush(window);
+ break;
+ case QPointingDevice::DeviceType::Puck:
+ case QPointingDevice::DeviceType::Stylus:
+ case QPointingDevice::DeviceType::Airbrush:
+ QTest::lastMouseTimestamp += QTest::defaultMouseDelay();
+ QWindowSystemInterface::handleTabletEvent(window, QTest::lastMouseTimestamp, dev, p, window->mapToGlobal(p),
+ pressedTabletButton, 0, 0, 0, 0, 0, 0, pressedTabletModifiers);
+ break;
+ default:
+ qWarning() << "can't send a move event from" << dev;
+ break;
+ }
+ }
+
+ void pointerRelease(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p,
+ Qt::MouseButton button, Qt::KeyboardModifiers modifiers)
+ {
+ switch (dev->type()) {
+ case QPointingDevice::DeviceType::Mouse:
+ case QPointingDevice::DeviceType::TouchPad:
+ QTest::mouseRelease(window, button, modifiers, p);
+ break;
+ case QPointingDevice::DeviceType::TouchScreen:
+ QTest::touchEvent(window, const_cast<QPointingDevice *>(dev)).release(pointId, p, window);
+ QQuickTouchUtils::flush(window);
+ break;
+ case QPointingDevice::DeviceType::Puck:
+ case QPointingDevice::DeviceType::Stylus:
+ case QPointingDevice::DeviceType::Airbrush:
+ QTest::lastMouseTimestamp += QTest::defaultMouseDelay();
+ QWindowSystemInterface::handleTabletEvent(window, QTest::lastMouseTimestamp, dev, p, window->mapToGlobal(p),
+ Qt::NoButton, 0, 0, 0, 0, 0, 0, modifiers);
+ break;
+ default:
+ qWarning() << "can't send a press event from" << dev;
+ break;
+ }
+ }
+
}
QT_END_NAMESPACE
diff --git a/src/quicktestutils/quick/viewtestutils_p.h b/src/quicktestutils/quick/viewtestutils_p.h
index b729fcf3fa..ff8905afa6 100644
--- a/src/quicktestutils/quick/viewtestutils_p.h
+++ b/src/quicktestutils/quick/viewtestutils_p.h
@@ -179,6 +179,17 @@ namespace QQuickTest {
[[nodiscard]] bool initView(QQuickView &v, const QUrl &url,
bool moveMouseOut = true, QByteArray *errorMessage = nullptr);
[[nodiscard]] bool showView(QQuickView &v, const QUrl &url);
+
+ void pointerPress(const QPointingDevice *dev, QQuickWindow *window,
+ int pointId, const QPoint &p, Qt::MouseButton button = Qt::LeftButton,
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+
+ void pointerMove(const QPointingDevice *dev, QQuickWindow *window, int pointId,
+ const QPoint &p);
+
+ void pointerRelease(const QPointingDevice *dev, QQuickWindow *window, int pointId,
+ const QPoint &p, Qt::MouseButton button = Qt::LeftButton,
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier);
}
QT_END_NAMESPACE
diff --git a/src/quicktestutils/quick/visualtestutils.cpp b/src/quicktestutils/quick/visualtestutils.cpp
index b7bd561028..ddbf8ca9f6 100644
--- a/src/quicktestutils/quick/visualtestutils.cpp
+++ b/src/quicktestutils/quick/visualtestutils.cpp
@@ -15,7 +15,7 @@ QQuickItem *QQuickVisualTestUtils::findVisibleChild(QQuickItem *parent, const QS
{
QQuickItem *item = nullptr;
QList<QQuickItem*> items = parent->findChildren<QQuickItem*>(objectName);
- for (int i = 0; i < items.count(); ++i) {
+ for (int i = 0; i < items.size(); ++i) {
if (items.at(i)->isVisible() && !QQuickItemPrivate::get(items.at(i))->culled) {
item = items.at(i);
break;
@@ -27,7 +27,7 @@ QQuickItem *QQuickVisualTestUtils::findVisibleChild(QQuickItem *parent, const QS
void QQuickVisualTestUtils::dumpTree(QQuickItem *parent, int depth)
{
static QString padding = QStringLiteral(" ");
- for (int i = 0; i < parent->childItems().count(); ++i) {
+ for (int i = 0; i < parent->childItems().size(); ++i) {
QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
if (!item)
continue;
diff --git a/src/quicktestutils/quick/visualtestutils_p.h b/src/quicktestutils/quick/visualtestutils_p.h
index 953d374327..ae618a04e0 100644
--- a/src/quicktestutils/quick/visualtestutils_p.h
+++ b/src/quicktestutils/quick/visualtestutils_p.h
@@ -46,7 +46,7 @@ namespace QQuickVisualTestUtils
using namespace Qt::StringLiterals;
const QMetaObject &mo = T::staticMetaObject;
- for (int i = 0; i < parent->childItems().count(); ++i) {
+ for (int i = 0; i < parent->childItems().size(); ++i) {
QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
if (!item)
continue;
@@ -75,7 +75,7 @@ namespace QQuickVisualTestUtils
{
QList<T*> items;
const QMetaObject &mo = T::staticMetaObject;
- for (int i = 0; i < parent->childItems().count(); ++i) {
+ for (int i = 0; i < parent->childItems().size(); ++i) {
QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
if (!item || (visibleOnly && (!item->isVisible() || QQuickItemPrivate::get(item)->culled)))
continue;
@@ -91,7 +91,7 @@ namespace QQuickVisualTestUtils
QList<T*> findItems(QQuickItem *parent, const QString &objectName, const QList<int> &indexes)
{
QList<T*> items;
- for (int i=0; i<indexes.count(); i++)
+ for (int i=0; i<indexes.size(); i++)
items << qobject_cast<QQuickItem*>(findItem<T>(parent, objectName, indexes[i]));
return items;
}
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index c4c313172e..b8bd2aca2f 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -249,7 +249,10 @@ void QQuickWidgetPrivate::handleWindowChange()
QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
- execute();
+ if (!source.isEmpty())
+ execute();
+ else if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(root))
+ sgItem->setParentItem(offscreenWindow->contentItem());
}
QQuickWidgetPrivate::QQuickWidgetPrivate()
@@ -610,6 +613,7 @@ QQuickWidget::QQuickWidget(QWidget *parent)
{
setMouseTracking(true);
setFocusPolicy(Qt::StrongFocus);
+ setAttribute(Qt::WA_AcceptTouchEvents);
d_func()->init();
}
@@ -1620,9 +1624,23 @@ bool QQuickWidget::event(QEvent *e)
case QEvent::TouchBegin:
case QEvent::TouchEnd:
case QEvent::TouchUpdate:
- case QEvent::TouchCancel:
+ case QEvent::TouchCancel: {
// Touch events only have local and global positions, no need to map.
- return QCoreApplication::sendEvent(d->offscreenWindow, e);
+ bool res = QCoreApplication::sendEvent(d->offscreenWindow, e);
+ if (e->isAccepted() && e->type() == QEvent::TouchBegin) {
+ // If the TouchBegin got accepted, then make sure all points that have
+ // an exclusive grabber are also accepted so that the widget code for
+ // delivering touch events make this widget an implicit grabber of those
+ // points.
+ QPointerEvent *pointerEvent = static_cast<QPointerEvent *>(e);
+ auto deliveredPoints = pointerEvent->points();
+ for (auto &point : deliveredPoints) {
+ if (pointerEvent->exclusiveGrabber(point))
+ point.setAccepted(true);
+ }
+ }
+ return res;
+ }
case QEvent::FocusAboutToChange:
return QCoreApplication::sendEvent(d->offscreenWindow, e);