aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/3rdparty/cplusplus/TranslationUnit.cpp85
-rw-r--r--src/libs/3rdparty/cplusplus/TranslationUnit.h23
-rw-r--r--src/libs/3rdparty/libptyqt/conptyprocess.cpp80
-rw-r--r--src/libs/3rdparty/libptyqt/conptyprocess.h77
-rw-r--r--src/libs/3rdparty/libptyqt/iptyprocess.h8
-rw-r--r--src/libs/3rdparty/libptyqt/ptyqt.cpp13
-rw-r--r--src/libs/3rdparty/libptyqt/ptyqt.h2
-rw-r--r--src/libs/3rdparty/libptyqt/ptyqt.qbs65
-rw-r--r--src/libs/3rdparty/libptyqt/unixptyprocess.cpp12
-rw-r--r--src/libs/3rdparty/libptyqt/unixptyprocess.h2
-rw-r--r--src/libs/3rdparty/libptyqt/winptyprocess.cpp2
-rw-r--r--src/libs/3rdparty/libptyqt/winptyprocess.h2
-rw-r--r--src/libs/3rdparty/libvterm/include/vterm.h2
-rw-r--r--src/libs/3rdparty/libvterm/src/mouse.c2
-rw-r--r--src/libs/3rdparty/libvterm/src/screen.c14
-rw-r--r--src/libs/3rdparty/libvterm/src/state.c56
-rw-r--r--src/libs/3rdparty/libvterm/src/vterm.c1
-rw-r--r--src/libs/3rdparty/libvterm/src/vterm_internal.h1
-rw-r--r--src/libs/3rdparty/libvterm/vterm.qbs59
-rw-r--r--src/libs/3rdparty/tl_expected/include/tl/expected.hpp758
-rw-r--r--src/libs/3rdparty/winpty/winpty.qbs5
-rw-r--r--src/libs/3rdparty/yaml-cpp/README.md59
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/anchor.h2
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/binary.h12
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/depthguard.h77
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h85
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitfromevents.h24
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitter.h35
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emittermanip.h19
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/eventhandler.h9
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h94
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/convert.h276
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h26
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/impl.h116
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator.h11
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h4
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/memory.h7
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node.h32
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_data.h24
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h28
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/impl.h173
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/iterator.h5
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/node.h11
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/ptr.h11
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noexcept.h18
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noncopyable.h25
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/ostream_wrapper.h10
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/parser.h10
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/stlemitter.h9
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/traits.h36
-rw-r--r--src/libs/3rdparty/yaml-cpp/patches/0001-yaml-cpp-Strip-unneeded-sources.patch2631
-rw-r--r--src/libs/3rdparty/yaml-cpp/patches/0002-yaml-cpp-Make-dll.h-compatible-with-fvisibility-hidd.patch42
-rw-r--r--src/libs/3rdparty/yaml-cpp/patches/0003-yaml-cpp-MSVC-Fix-unknown-override-specifier-for-_NO.patch52
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/binary.cpp17
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/collectionstack.h6
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/convert.cpp21
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/depthguard.cpp9
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/directives.cpp13
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/directives.h2
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emit.cpp2
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitfromevents.cpp11
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitter.cpp93
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitterstate.cpp97
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitterstate.h17
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitterutils.cpp112
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitterutils.h9
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/exceptions.cpp35
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/exp.cpp21
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/exp.h66
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/memory.cpp4
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/node.cpp2
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/node_data.cpp98
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp16
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/nodebuilder.h36
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/nodeevents.cpp31
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/nodeevents.h12
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/null.cpp2
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/ostream_wrapper.cpp17
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/parse.cpp14
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/parser.cpp28
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/ptr_vector.h12
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/regex_yaml.cpp20
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/regex_yaml.h15
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/regeximpl.h23
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scanner.cpp21
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scanner.h4
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scanscalar.cpp9
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scanscalar.h2
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scantag.cpp2
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scantoken.cpp10
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/setting.h71
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/simplekey.cpp8
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/singledocparser.cpp63
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/singledocparser.h18
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/stream.cpp60
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/stream.h12
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/streamcharsource.h18
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/tag.cpp7
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/tag.h2
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/token.h17
-rw-r--r--src/libs/3rdparty/yaml-cpp/yaml-cpp.pc.cmake11
-rw-r--r--src/libs/3rdparty/yaml-cpp/yaml-cpp.qbs197
-rw-r--r--src/libs/CMakeLists.txt2
-rw-r--r--src/libs/advanceddockingsystem/CMakeLists.txt1
-rw-r--r--src/libs/advanceddockingsystem/ads_globals.cpp1
-rw-r--r--src/libs/advanceddockingsystem/advanceddockingsystem.qbs2
-rw-r--r--src/libs/advanceddockingsystem/autohidetab.cpp17
-rw-r--r--src/libs/advanceddockingsystem/dockareatitlebar.cpp32
-rw-r--r--src/libs/advanceddockingsystem/dockmanager.cpp17
-rw-r--r--src/libs/advanceddockingsystem/dockmanager.h5
-rw-r--r--src/libs/advanceddockingsystem/dockwidgettab.cpp18
-rw-r--r--src/libs/advanceddockingsystem/linux/floatingwidgettitlebar.cpp2
-rw-r--r--src/libs/advanceddockingsystem/workspaceview.cpp1
-rw-r--r--src/libs/aggregation/aggregate.h4
-rw-r--r--src/libs/aggregation/aggregation.qbs23
-rw-r--r--src/libs/cplusplus/CMakeLists.txt1
-rw-r--r--src/libs/cplusplus/CppDocument.cpp4
-rw-r--r--src/libs/cplusplus/CppDocument.h1
-rw-r--r--src/libs/cplusplus/FastPreprocessor.cpp6
-rw-r--r--src/libs/cplusplus/LookupContext.cpp38
-rw-r--r--src/libs/cplusplus/ResolveExpression.cpp8
-rw-r--r--src/libs/cplusplus/SnapshotSymbolVisitor.cpp6
-rw-r--r--src/libs/cplusplus/TypeOfExpression.cpp6
-rw-r--r--src/libs/cplusplus/cplusplus.qbs249
-rw-r--r--src/libs/cplusplus/cppmodelmanagerbase.cpp62
-rw-r--r--src/libs/cplusplus/cppmodelmanagerbase.h37
-rw-r--r--src/libs/cplusplus/declarationcomments.cpp175
-rw-r--r--src/libs/cplusplus/declarationcomments.h35
-rw-r--r--src/libs/extensionsystem/CMakeLists.txt5
-rw-r--r--src/libs/extensionsystem/extensionsystem.qbs71
-rw-r--r--src/libs/extensionsystem/extensionsystem_global.h12
-rw-r--r--src/libs/extensionsystem/iplugin.cpp53
-rw-r--r--src/libs/extensionsystem/iplugin.h25
-rw-r--r--src/libs/extensionsystem/optionsparser.cpp15
-rw-r--r--src/libs/extensionsystem/optionsparser.h2
-rw-r--r--src/libs/extensionsystem/pluginmanager.cpp270
-rw-r--r--src/libs/extensionsystem/pluginmanager.h5
-rw-r--r--src/libs/extensionsystem/pluginmanager_p.h22
-rw-r--r--src/libs/extensionsystem/pluginspec.cpp8
-rw-r--r--src/libs/extensionsystem/pluginspec.h19
-rw-r--r--src/libs/extensionsystem/pluginspec_p.h4
-rw-r--r--src/libs/extensionsystem/pluginview.cpp1
-rw-r--r--src/libs/glsl/glslsymbol.cpp2
-rw-r--r--src/libs/languageserverprotocol/clientcapabilities.cpp42
-rw-r--r--src/libs/languageserverprotocol/clientcapabilities.h10
-rw-r--r--src/libs/languageserverprotocol/jsonkeys.h437
-rw-r--r--src/libs/languageserverprotocol/jsonobject.cpp8
-rw-r--r--src/libs/languageserverprotocol/jsonobject.h65
-rw-r--r--src/libs/languageserverprotocol/languagefeatures.cpp4
-rw-r--r--src/libs/languageserverprotocol/languagefeatures.h4
-rw-r--r--src/libs/languageserverprotocol/languageserverprotocol.qbs96
-rw-r--r--src/libs/languageserverprotocol/lsptypes.cpp78
-rw-r--r--src/libs/languageserverprotocol/lsptypes.h124
-rw-r--r--src/libs/languageserverprotocol/servercapabilities.cpp18
-rw-r--r--src/libs/languageserverprotocol/servercapabilities.h12
-rw-r--r--src/libs/languageserverprotocol/workspace.cpp7
-rw-r--r--src/libs/languageserverprotocol/workspace.h10
-rw-r--r--src/libs/languageutils/languageutils.qbs26
-rw-r--r--src/libs/modelinglib/qmt/config/configcontroller.h4
-rw-r--r--src/libs/modelinglib/qmt/config/textscanner.h5
-rw-r--r--src/libs/modelinglib/qmt/controller/namecontroller.h2
-rw-r--r--src/libs/modelinglib/qmt/controller/undocontroller.h5
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/latchcontroller.h6
-rw-r--r--src/libs/modelinglib/qmt/model_controller/modelcontroller.cpp2
-rw-r--r--src/libs/modelinglib/qmt/model_ui/sortedtreemodel.h4
-rw-r--r--src/libs/modelinglib/qmt/model_ui/treemodelmanager.h5
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.cpp2
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.h6
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.h5
-rw-r--r--src/libs/modelinglib/qmt/stereotype/stereotypecontroller.h4
-rw-r--r--src/libs/modelinglib/qmt/style/stylecontroller.h4
-rw-r--r--src/libs/nanotrace/nanotrace.cpp116
-rw-r--r--src/libs/nanotrace/nanotrace.h2
m---------src/libs/qlitehtml0
-rw-r--r--src/libs/qmldebug/qmldebug.qbs66
-rw-r--r--src/libs/qmleditorwidgets/contextpanewidgetimage.cpp27
-rw-r--r--src/libs/qmljs/CMakeLists.txt1
-rw-r--r--src/libs/qmljs/jsoncheck.cpp722
-rw-r--r--src/libs/qmljs/jsoncheck.h390
-rw-r--r--src/libs/qmljs/qmljs.qbs147
-rw-r--r--src/libs/qmljs/qmljsbundle.cpp22
-rw-r--r--src/libs/qmljs/qmljsbundle.h7
-rw-r--r--src/libs/qmljs/qmljscheck.cpp77
-rw-r--r--src/libs/qmljs/qmljsdialect.cpp2
-rw-r--r--src/libs/qmljs/qmljsfindexportedcpptypes.cpp19
-rw-r--r--src/libs/qmljs/qmljsicontextpane.h34
-rw-r--r--src/libs/qmljs/qmljsinterpreter.cpp28
-rw-r--r--src/libs/qmljs/qmljsinterpreter.h19
-rw-r--r--src/libs/qmljs/qmljslink.cpp19
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.cpp28
-rw-r--r--src/libs/qmljs/qmljsplugindumper.cpp4
-rw-r--r--src/libs/qmljs/qmljsstaticanalysismessage.cpp2
-rw-r--r--src/libs/qmljs/qmljsstaticanalysismessage.h1
-rw-r--r--src/libs/qmlpuppetcommunication/container/sharedmemory_unix.cpp4
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/mainwidget.cpp4
-rw-r--r--src/libs/qtcreatorcdbext/CMakeLists.txt1
-rw-r--r--src/libs/solutions/CMakeLists.txt1
-rw-r--r--src/libs/solutions/solutions.qbs1
-rw-r--r--src/libs/solutions/spinner/icons/spinner_large.pngbin1346 -> 850 bytes
-rw-r--r--src/libs/solutions/spinner/icons/spinner_large@2x.pngbin0 -> 1698 bytes
-rw-r--r--src/libs/solutions/spinner/icons/spinner_medium.pngbin765 -> 447 bytes
-rw-r--r--src/libs/solutions/spinner/icons/spinner_medium@2x.pngbin0 -> 875 bytes
-rw-r--r--src/libs/solutions/spinner/icons/spinner_small.pngbin315 -> 210 bytes
-rw-r--r--src/libs/solutions/spinner/icons/spinner_small@2x.pngbin0 -> 302 bytes
-rw-r--r--src/libs/solutions/spinner/spinner.cpp21
-rw-r--r--src/libs/solutions/spinner/spinner.h2
-rw-r--r--src/libs/solutions/spinner/spinner.qbs9
-rw-r--r--src/libs/solutions/spinner/spinner.qrc3
-rw-r--r--src/libs/solutions/tasking/barrier.h48
-rw-r--r--src/libs/solutions/tasking/concurrentcall.h5
-rw-r--r--src/libs/solutions/tasking/networkquery.h4
-rw-r--r--src/libs/solutions/tasking/tasking.qbs9
-rw-r--r--src/libs/solutions/tasking/tasktree.cpp85
-rw-r--r--src/libs/solutions/tasking/tasktree.h59
-rw-r--r--src/libs/solutions/terminal/CMakeLists.txt13
-rw-r--r--src/libs/solutions/terminal/celliterator.cpp94
-rw-r--r--src/libs/solutions/terminal/celliterator.h99
-rw-r--r--src/libs/solutions/terminal/glyphcache.cpp48
-rw-r--r--src/libs/solutions/terminal/glyphcache.h34
-rw-r--r--src/libs/solutions/terminal/images/passwordlock.pngbin0 -> 840 bytes
-rw-r--r--src/libs/solutions/terminal/keys.cpp90
-rw-r--r--src/libs/solutions/terminal/keys.h15
-rw-r--r--src/libs/solutions/terminal/scrollback.cpp61
-rw-r--r--src/libs/solutions/terminal/scrollback.h57
-rw-r--r--src/libs/solutions/terminal/surfaceintegration.h22
-rw-r--r--src/libs/solutions/terminal/terminal.qbs26
-rw-r--r--src/libs/solutions/terminal/terminal.qrc5
-rw-r--r--src/libs/solutions/terminal/terminal_global.h14
-rw-r--r--src/libs/solutions/terminal/terminalsurface.cpp689
-rw-r--r--src/libs/solutions/terminal/terminalsurface.h119
-rw-r--r--src/libs/solutions/terminal/terminalview.cpp1300
-rw-r--r--src/libs/solutions/terminal/terminalview.h227
-rw-r--r--src/libs/sqlite/sqlite.qbs6
-rw-r--r--src/libs/tracing/CMakeLists.txt10
-rw-r--r--src/libs/tracing/qml/CategoryLabel.qml10
-rw-r--r--src/libs/tracing/qml/TimelineLabels.qml8
-rw-r--r--src/libs/tracing/runscenegraphtest.cpp34
-rw-r--r--src/libs/tracing/runscenegraphtest.h13
-rw-r--r--src/libs/tracing/timelinemodel.cpp48
-rw-r--r--src/libs/tracing/timelinemodel.h1
-rw-r--r--src/libs/tracing/timelinerenderer.cpp35
-rw-r--r--src/libs/tracing/timelinezoomcontrol.cpp4
-rw-r--r--src/libs/tracing/tracing.qbs94
-rw-r--r--src/libs/utils/CMakeLists.txt22
-rw-r--r--src/libs/utils/QtConcurrentTools4
-rw-r--r--src/libs/utils/algorithm.h9
-rw-r--r--src/libs/utils/appinfo.cpp20
-rw-r--r--src/libs/utils/appinfo.h30
-rw-r--r--src/libs/utils/archive.h39
-rw-r--r--src/libs/utils/aspects.cpp2510
-rw-r--r--src/libs/utils/aspects.h756
-rw-r--r--src/libs/utils/async.h5
-rw-r--r--src/libs/utils/basetreeview.cpp20
-rw-r--r--src/libs/utils/basetreeview.h8
-rw-r--r--src/libs/utils/changeset.cpp12
-rw-r--r--src/libs/utils/changeset.h4
-rw-r--r--src/libs/utils/checkablemessagebox.cpp29
-rw-r--r--src/libs/utils/checkablemessagebox.h11
-rw-r--r--src/libs/utils/commandline.cpp8
-rw-r--r--src/libs/utils/commandline.h1
-rw-r--r--src/libs/utils/delegates.cpp2
-rw-r--r--src/libs/utils/delegates.h4
-rw-r--r--src/libs/utils/detailsbutton.h3
-rw-r--r--src/libs/utils/devicefileaccess.cpp126
-rw-r--r--src/libs/utils/devicefileaccess.h4
-rw-r--r--src/libs/utils/deviceshell.cpp91
-rw-r--r--src/libs/utils/deviceshell.h11
-rw-r--r--src/libs/utils/differ.cpp7
-rw-r--r--src/libs/utils/displayname.cpp6
-rw-r--r--src/libs/utils/displayname.h9
-rw-r--r--src/libs/utils/dropsupport.cpp6
-rw-r--r--src/libs/utils/elfreader.h6
-rw-r--r--src/libs/utils/environment.cpp14
-rw-r--r--src/libs/utils/environment.h6
-rw-r--r--src/libs/utils/environmentdialog.h8
-rw-r--r--src/libs/utils/environmentfwd.h4
-rw-r--r--src/libs/utils/environmentmodel.h2
-rw-r--r--src/libs/utils/execmenu.cpp12
-rw-r--r--src/libs/utils/execmenu.h1
-rw-r--r--src/libs/utils/faketooltip.h2
-rw-r--r--src/libs/utils/fancylineedit.cpp186
-rw-r--r--src/libs/utils/fancylineedit.h22
-rw-r--r--src/libs/utils/fancymainwindow.cpp72
-rw-r--r--src/libs/utils/fancymainwindow.h15
-rw-r--r--src/libs/utils/fileinprojectfinder.cpp2
-rw-r--r--src/libs/utils/filepath.cpp222
-rw-r--r--src/libs/utils/filepath.h7
-rw-r--r--src/libs/utils/filesearch.cpp702
-rw-r--r--src/libs/utils/filesearch.h176
-rw-r--r--src/libs/utils/filestreamer.cpp10
-rw-r--r--src/libs/utils/filestreamer.h4
-rw-r--r--src/libs/utils/filesystemmodel.cpp8
-rw-r--r--src/libs/utils/filesystemwatcher.cpp33
-rw-r--r--src/libs/utils/fileutils.cpp17
-rw-r--r--src/libs/utils/fileutils.h3
-rw-r--r--src/libs/utils/filewizardpage.cpp3
-rw-r--r--src/libs/utils/fixedsizeclicklabel.cpp96
-rw-r--r--src/libs/utils/fixedsizeclicklabel.h39
-rw-r--r--src/libs/utils/fsengine/fileiconprovider.cpp72
-rw-r--r--src/libs/utils/fsengine/fileiconprovider.h2
-rw-r--r--src/libs/utils/fsengine/fileiteratordevicesappender.h3
-rw-r--r--src/libs/utils/fsengine/fsenginehandler.cpp15
-rw-r--r--src/libs/utils/functiontraits.h169
-rw-r--r--src/libs/utils/fuzzymatcher.h6
-rw-r--r--src/libs/utils/highlightingitemdelegate.cpp12
-rw-r--r--src/libs/utils/highlightingitemdelegate.h2
-rw-r--r--src/libs/utils/historycompleter.cpp15
-rw-r--r--src/libs/utils/historycompleter.h14
-rw-r--r--src/libs/utils/hostosinfo.cpp13
-rw-r--r--src/libs/utils/hostosinfo.h4
-rw-r--r--src/libs/utils/icon.cpp57
-rw-r--r--src/libs/utils/icon.h8
-rw-r--r--src/libs/utils/iconbutton.cpp62
-rw-r--r--src/libs/utils/iconbutton.h27
-rw-r--r--src/libs/utils/id.cpp6
-rw-r--r--src/libs/utils/id.h3
-rw-r--r--src/libs/utils/images/continue_1_small.pngbin0 -> 93 bytes
-rw-r--r--src/libs/utils/images/continue_1_small@2x.pngbin0 -> 96 bytes
-rw-r--r--src/libs/utils/images/continue_2_small.pngbin0 -> 136 bytes
-rw-r--r--src/libs/utils/images/continue_2_small@2x.pngbin0 -> 161 bytes
-rw-r--r--src/libs/utils/images/debugger_overlay_small.pngbin0 -> 158 bytes
-rw-r--r--src/libs/utils/images/debugger_overlay_small@2x.pngbin0 -> 175 bytes
-rw-r--r--src/libs/utils/infobar.cpp11
-rw-r--r--src/libs/utils/infobar.h9
-rw-r--r--src/libs/utils/itemviews.cpp28
-rw-r--r--src/libs/utils/itemviews.h20
-rw-r--r--src/libs/utils/json.cpp722
-rw-r--r--src/libs/utils/json.h398
-rw-r--r--src/libs/utils/launcherinterface.cpp4
-rw-r--r--src/libs/utils/launchersocket.h1
-rw-r--r--src/libs/utils/layoutbuilder.cpp139
-rw-r--r--src/libs/utils/layoutbuilder.h15
-rw-r--r--src/libs/utils/link.h15
-rw-r--r--src/libs/utils/macroexpander.cpp4
-rw-r--r--src/libs/utils/macroexpander.h3
-rw-r--r--src/libs/utils/mapreduce.h594
-rw-r--r--src/libs/utils/mimetypes2/mimedatabase.cpp56
-rw-r--r--src/libs/utils/mimetypes2/mimedatabase_p.h10
-rw-r--r--src/libs/utils/mimetypes2/mimemagicrule_p.h2
-rw-r--r--src/libs/utils/mimetypes2/mimeprovider.cpp2
-rw-r--r--src/libs/utils/mimetypes2/mimetype.h2
-rw-r--r--src/libs/utils/mimetypes2/mimeutils.cpp24
-rw-r--r--src/libs/utils/mimeutils.h1
-rw-r--r--src/libs/utils/minimizableinfobars.cpp11
-rw-r--r--src/libs/utils/minimizableinfobars.h10
-rw-r--r--src/libs/utils/namevaluedictionary.h2
-rw-r--r--src/libs/utils/namevalueitem.h1
-rw-r--r--src/libs/utils/namevaluesdialog.cpp22
-rw-r--r--src/libs/utils/namevaluesdialog.h23
-rw-r--r--src/libs/utils/namevaluevalidator.h2
-rw-r--r--src/libs/utils/navigationtreeview.cpp3
-rw-r--r--src/libs/utils/navigationtreeview.h1
-rw-r--r--src/libs/utils/networkaccessmanager.h1
-rw-r--r--src/libs/utils/optionpushbutton.cpp7
-rw-r--r--src/libs/utils/optionpushbutton.h2
-rw-r--r--src/libs/utils/overlaywidget.h1
-rw-r--r--src/libs/utils/passworddialog.cpp204
-rw-r--r--src/libs/utils/passworddialog.h68
-rw-r--r--src/libs/utils/pathchooser.cpp119
-rw-r--r--src/libs/utils/pathchooser.h5
-rw-r--r--src/libs/utils/pathlisteditor.cpp2
-rw-r--r--src/libs/utils/persistentcachestore.cpp115
-rw-r--r--src/libs/utils/persistentcachestore.h22
-rw-r--r--src/libs/utils/persistentsettings.cpp186
-rw-r--r--src/libs/utils/persistentsettings.h17
-rw-r--r--src/libs/utils/port.h2
-rw-r--r--src/libs/utils/process.cpp51
-rw-r--r--src/libs/utils/process.h39
-rw-r--r--src/libs/utils/processhandle.cpp2
-rw-r--r--src/libs/utils/processinterface.h24
-rw-r--r--src/libs/utils/processutils.cpp33
-rw-r--r--src/libs/utils/processutils.h5
-rw-r--r--src/libs/utils/progressindicator.h1
-rw-r--r--src/libs/utils/projectintropage.cpp1
-rw-r--r--src/libs/utils/qtcsettings.cpp39
-rw-r--r--src/libs/utils/qtcsettings.h82
-rw-r--r--src/libs/utils/removefiledialog.h2
-rw-r--r--src/libs/utils/runextensions.cpp23
-rw-r--r--src/libs/utils/runextensions.h479
-rw-r--r--src/libs/utils/savefile.cpp4
-rw-r--r--src/libs/utils/searchresultitem.h11
-rw-r--r--src/libs/utils/settingsaccessor.cpp103
-rw-r--r--src/libs/utils/settingsaccessor.h82
-rw-r--r--src/libs/utils/settingsutils.h45
-rw-r--r--src/libs/utils/statuslabel.h2
-rw-r--r--src/libs/utils/store.cpp193
-rw-r--r--src/libs/utils/store.h48
-rw-r--r--src/libs/utils/storekey.h69
-rw-r--r--src/libs/utils/stringtable.h2
-rw-r--r--src/libs/utils/stringutils.cpp42
-rw-r--r--src/libs/utils/stringutils.h3
-rw-r--r--src/libs/utils/styleanimator.h2
-rw-r--r--src/libs/utils/styledbar.h3
-rw-r--r--src/libs/utils/stylehelper.cpp10
-rw-r--r--src/libs/utils/stylehelper.h3
-rw-r--r--src/libs/utils/terminalcommand.cpp15
-rw-r--r--src/libs/utils/terminalcommand.h11
-rw-r--r--src/libs/utils/terminalhooks.cpp22
-rw-r--r--src/libs/utils/terminalhooks.h23
-rw-r--r--src/libs/utils/terminalinterface.cpp8
-rw-r--r--src/libs/utils/textfileformat.cpp13
-rw-r--r--src/libs/utils/textfileformat.h4
-rw-r--r--src/libs/utils/textutils.cpp41
-rw-r--r--src/libs/utils/textutils.h22
-rw-r--r--src/libs/utils/theme/theme_p.h6
-rw-r--r--src/libs/utils/tooltip/tips.h4
-rw-r--r--src/libs/utils/transientscroll.h2
-rw-r--r--src/libs/utils/treemodel.cpp11
-rw-r--r--src/libs/utils/treemodel.h21
-rw-r--r--src/libs/utils/treeviewcombobox.h2
-rw-r--r--src/libs/utils/unarchiver.cpp (renamed from src/libs/utils/archive.cpp)113
-rw-r--r--src/libs/utils/unarchiver.h57
-rw-r--r--src/libs/utils/uncommentselection.cpp50
-rw-r--r--src/libs/utils/uncommentselection.h2
-rw-r--r--src/libs/utils/unixutils.cpp35
-rw-r--r--src/libs/utils/unixutils.h23
-rw-r--r--src/libs/utils/utils.qbs905
-rw-r--r--src/libs/utils/utils.qrc6
-rw-r--r--src/libs/utils/utilsicons.cpp9
-rw-r--r--src/libs/utils/utilsicons.h5
-rw-r--r--src/libs/utils/variablechooser.cpp4
-rw-r--r--src/libs/utils/variablechooser.h2
-rw-r--r--src/libs/utils/wizard.cpp7
423 files changed, 15323 insertions, 10370 deletions
diff --git a/src/libs/3rdparty/cplusplus/TranslationUnit.cpp b/src/libs/3rdparty/cplusplus/TranslationUnit.cpp
index 62f4c570c79..848f61285cb 100644
--- a/src/libs/3rdparty/cplusplus/TranslationUnit.cpp
+++ b/src/libs/3rdparty/cplusplus/TranslationUnit.cpp
@@ -105,6 +105,35 @@ int TranslationUnit::commentCount() const
const Token &TranslationUnit::commentAt(int index) const
{ return _comments->at(index); }
+std::vector<Token> TranslationUnit::allTokens() const
+{
+ std::vector<Token> all;
+ int tokIndex = 0;
+ int commentIndex = 0;
+ while (true) {
+ if (tokIndex == tokenCount()) {
+ for (int i = commentIndex; i < commentCount(); ++i)
+ all.push_back(commentAt(i));
+ break;
+ }
+ if (commentIndex == commentCount()) {
+ for (int i = tokIndex; i < tokenCount(); ++i)
+ all.push_back(tokenAt(i));
+ break;
+ }
+ const Token &tok = tokenAt(tokIndex);
+ const Token &comment = commentAt(commentIndex);
+ if (tok.utf16charsBegin() < comment.utf16charsBegin()) {
+ all.push_back(tok);
+ ++tokIndex;
+ } else {
+ all.push_back(comment);
+ ++commentIndex;
+ }
+ }
+ return all;
+}
+
const Identifier *TranslationUnit::identifier(int index) const
{ return tokenAt(index).identifier; }
@@ -379,35 +408,57 @@ int TranslationUnit::findColumnNumber(int utf16CharOffset, int lineNumber) const
return utf16CharOffset - _lineOffsets[lineNumber];
}
-void TranslationUnit::getTokenPosition(int index,
- int *line,
- int *column,
- const StringLiteral **fileName) const
-{ return getPosition(tokenAt(index).utf16charsBegin(), line, column, fileName); }
-
int TranslationUnit::getTokenPositionInDocument(int index, const QTextDocument *doc) const
{
- int line, column;
- getTokenPosition(index, &line, &column);
- return Utils::Text::positionInText(doc, line, column);
+ return getTokenPositionInDocument(_tokens->at(index), doc);
}
int TranslationUnit::getTokenEndPositionInDocument(int index, const QTextDocument *doc) const
{
- int line, column;
- getTokenEndPosition(index, &line, &column);
- return Utils::Text::positionInText(doc, line, column);
+ return getTokenEndPositionInDocument(_tokens->at(index), doc);
}
-void TranslationUnit::getTokenStartPosition(int index, int *line,
- int *column,
- const StringLiteral **fileName) const
-{ return getPosition(tokenAt(index).utf16charsBegin(), line, column, fileName); }
+void TranslationUnit::getTokenPosition(int index, int *line,
+ int *column,
+ const StringLiteral **fileName) const
+{
+ return getTokenPosition(_tokens->at(index), line, column, fileName);
+}
void TranslationUnit::getTokenEndPosition(int index, int *line,
int *column,
const StringLiteral **fileName) const
-{ return getPosition(tokenAt(index).utf16charsEnd(), line, column, fileName); }
+{
+ return getTokenEndPosition(_tokens->at(index), line, column, fileName);
+}
+
+void TranslationUnit::getTokenPosition(const Token &token, int *line, int *column,
+ const StringLiteral **fileName) const
+{
+ return getPosition(token.utf16charsBegin(), line, column, fileName);
+}
+
+void TranslationUnit::getTokenEndPosition(const Token &token, int *line,
+ int *column, const StringLiteral **fileName) const
+{
+ return getPosition(token.utf16charsEnd(), line, column, fileName);
+}
+
+int TranslationUnit::getTokenPositionInDocument(const Token token,
+ const QTextDocument *doc) const
+{
+ int line, column;
+ getTokenPosition(token, &line, &column);
+ return Utils::Text::positionInText(doc, line, column);
+}
+
+int TranslationUnit::getTokenEndPositionInDocument(const Token &token,
+ const QTextDocument *doc) const
+{
+ int line, column;
+ getTokenEndPosition(token, &line, &column);
+ return Utils::Text::positionInText(doc, line, column);
+}
void TranslationUnit::getPosition(int utf16charOffset,
int *line,
diff --git a/src/libs/3rdparty/cplusplus/TranslationUnit.h b/src/libs/3rdparty/cplusplus/TranslationUnit.h
index 9694177a752..40f79d0091d 100644
--- a/src/libs/3rdparty/cplusplus/TranslationUnit.h
+++ b/src/libs/3rdparty/cplusplus/TranslationUnit.h
@@ -65,6 +65,9 @@ public:
int commentCount() const;
const Token &commentAt(int index) const;
+ // Including comments.
+ std::vector<Token> allTokens() const;
+
int matchingBrace(int index) const;
const Identifier *identifier(int index) const;
const Literal *literal(int index) const;
@@ -110,27 +113,27 @@ public:
void resetAST();
void release();
- void getTokenStartPosition(int index, int *line,
- int *column = nullptr,
- const StringLiteral **fileName = nullptr) const;
-
+ void getTokenPosition(int index, int *line,
+ int *column = nullptr,
+ const StringLiteral **fileName = nullptr) const;
void getTokenEndPosition(int index, int *line,
int *column = nullptr,
const StringLiteral **fileName = nullptr) const;
-
void getPosition(int utf16charOffset,
int *line,
int *column = nullptr,
const StringLiteral **fileName = nullptr) const;
- void getTokenPosition(int index,
- int *line,
- int *column = nullptr,
- const StringLiteral **fileName = nullptr) const;
-
int getTokenPositionInDocument(int index, const QTextDocument *doc) const;
int getTokenEndPositionInDocument(int index, const QTextDocument *doc) const;
+ void getTokenPosition(const Token &token, int *line, int *column = nullptr,
+ const StringLiteral **fileName = nullptr) const;
+ void getTokenEndPosition(const Token &token, int *line, int *column = nullptr,
+ const StringLiteral **fileName = nullptr) const;
+ int getTokenPositionInDocument(const Token token, const QTextDocument *doc) const;
+ int getTokenEndPositionInDocument(const Token &token, const QTextDocument *doc) const;
+
void pushLineOffset(int offset);
void pushPreprocessorLine(int utf16charOffset,
int line,
diff --git a/src/libs/3rdparty/libptyqt/conptyprocess.cpp b/src/libs/3rdparty/libptyqt/conptyprocess.cpp
index cb18b332066..6464dbeb347 100644
--- a/src/libs/3rdparty/libptyqt/conptyprocess.cpp
+++ b/src/libs/3rdparty/libptyqt/conptyprocess.cpp
@@ -12,6 +12,76 @@
#define READ_INTERVAL_MSEC 500
+//ConPTY is available only on Windows 10 released after 1903 (19H1) Windows release
+class WindowsContext
+{
+private:
+ WindowsContext() {}
+
+public:
+ typedef HRESULT (*CreatePseudoConsolePtr)(
+ COORD size, // ConPty Dimensions
+ HANDLE hInput, // ConPty Input
+ HANDLE hOutput, // ConPty Output
+ DWORD dwFlags, // ConPty Flags
+ HPCON* phPC); // ConPty Reference
+
+ typedef HRESULT (*ResizePseudoConsolePtr)(HPCON hPC, COORD size);
+
+ typedef VOID (*ClosePseudoConsolePtr)(HPCON hPC);
+
+ static WindowsContext &instance()
+ {
+ static WindowsContext ctx;
+ return ctx;
+ }
+
+ bool init()
+ {
+ //already initialized
+ if (createPseudoConsole)
+ return true;
+
+ //try to load symbols from library
+ //if it fails -> we can't use ConPty API
+ HANDLE kernel32Handle = LoadLibraryExW(L"kernel32.dll", 0, 0);
+
+ if (kernel32Handle != nullptr)
+ {
+ createPseudoConsole = (CreatePseudoConsolePtr)GetProcAddress((HMODULE)kernel32Handle, "CreatePseudoConsole");
+ resizePseudoConsole = (ResizePseudoConsolePtr)GetProcAddress((HMODULE)kernel32Handle, "ResizePseudoConsole");
+ closePseudoConsole = (ClosePseudoConsolePtr)GetProcAddress((HMODULE)kernel32Handle, "ClosePseudoConsole");
+ if (createPseudoConsole == NULL || resizePseudoConsole == NULL || closePseudoConsole == NULL)
+ {
+ m_lastError = QString("WindowsContext/ConPty error: %1").arg("Invalid on load API functions");
+ return false;
+ }
+ }
+ else
+ {
+ m_lastError = QString("WindowsContext/ConPty error: %1").arg("Unable to load kernel32");
+ return false;
+ }
+
+ return true;
+ }
+
+ QString lastError()
+ {
+ return m_lastError;
+ }
+
+public:
+ //vars
+ CreatePseudoConsolePtr createPseudoConsole{nullptr};
+ ResizePseudoConsolePtr resizePseudoConsole{nullptr};
+ ClosePseudoConsolePtr closePseudoConsole{nullptr};
+
+private:
+ QString m_lastError;
+};
+
+
HRESULT ConPtyProcess::createPseudoConsoleAndPipes(HPCON* phPC, HANDLE* phPipeIn, HANDLE* phPipeOut, qint16 cols, qint16 rows)
{
HRESULT hr{ E_UNEXPECTED };
@@ -23,7 +93,7 @@ HRESULT ConPtyProcess::createPseudoConsoleAndPipes(HPCON* phPC, HANDLE* phPipeIn
CreatePipe(phPipeIn, &hPipePTYOut, NULL, 0))
{
// Create the Pseudo Console of the required size, attached to the PTY-end of the pipes
- hr = m_winContext.createPseudoConsole({cols, rows}, hPipePTYIn, hPipePTYOut, 0, phPC);
+ hr = WindowsContext::instance().createPseudoConsole({cols, rows}, hPipePTYIn, hPipePTYOut, 0, phPC);
// Note: We can close the handles to the PTY-end of the pipes here
// because the handles are dup'ed into the ConHost and will be released
@@ -108,7 +178,7 @@ bool ConPtyProcess::startProcess(const QString &executable,
qint16 rows)
{
if (!isAvailable()) {
- m_lastError = m_winContext.lastError();
+ m_lastError = WindowsContext::instance().lastError();
return false;
}
@@ -228,7 +298,7 @@ bool ConPtyProcess::resize(qint16 cols, qint16 rows)
return false;
}
- bool res = SUCCEEDED(m_winContext.resizePseudoConsole(m_ptyHandler, {cols, rows}));
+ bool res = SUCCEEDED(WindowsContext::instance().resizePseudoConsole(m_ptyHandler, {cols, rows}));
if (res)
{
@@ -248,7 +318,7 @@ bool ConPtyProcess::kill()
m_aboutToDestruct = true;
// Close ConPTY - this will terminate client process if running
- m_winContext.closePseudoConsole(m_ptyHandler);
+ WindowsContext::instance().closePseudoConsole(m_ptyHandler);
// Clean-up the pipes
if (INVALID_HANDLE_VALUE != m_hPipeOut)
@@ -334,7 +404,7 @@ bool ConPtyProcess::isAvailable()
qint32 buildNumber = QSysInfo::kernelVersion().split(".").last().toInt();
if (buildNumber < CONPTY_MINIMAL_WINDOWS_VERSION)
return false;
- return m_winContext.init();
+ return WindowsContext::instance().init();
}
void ConPtyProcess::moveToThread(QThread *targetThread)
diff --git a/src/libs/3rdparty/libptyqt/conptyprocess.h b/src/libs/3rdparty/libptyqt/conptyprocess.h
index d4ffd62b7ee..aaf56fe76f1 100644
--- a/src/libs/3rdparty/libptyqt/conptyprocess.h
+++ b/src/libs/3rdparty/libptyqt/conptyprocess.h
@@ -25,80 +25,6 @@ typedef VOID* HPCON;
class QWinEventNotifier;
-template <typename T>
-std::vector<T> vectorFromString(const std::basic_string<T> &str)
-{
- return std::vector<T>(str.begin(), str.end());
-}
-
-//ConPTY available only on Windows 10 releazed after 1903 (19H1) Windows release
-class WindowsContext
-{
-public:
- typedef HRESULT (*CreatePseudoConsolePtr)(
- COORD size, // ConPty Dimensions
- HANDLE hInput, // ConPty Input
- HANDLE hOutput, // ConPty Output
- DWORD dwFlags, // ConPty Flags
- HPCON* phPC); // ConPty Reference
-
- typedef HRESULT (*ResizePseudoConsolePtr)(HPCON hPC, COORD size);
-
- typedef VOID (*ClosePseudoConsolePtr)(HPCON hPC);
-
- WindowsContext()
- : createPseudoConsole(nullptr)
- , resizePseudoConsole(nullptr)
- , closePseudoConsole(nullptr)
- {
-
- }
-
- bool init()
- {
- //already initialized
- if (createPseudoConsole)
- return true;
-
- //try to load symbols from library
- //if it fails -> we can't use ConPty API
- HANDLE kernel32Handle = LoadLibraryExW(L"kernel32.dll", 0, 0);
-
- if (kernel32Handle != nullptr)
- {
- createPseudoConsole = (CreatePseudoConsolePtr)GetProcAddress((HMODULE)kernel32Handle, "CreatePseudoConsole");
- resizePseudoConsole = (ResizePseudoConsolePtr)GetProcAddress((HMODULE)kernel32Handle, "ResizePseudoConsole");
- closePseudoConsole = (ClosePseudoConsolePtr)GetProcAddress((HMODULE)kernel32Handle, "ClosePseudoConsole");
- if (createPseudoConsole == NULL || resizePseudoConsole == NULL || closePseudoConsole == NULL)
- {
- m_lastError = QString("WindowsContext/ConPty error: %1").arg("Invalid on load API functions");
- return false;
- }
- }
- else
- {
- m_lastError = QString("WindowsContext/ConPty error: %1").arg("Unable to load kernel32");
- return false;
- }
-
- return true;
- }
-
- QString lastError()
- {
- return m_lastError;
- }
-
-public:
- //vars
- CreatePseudoConsolePtr createPseudoConsole;
- ResizePseudoConsolePtr resizePseudoConsole;
- ClosePseudoConsolePtr closePseudoConsole;
-
-private:
- QString m_lastError;
-};
-
class PtyBuffer : public QIODevice
{
friend class ConPtyProcess;
@@ -141,7 +67,7 @@ public:
virtual QIODevice *notifier();
virtual QByteArray readAll();
virtual qint64 write(const QByteArray &byteArray);
- bool isAvailable();
+ static bool isAvailable();
void moveToThread(QThread *targetThread);
private:
@@ -149,7 +75,6 @@ private:
HRESULT initializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX* pStartupInfo, HPCON hPC);
private:
- WindowsContext m_winContext;
HPCON m_ptyHandler{INVALID_HANDLE_VALUE};
HANDLE m_hPipeIn{INVALID_HANDLE_VALUE}, m_hPipeOut{INVALID_HANDLE_VALUE};
diff --git a/src/libs/3rdparty/libptyqt/iptyprocess.h b/src/libs/3rdparty/libptyqt/iptyprocess.h
index 3d974908c86..6005b0efde1 100644
--- a/src/libs/3rdparty/libptyqt/iptyprocess.h
+++ b/src/libs/3rdparty/libptyqt/iptyprocess.h
@@ -11,6 +11,8 @@ class IPtyProcess
{
public:
enum PtyType { UnixPty = 0, WinPty = 1, ConPty = 2, AutoPty = 3 };
+ enum PtyInputFlag { None = 0x0, InputModeHidden = 0x1, };
+ Q_DECLARE_FLAGS(PtyInputFlags, PtyInputFlag)
IPtyProcess() = default;
IPtyProcess(const IPtyProcess &) = delete;
@@ -32,7 +34,6 @@ public:
virtual QIODevice *notifier() = 0;
virtual QByteArray readAll() = 0;
virtual qint64 write(const QByteArray &byteArray) = 0;
- virtual bool isAvailable() = 0;
virtual void moveToThread(QThread *targetThread) = 0;
qint64 pid() { return m_pid; }
QPair<qint16, qint16> size() { return m_size; }
@@ -44,6 +45,8 @@ public:
return m_trace;
}
+ PtyInputFlags inputFlags() { return m_inputFlags; }
+
protected:
QString m_shellPath;
QString m_lastError;
@@ -51,6 +54,9 @@ protected:
int m_exitCode{0};
QPair<qint16, qint16> m_size; //cols / rows
bool m_trace{false};
+ PtyInputFlags m_inputFlags;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(IPtyProcess::PtyInputFlags)
+
#endif // IPTYPROCESS_H
diff --git a/src/libs/3rdparty/libptyqt/ptyqt.cpp b/src/libs/3rdparty/libptyqt/ptyqt.cpp
index b3e7aa1b164..06fe4498190 100644
--- a/src/libs/3rdparty/libptyqt/ptyqt.cpp
+++ b/src/libs/3rdparty/libptyqt/ptyqt.cpp
@@ -10,6 +10,15 @@
#include "unixptyprocess.h"
#endif
+bool PtyQt::isUsingConPTY()
+{
+#ifdef Q_OS_WIN
+ if (ConPtyProcess::isAvailable() && qgetenv("QTC_USE_WINPTY").isEmpty())
+ return true;
+#endif
+
+ return false;
+}
IPtyProcess *PtyQt::createPtyProcess(IPtyProcess::PtyType ptyType)
{
@@ -34,7 +43,7 @@ IPtyProcess *PtyQt::createPtyProcess(IPtyProcess::PtyType ptyType)
}
#ifdef Q_OS_WIN
- if (ConPtyProcess().isAvailable() && qgetenv("QTC_USE_WINPTY").isEmpty())
+ if (isUsingConPTY())
return new ConPtyProcess();
else
return new WinPtyProcess();
@@ -43,3 +52,5 @@ IPtyProcess *PtyQt::createPtyProcess(IPtyProcess::PtyType ptyType)
return new UnixPtyProcess();
#endif
}
+
+
diff --git a/src/libs/3rdparty/libptyqt/ptyqt.h b/src/libs/3rdparty/libptyqt/ptyqt.h
index 23b80d346bb..85f27b33a9b 100644
--- a/src/libs/3rdparty/libptyqt/ptyqt.h
+++ b/src/libs/3rdparty/libptyqt/ptyqt.h
@@ -7,6 +7,8 @@ class PtyQt
{
public:
static IPtyProcess *createPtyProcess(IPtyProcess::PtyType ptyType);
+
+ static bool isUsingConPTY();
};
#endif // PTYQT_H
diff --git a/src/libs/3rdparty/libptyqt/ptyqt.qbs b/src/libs/3rdparty/libptyqt/ptyqt.qbs
index 7ff4da9f560..3b56dd8e465 100644
--- a/src/libs/3rdparty/libptyqt/ptyqt.qbs
+++ b/src/libs/3rdparty/libptyqt/ptyqt.qbs
@@ -1,45 +1,40 @@
-import qbs
-
-Project {
+QtcLibrary {
name: "ptyqt"
+ type: "staticlibrary"
- QtcLibrary {
- Depends { name: "Qt.core" }
- Depends { name: "Qt.network"; condition: qbs.targetOS.contains("windows") }
- Depends { name: "winpty"; condition: qbs.targetOS.contains("windows") }
+ Depends { name: "Qt.core" }
+ Depends { name: "Qt.network"; condition: qbs.targetOS.contains("windows") }
+ Depends { name: "winpty"; condition: qbs.targetOS.contains("windows") }
- type: "staticlibrary"
+ files: [
+ "iptyprocess.h",
+ "ptyqt.cpp",
+ "ptyqt.h",
+ ]
+ Group {
+ name: "ptyqt UNIX files"
+ condition: qbs.targetOS.contains("unix")
files: [
- "iptyprocess.h",
- "ptyqt.cpp",
- "ptyqt.h",
+ "unixptyprocess.cpp",
+ "unixptyprocess.h",
]
+ }
- Group {
- name: "ptyqt UNIX files"
- condition: qbs.targetOS.contains("unix")
- files: [
- "unixptyprocess.cpp",
- "unixptyprocess.h",
- ]
- }
-
- Group {
- name: "ptyqt Windows files"
- condition: qbs.targetOS.contains("windows")
- files: [
- "conptyprocess.cpp",
- "conptyprocess.h",
- "winptyprocess.cpp",
- "winptyprocess.h",
- ]
- }
+ Group {
+ name: "ptyqt Windows files"
+ condition: qbs.targetOS.contains("windows")
+ files: [
+ "conptyprocess.cpp",
+ "conptyprocess.h",
+ "winptyprocess.cpp",
+ "winptyprocess.h",
+ ]
+ }
- Export {
- Depends { name: "cpp" }
- Depends { name: "winpty"; condition: qbs.targetOS.contains("windows") }
- cpp.includePaths: base.concat(exportingProduct.sourceDirectory)
- }
+ Export {
+ Depends { name: "cpp" }
+ Depends { name: "winpty"; condition: qbs.targetOS.contains("windows") }
+ cpp.includePaths: exportingProduct.sourceDirectory
}
}
diff --git a/src/libs/3rdparty/libptyqt/unixptyprocess.cpp b/src/libs/3rdparty/libptyqt/unixptyprocess.cpp
index a72712c1eb4..e9ec1d590f6 100644
--- a/src/libs/3rdparty/libptyqt/unixptyprocess.cpp
+++ b/src/libs/3rdparty/libptyqt/unixptyprocess.cpp
@@ -172,6 +172,12 @@ bool UnixPtyProcess::startProcess(const QString &shellPath,
static std::array<char, maxRead> buffer;
int len = ::read(m_shellProcess.m_handleMaster, buffer.data(), buffer.size());
+
+ struct termios termAttributes;
+ tcgetattr(m_shellProcess.m_handleMaster, &termAttributes);
+ const bool isPasswordEntry = !(termAttributes.c_lflag & ECHO) && (termAttributes.c_lflag & ICANON);
+ m_inputFlags.setFlag(PtyInputFlag::InputModeHidden, isPasswordEntry);
+
if (len > 0) {
m_shellReadBuffer.append(buffer.data(), len);
m_shellProcess.emitReadyRead();
@@ -185,14 +191,12 @@ bool UnixPtyProcess::startProcess(const QString &shellPath,
});
QStringList varNames;
- foreach (QString line, environment) {
+ for (const QString &line : std::as_const(environment))
varNames.append(line.split("=").first());
- }
QProcessEnvironment envFormat;
- foreach (QString line, environment) {
+ for (const QString &line : std::as_const(environment))
envFormat.insert(line.split("=").first(), line.split("=").last());
- }
m_shellProcess.setWorkingDirectory(workingDir);
m_shellProcess.setProcessEnvironment(envFormat);
diff --git a/src/libs/3rdparty/libptyqt/unixptyprocess.h b/src/libs/3rdparty/libptyqt/unixptyprocess.h
index e4df0d2f74d..f7e3a2e5281 100644
--- a/src/libs/3rdparty/libptyqt/unixptyprocess.h
+++ b/src/libs/3rdparty/libptyqt/unixptyprocess.h
@@ -54,7 +54,7 @@ public:
virtual QIODevice *notifier();
virtual QByteArray readAll();
virtual qint64 write(const QByteArray &byteArray);
- virtual bool isAvailable();
+ static bool isAvailable();
void moveToThread(QThread *targetThread);
private:
diff --git a/src/libs/3rdparty/libptyqt/winptyprocess.cpp b/src/libs/3rdparty/libptyqt/winptyprocess.cpp
index 0509bb77c37..7a781bc1953 100644
--- a/src/libs/3rdparty/libptyqt/winptyprocess.cpp
+++ b/src/libs/3rdparty/libptyqt/winptyprocess.cpp
@@ -77,7 +77,7 @@ bool WinPtyProcess::startProcess(const QString &executable,
//env
std::wstringstream envBlock;
- foreach (QString line, environment)
+ for (const QString &line : environment)
{
envBlock << line.toStdWString() << L'\0';
}
diff --git a/src/libs/3rdparty/libptyqt/winptyprocess.h b/src/libs/3rdparty/libptyqt/winptyprocess.h
index 0bfb27c02c4..ee91fbdf8d6 100644
--- a/src/libs/3rdparty/libptyqt/winptyprocess.h
+++ b/src/libs/3rdparty/libptyqt/winptyprocess.h
@@ -26,7 +26,7 @@ public:
QIODevice *notifier();
QByteArray readAll();
qint64 write(const QByteArray &byteArray);
- bool isAvailable();
+ static bool isAvailable();
void moveToThread(QThread *targetThread);
private:
diff --git a/src/libs/3rdparty/libvterm/include/vterm.h b/src/libs/3rdparty/libvterm/include/vterm.h
index cb16ff2a044..d08dd382db3 100644
--- a/src/libs/3rdparty/libvterm/include/vterm.h
+++ b/src/libs/3rdparty/libvterm/include/vterm.h
@@ -13,6 +13,7 @@ extern "C" {
#define VTERM_VERSION_MAJOR 0
#define VTERM_VERSION_MINOR 3
+#define VTERM_VERSION_PATCH 3
#define VTERM_CHECK_VERSION \
vterm_check_version(VTERM_VERSION_MAJOR, VTERM_VERSION_MINOR)
@@ -258,6 +259,7 @@ typedef enum {
VTERM_PROP_REVERSE, // bool
VTERM_PROP_CURSORSHAPE, // number
VTERM_PROP_MOUSE, // number
+ VTERM_PROP_FOCUSREPORT, // bool
VTERM_N_PROPS
} VTermProp;
diff --git a/src/libs/3rdparty/libvterm/src/mouse.c b/src/libs/3rdparty/libvterm/src/mouse.c
index bd713f8106a..f74abc3d9d2 100644
--- a/src/libs/3rdparty/libvterm/src/mouse.c
+++ b/src/libs/3rdparty/libvterm/src/mouse.c
@@ -93,7 +93,7 @@ void vterm_mouse_button(VTerm *vt, int button, bool pressed, VTermModifier mod)
if(button < 4) {
output_mouse(state, button-1, pressed, mod, state->mouse_col, state->mouse_row);
}
- else if(button < 6) {
+ else if(button < 8) {
output_mouse(state, button-4 + 0x40, pressed, mod, state->mouse_col, state->mouse_row);
}
}
diff --git a/src/libs/3rdparty/libvterm/src/screen.c b/src/libs/3rdparty/libvterm/src/screen.c
index 9d1028e67ae..6c549094a9a 100644
--- a/src/libs/3rdparty/libvterm/src/screen.c
+++ b/src/libs/3rdparty/libvterm/src/screen.c
@@ -595,8 +595,15 @@ static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int new
new_row_start, new_row_end, old_row_start, old_row_end, width);
#endif
- if(new_row_start < 0)
+ if(new_row_start < 0) {
+ if(old_row_start <= old_cursor.row && old_cursor.row < old_row_end) {
+ new_cursor.row = 0;
+ new_cursor.col = old_cursor.col;
+ if(new_cursor.col >= new_cols)
+ new_cursor.col = new_cols-1;
+ }
break;
+ }
for(new_row = new_row_start, old_row = old_row_start; new_row <= new_row_end; new_row++) {
int count = width >= new_cols ? new_cols : width;
@@ -660,8 +667,9 @@ static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int new
if(old_row >= 0 && bufidx == BUFIDX_PRIMARY) {
/* Push spare lines to scrollback buffer */
- for(int row = 0; row <= old_row; row++)
- sb_pushline_from_row(screen, row);
+ if(screen->callbacks && screen->callbacks->sb_pushline)
+ for(int row = 0; row <= old_row; row++)
+ sb_pushline_from_row(screen, row);
if(active)
statefields->pos.row -= (old_row + 1);
}
diff --git a/src/libs/3rdparty/libvterm/src/state.c b/src/libs/3rdparty/libvterm/src/state.c
index 313e746e77c..ce8e0342370 100644
--- a/src/libs/3rdparty/libvterm/src/state.c
+++ b/src/libs/3rdparty/libvterm/src/state.c
@@ -801,6 +801,7 @@ static void set_dec_mode(VTermState *state, int num, int val)
break;
case 1004:
+ settermprop_bool(state, VTERM_PROP_FOCUSREPORT, val);
state->mode.report_focus = val;
break;
@@ -949,6 +950,7 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
switch(intermed[0]) {
case ' ':
+ case '!':
case '"':
case '$':
case '\'':
@@ -1311,8 +1313,10 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
break;
case LEADER('?', 0x68): // DEC private mode set
- if(!CSI_ARG_IS_MISSING(args[0]))
- set_dec_mode(state, CSI_ARG(args[0]), 1);
+ for(int i = 0; i < argcount; i++) {
+ if(!CSI_ARG_IS_MISSING(args[i]))
+ set_dec_mode(state, CSI_ARG(args[i]), 1);
+ }
break;
case 0x6a: // HPB - ECMA-48 8.3.58
@@ -1333,8 +1337,10 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
break;
case LEADER('?', 0x6c): // DEC private mode reset
- if(!CSI_ARG_IS_MISSING(args[0]))
- set_dec_mode(state, CSI_ARG(args[0]), 0);
+ for(int i = 0; i < argcount; i++) {
+ if(!CSI_ARG_IS_MISSING(args[i]))
+ set_dec_mode(state, CSI_ARG(args[i]), 0);
+ }
break;
case 0x6d: // SGR - ECMA-48 8.3.117
@@ -1386,7 +1392,7 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
break;
- case LEADER('!', 0x70): // DECSTR - DEC soft terminal reset
+ case INTERMED('!', 0x70): // DECSTR - DEC soft terminal reset
vterm_state_reset(state, 0);
break;
@@ -1652,8 +1658,18 @@ static void osc_selection(VTermState *state, VTermStringFragment frag)
frag.len--;
}
- if(!frag.len)
+ if(!frag.len) {
+ /* Clear selection if we're already finished but didn't do anything */
+ if(frag.final && state->selection.callbacks->set) {
+ (*state->selection.callbacks->set)(state->tmp.selection.mask, (VTermStringFragment){
+ .str = NULL,
+ .len = 0,
+ .initial = state->tmp.selection.state != SELECTION_SET,
+ .final = true,
+ }, state->selection.user);
+ }
return;
+ }
if(state->tmp.selection.state == SELECTION_SELECTED) {
if(frag.str[0] == '?') {
@@ -1671,6 +1687,9 @@ static void osc_selection(VTermState *state, VTermStringFragment frag)
return;
}
+ if(state->tmp.selection.state == SELECTION_INVALID)
+ return;
+
if(state->selection.callbacks->set) {
size_t bufcur = 0;
char *buffer = state->selection.buffer;
@@ -1706,11 +1725,21 @@ static void osc_selection(VTermState *state, VTermStringFragment frag)
uint8_t b = unbase64one(frag.str[0]);
if(b == 0xFF) {
DEBUG_LOG("base64decode bad input %02X\n", (uint8_t)frag.str[0]);
+
+ state->tmp.selection.state = SELECTION_INVALID;
+ if(state->selection.callbacks->set) {
+ (*state->selection.callbacks->set)(state->tmp.selection.mask, (VTermStringFragment){
+ .str = NULL,
+ .len = 0,
+ .initial = true,
+ .final = true,
+ }, state->selection.user);
+ }
+ break;
}
- else {
- x = (x << 6) | b;
- n++;
- }
+
+ x = (x << 6) | b;
+ n++;
frag.str++, frag.len--;
if(n == 4) {
@@ -1730,7 +1759,7 @@ static void osc_selection(VTermState *state, VTermStringFragment frag)
.str = state->selection.buffer,
.len = bufcur,
.initial = state->tmp.selection.state == SELECTION_SET_INITIAL,
- .final = frag.final,
+ .final = frag.final && !frag.len,
}, state->selection.user);
state->tmp.selection.state = SELECTION_SET;
}
@@ -1842,7 +1871,7 @@ static void request_status_string(VTermState *state, VTermStringFragment frag)
case ' '|('q'<<8): {
// Query DECSCUSR
- int reply = 2;
+ int reply;
switch(state->mode.cursor_shape) {
case VTERM_PROP_CURSORSHAPE_BLOCK: reply = 2; break;
case VTERM_PROP_CURSORSHAPE_UNDERLINE: reply = 4; break;
@@ -2196,6 +2225,9 @@ int vterm_state_set_termprop(VTermState *state, VTermProp prop, VTermValue *val)
if(val->number == VTERM_PROP_MOUSE_MOVE)
state->mouse_flags |= MOUSE_WANT_MOVE;
return 1;
+ case VTERM_PROP_FOCUSREPORT:
+ state->mode.report_focus = val->boolean;
+ return 1;
case VTERM_N_PROPS:
return 0;
diff --git a/src/libs/3rdparty/libvterm/src/vterm.c b/src/libs/3rdparty/libvterm/src/vterm.c
index 0997887f5fb..e1f676f5b62 100644
--- a/src/libs/3rdparty/libvterm/src/vterm.c
+++ b/src/libs/3rdparty/libvterm/src/vterm.c
@@ -295,6 +295,7 @@ VTermValueType vterm_get_prop_type(VTermProp prop)
case VTERM_PROP_REVERSE: return VTERM_VALUETYPE_BOOL;
case VTERM_PROP_CURSORSHAPE: return VTERM_VALUETYPE_INT;
case VTERM_PROP_MOUSE: return VTERM_VALUETYPE_INT;
+ case VTERM_PROP_FOCUSREPORT: return VTERM_VALUETYPE_BOOL;
case VTERM_N_PROPS: return 0;
}
diff --git a/src/libs/3rdparty/libvterm/src/vterm_internal.h b/src/libs/3rdparty/libvterm/src/vterm_internal.h
index ad61bff8b0f..5d934aff071 100644
--- a/src/libs/3rdparty/libvterm/src/vterm_internal.h
+++ b/src/libs/3rdparty/libvterm/src/vterm_internal.h
@@ -158,6 +158,7 @@ struct VTermState
SELECTION_QUERY,
SELECTION_SET_INITIAL,
SELECTION_SET,
+ SELECTION_INVALID,
} state : 8;
uint32_t recvpartial;
uint32_t sendpartial;
diff --git a/src/libs/3rdparty/libvterm/vterm.qbs b/src/libs/3rdparty/libvterm/vterm.qbs
index 18ccb638aab..e35658908da 100644
--- a/src/libs/3rdparty/libvterm/vterm.qbs
+++ b/src/libs/3rdparty/libvterm/vterm.qbs
@@ -1,34 +1,35 @@
-Project {
- QtcLibrary {
- name: "vterm"
- type: "staticlibrary"
+QtcLibrary {
+ name: "vterm"
+ type: "staticlibrary"
- Depends { name: "cpp" }
- cpp.includePaths: base.concat("include")
- cpp.warningLevel: "none"
+ useQt: false
+
+ Depends { name: "cpp" }
- Group {
- prefix: "src/"
- files: [
- "encoding.c",
- "fullwidth.inc",
- "keyboard.c",
- "mouse.c",
- "parser.c",
- "pen.c",
- "rect.h",
- "screen.c",
- "state.c",
- "unicode.c",
- "utf8.h",
- "vterm.c",
- "vterm_internal.h",
- ]
- }
+ cpp.includePaths: base.concat("include")
+ cpp.warningLevel: "none"
- Export {
- Depends { name: "cpp" }
- cpp.includePaths: base.concat("include")
- }
+ Group {
+ prefix: "src/"
+ files: [
+ "encoding.c",
+ "fullwidth.inc",
+ "keyboard.c",
+ "mouse.c",
+ "parser.c",
+ "pen.c",
+ "rect.h",
+ "screen.c",
+ "state.c",
+ "unicode.c",
+ "utf8.h",
+ "vterm.c",
+ "vterm_internal.h",
+ ]
+ }
+
+ Export {
+ Depends { name: "cpp" }
+ cpp.includePaths: "include"
}
}
diff --git a/src/libs/3rdparty/tl_expected/include/tl/expected.hpp b/src/libs/3rdparty/tl_expected/include/tl/expected.hpp
index d8ed472bdd1..afee404d43e 100644
--- a/src/libs/3rdparty/tl_expected/include/tl/expected.hpp
+++ b/src/libs/3rdparty/tl_expected/include/tl/expected.hpp
@@ -1,6 +1,6 @@
///
// expected - An implementation of std::expected with extensions
-// Written in 2017 by Simon Brand (simonrbrand@gmail.com, @TartanLlama)
+// Written in 2017 by Sy Brand (tartanllama@gmail.com, @TartanLlama)
//
// Documentation available at http://tl.tartanllama.xyz/
//
@@ -17,8 +17,8 @@
#define TL_EXPECTED_HPP
#define TL_EXPECTED_VERSION_MAJOR 1
-#define TL_EXPECTED_VERSION_MINOR 0
-#define TL_EXPECTED_VERSION_PATCH 1
+#define TL_EXPECTED_VERSION_MINOR 1
+#define TL_EXPECTED_VERSION_PATCH 0
#include <exception>
#include <functional>
@@ -51,6 +51,16 @@
#define TL_EXPECTED_GCC55
#endif
+#if !defined(TL_ASSERT)
+//can't have assert in constexpr in C++11 and GCC 4.9 has a compiler bug
+#if (__cplusplus > 201103L) && !defined(TL_EXPECTED_GCC49)
+#include <cassert>
+#define TL_ASSERT(x) assert(x)
+#else
+#define TL_ASSERT(x)
+#endif
+#endif
+
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
!defined(__clang__))
// GCC < 5 doesn't support overloading on const&& for member functions
@@ -66,30 +76,30 @@
#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \
std::is_trivially_destructible<T>
-// GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks std::vector
-// for non-copyable types
-#elif (defined(__GNUC__) && __GNUC__ < 8 && \
- !defined(__clang__))
+// GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks
+// std::vector for non-copyable types
+#elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__))
#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
namespace tl {
- namespace detail {
- template<class T>
- struct is_trivially_copy_constructible : std::is_trivially_copy_constructible<T>{};
+namespace detail {
+template <class T>
+struct is_trivially_copy_constructible
+ : std::is_trivially_copy_constructible<T> {};
#ifdef _GLIBCXX_VECTOR
- template<class T, class A>
- struct is_trivially_copy_constructible<std::vector<T,A>>
- : std::false_type{};
+template <class T, class A>
+struct is_trivially_copy_constructible<std::vector<T, A>> : std::false_type {};
#endif
- }
-}
+} // namespace detail
+} // namespace tl
#endif
-#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
+#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
tl::detail::is_trivially_copy_constructible<T>
-#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
+#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
std::is_trivially_copy_assignable<T>
-#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>
+#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \
+ std::is_trivially_destructible<T>
#else
#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
std::is_trivially_copy_constructible<T>
@@ -138,6 +148,17 @@ public:
constexpr explicit unexpected(E &&e) : m_val(std::move(e)) {}
+ template <class... Args, typename std::enable_if<std::is_constructible<
+ E, Args &&...>::value>::type * = nullptr>
+ constexpr explicit unexpected(Args &&...args)
+ : m_val(std::forward<Args>(args)...) {}
+ template <
+ class U, class... Args,
+ typename std::enable_if<std::is_constructible<
+ E, std::initializer_list<U> &, Args &&...>::value>::type * = nullptr>
+ constexpr explicit unexpected(std::initializer_list<U> l, Args &&...args)
+ : m_val(l, std::forward<Args>(args)...) {}
+
constexpr const E &value() const & { return m_val; }
TL_EXPECTED_11_CONSTEXPR E &value() & { return m_val; }
TL_EXPECTED_11_CONSTEXPR E &&value() && { return std::move(m_val); }
@@ -147,6 +168,10 @@ private:
E m_val;
};
+#ifdef __cpp_deduction_guides
+template <class E> unexpected(E) -> unexpected<E>;
+#endif
+
template <class E>
constexpr bool operator==(const unexpected<E> &lhs, const unexpected<E> &rhs) {
return lhs.value() == rhs.value();
@@ -183,16 +208,17 @@ struct unexpect_t {
static constexpr unexpect_t unexpect{};
namespace detail {
-template<typename E>
+template <typename E>
[[noreturn]] TL_EXPECTED_11_CONSTEXPR void throw_exception(E &&e) {
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
- throw std::forward<E>(e);
+ throw std::forward<E>(e);
#else
- #ifdef _MSC_VER
- __assume(0);
- #else
- __builtin_unreachable();
- #endif
+ (void)e;
+#ifdef _MSC_VER
+ __assume(0);
+#else
+ __builtin_unreachable();
+#endif
#endif
}
@@ -213,7 +239,7 @@ template <class...> struct conjunction : std::true_type {};
template <class B> struct conjunction<B> : B {};
template <class B, class... Bs>
struct conjunction<B, Bs...>
- : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
+ : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
@@ -223,45 +249,52 @@ struct conjunction<B, Bs...>
// which results in a hard-error when using it in a noexcept expression
// in some cases. This is a check to workaround the common failing case.
#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
-template <class T> struct is_pointer_to_non_const_member_func : std::false_type {};
+template <class T>
+struct is_pointer_to_non_const_member_func : std::false_type {};
template <class T, class Ret, class... Args>
-struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...)> : std::true_type {};
+struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)>
+ : std::true_type {};
template <class T, class Ret, class... Args>
-struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...)&> : std::true_type {};
+struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &>
+ : std::true_type {};
template <class T, class Ret, class... Args>
-struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) &&> : std::true_type {};
+struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &&>
+ : std::true_type {};
template <class T, class Ret, class... Args>
-struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) volatile> : std::true_type {};
+struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile>
+ : std::true_type {};
template <class T, class Ret, class... Args>
-struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) volatile &> : std::true_type {};
+struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile &>
+ : std::true_type {};
template <class T, class Ret, class... Args>
-struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) volatile &&> : std::true_type {};
+struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile &&>
+ : std::true_type {};
template <class T> struct is_const_or_const_ref : std::false_type {};
-template <class T> struct is_const_or_const_ref<T const&> : std::true_type {};
+template <class T> struct is_const_or_const_ref<T const &> : std::true_type {};
template <class T> struct is_const_or_const_ref<T const> : std::true_type {};
#endif
// std::invoke from C++17
// https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
-template <typename Fn, typename... Args,
+template <
+ typename Fn, typename... Args,
#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
- typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value
- && is_const_or_const_ref<Args...>::value)>,
+ typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value &&
+ is_const_or_const_ref<Args...>::value)>,
#endif
- typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
- int = 0>
- constexpr auto invoke(Fn && f, Args && ... args) noexcept(
+ typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>, int = 0>
+constexpr auto invoke(Fn &&f, Args &&...args) noexcept(
noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
- -> decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
+ -> decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
return std::mem_fn(f)(std::forward<Args>(args)...);
}
template <typename Fn, typename... Args,
- typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
- constexpr auto invoke(Fn && f, Args && ... args) noexcept(
+ typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
+constexpr auto invoke(Fn &&f, Args &&...args) noexcept(
noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
- -> decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
+ -> decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
return std::forward<Fn>(f)(std::forward<Args>(args)...);
}
@@ -270,9 +303,11 @@ template <class F, class, class... Us> struct invoke_result_impl;
template <class F, class... Us>
struct invoke_result_impl<
- F, decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...), void()),
- Us...> {
- using type = decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
+ F,
+ decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...), void()),
+ Us...> {
+ using type =
+ decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
};
template <class F, class... Us>
@@ -289,69 +324,67 @@ template <class T, class U = T> struct is_nothrow_swappable : std::true_type {};
#else
// https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept
namespace swap_adl_tests {
- // if swap ADL finds this then it would call std::swap otherwise (same
- // signature)
- struct tag {};
-
- template <class T> tag swap(T&, T&);
- template <class T, std::size_t N> tag swap(T(&a)[N], T(&b)[N]);
-
- // helper functions to test if an unqualified swap is possible, and if it
- // becomes std::swap
- template <class, class> std::false_type can_swap(...) noexcept(false);
- template <class T, class U,
- class = decltype(swap(std::declval<T&>(), std::declval<U&>()))>
- std::true_type can_swap(int) noexcept(noexcept(swap(std::declval<T&>(),
- std::declval<U&>())));
-
- template <class, class> std::false_type uses_std(...);
- template <class T, class U>
- std::is_same<decltype(swap(std::declval<T&>(), std::declval<U&>())), tag>
- uses_std(int);
-
- template <class T>
- struct is_std_swap_noexcept
+// if swap ADL finds this then it would call std::swap otherwise (same
+// signature)
+struct tag {};
+
+template <class T> tag swap(T &, T &);
+template <class T, std::size_t N> tag swap(T (&a)[N], T (&b)[N]);
+
+// helper functions to test if an unqualified swap is possible, and if it
+// becomes std::swap
+template <class, class> std::false_type can_swap(...) noexcept(false);
+template <class T, class U,
+ class = decltype(swap(std::declval<T &>(), std::declval<U &>()))>
+std::true_type can_swap(int) noexcept(noexcept(swap(std::declval<T &>(),
+ std::declval<U &>())));
+
+template <class, class> std::false_type uses_std(...);
+template <class T, class U>
+std::is_same<decltype(swap(std::declval<T &>(), std::declval<U &>())), tag>
+uses_std(int);
+
+template <class T>
+struct is_std_swap_noexcept
: std::integral_constant<bool,
- std::is_nothrow_move_constructible<T>::value&&
- std::is_nothrow_move_assignable<T>::value> {};
+ std::is_nothrow_move_constructible<T>::value &&
+ std::is_nothrow_move_assignable<T>::value> {};
- template <class T, std::size_t N>
- struct is_std_swap_noexcept<T[N]> : is_std_swap_noexcept<T> {};
+template <class T, std::size_t N>
+struct is_std_swap_noexcept<T[N]> : is_std_swap_noexcept<T> {};
- template <class T, class U>
- struct is_adl_swap_noexcept
+template <class T, class U>
+struct is_adl_swap_noexcept
: std::integral_constant<bool, noexcept(can_swap<T, U>(0))> {};
} // namespace swap_adl_tests
template <class T, class U = T>
struct is_swappable
- : std::integral_constant<
- bool,
- decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
- (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
- (std::is_move_assignable<T>::value &&
- std::is_move_constructible<T>::value))> {};
+ : std::integral_constant<
+ bool,
+ decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
+ (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
+ (std::is_move_assignable<T>::value &&
+ std::is_move_constructible<T>::value))> {};
template <class T, std::size_t N>
struct is_swappable<T[N], T[N]>
- : std::integral_constant<
- bool,
- decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
- (!decltype(
- detail::swap_adl_tests::uses_std<T[N], T[N]>(0))::value ||
- is_swappable<T, T>::value)> {};
+ : std::integral_constant<
+ bool,
+ decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
+ (!decltype(detail::swap_adl_tests::uses_std<T[N], T[N]>(
+ 0))::value ||
+ is_swappable<T, T>::value)> {};
template <class T, class U = T>
struct is_nothrow_swappable
- : std::integral_constant<
- bool,
- is_swappable<T, U>::value &&
- ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value
- && detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
- (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
- detail::swap_adl_tests::is_adl_swap_noexcept<T,
- U>::value))> {
-};
+ : std::integral_constant<
+ bool,
+ is_swappable<T, U>::value &&
+ ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
+ detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
+ (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
+ detail::swap_adl_tests::is_adl_swap_noexcept<T, U>::value))> {};
#endif
#endif
@@ -393,14 +426,10 @@ using is_move_constructible_or_void =
is_void_or<T, std::is_move_constructible<T>>;
template <class T>
-using is_copy_assignable_or_void =
- is_void_or<T, std::is_copy_assignable<T>>;
-
+using is_copy_assignable_or_void = is_void_or<T, std::is_copy_assignable<T>>;
template <class T>
-using is_move_assignable_or_void =
- is_void_or<T, std::is_move_assignable<T>>;
-
+using is_move_assignable_or_void = is_void_or<T, std::is_move_assignable<T>>;
} // namespace detail
@@ -423,19 +452,19 @@ struct expected_storage_base {
template <class... Args,
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
nullptr>
- constexpr expected_storage_base(in_place_t, Args &&... args)
+ constexpr expected_storage_base(in_place_t, Args &&...args)
: m_val(std::forward<Args>(args)...), m_has_val(true) {}
template <class U, class... Args,
detail::enable_if_t<std::is_constructible<
T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
template <class... Args,
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
nullptr>
- constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
+ constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
: m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
template <class U, class... Args,
@@ -443,7 +472,7 @@ struct expected_storage_base {
E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr explicit expected_storage_base(unexpect_t,
std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
~expected_storage_base() {
@@ -470,19 +499,19 @@ template <class T, class E> struct expected_storage_base<T, E, true, true> {
template <class... Args,
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
nullptr>
- constexpr expected_storage_base(in_place_t, Args &&... args)
+ constexpr expected_storage_base(in_place_t, Args &&...args)
: m_val(std::forward<Args>(args)...), m_has_val(true) {}
template <class U, class... Args,
detail::enable_if_t<std::is_constructible<
T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
template <class... Args,
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
nullptr>
- constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
+ constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
: m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
template <class U, class... Args,
@@ -490,7 +519,7 @@ template <class T, class E> struct expected_storage_base<T, E, true, true> {
E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr explicit expected_storage_base(unexpect_t,
std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
~expected_storage_base() = default;
@@ -511,19 +540,19 @@ template <class T, class E> struct expected_storage_base<T, E, true, false> {
template <class... Args,
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
nullptr>
- constexpr expected_storage_base(in_place_t, Args &&... args)
+ constexpr expected_storage_base(in_place_t, Args &&...args)
: m_val(std::forward<Args>(args)...), m_has_val(true) {}
template <class U, class... Args,
detail::enable_if_t<std::is_constructible<
T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
template <class... Args,
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
nullptr>
- constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
+ constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
: m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
template <class U, class... Args,
@@ -531,7 +560,7 @@ template <class T, class E> struct expected_storage_base<T, E, true, false> {
E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr explicit expected_storage_base(unexpect_t,
std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
~expected_storage_base() {
@@ -556,19 +585,19 @@ template <class T, class E> struct expected_storage_base<T, E, false, true> {
template <class... Args,
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
nullptr>
- constexpr expected_storage_base(in_place_t, Args &&... args)
+ constexpr expected_storage_base(in_place_t, Args &&...args)
: m_val(std::forward<Args>(args)...), m_has_val(true) {}
template <class U, class... Args,
detail::enable_if_t<std::is_constructible<
T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
template <class... Args,
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
nullptr>
- constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
+ constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
: m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
template <class U, class... Args,
@@ -576,7 +605,7 @@ template <class T, class E> struct expected_storage_base<T, E, false, true> {
E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr explicit expected_storage_base(unexpect_t,
std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
~expected_storage_base() {
@@ -594,7 +623,13 @@ template <class T, class E> struct expected_storage_base<T, E, false, true> {
// `T` is `void`, `E` is trivially-destructible
template <class E> struct expected_storage_base<void, E, false, true> {
- TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base() : m_has_val(true) {}
+ #if __GNUC__ <= 5
+ //no constexpr for GCC 4/5 bug
+ #else
+ TL_EXPECTED_MSVC2015_CONSTEXPR
+ #endif
+ expected_storage_base() : m_has_val(true) {}
+
constexpr expected_storage_base(no_init_t) : m_val(), m_has_val(false) {}
constexpr expected_storage_base(in_place_t) : m_has_val(true) {}
@@ -602,7 +637,7 @@ template <class E> struct expected_storage_base<void, E, false, true> {
template <class... Args,
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
nullptr>
- constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
+ constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
: m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
template <class U, class... Args,
@@ -610,7 +645,7 @@ template <class E> struct expected_storage_base<void, E, false, true> {
E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr explicit expected_storage_base(unexpect_t,
std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
~expected_storage_base() = default;
@@ -632,7 +667,7 @@ template <class E> struct expected_storage_base<void, E, false, false> {
template <class... Args,
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
nullptr>
- constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
+ constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
: m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
template <class U, class... Args,
@@ -640,7 +675,7 @@ template <class E> struct expected_storage_base<void, E, false, false> {
E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr explicit expected_storage_base(unexpect_t,
std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
~expected_storage_base() {
@@ -662,7 +697,7 @@ template <class T, class E>
struct expected_operations_base : expected_storage_base<T, E> {
using expected_storage_base<T, E>::expected_storage_base;
- template <class... Args> void construct(Args &&... args) noexcept {
+ template <class... Args> void construct(Args &&...args) noexcept {
new (std::addressof(this->m_val)) T(std::forward<Args>(args)...);
this->m_has_val = true;
}
@@ -672,13 +707,13 @@ struct expected_operations_base : expected_storage_base<T, E> {
this->m_has_val = true;
}
- template <class... Args> void construct_error(Args &&... args) noexcept {
+ template <class... Args> void construct_error(Args &&...args) noexcept {
new (std::addressof(this->m_unexpect))
unexpected<E>(std::forward<Args>(args)...);
this->m_has_val = false;
}
- #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
+#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
// These assign overloads ensure that the most efficient assignment
// implementation is used while maintaining the strong exception guarantee.
@@ -778,7 +813,7 @@ struct expected_operations_base : expected_storage_base<T, E> {
}
}
- #else
+#else
// If exceptions are disabled then we can just copy-construct
void assign(const expected_operations_base &rhs) noexcept {
@@ -795,11 +830,11 @@ struct expected_operations_base : expected_storage_base<T, E> {
geterr().~unexpected<E>();
construct(std::move(rhs).get());
} else {
- assign_common(rhs);
+ assign_common(std::move(rhs));
}
}
- #endif
+#endif
// The common part of move/copy assigning
template <class Rhs> void assign_common(Rhs &&rhs) {
@@ -807,7 +842,7 @@ struct expected_operations_base : expected_storage_base<T, E> {
if (rhs.m_has_val) {
get() = std::forward<Rhs>(rhs).get();
} else {
- destroy_val();
+ destroy_val();
construct_error(std::forward<Rhs>(rhs).geterr());
}
} else {
@@ -839,9 +874,7 @@ struct expected_operations_base : expected_storage_base<T, E> {
}
#endif
- TL_EXPECTED_11_CONSTEXPR void destroy_val() {
- get().~T();
- }
+ TL_EXPECTED_11_CONSTEXPR void destroy_val() { get().~T(); }
};
// This base class provides some handy member functions which can be used in
@@ -858,7 +891,7 @@ struct expected_operations_base<void, E> : expected_storage_base<void, E> {
this->m_has_val = true;
}
- template <class... Args> void construct_error(Args &&... args) noexcept {
+ template <class... Args> void construct_error(Args &&...args) noexcept {
new (std::addressof(this->m_unexpect))
unexpected<E>(std::forward<Args>(args)...);
this->m_has_val = false;
@@ -895,7 +928,7 @@ struct expected_operations_base<void, E> : expected_storage_base<void, E> {
#endif
TL_EXPECTED_11_CONSTEXPR void destroy_val() {
- //no-op
+ // no-op
}
};
@@ -1220,14 +1253,17 @@ class expected : private detail::expected_move_assign_base<T, E>,
"T must not be in_place_t");
static_assert(!std::is_same<T, std::remove_cv<unexpect_t>::type>::value,
"T must not be unexpect_t");
- static_assert(!std::is_same<T, typename std::remove_cv<unexpected<E>>::type>::value,
- "T must not be unexpected<E>");
+ static_assert(
+ !std::is_same<T, typename std::remove_cv<unexpected<E>>::type>::value,
+ "T must not be unexpected<E>");
static_assert(!std::is_reference<E>::value, "E must not be a reference");
T *valptr() { return std::addressof(this->m_val); }
- const T *valptr() const { return std::addressof(this->m_val); }
+ const T *valptr() const { return std::addressof(this->m_val); }
unexpected<E> *errptr() { return std::addressof(this->m_unexpect); }
- const unexpected<E> *errptr() const { return std::addressof(this->m_unexpect); }
+ const unexpected<E> *errptr() const {
+ return std::addressof(this->m_unexpect);
+ }
template <class U = T,
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
@@ -1272,24 +1308,26 @@ public:
#else
template <class F>
TL_EXPECTED_11_CONSTEXPR auto
- and_then(F &&f) & -> decltype(and_then_impl(std::declval<expected&>(), std::forward<F>(f))) {
+ and_then(F &&f) & -> decltype(and_then_impl(std::declval<expected &>(),
+ std::forward<F>(f))) {
return and_then_impl(*this, std::forward<F>(f));
}
template <class F>
- TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && -> decltype(
- and_then_impl(std::declval<expected&&>(), std::forward<F>(f))) {
+ TL_EXPECTED_11_CONSTEXPR auto
+ and_then(F &&f) && -> decltype(and_then_impl(std::declval<expected &&>(),
+ std::forward<F>(f))) {
return and_then_impl(std::move(*this), std::forward<F>(f));
}
template <class F>
- constexpr auto and_then(F &&f) const & -> decltype(
- and_then_impl(std::declval<expected const&>(), std::forward<F>(f))) {
+ constexpr auto and_then(F &&f) const & -> decltype(and_then_impl(
+ std::declval<expected const &>(), std::forward<F>(f))) {
return and_then_impl(*this, std::forward<F>(f));
}
#ifndef TL_EXPECTED_NO_CONSTRR
template <class F>
- constexpr auto and_then(F &&f) const && -> decltype(
- and_then_impl(std::declval<expected const&&>(), std::forward<F>(f))) {
+ constexpr auto and_then(F &&f) const && -> decltype(and_then_impl(
+ std::declval<expected const &&>(), std::forward<F>(f))) {
return and_then_impl(std::move(*this), std::forward<F>(f));
}
#endif
@@ -1297,7 +1335,7 @@ public:
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
- template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & {
+ template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & {
return expected_map_impl(*this, std::forward<F>(f));
}
template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) && {
@@ -1311,14 +1349,14 @@ public:
}
#else
template <class F>
- TL_EXPECTED_11_CONSTEXPR decltype(
- expected_map_impl(std::declval<expected &>(), std::declval<F &&>()))
+ TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(
+ std::declval<expected &>(), std::declval<F &&>()))
map(F &&f) & {
return expected_map_impl(*this, std::forward<F>(f));
}
template <class F>
- TL_EXPECTED_11_CONSTEXPR decltype(
- expected_map_impl(std::declval<expected>(), std::declval<F &&>()))
+ TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(),
+ std::declval<F &&>()))
map(F &&f) && {
return expected_map_impl(std::move(*this), std::forward<F>(f));
}
@@ -1341,7 +1379,7 @@ public:
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
- template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) & {
+ template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) & {
return expected_map_impl(*this, std::forward<F>(f));
}
template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) && {
@@ -1354,15 +1392,15 @@ public:
return expected_map_impl(std::move(*this), std::forward<F>(f));
}
#else
- template <class F>
- TL_EXPECTED_11_CONSTEXPR decltype(
- expected_map_impl(std::declval<expected &>(), std::declval<F &&>()))
+ template <class F>
+ TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(
+ std::declval<expected &>(), std::declval<F &&>()))
transform(F &&f) & {
return expected_map_impl(*this, std::forward<F>(f));
}
template <class F>
- TL_EXPECTED_11_CONSTEXPR decltype(
- expected_map_impl(std::declval<expected>(), std::declval<F &&>()))
+ TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(),
+ std::declval<F &&>()))
transform(F &&f) && {
return expected_map_impl(std::move(*this), std::forward<F>(f));
}
@@ -1385,54 +1423,87 @@ public:
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
- template<class F>
- TL_EXPECTED_11_CONSTEXPR auto transform_or(F &&f) &
- {
- return transform_or_impl(*this, std::forward<F>(f));
- }
- template<class F>
- TL_EXPECTED_11_CONSTEXPR auto transform_or(F &&f) &&
- {
- return transform_or_impl(std::move(*this), std::forward<F>(f));
- }
- template<class F>
- constexpr auto transform_or(F &&f) const &
- {
- return transform_or_impl(*this, std::forward<F>(f));
- }
- template<class F>
- constexpr auto transform_or(F &&f) const &&
- {
- return transform_or_impl(std::move(*this), std::forward<F>(f));
+ template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) & {
+ return map_error_impl(*this, std::forward<F>(f));
+ }
+ template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) && {
+ return map_error_impl(std::move(*this), std::forward<F>(f));
+ }
+ template <class F> constexpr auto map_error(F &&f) const & {
+ return map_error_impl(*this, std::forward<F>(f));
+ }
+ template <class F> constexpr auto map_error(F &&f) const && {
+ return map_error_impl(std::move(*this), std::forward<F>(f));
}
#else
- template<class F>
- TL_EXPECTED_11_CONSTEXPR decltype(transform_or_impl(std::declval<expected &>(),
- std::declval<F &&>()))
- transform_or(F &&f) &
- {
- return transform_or_impl(*this, std::forward<F>(f));
+ template <class F>
+ TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(),
+ std::declval<F &&>()))
+ map_error(F &&f) & {
+ return map_error_impl(*this, std::forward<F>(f));
}
- template<class F>
- TL_EXPECTED_11_CONSTEXPR decltype(transform_or_impl(std::declval<expected &&>(),
- std::declval<F &&>()))
- transform_or(F &&f) &&
- {
- return transform_or_impl(std::move(*this), std::forward<F>(f));
+ template <class F>
+ TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(),
+ std::declval<F &&>()))
+ map_error(F &&f) && {
+ return map_error_impl(std::move(*this), std::forward<F>(f));
+ }
+ template <class F>
+ constexpr decltype(map_error_impl(std::declval<const expected &>(),
+ std::declval<F &&>()))
+ map_error(F &&f) const & {
+ return map_error_impl(*this, std::forward<F>(f));
+ }
+
+#ifndef TL_EXPECTED_NO_CONSTRR
+ template <class F>
+ constexpr decltype(map_error_impl(std::declval<const expected &&>(),
+ std::declval<F &&>()))
+ map_error(F &&f) const && {
+ return map_error_impl(std::move(*this), std::forward<F>(f));
+ }
+#endif
+#endif
+#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
+ !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
+ template <class F> TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) & {
+ return map_error_impl(*this, std::forward<F>(f));
+ }
+ template <class F> TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) && {
+ return map_error_impl(std::move(*this), std::forward<F>(f));
}
- template<class F>
- constexpr decltype(transform_or_impl(std::declval<const expected &>(), std::declval<F &&>()))
- transform_or(F &&f) const &
- {
- return transform_or_impl(*this, std::forward<F>(f));
+ template <class F> constexpr auto transform_error(F &&f) const & {
+ return map_error_impl(*this, std::forward<F>(f));
+ }
+ template <class F> constexpr auto transform_error(F &&f) const && {
+ return map_error_impl(std::move(*this), std::forward<F>(f));
+ }
+#else
+ template <class F>
+ TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(),
+ std::declval<F &&>()))
+ transform_error(F &&f) & {
+ return map_error_impl(*this, std::forward<F>(f));
+ }
+ template <class F>
+ TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(),
+ std::declval<F &&>()))
+ transform_error(F &&f) && {
+ return map_error_impl(std::move(*this), std::forward<F>(f));
+ }
+ template <class F>
+ constexpr decltype(map_error_impl(std::declval<const expected &>(),
+ std::declval<F &&>()))
+ transform_error(F &&f) const & {
+ return map_error_impl(*this, std::forward<F>(f));
}
#ifndef TL_EXPECTED_NO_CONSTRR
- template<class F>
- constexpr decltype(transform_or_impl(std::declval<const expected &&>(), std::declval<F &&>()))
- transform_or(F &&f) const &&
- {
- return transform_or_impl(std::move(*this), std::forward<F>(f));
+ template <class F>
+ constexpr decltype(map_error_impl(std::declval<const expected &&>(),
+ std::declval<F &&>()))
+ transform_error(F &&f) const && {
+ return map_error_impl(std::move(*this), std::forward<F>(f));
}
#endif
#endif
@@ -1462,14 +1533,14 @@ public:
template <class... Args,
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
nullptr>
- constexpr expected(in_place_t, Args &&... args)
+ constexpr expected(in_place_t, Args &&...args)
: impl_base(in_place, std::forward<Args>(args)...),
ctor_base(detail::default_constructor_tag{}) {}
template <class U, class... Args,
detail::enable_if_t<std::is_constructible<
T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
- constexpr expected(in_place_t, std::initializer_list<U> il, Args &&... args)
+ constexpr expected(in_place_t, std::initializer_list<U> il, Args &&...args)
: impl_base(in_place, il, std::forward<Args>(args)...),
ctor_base(detail::default_constructor_tag{}) {}
@@ -1482,7 +1553,7 @@ public:
: impl_base(unexpect, e.value()),
ctor_base(detail::default_constructor_tag{}) {}
- template <
+ template <
class G = E,
detail::enable_if_t<std::is_constructible<E, const G &>::value> * =
nullptr,
@@ -1500,7 +1571,7 @@ public:
: impl_base(unexpect, std::move(e.value())),
ctor_base(detail::default_constructor_tag{}) {}
- template <
+ template <
class G = E,
detail::enable_if_t<std::is_constructible<E, G &&>::value> * = nullptr,
detail::enable_if_t<std::is_convertible<G &&, E>::value> * = nullptr>
@@ -1512,15 +1583,15 @@ public:
template <class... Args,
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
nullptr>
- constexpr explicit expected(unexpect_t, Args &&... args)
+ constexpr explicit expected(unexpect_t, Args &&...args)
: impl_base(unexpect, std::forward<Args>(args)...),
ctor_base(detail::default_constructor_tag{}) {}
- template <class U, class... Args,
+ template <class U, class... Args,
detail::enable_if_t<std::is_constructible<
E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
constexpr explicit expected(unexpect_t, std::initializer_list<U> il,
- Args &&... args)
+ Args &&...args)
: impl_base(unexpect, il, std::forward<Args>(args)...),
ctor_base(detail::default_constructor_tag{}) {}
@@ -1535,11 +1606,11 @@ public:
if (rhs.has_value()) {
this->construct(*rhs);
} else {
- this->construct_error(rhs.error());
+ this->construct_error(rhs.error());
}
}
- template <class U, class G,
+ template <class U, class G,
detail::enable_if_t<(std::is_convertible<U const &, T>::value &&
std::is_convertible<G const &, E>::value)> * =
nullptr,
@@ -1550,8 +1621,8 @@ public:
if (rhs.has_value()) {
this->construct(*rhs);
} else {
- this->construct_error(rhs.error());
- }
+ this->construct_error(rhs.error());
+ }
}
template <
@@ -1564,11 +1635,11 @@ public:
if (rhs.has_value()) {
this->construct(std::move(*rhs));
} else {
- this->construct_error(std::move(rhs.error()));
- }
+ this->construct_error(std::move(rhs.error()));
+ }
}
- template <
+ template <
class U, class G,
detail::enable_if_t<(std::is_convertible<U &&, T>::value &&
std::is_convertible<G &&, E>::value)> * = nullptr,
@@ -1578,8 +1649,8 @@ public:
if (rhs.has_value()) {
this->construct(std::move(*rhs));
} else {
- this->construct_error(std::move(rhs.error()));
- }
+ this->construct_error(std::move(rhs.error()));
+ }
}
template <
@@ -1589,7 +1660,7 @@ public:
explicit TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v)
: expected(in_place, std::forward<U>(v)) {}
- template <
+ template <
class U = T,
detail::enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr,
detail::expected_enable_forward_value<T, E, U> * = nullptr>
@@ -1620,7 +1691,7 @@ public:
return *this;
}
- template <
+ template <
class U = T, class G = T,
detail::enable_if_t<!std::is_nothrow_constructible<T, U &&>::value> * =
nullptr,
@@ -1639,7 +1710,7 @@ public:
auto tmp = std::move(err());
err().~unexpected<E>();
- #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
+#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
try {
::new (valptr()) T(std::forward<U>(v));
this->m_has_val = true;
@@ -1647,10 +1718,10 @@ public:
err() = std::move(tmp);
throw;
}
- #else
- ::new (valptr()) T(std::forward<U>(v));
- this->m_has_val = true;
- #endif
+#else
+ ::new (valptr()) T(std::forward<U>(v));
+ this->m_has_val = true;
+#endif
}
return *this;
@@ -1688,26 +1759,27 @@ public:
template <class... Args, detail::enable_if_t<std::is_nothrow_constructible<
T, Args &&...>::value> * = nullptr>
- void emplace(Args &&... args) {
+ void emplace(Args &&...args) {
if (has_value()) {
- val() = T(std::forward<Args>(args)...);
+ val().~T();
} else {
err().~unexpected<E>();
- ::new (valptr()) T(std::forward<Args>(args)...);
this->m_has_val = true;
}
+ ::new (valptr()) T(std::forward<Args>(args)...);
}
- template <class... Args, detail::enable_if_t<!std::is_nothrow_constructible<
+ template <class... Args, detail::enable_if_t<!std::is_nothrow_constructible<
T, Args &&...>::value> * = nullptr>
- void emplace(Args &&... args) {
+ void emplace(Args &&...args) {
if (has_value()) {
- val() = T(std::forward<Args>(args)...);
+ val().~T();
+ ::new (valptr()) T(std::forward<Args>(args)...);
} else {
auto tmp = std::move(err());
err().~unexpected<E>();
- #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
+#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
try {
::new (valptr()) T(std::forward<Args>(args)...);
this->m_has_val = true;
@@ -1715,17 +1787,17 @@ public:
err() = std::move(tmp);
throw;
}
- #else
+#else
::new (valptr()) T(std::forward<Args>(args)...);
this->m_has_val = true;
- #endif
+#endif
}
}
template <class U, class... Args,
detail::enable_if_t<std::is_nothrow_constructible<
T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
- void emplace(std::initializer_list<U> il, Args &&... args) {
+ void emplace(std::initializer_list<U> il, Args &&...args) {
if (has_value()) {
T t(il, std::forward<Args>(args)...);
val() = std::move(t);
@@ -1736,10 +1808,10 @@ public:
}
}
- template <class U, class... Args,
+ template <class U, class... Args,
detail::enable_if_t<!std::is_nothrow_constructible<
T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
- void emplace(std::initializer_list<U> il, Args &&... args) {
+ void emplace(std::initializer_list<U> il, Args &&...args) {
if (has_value()) {
T t(il, std::forward<Args>(args)...);
val() = std::move(t);
@@ -1747,7 +1819,7 @@ public:
auto tmp = std::move(err());
err().~unexpected<E>();
- #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
+#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
try {
::new (valptr()) T(il, std::forward<Args>(args)...);
this->m_has_val = true;
@@ -1755,10 +1827,10 @@ public:
err() = std::move(tmp);
throw;
}
- #else
+#else
::new (valptr()) T(il, std::forward<Args>(args)...);
this->m_has_val = true;
- #endif
+#endif
}
}
@@ -1770,7 +1842,7 @@ private:
using e_is_nothrow_move_constructible = std::true_type;
using move_constructing_e_can_throw = std::false_type;
- void swap_where_both_have_value(expected &/*rhs*/ , t_is_void) noexcept {
+ void swap_where_both_have_value(expected & /*rhs*/, t_is_void) noexcept {
// swapping void is a no-op
}
@@ -1828,12 +1900,12 @@ private:
void swap_where_only_one_has_value_and_t_is_not_void(
expected &rhs, move_constructing_t_can_throw,
- t_is_nothrow_move_constructible) {
+ e_is_nothrow_move_constructible) {
auto temp = std::move(rhs.err());
rhs.err().~unexpected_type();
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
try {
- ::new (rhs.valptr()) T(val());
+ ::new (rhs.valptr()) T(std::move(val()));
val().~T();
::new (errptr()) unexpected_type(std::move(temp));
std::swap(this->m_has_val, rhs.m_has_val);
@@ -1842,7 +1914,7 @@ private:
throw;
}
#else
- ::new (rhs.valptr()) T(val());
+ ::new (rhs.valptr()) T(std::move(val()));
val().~T();
::new (errptr()) unexpected_type(std::move(temp));
std::swap(this->m_has_val, rhs.m_has_val);
@@ -1872,27 +1944,37 @@ public:
}
}
- constexpr const T *operator->() const { return valptr(); }
- TL_EXPECTED_11_CONSTEXPR T *operator->() { return valptr(); }
+ constexpr const T *operator->() const {
+ TL_ASSERT(has_value());
+ return valptr();
+ }
+ TL_EXPECTED_11_CONSTEXPR T *operator->() {
+ TL_ASSERT(has_value());
+ return valptr();
+ }
template <class U = T,
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
constexpr const U &operator*() const & {
+ TL_ASSERT(has_value());
return val();
}
template <class U = T,
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
TL_EXPECTED_11_CONSTEXPR U &operator*() & {
+ TL_ASSERT(has_value());
return val();
}
template <class U = T,
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
constexpr const U &&operator*() const && {
+ TL_ASSERT(has_value());
return std::move(val());
}
template <class U = T,
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
TL_EXPECTED_11_CONSTEXPR U &&operator*() && {
+ TL_ASSERT(has_value());
return std::move(val());
}
@@ -1928,10 +2010,22 @@ public:
return std::move(val());
}
- constexpr const E &error() const & { return err().value(); }
- TL_EXPECTED_11_CONSTEXPR E &error() & { return err().value(); }
- constexpr const E &&error() const && { return std::move(err().value()); }
- TL_EXPECTED_11_CONSTEXPR E &&error() && { return std::move(err().value()); }
+ constexpr const E &error() const & {
+ TL_ASSERT(!has_value());
+ return err().value();
+ }
+ TL_EXPECTED_11_CONSTEXPR E &error() & {
+ TL_ASSERT(!has_value());
+ return err().value();
+ }
+ constexpr const E &&error() const && {
+ TL_ASSERT(!has_value());
+ return std::move(err().value());
+ }
+ TL_EXPECTED_11_CONSTEXPR E &&error() && {
+ TL_ASSERT(!has_value());
+ return std::move(err().value());
+ }
template <class U> constexpr T value_or(U &&v) const & {
static_assert(std::is_copy_constructible<T>::value &&
@@ -2001,7 +2095,7 @@ constexpr auto and_then_impl(Exp &&exp, F &&f) -> Ret {
#ifdef TL_EXPECTED_CXX14
template <class Exp, class F,
- detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
+ detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
class Ret = decltype(detail::invoke(std::declval<F>(),
*std::declval<Exp>())),
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
@@ -2013,7 +2107,7 @@ constexpr auto expected_map_impl(Exp &&exp, F &&f) {
}
template <class Exp, class F,
- detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
+ detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
class Ret = decltype(detail::invoke(std::declval<F>(),
*std::declval<Exp>())),
detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
@@ -2038,7 +2132,7 @@ constexpr auto expected_map_impl(Exp &&exp, F &&f) {
}
template <class Exp, class F,
- detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
+ detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
class Ret = decltype(detail::invoke(std::declval<F>())),
detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
auto expected_map_impl(Exp &&exp, F &&f) {
@@ -2049,10 +2143,10 @@ auto expected_map_impl(Exp &&exp, F &&f) {
}
return result(unexpect, std::forward<Exp>(exp).error());
-}
+}
#else
template <class Exp, class F,
- detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
+ detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
class Ret = decltype(detail::invoke(std::declval<F>(),
*std::declval<Exp>())),
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
@@ -2067,7 +2161,7 @@ constexpr auto expected_map_impl(Exp &&exp, F &&f)
}
template <class Exp, class F,
- detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
+ detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
class Ret = decltype(detail::invoke(std::declval<F>(),
*std::declval<Exp>())),
detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
@@ -2082,7 +2176,7 @@ auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> {
}
template <class Exp, class F,
- detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
+ detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
class Ret = decltype(detail::invoke(std::declval<F>())),
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
@@ -2095,7 +2189,7 @@ constexpr auto expected_map_impl(Exp &&exp, F &&f)
}
template <class Exp, class F,
- detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
+ detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
class Ret = decltype(detail::invoke(std::declval<F>())),
detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
@@ -2106,31 +2200,29 @@ auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> {
}
return unexpected<err_t<Exp>>(std::forward<Exp>(exp).error());
-}
+}
#endif
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
-template<class Exp,
- class F,
- detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
- class Ret = decltype(detail::invoke(std::declval<F>(), std::declval<Exp>().error())),
- detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
-constexpr auto transform_or_impl(Exp &&exp, F &&f)
-{
+template <class Exp, class F,
+ detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
+ class Ret = decltype(detail::invoke(std::declval<F>(),
+ std::declval<Exp>().error())),
+ detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
+constexpr auto map_error_impl(Exp &&exp, F &&f) {
using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
return exp.has_value()
? result(*std::forward<Exp>(exp))
: result(unexpect, detail::invoke(std::forward<F>(f),
std::forward<Exp>(exp).error()));
}
-template<class Exp,
- class F,
- detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
- class Ret = decltype(detail::invoke(std::declval<F>(), std::declval<Exp>().error())),
- detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
-auto transform_or_impl(Exp &&exp, F &&f)
-{
+template <class Exp, class F,
+ detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
+ class Ret = decltype(detail::invoke(std::declval<F>(),
+ std::declval<Exp>().error())),
+ detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
+auto map_error_impl(Exp &&exp, F &&f) {
using result = expected<exp_t<Exp>, monostate>;
if (exp.has_value()) {
return result(*std::forward<Exp>(exp));
@@ -2139,26 +2231,24 @@ auto transform_or_impl(Exp &&exp, F &&f)
detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
return result(unexpect, monostate{});
}
-template<class Exp,
- class F,
- detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
- class Ret = decltype(detail::invoke(std::declval<F>(), std::declval<Exp>().error())),
- detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
-constexpr auto transform_or_impl(Exp &&exp, F &&f)
-{
+template <class Exp, class F,
+ detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
+ class Ret = decltype(detail::invoke(std::declval<F>(),
+ std::declval<Exp>().error())),
+ detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
+constexpr auto map_error_impl(Exp &&exp, F &&f) {
using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
return exp.has_value()
? result()
: result(unexpect, detail::invoke(std::forward<F>(f),
std::forward<Exp>(exp).error()));
}
-template<class Exp,
- class F,
- detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
- class Ret = decltype(detail::invoke(std::declval<F>(), std::declval<Exp>().error())),
- detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
-auto transform_or_impl(Exp &&exp, F &&f)
-{
+template <class Exp, class F,
+ detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
+ class Ret = decltype(detail::invoke(std::declval<F>(),
+ std::declval<Exp>().error())),
+ detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
+auto map_error_impl(Exp &&exp, F &&f) {
using result = expected<exp_t<Exp>, monostate>;
if (exp.has_value()) {
return result();
@@ -2168,13 +2258,13 @@ auto transform_or_impl(Exp &&exp, F &&f)
return result(unexpect, monostate{});
}
#else
-template<class Exp,
- class F,
- detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
- class Ret = decltype(detail::invoke(std::declval<F>(), std::declval<Exp>().error())),
- detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
-constexpr auto transform_or_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, detail::decay_t<Ret>>
-{
+template <class Exp, class F,
+ detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
+ class Ret = decltype(detail::invoke(std::declval<F>(),
+ std::declval<Exp>().error())),
+ detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
+constexpr auto map_error_impl(Exp &&exp, F &&f)
+ -> expected<exp_t<Exp>, detail::decay_t<Ret>> {
using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
return exp.has_value()
@@ -2183,13 +2273,12 @@ constexpr auto transform_or_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, detai
std::forward<Exp>(exp).error()));
}
-template<class Exp,
- class F,
- detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
- class Ret = decltype(detail::invoke(std::declval<F>(), std::declval<Exp>().error())),
- detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
-auto transform_or_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate>
-{
+template <class Exp, class F,
+ detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
+ class Ret = decltype(detail::invoke(std::declval<F>(),
+ std::declval<Exp>().error())),
+ detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
+auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
using result = expected<exp_t<Exp>, monostate>;
if (exp.has_value()) {
return result(*std::forward<Exp>(exp));
@@ -2199,13 +2288,13 @@ auto transform_or_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate>
return result(unexpect, monostate{});
}
-template<class Exp,
- class F,
- detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
- class Ret = decltype(detail::invoke(std::declval<F>(), std::declval<Exp>().error())),
- detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
-constexpr auto transform_or_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, detail::decay_t<Ret>>
-{
+template <class Exp, class F,
+ detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
+ class Ret = decltype(detail::invoke(std::declval<F>(),
+ std::declval<Exp>().error())),
+ detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
+constexpr auto map_error_impl(Exp &&exp, F &&f)
+ -> expected<exp_t<Exp>, detail::decay_t<Ret>> {
using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
return exp.has_value()
@@ -2214,13 +2303,12 @@ constexpr auto transform_or_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, detai
std::forward<Exp>(exp).error()));
}
-template<class Exp,
- class F,
- detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
- class Ret = decltype(detail::invoke(std::declval<F>(), std::declval<Exp>().error())),
- detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
-auto transform_or_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate>
-{
+template <class Exp, class F,
+ detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
+ class Ret = decltype(detail::invoke(std::declval<F>(),
+ std::declval<Exp>().error())),
+ detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
+auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
using result = expected<exp_t<Exp>, monostate>;
if (exp.has_value()) {
return result();
@@ -2228,7 +2316,7 @@ auto transform_or_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate>
detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
return result(unexpect, monostate{});
-}
+}
#endif
#ifdef TL_EXPECTED_CXX14
@@ -2238,9 +2326,9 @@ template <class Exp, class F,
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
constexpr auto or_else_impl(Exp &&exp, F &&f) {
static_assert(detail::is_expected<Ret>::value, "F must return an expected");
- return exp.has_value()
- ? std::forward<Exp>(exp)
- : detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
+ return exp.has_value() ? std::forward<Exp>(exp)
+ : detail::invoke(std::forward<F>(f),
+ std::forward<Exp>(exp).error());
}
template <class Exp, class F,
@@ -2248,32 +2336,32 @@ template <class Exp, class F,
std::declval<Exp>().error())),
detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
- return exp.has_value()
- ? std::forward<Exp>(exp)
- : (detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error()),
- std::forward<Exp>(exp));
+ return exp.has_value() ? std::forward<Exp>(exp)
+ : (detail::invoke(std::forward<F>(f),
+ std::forward<Exp>(exp).error()),
+ std::forward<Exp>(exp));
}
#else
template <class Exp, class F,
class Ret = decltype(detail::invoke(std::declval<F>(),
std::declval<Exp>().error())),
- detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
+ detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
auto or_else_impl(Exp &&exp, F &&f) -> Ret {
static_assert(detail::is_expected<Ret>::value, "F must return an expected");
- return exp.has_value()
- ? std::forward<Exp>(exp)
- : detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
+ return exp.has_value() ? std::forward<Exp>(exp)
+ : detail::invoke(std::forward<F>(f),
+ std::forward<Exp>(exp).error());
}
template <class Exp, class F,
class Ret = decltype(detail::invoke(std::declval<F>(),
std::declval<Exp>().error())),
- detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
+ detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
- return exp.has_value()
- ? std::forward<Exp>(exp)
- : (detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error()),
- std::forward<Exp>(exp));
+ return exp.has_value() ? std::forward<Exp>(exp)
+ : (detail::invoke(std::forward<F>(f),
+ std::forward<Exp>(exp).error()),
+ std::forward<Exp>(exp));
}
#endif
} // namespace detail
@@ -2292,6 +2380,20 @@ constexpr bool operator!=(const expected<T, E> &lhs,
? true
: (!lhs.has_value() ? lhs.error() != rhs.error() : *lhs != *rhs);
}
+template <class E, class F>
+constexpr bool operator==(const expected<void, E> &lhs,
+ const expected<void, F> &rhs) {
+ return (lhs.has_value() != rhs.has_value())
+ ? false
+ : (!lhs.has_value() ? lhs.error() == rhs.error() : true);
+}
+template <class E, class F>
+constexpr bool operator!=(const expected<void, E> &lhs,
+ const expected<void, F> &rhs) {
+ return (lhs.has_value() != rhs.has_value())
+ ? true
+ : (!lhs.has_value() ? lhs.error() == rhs.error() : false);
+}
template <class T, class E, class U>
constexpr bool operator==(const expected<T, E> &x, const U &v) {
diff --git a/src/libs/3rdparty/winpty/winpty.qbs b/src/libs/3rdparty/winpty/winpty.qbs
index f6160fe9e62..35d56f92655 100644
--- a/src/libs/3rdparty/winpty/winpty.qbs
+++ b/src/libs/3rdparty/winpty/winpty.qbs
@@ -5,7 +5,6 @@ Project {
name: "Winpty"
condition: qbs.targetOS.contains("windows")
-
Product {
name: "winpty_genversion_header"
type: "hpp"
@@ -199,8 +198,8 @@ Project {
Export {
Depends { name: "cpp" }
- cpp.defines: base.concat("COMPILING_WINPTY_DLL")
- cpp.includePaths: base.concat(exportingProduct.sourceDirectory + "/src/include")
+ cpp.defines: "COMPILING_WINPTY_DLL"
+ cpp.includePaths: exportingProduct.sourceDirectory + "/src/include"
}
}
}
diff --git a/src/libs/3rdparty/yaml-cpp/README.md b/src/libs/3rdparty/yaml-cpp/README.md
index f33d3503a15..70c231445d3 100644
--- a/src/libs/3rdparty/yaml-cpp/README.md
+++ b/src/libs/3rdparty/yaml-cpp/README.md
@@ -1,51 +1,58 @@
-# yaml-cpp [![Build Status](https://travis-ci.org/jbeder/yaml-cpp.svg?branch=master)](https://travis-ci.org/jbeder/yaml-cpp) [![Documentation](https://codedocs.xyz/jbeder/yaml-cpp.svg)](https://codedocs.xyz/jbeder/yaml-cpp/)
+# yaml-cpp ![Build Status](https://github.com/jbeder/yaml-cpp/actions/workflows/build.yml/badge.svg) [![Documentation](https://codedocs.xyz/jbeder/yaml-cpp.svg)](https://codedocs.xyz/jbeder/yaml-cpp/)
-yaml-cpp is a [YAML](http://www.yaml.org/) parser and emitter in C++ matching the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html).
+`yaml-cpp` is a [YAML](http://www.yaml.org/) parser and emitter in C++ matching the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html).
-To get a feel for how it can be used, see the [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) or [How to Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML). For the old API (version < 0.5.0), see [How To Parse A Document](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)).
+## Usage
-# Problems? #
+See [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) and [How to Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML) for reference. For the old API (until 0.5.0), see [How To Parse A Document](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)).
-If you find a bug, post an [issue](https://github.com/jbeder/yaml-cpp/issues)! If you have questions about how to use yaml-cpp, please post it on http://stackoverflow.com and tag it [`yaml-cpp`](http://stackoverflow.com/questions/tagged/yaml-cpp).
+## Any Problems?
-# How to Build #
+If you find a bug, post an [issue](https://github.com/jbeder/yaml-cpp/issues)! If you have questions about how to use yaml-cpp, please post it on http://stackoverflow.com and tag it [`yaml-cpp`](http://stackoverflow.com/questions/tagged/yaml-cpp).
-yaml-cpp uses [CMake](http://www.cmake.org) to support cross-platform building. The basic steps to build are:
+## How to Build
-1. Download and install [CMake](http://www.cmake.org) (Resources -> Download).
+`yaml-cpp` uses [CMake](http://www.cmake.org) to support cross-platform building. Install [CMake](http://www.cmake.org) _(Resources -> Download)_ before proceeding. The basic steps to build are:
-**Note:** If you don't use the provided installer for your platform, make sure that you add CMake's bin folder to your path.
+**Note:** If you don't use the provided installer for your platform, make sure that you add `CMake`'s bin folder to your path.
-2. Navigate into the source directory, and type:
+#### 1. Navigate into the source directory, create build folder and run `CMake`:
-```
+```sh
mkdir build
cd build
+cmake [-G generator] [-DYAML_BUILD_SHARED_LIBS=on|OFF] ..
```
-3. Run CMake. The basic syntax is:
-
-```
-cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] ..
-```
-
- * The `generator` is whatever type of build system you'd like to use. To see a full list of generators on your platform, just run `cmake` (with no arguments). For example:
- * On Windows, you might use "Visual Studio 12 2013" to generate a Visual Studio 2013 solution or "Visual Studio 14 2015 Win64" to generate a 64-bit Visual Studio 2015 solution.
- * On OS X, you might use "Xcode" to generate an Xcode project
- * On a UNIX-y system, simply omit the option to generate a makefile
+ * The `generator` option is the build system you'd like to use. Run `cmake` without arguments to see a full list of available generators.
+ * On Windows, you might use "Visual Studio 12 2013" (VS 2013 32-bits), or "Visual Studio 14 2015 Win64" (VS 2015 64-bits).
+ * On OS X, you might use "Xcode".
+ * On a UNIX-like system, omit the option (for a Makefile).
- * yaml-cpp defaults to building a static library, but you may build a shared library by specifying `-DBUILD_SHARED_LIBS=ON`.
+ * `yaml-cpp` builds a static library by default, you may want to build a shared library by specifying `-DYAML_BUILD_SHARED_LIBS=ON`.
* For more options on customizing the build, see the [CMakeLists.txt](https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt) file.
-4. Build it!
+#### 2. Build it!
+ * The command you'll need to run depends on the generator you chose earlier.
-5. To clean up, just remove the `build` directory.
+**Note:** To clean up, just remove the `build` directory.
-# Recent Release #
+## Recent Releases
-[yaml-cpp 0.6.0](https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.6.0) has been released! This release requires C++11, and no longer depends on Boost.
+[yaml-cpp 0.6.0](https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.6.0) released! This release requires C++11, and no longer depends on Boost.
[yaml-cpp 0.3.0](https://github.com/jbeder/yaml-cpp/releases/tag/release-0.3.0) is still available if you want the old API.
**The old API will continue to be supported, and will still receive bugfixes!** The 0.3.x and 0.4.x versions will be old API releases, and 0.5.x and above will all be new API releases.
+
+# API Documentation
+
+The autogenerated API reference is hosted on [CodeDocs](https://codedocs.xyz/jbeder/yaml-cpp/index.html)
+
+# Third Party Integrations
+
+The following projects are not officially supported:
+
+- [Qt wrapper](https://gist.github.com/brcha/d392b2fe5f1e427cc8a6)
+- [UnrealEngine Wrapper](https://github.com/jwindgassen/UnrealYAML)
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/anchor.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/anchor.h
index 06759c724d2..f46d1d79dd8 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/anchor.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/anchor.h
@@ -10,7 +10,7 @@
#include <cstddef>
namespace YAML {
-typedef std::size_t anchor_t;
+using anchor_t = std::size_t;
const anchor_t NullAnchor = 0;
}
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/binary.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/binary.h
index 29d5dbd027a..1050dae98c3 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/binary.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/binary.h
@@ -19,9 +19,13 @@ YAML_CPP_API std::vector<unsigned char> DecodeBase64(const std::string &input);
class YAML_CPP_API Binary {
public:
- Binary() : m_unownedData(0), m_unownedSize(0) {}
Binary(const unsigned char *data_, std::size_t size_)
- : m_unownedData(data_), m_unownedSize(size_) {}
+ : m_data{}, m_unownedData(data_), m_unownedSize(size_) {}
+ Binary() : Binary(nullptr, 0) {}
+ Binary(const Binary &) = default;
+ Binary(Binary &&) = default;
+ Binary &operator=(const Binary &) = default;
+ Binary &operator=(Binary &&) = default;
bool owned() const { return !m_unownedData; }
std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; }
@@ -35,7 +39,7 @@ class YAML_CPP_API Binary {
rhs.clear();
rhs.resize(m_unownedSize);
std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin());
- m_unownedData = 0;
+ m_unownedData = nullptr;
m_unownedSize = 0;
} else {
m_data.swap(rhs);
@@ -62,6 +66,6 @@ class YAML_CPP_API Binary {
const unsigned char *m_unownedData;
std::size_t m_unownedSize;
};
-}
+} // namespace YAML
#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/depthguard.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/depthguard.h
new file mode 100644
index 00000000000..8ca61ac6ccc
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/depthguard.h
@@ -0,0 +1,77 @@
+#ifndef DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000
+#define DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "exceptions.h"
+
+namespace YAML {
+
+/**
+ * @brief The DeepRecursion class
+ * An exception class which is thrown by DepthGuard. Ideally it should be
+ * a member of DepthGuard. However, DepthGuard is a templated class which means
+ * that any catch points would then need to know the template parameters. It is
+ * simpler for clients to not have to know at the catch point what was the
+ * maximum depth.
+ */
+class DeepRecursion : public ParserException {
+public:
+ virtual ~DeepRecursion() = default;
+
+ DeepRecursion(int depth, const Mark& mark_, const std::string& msg_);
+
+ // Returns the recursion depth when the exception was thrown
+ int depth() const {
+ return m_depth;
+ }
+
+private:
+ int m_depth = 0;
+};
+
+/**
+ * @brief The DepthGuard class
+ * DepthGuard takes a reference to an integer. It increments the integer upon
+ * construction of DepthGuard and decrements the integer upon destruction.
+ *
+ * If the integer would be incremented past max_depth, then an exception is
+ * thrown. This is ideally geared toward guarding against deep recursion.
+ *
+ * @param max_depth
+ * compile-time configurable maximum depth.
+ */
+template <int max_depth = 2000>
+class DepthGuard final {
+public:
+ DepthGuard(int & depth_, const Mark& mark_, const std::string& msg_) : m_depth(depth_) {
+ ++m_depth;
+ if ( max_depth <= m_depth ) {
+ throw DeepRecursion{m_depth, mark_, msg_};
+ }
+ }
+
+ DepthGuard(const DepthGuard & copy_ctor) = delete;
+ DepthGuard(DepthGuard && move_ctor) = delete;
+ DepthGuard & operator=(const DepthGuard & copy_assign) = delete;
+ DepthGuard & operator=(DepthGuard && move_assign) = delete;
+
+ ~DepthGuard() {
+ --m_depth;
+ }
+
+ int current_depth() const {
+ return m_depth;
+ }
+
+private:
+ int & m_depth;
+};
+
+} // namespace YAML
+
+#endif // DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
index 897f1533df6..eabdda1d95c 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
@@ -1,42 +1,61 @@
#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-#if defined(_MSC_VER) || \
- (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
- (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
-#pragma once
-#endif
-
-// The following ifdef block is the standard way of creating macros which make
-// exporting from a DLL simpler. All files within this DLL are compiled with the
-// yaml_cpp_EXPORTS symbol defined on the command line. This symbol should not
-// be defined on any project that uses this DLL. This way any other project
-// whose source files include this file see YAML_CPP_API functions as being
-// imported from a DLL, whereas this DLL sees symbols defined with this macro as
-// being exported.
-#undef YAML_CPP_API
+// Definition YAML_CPP_STATIC_DEFINE using to building YAML-CPP as static
+// library (definition created by CMake or defined manually)
-#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined
- // manually)
+// Definition yaml_cpp_EXPORTS using to building YAML-CPP as dll/so library
+// (definition created by CMake or defined manually)
-#if defined(_WIN32) || defined(WIN32)
-# define YAML_CPP_API_IMPORT __declspec(dllimport)
-# define YAML_CPP_API_EXPORT __declspec(dllexport)
+#ifdef YAML_CPP_STATIC_DEFINE
+# define YAML_CPP_API
+# define YAML_CPP_NO_EXPORT
#else
-# define YAML_CPP_API_IMPORT __attribute__((visibility("default")))
-# define YAML_CPP_API_EXPORT __attribute__((visibility("default")))
+# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
+# ifndef YAML_CPP_API
+# ifdef yaml_cpp_EXPORTS
+ /* We are building this library */
+# pragma message( "Defining YAML_CPP_API for DLL export" )
+# define YAML_CPP_API __declspec(dllexport)
+# else
+ /* We are using this library */
+# pragma message( "Defining YAML_CPP_API for DLL import" )
+# define YAML_CPP_API __declspec(dllimport)
+# endif
+# endif
+# ifndef YAML_CPP_NO_EXPORT
+# define YAML_CPP_NO_EXPORT
+# endif
+# else /* No _MSC_VER */
+# ifndef YAML_CPP_API
+# ifdef yaml_cpp_EXPORTS
+ /* We are building this library */
+# define YAML_CPP_API __attribute__((visibility("default")))
+# else
+ /* We are using this library */
+# define YAML_CPP_API __attribute__((visibility("default")))
+# endif
+# endif
+# ifndef YAML_CPP_NO_EXPORT
+# define YAML_CPP_NO_EXPORT __attribute__((visibility("hidden")))
+# endif
+# endif /* _MSC_VER */
+#endif /* YAML_CPP_STATIC_DEFINE */
+
+#ifndef YAML_CPP_DEPRECATED
+# ifdef _MSC_VER
+# define YAML_CPP_DEPRECATED __declspec(deprecated)
+# else
+# define YAML_CPP_DEPRECATED __attribute__ ((__deprecated__))
+# endif
#endif
-#ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake
- // or defined manually)
-// #pragma message( "Defining YAML_CPP_API for DLL export" )
-#define YAML_CPP_API YAML_CPP_API_EXPORT
-#else // yaml_cpp_EXPORTS
-// #pragma message( "Defining YAML_CPP_API for DLL import" )
-#define YAML_CPP_API YAML_CPP_API_IMPORT
-#endif // yaml_cpp_EXPORTS
-#else // YAML_CPP_DLL
-#define YAML_CPP_API
-#endif // YAML_CPP_DLL
+#ifndef YAML_CPP_DEPRECATED_EXPORT
+# define YAML_CPP_DEPRECATED_EXPORT YAML_CPP_API YAML_CPP_DEPRECATED
+#endif
+
+#ifndef YAML_CPP_DEPRECATED_NO_EXPORT
+# define YAML_CPP_DEPRECATED_NO_EXPORT YAML_CPP_NO_EXPORT YAML_CPP_DEPRECATED
+#endif
-#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#endif /* DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 */
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitfromevents.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitfromevents.h
index f14b051ab0e..1f389c5a138 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitfromevents.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitfromevents.h
@@ -24,21 +24,21 @@ class EmitFromEvents : public EventHandler {
public:
EmitFromEvents(Emitter& emitter);
- virtual void OnDocumentStart(const Mark& mark);
- virtual void OnDocumentEnd();
+ void OnDocumentStart(const Mark& mark) override;
+ void OnDocumentEnd() override;
- virtual void OnNull(const Mark& mark, anchor_t anchor);
- virtual void OnAlias(const Mark& mark, anchor_t anchor);
- virtual void OnScalar(const Mark& mark, const std::string& tag,
- anchor_t anchor, const std::string& value);
+ void OnNull(const Mark& mark, anchor_t anchor) override;
+ void OnAlias(const Mark& mark, anchor_t anchor) override;
+ void OnScalar(const Mark& mark, const std::string& tag,
+ anchor_t anchor, const std::string& value) override;
- virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
- anchor_t anchor, EmitterStyle::value style);
- virtual void OnSequenceEnd();
+ void OnSequenceStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style) override;
+ void OnSequenceEnd() override;
- virtual void OnMapStart(const Mark& mark, const std::string& tag,
- anchor_t anchor, EmitterStyle::value style);
- virtual void OnMapEnd();
+ void OnMapStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style) override;
+ void OnMapEnd() override;
private:
void BeginNode();
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitter.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitter.h
index ef92cc4035b..210b1ec9744 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitter.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitter.h
@@ -7,16 +7,18 @@
#pragma once
#endif
+#include <cmath>
#include <cstddef>
+#include <limits>
#include <memory>
#include <sstream>
#include <string>
+#include <type_traits>
#include "yaml-cpp/binary.h"
#include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterdef.h"
#include "yaml-cpp/emittermanip.h"
-#include "yaml-cpp/noncopyable.h"
#include "yaml-cpp/null.h"
#include "yaml-cpp/ostream_wrapper.h"
@@ -28,10 +30,12 @@ struct _Null;
namespace YAML {
class EmitterState;
-class YAML_CPP_API Emitter : private noncopyable {
+class YAML_CPP_API Emitter {
public:
Emitter();
explicit Emitter(std::ostream& stream);
+ Emitter(const Emitter&) = delete;
+ Emitter& operator=(const Emitter&) = delete;
~Emitter();
// output
@@ -46,6 +50,7 @@ class YAML_CPP_API Emitter : private noncopyable {
bool SetOutputCharset(EMITTER_MANIP value);
bool SetStringFormat(EMITTER_MANIP value);
bool SetBoolFormat(EMITTER_MANIP value);
+ bool SetNullFormat(EMITTER_MANIP value);
bool SetIntBase(EMITTER_MANIP value);
bool SetSeqFormat(EMITTER_MANIP value);
bool SetMapFormat(EMITTER_MANIP value);
@@ -54,6 +59,7 @@ class YAML_CPP_API Emitter : private noncopyable {
bool SetPostCommentIndent(std::size_t n);
bool SetFloatPrecision(std::size_t n);
bool SetDoublePrecision(std::size_t n);
+ void RestoreGlobalModifiedSettings();
// local setters
Emitter& SetLocalValue(EMITTER_MANIP value);
@@ -119,6 +125,7 @@ class YAML_CPP_API Emitter : private noncopyable {
void SpaceOrIndentTo(bool requireSpace, std::size_t indent);
const char* ComputeFullBoolName(bool b) const;
+ const char* ComputeNullName() const;
bool CanEmitNewline() const;
private:
@@ -152,7 +159,27 @@ inline Emitter& Emitter::WriteStreamable(T value) {
std::stringstream stream;
SetStreamablePrecision<T>(stream);
- stream << value;
+
+ bool special = false;
+ if (std::is_floating_point<T>::value) {
+ if ((std::numeric_limits<T>::has_quiet_NaN ||
+ std::numeric_limits<T>::has_signaling_NaN) &&
+ std::isnan(value)) {
+ special = true;
+ stream << ".nan";
+ } else if (std::numeric_limits<T>::has_infinity && std::isinf(value)) {
+ special = true;
+ if (std::signbit(value)) {
+ stream << "-.inf";
+ } else {
+ stream << ".inf";
+ }
+ }
+ }
+
+ if (!special) {
+ stream << value;
+ }
m_stream << stream.str();
StartedScalar();
@@ -249,6 +276,6 @@ inline Emitter& operator<<(Emitter& emitter, _Indent indent) {
inline Emitter& operator<<(Emitter& emitter, _Precision precision) {
return emitter.SetLocalPrecision(precision);
}
-}
+} // namespace YAML
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emittermanip.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emittermanip.h
index 89f7256714e..976d14950fc 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emittermanip.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emittermanip.h
@@ -19,6 +19,7 @@ enum EMITTER_MANIP {
// output character set
EmitNonAscii,
EscapeNonAscii,
+ EscapeAsJson,
// string manipulators
// Auto, // duplicate
@@ -26,6 +27,12 @@ enum EMITTER_MANIP {
DoubleQuoted,
Literal,
+ // null manipulators
+ LowerNull,
+ UpperNull,
+ CamelNull,
+ TildeNull,
+
// bool manipulators
YesNoBool, // yes, no
TrueFalseBool, // true, false
@@ -74,14 +81,14 @@ struct _Alias {
std::string content;
};
-inline _Alias Alias(const std::string content) { return _Alias(content); }
+inline _Alias Alias(const std::string& content) { return _Alias(content); }
struct _Anchor {
_Anchor(const std::string& content_) : content(content_) {}
std::string content;
};
-inline _Anchor Anchor(const std::string content) { return _Anchor(content); }
+inline _Anchor Anchor(const std::string& content) { return _Anchor(content); }
struct _Tag {
struct Type {
@@ -96,11 +103,11 @@ struct _Tag {
Type::value type;
};
-inline _Tag VerbatimTag(const std::string content) {
+inline _Tag VerbatimTag(const std::string& content) {
return _Tag("", content, _Tag::Type::Verbatim);
}
-inline _Tag LocalTag(const std::string content) {
+inline _Tag LocalTag(const std::string& content) {
return _Tag("", content, _Tag::Type::PrimaryHandle);
}
@@ -108,7 +115,7 @@ inline _Tag LocalTag(const std::string& prefix, const std::string content) {
return _Tag(prefix, content, _Tag::Type::NamedHandle);
}
-inline _Tag SecondaryTag(const std::string content) {
+inline _Tag SecondaryTag(const std::string& content) {
return _Tag("", content, _Tag::Type::NamedHandle);
}
@@ -117,7 +124,7 @@ struct _Comment {
std::string content;
};
-inline _Comment Comment(const std::string content) { return _Comment(content); }
+inline _Comment Comment(const std::string& content) { return _Comment(content); }
struct _Precision {
_Precision(int floatPrecision_, int doublePrecision_)
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/eventhandler.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/eventhandler.h
index efe381c6218..7242fe1f5ba 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/eventhandler.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/eventhandler.h
@@ -17,7 +17,7 @@ struct Mark;
class EventHandler {
public:
- virtual ~EventHandler() {}
+ virtual ~EventHandler() = default;
virtual void OnDocumentStart(const Mark& mark) = 0;
virtual void OnDocumentEnd() = 0;
@@ -34,7 +34,12 @@ class EventHandler {
virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) = 0;
virtual void OnMapEnd() = 0;
+
+ virtual void OnAnchor(const Mark& /*mark*/,
+ const std::string& /*anchor_name*/) {
+ // empty default implementation for compatibility
+ }
};
-}
+} // namespace YAML
#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
index eae31968b7f..f6b2602ae1c 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
@@ -8,13 +8,12 @@
#endif
#include "yaml-cpp/mark.h"
+#include "yaml-cpp/noexcept.h"
#include "yaml-cpp/traits.h"
#include <sstream>
#include <stdexcept>
#include <string>
-#define YAML_CPP_NOEXCEPT noexcept
-
namespace YAML {
// error messages
namespace ErrorMsg {
@@ -66,7 +65,7 @@ const char* const ZERO_INDENT_IN_BLOCK =
const char* const CHAR_IN_BLOCK = "unexpected character in block scalar";
const char* const AMBIGUOUS_ANCHOR =
"cannot assign the same alias to multiple nodes";
-const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined";
+const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined: ";
const char* const INVALID_NODE =
"invalid node; this may result from using a map iterator as a sequence "
@@ -101,6 +100,12 @@ inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
return stream.str();
}
+inline const std::string KEY_NOT_FOUND_WITH_KEY(const char* key) {
+ std::stringstream stream;
+ stream << KEY_NOT_FOUND << ": " << key;
+ return stream.str();
+}
+
template <typename T>
inline const std::string KEY_NOT_FOUND_WITH_KEY(
const T& key, typename enable_if<is_numeric<T>>::type* = 0) {
@@ -108,13 +113,48 @@ inline const std::string KEY_NOT_FOUND_WITH_KEY(
stream << KEY_NOT_FOUND << ": " << key;
return stream.str();
}
+
+template <typename T>
+inline const std::string BAD_SUBSCRIPT_WITH_KEY(
+ const T&, typename disable_if<is_numeric<T>>::type* = nullptr) {
+ return BAD_SUBSCRIPT;
+}
+
+inline const std::string BAD_SUBSCRIPT_WITH_KEY(const std::string& key) {
+ std::stringstream stream;
+ stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
+ return stream.str();
+}
+
+inline const std::string BAD_SUBSCRIPT_WITH_KEY(const char* key) {
+ std::stringstream stream;
+ stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
+ return stream.str();
+}
+
+template <typename T>
+inline const std::string BAD_SUBSCRIPT_WITH_KEY(
+ const T& key, typename enable_if<is_numeric<T>>::type* = nullptr) {
+ std::stringstream stream;
+ stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
+ return stream.str();
+}
+
+inline const std::string INVALID_NODE_WITH_KEY(const std::string& key) {
+ std::stringstream stream;
+ if (key.empty()) {
+ return INVALID_NODE;
+ }
+ stream << "invalid node; first invalid key: \"" << key << "\"";
+ return stream.str();
}
+} // namespace ErrorMsg
class YAML_CPP_API Exception : public std::runtime_error {
public:
Exception(const Mark& mark_, const std::string& msg_)
: std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
- virtual ~Exception() YAML_CPP_NOEXCEPT;
+ ~Exception() YAML_CPP_NOEXCEPT override;
Exception(const Exception&) = default;
@@ -125,7 +165,7 @@ class YAML_CPP_API Exception : public std::runtime_error {
static const std::string build_what(const Mark& mark,
const std::string& msg) {
if (mark.is_null()) {
- return msg.c_str();
+ return msg;
}
std::stringstream output;
@@ -140,7 +180,7 @@ class YAML_CPP_API ParserException : public Exception {
ParserException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {}
ParserException(const ParserException&) = default;
- virtual ~ParserException() YAML_CPP_NOEXCEPT;
+ ~ParserException() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API RepresentationException : public Exception {
@@ -148,7 +188,7 @@ class YAML_CPP_API RepresentationException : public Exception {
RepresentationException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {}
RepresentationException(const RepresentationException&) = default;
- virtual ~RepresentationException() YAML_CPP_NOEXCEPT;
+ ~RepresentationException() YAML_CPP_NOEXCEPT override;
};
// representation exceptions
@@ -157,7 +197,7 @@ class YAML_CPP_API InvalidScalar : public RepresentationException {
InvalidScalar(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
InvalidScalar(const InvalidScalar&) = default;
- virtual ~InvalidScalar() YAML_CPP_NOEXCEPT;
+ ~InvalidScalar() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API KeyNotFound : public RepresentationException {
@@ -167,7 +207,7 @@ class YAML_CPP_API KeyNotFound : public RepresentationException {
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {
}
KeyNotFound(const KeyNotFound&) = default;
- virtual ~KeyNotFound() YAML_CPP_NOEXCEPT;
+ ~KeyNotFound() YAML_CPP_NOEXCEPT override;
};
template <typename T>
@@ -175,7 +215,7 @@ class YAML_CPP_API TypedKeyNotFound : public KeyNotFound {
public:
TypedKeyNotFound(const Mark& mark_, const T& key_)
: KeyNotFound(mark_, key_), key(key_) {}
- virtual ~TypedKeyNotFound() YAML_CPP_NOEXCEPT {}
+ ~TypedKeyNotFound() YAML_CPP_NOEXCEPT override = default;
T key;
};
@@ -188,10 +228,11 @@ inline TypedKeyNotFound<T> MakeTypedKeyNotFound(const Mark& mark,
class YAML_CPP_API InvalidNode : public RepresentationException {
public:
- InvalidNode()
- : RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {}
+ InvalidNode(const std::string& key)
+ : RepresentationException(Mark::null_mark(),
+ ErrorMsg::INVALID_NODE_WITH_KEY(key)) {}
InvalidNode(const InvalidNode&) = default;
- virtual ~InvalidNode() YAML_CPP_NOEXCEPT;
+ ~InvalidNode() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API BadConversion : public RepresentationException {
@@ -199,7 +240,7 @@ class YAML_CPP_API BadConversion : public RepresentationException {
explicit BadConversion(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {}
BadConversion(const BadConversion&) = default;
- virtual ~BadConversion() YAML_CPP_NOEXCEPT;
+ ~BadConversion() YAML_CPP_NOEXCEPT override;
};
template <typename T>
@@ -213,15 +254,16 @@ class YAML_CPP_API BadDereference : public RepresentationException {
BadDereference()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {}
BadDereference(const BadDereference&) = default;
- virtual ~BadDereference() YAML_CPP_NOEXCEPT;
+ ~BadDereference() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API BadSubscript : public RepresentationException {
public:
- BadSubscript()
- : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {}
+ template <typename Key>
+ BadSubscript(const Mark& mark_, const Key& key)
+ : RepresentationException(mark_, ErrorMsg::BAD_SUBSCRIPT_WITH_KEY(key)) {}
BadSubscript(const BadSubscript&) = default;
- virtual ~BadSubscript() YAML_CPP_NOEXCEPT;
+ ~BadSubscript() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API BadPushback : public RepresentationException {
@@ -229,7 +271,7 @@ class YAML_CPP_API BadPushback : public RepresentationException {
BadPushback()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {}
BadPushback(const BadPushback&) = default;
- virtual ~BadPushback() YAML_CPP_NOEXCEPT;
+ ~BadPushback() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API BadInsert : public RepresentationException {
@@ -237,7 +279,7 @@ class YAML_CPP_API BadInsert : public RepresentationException {
BadInsert()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {}
BadInsert(const BadInsert&) = default;
- virtual ~BadInsert() YAML_CPP_NOEXCEPT;
+ ~BadInsert() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API EmitterException : public Exception {
@@ -245,17 +287,17 @@ class YAML_CPP_API EmitterException : public Exception {
EmitterException(const std::string& msg_)
: Exception(Mark::null_mark(), msg_) {}
EmitterException(const EmitterException&) = default;
- virtual ~EmitterException() YAML_CPP_NOEXCEPT;
+ ~EmitterException() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API BadFile : public Exception {
public:
- BadFile() : Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {}
+ explicit BadFile(const std::string& filename)
+ : Exception(Mark::null_mark(),
+ std::string(ErrorMsg::BAD_FILE) + ": " + filename) {}
BadFile(const BadFile&) = default;
- virtual ~BadFile() YAML_CPP_NOEXCEPT;
+ ~BadFile() YAML_CPP_NOEXCEPT override;
};
-}
-
-#undef YAML_CPP_NOEXCEPT
+} // namespace YAML
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/convert.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/convert.h
index 45a878ab0c0..d0eb450f731 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/convert.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/convert.h
@@ -8,12 +8,20 @@
#endif
#include <array>
+#include <cmath>
#include <limits>
#include <list>
#include <map>
+#include <unordered_map>
#include <sstream>
+#include <type_traits>
+#include <valarray>
#include <vector>
+#if __cplusplus >= 201703L
+#include <string_view>
+#endif
+
#include "yaml-cpp/binary.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/node/iterator.h"
@@ -21,6 +29,7 @@
#include "yaml-cpp/node/type.h"
#include "yaml-cpp/null.h"
+
namespace YAML {
class Binary;
struct _Null;
@@ -71,14 +80,33 @@ struct convert<std::string> {
// C-strings can only be encoded
template <>
struct convert<const char*> {
- static Node encode(const char*& rhs) { return Node(rhs); }
+ static Node encode(const char* rhs) { return Node(rhs); }
+};
+
+template <>
+struct convert<char*> {
+ static Node encode(const char* rhs) { return Node(rhs); }
};
template <std::size_t N>
-struct convert<const char[N]> {
- static Node encode(const char(&rhs)[N]) { return Node(rhs); }
+struct convert<char[N]> {
+ static Node encode(const char* rhs) { return Node(rhs); }
};
+#if __cplusplus >= 201703L
+template <>
+struct convert<std::string_view> {
+ static Node encode(std::string_view rhs) { return Node(std::string(rhs)); }
+
+ static bool decode(const Node& node, std::string_view& rhs) {
+ if (!node.IsScalar())
+ return false;
+ rhs = node.Scalar();
+ return true;
+ }
+};
+#endif
+
template <>
struct convert<_Null> {
static Node encode(const _Null& /* rhs */) { return Node(); }
@@ -88,42 +116,98 @@ struct convert<_Null> {
}
};
-#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \
- template <> \
- struct convert<type> { \
- static Node encode(const type& rhs) { \
- std::stringstream stream; \
- stream.precision(std::numeric_limits<type>::digits10 + 1); \
- stream << rhs; \
- return Node(stream.str()); \
- } \
- \
- static bool decode(const Node& node, type& rhs) { \
- if (node.Type() != NodeType::Scalar) \
- return false; \
- const std::string& input = node.Scalar(); \
- std::stringstream stream(input); \
- stream.unsetf(std::ios::dec); \
- if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \
- return true; \
- if (std::numeric_limits<type>::has_infinity) { \
- if (conversion::IsInfinity(input)) { \
- rhs = std::numeric_limits<type>::infinity(); \
- return true; \
- } else if (conversion::IsNegativeInfinity(input)) { \
- rhs = negative_op std::numeric_limits<type>::infinity(); \
- return true; \
- } \
- } \
- \
- if (std::numeric_limits<type>::has_quiet_NaN && \
- conversion::IsNaN(input)) { \
- rhs = std::numeric_limits<type>::quiet_NaN(); \
- return true; \
- } \
- \
- return false; \
- } \
+namespace conversion {
+template <typename T>
+typename std::enable_if< std::is_floating_point<T>::value, void>::type
+inner_encode(const T& rhs, std::stringstream& stream){
+ if (std::isnan(rhs)) {
+ stream << ".nan";
+ } else if (std::isinf(rhs)) {
+ if (std::signbit(rhs)) {
+ stream << "-.inf";
+ } else {
+ stream << ".inf";
+ }
+ } else {
+ stream << rhs;
+ }
+}
+
+template <typename T>
+typename std::enable_if<!std::is_floating_point<T>::value, void>::type
+inner_encode(const T& rhs, std::stringstream& stream){
+ stream << rhs;
+}
+
+template <typename T>
+typename std::enable_if<(std::is_same<T, unsigned char>::value ||
+ std::is_same<T, signed char>::value), bool>::type
+ConvertStreamTo(std::stringstream& stream, T& rhs) {
+ int num;
+ if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) {
+ if (num >= (std::numeric_limits<T>::min)() &&
+ num <= (std::numeric_limits<T>::max)()) {
+ rhs = static_cast<T>(num);
+ return true;
+ }
+ }
+ return false;
+}
+
+template <typename T>
+typename std::enable_if<!(std::is_same<T, unsigned char>::value ||
+ std::is_same<T, signed char>::value), bool>::type
+ConvertStreamTo(std::stringstream& stream, T& rhs) {
+ if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) {
+ return true;
+ }
+ return false;
+}
+}
+
+#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \
+ template <> \
+ struct convert<type> { \
+ \
+ static Node encode(const type& rhs) { \
+ std::stringstream stream; \
+ stream.precision(std::numeric_limits<type>::max_digits10); \
+ conversion::inner_encode(rhs, stream); \
+ return Node(stream.str()); \
+ } \
+ \
+ static bool decode(const Node& node, type& rhs) { \
+ if (node.Type() != NodeType::Scalar) { \
+ return false; \
+ } \
+ const std::string& input = node.Scalar(); \
+ std::stringstream stream(input); \
+ stream.unsetf(std::ios::dec); \
+ if ((stream.peek() == '-') && std::is_unsigned<type>::value) { \
+ return false; \
+ } \
+ if (conversion::ConvertStreamTo(stream, rhs)) { \
+ return true; \
+ } \
+ if (std::numeric_limits<type>::has_infinity) { \
+ if (conversion::IsInfinity(input)) { \
+ rhs = std::numeric_limits<type>::infinity(); \
+ return true; \
+ } else if (conversion::IsNegativeInfinity(input)) { \
+ rhs = negative_op std::numeric_limits<type>::infinity(); \
+ return true; \
+ } \
+ } \
+ \
+ if (std::numeric_limits<type>::has_quiet_NaN) { \
+ if (conversion::IsNaN(input)) { \
+ rhs = std::numeric_limits<type>::quiet_NaN(); \
+ return true; \
+ } \
+ } \
+ \
+ return false; \
+ } \
}
#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \
@@ -162,81 +246,104 @@ struct convert<bool> {
};
// std::map
-template <typename K, typename V>
-struct convert<std::map<K, V>> {
- static Node encode(const std::map<K, V>& rhs) {
+template <typename K, typename V, typename C, typename A>
+struct convert<std::map<K, V, C, A>> {
+ static Node encode(const std::map<K, V, C, A>& rhs) {
Node node(NodeType::Map);
- for (typename std::map<K, V>::const_iterator it = rhs.begin();
- it != rhs.end(); ++it)
- node.force_insert(it->first, it->second);
+ for (const auto& element : rhs)
+ node.force_insert(element.first, element.second);
return node;
}
- static bool decode(const Node& node, std::map<K, V>& rhs) {
+ static bool decode(const Node& node, std::map<K, V, C, A>& rhs) {
if (!node.IsMap())
return false;
rhs.clear();
- for (const_iterator it = node.begin(); it != node.end(); ++it)
+ for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
- rhs[it->first.template as<K>()] = it->second.template as<V>();
+ rhs[element.first.template as<K>()] = element.second.template as<V>();
#else
- rhs[it->first.as<K>()] = it->second.as<V>();
+ rhs[element.first.as<K>()] = element.second.as<V>();
+#endif
+ return true;
+ }
+};
+
+// std::unordered_map
+template <typename K, typename V, typename H, typename P, typename A>
+struct convert<std::unordered_map<K, V, H, P, A>> {
+ static Node encode(const std::unordered_map<K, V, H, P, A>& rhs) {
+ Node node(NodeType::Map);
+ for (const auto& element : rhs)
+ node.force_insert(element.first, element.second);
+ return node;
+ }
+
+ static bool decode(const Node& node, std::unordered_map<K, V, H, P, A>& rhs) {
+ if (!node.IsMap())
+ return false;
+
+ rhs.clear();
+ for (const auto& element : node)
+#if defined(__GNUC__) && __GNUC__ < 4
+ // workaround for GCC 3:
+ rhs[element.first.template as<K>()] = element.second.template as<V>();
+#else
+ rhs[element.first.as<K>()] = element.second.as<V>();
#endif
return true;
}
};
// std::vector
-template <typename T>
-struct convert<std::vector<T>> {
- static Node encode(const std::vector<T>& rhs) {
+template <typename T, typename A>
+struct convert<std::vector<T, A>> {
+ static Node encode(const std::vector<T, A>& rhs) {
Node node(NodeType::Sequence);
- for (typename std::vector<T>::const_iterator it = rhs.begin();
- it != rhs.end(); ++it)
- node.push_back(*it);
+ for (const auto& element : rhs)
+ node.push_back(element);
return node;
}
- static bool decode(const Node& node, std::vector<T>& rhs) {
+ static bool decode(const Node& node, std::vector<T, A>& rhs) {
if (!node.IsSequence())
return false;
rhs.clear();
- for (const_iterator it = node.begin(); it != node.end(); ++it)
+ for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
- rhs.push_back(it->template as<T>());
+ rhs.push_back(element.template as<T>());
#else
- rhs.push_back(it->as<T>());
+ rhs.push_back(element.as<T>());
#endif
return true;
}
};
// std::list
-template <typename T>
-struct convert<std::list<T>> {
- static Node encode(const std::list<T>& rhs) {
+template <typename T, typename A>
+struct convert<std::list<T,A>> {
+ static Node encode(const std::list<T,A>& rhs) {
Node node(NodeType::Sequence);
- for (typename std::list<T>::const_iterator it = rhs.begin();
- it != rhs.end(); ++it)
- node.push_back(*it);
+ for (const auto& element : rhs)
+ node.push_back(element);
return node;
}
- static bool decode(const Node& node, std::list<T>& rhs) {
+ static bool decode(const Node& node, std::list<T,A>& rhs) {
if (!node.IsSequence())
return false;
rhs.clear();
- for (const_iterator it = node.begin(); it != node.end(); ++it)
+ for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
- rhs.push_back(it->template as<T>());
+ rhs.push_back(element.template as<T>());
#else
- rhs.push_back(it->as<T>());
+ rhs.push_back(element.as<T>());
#endif
return true;
}
@@ -275,6 +382,37 @@ struct convert<std::array<T, N>> {
}
};
+
+// std::valarray
+template <typename T>
+struct convert<std::valarray<T>> {
+ static Node encode(const std::valarray<T>& rhs) {
+ Node node(NodeType::Sequence);
+ for (const auto& element : rhs) {
+ node.push_back(element);
+ }
+ return node;
+ }
+
+ static bool decode(const Node& node, std::valarray<T>& rhs) {
+ if (!node.IsSequence()) {
+ return false;
+ }
+
+ rhs.resize(node.size());
+ for (auto i = 0u; i < node.size(); ++i) {
+#if defined(__GNUC__) && __GNUC__ < 4
+ // workaround for GCC 3:
+ rhs[i] = node[i].template as<T>();
+#else
+ rhs[i] = node[i].as<T>();
+#endif
+ }
+ return true;
+ }
+};
+
+
// std::pair
template <typename T, typename U>
struct convert<std::pair<T, U>> {
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h
deleted file mode 100644
index 2c80705c9ae..00000000000
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-#define NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-
-#if defined(_MSC_VER) || \
- (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
- (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
-#pragma once
-#endif
-
-namespace YAML {
-namespace detail {
-struct unspecified_bool {
- struct NOT_ALLOWED;
- static void true_value(NOT_ALLOWED*) {}
-};
-typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*);
-}
-}
-
-#define YAML_CPP_OPERATOR_BOOL() \
- operator YAML::detail::unspecified_bool_type() const { \
- return this->operator!() ? 0 \
- : &YAML::detail::unspecified_bool::true_value; \
- }
-
-#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/impl.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/impl.h
index 09e55f838c2..b38038dfd22 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/impl.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/impl.h
@@ -9,6 +9,8 @@
#include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/detail/node_data.h"
+
+#include <algorithm>
#include <type_traits>
namespace YAML {
@@ -17,7 +19,7 @@ template <typename Key, typename Enable = void>
struct get_idx {
static node* get(const std::vector<node*>& /* sequence */,
const Key& /* key */, shared_memory_holder /* pMemory */) {
- return 0;
+ return nullptr;
}
};
@@ -27,13 +29,13 @@ struct get_idx<Key,
!std::is_same<Key, bool>::value>::type> {
static node* get(const std::vector<node*>& sequence, const Key& key,
shared_memory_holder /* pMemory */) {
- return key < sequence.size() ? sequence[key] : 0;
+ return key < sequence.size() ? sequence[key] : nullptr;
}
static node* get(std::vector<node*>& sequence, const Key& key,
shared_memory_holder pMemory) {
- if (key > sequence.size() || (key > 0 && !sequence[key-1]->is_defined()))
- return 0;
+ if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined()))
+ return nullptr;
if (key == sequence.size())
sequence.push_back(&pMemory->create_node());
return sequence[key];
@@ -46,13 +48,51 @@ struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
shared_memory_holder pMemory) {
return key >= 0 ? get_idx<std::size_t>::get(
sequence, static_cast<std::size_t>(key), pMemory)
- : 0;
+ : nullptr;
}
static node* get(std::vector<node*>& sequence, const Key& key,
shared_memory_holder pMemory) {
return key >= 0 ? get_idx<std::size_t>::get(
sequence, static_cast<std::size_t>(key), pMemory)
- : 0;
+ : nullptr;
+ }
+};
+
+template <typename Key, typename Enable = void>
+struct remove_idx {
+ static bool remove(std::vector<node*>&, const Key&, std::size_t&) {
+ return false;
+ }
+};
+
+template <typename Key>
+struct remove_idx<
+ Key, typename std::enable_if<std::is_unsigned<Key>::value &&
+ !std::is_same<Key, bool>::value>::type> {
+
+ static bool remove(std::vector<node*>& sequence, const Key& key,
+ std::size_t& seqSize) {
+ if (key >= sequence.size()) {
+ return false;
+ } else {
+ sequence.erase(sequence.begin() + key);
+ if (seqSize > key) {
+ --seqSize;
+ }
+ return true;
+ }
+ }
+};
+
+template <typename Key>
+struct remove_idx<Key,
+ typename std::enable_if<std::is_signed<Key>::value>::type> {
+
+ static bool remove(std::vector<node*>& sequence, const Key& key,
+ std::size_t& seqSize) {
+ return key >= 0 ? remove_idx<std::size_t>::remove(
+ sequence, static_cast<std::size_t>(key), seqSize)
+ : false;
}
};
@@ -66,7 +106,11 @@ inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
}
inline bool node::equals(const char* rhs, shared_memory_holder pMemory) {
- return equals<std::string>(rhs, pMemory);
+ std::string lhs;
+ if (convert<std::string>::decode(Node(*this, std::move(pMemory)), lhs)) {
+ return lhs == rhs;
+ }
+ return false;
}
// indexing
@@ -78,22 +122,20 @@ inline node* node_data::get(const Key& key,
break;
case NodeType::Undefined:
case NodeType::Null:
- return NULL;
+ return nullptr;
case NodeType::Sequence:
if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
return pNode;
- return NULL;
+ return nullptr;
case NodeType::Scalar:
- throw BadSubscript();
+ throw BadSubscript(m_mark, key);
}
- for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
- if (it->first->equals(key, pMemory)) {
- return it->second;
- }
- }
+ auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
+ return m.first->equals(key, pMemory);
+ });
- return NULL;
+ return it != m_map.end() ? it->second : nullptr;
}
template <typename Key>
@@ -112,13 +154,15 @@ inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
convert_to_map(pMemory);
break;
case NodeType::Scalar:
- throw BadSubscript();
+ throw BadSubscript(m_mark, key);
}
- for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
- if (it->first->equals(key, pMemory)) {
- return *it->second;
- }
+ auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
+ return m.first->equals(key, pMemory);
+ });
+
+ if (it != m_map.end()) {
+ return *it->second;
}
node& k = convert_to_node(key, pMemory);
@@ -129,20 +173,26 @@ inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
template <typename Key>
inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
- if (m_type != NodeType::Map)
- return false;
-
- for (kv_pairs::iterator it = m_undefinedPairs.begin();
- it != m_undefinedPairs.end();) {
- kv_pairs::iterator jt = std::next(it);
- if (it->first->equals(key, pMemory))
- m_undefinedPairs.erase(it);
- it = jt;
+ if (m_type == NodeType::Sequence) {
+ return remove_idx<Key>::remove(m_sequence, key, m_seqSize);
}
- for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
- if (it->first->equals(key, pMemory)) {
- m_map.erase(it);
+ if (m_type == NodeType::Map) {
+ kv_pairs::iterator it = m_undefinedPairs.begin();
+ while (it != m_undefinedPairs.end()) {
+ kv_pairs::iterator jt = std::next(it);
+ if (it->first->equals(key, pMemory)) {
+ m_undefinedPairs.erase(it);
+ }
+ it = jt;
+ }
+
+ auto iter = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
+ return m.first->equals(key, pMemory);
+ });
+
+ if (iter != m_map.end()) {
+ m_map.erase(iter);
return true;
}
}
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator.h
index 0ea3bc3f0e3..997c69a14c5 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator.h
@@ -8,12 +8,13 @@
#endif
#include "yaml-cpp/dll.h"
+#include "yaml-cpp/node/detail/node_iterator.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/ptr.h"
-#include "yaml-cpp/node/detail/node_iterator.h"
#include <cstddef>
#include <iterator>
+
namespace YAML {
namespace detail {
struct iterator_value;
@@ -25,7 +26,7 @@ class iterator_base {
template <typename>
friend class iterator_base;
struct enabler {};
- typedef node_iterator base_type;
+ using base_type = node_iterator;
struct proxy {
explicit proxy(const V& x) : m_ref(x) {}
@@ -40,7 +41,7 @@ class iterator_base {
using value_type = V;
using difference_type = std::ptrdiff_t;
using pointer = V*;
- using reference = V&;
+ using reference = V;
public:
iterator_base() : m_iterator(), m_pMemory() {}
@@ -89,7 +90,7 @@ class iterator_base {
base_type m_iterator;
shared_memory_holder m_pMemory;
};
-}
-}
+} // namespace detail
+} // namespace YAML
#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h
index 5f1ffe7436d..75c9de086c0 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h
@@ -20,8 +20,8 @@ template <typename V>
class iterator_base;
}
-typedef detail::iterator_base<detail::iterator_value> iterator;
-typedef detail::iterator_base<const detail::iterator_value> const_iterator;
+using iterator = detail::iterator_base<detail::iterator_value>;
+using const_iterator = detail::iterator_base<const detail::iterator_value>;
}
#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/memory.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/memory.h
index 8f2bc2657a2..e881545bf2f 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/memory.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/memory.h
@@ -22,11 +22,12 @@ namespace YAML {
namespace detail {
class YAML_CPP_API memory {
public:
+ memory() : m_nodes{} {}
node& create_node();
void merge(const memory& rhs);
private:
- typedef std::set<shared_node> Nodes;
+ using Nodes = std::set<shared_node>;
Nodes m_nodes;
};
@@ -40,7 +41,7 @@ class YAML_CPP_API memory_holder {
private:
shared_memory m_pMemory;
};
-}
-}
+} // namespace detail
+} // namespace YAML
#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node.h
index 8a776f62a9e..acf60ffb6df 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node.h
@@ -7,18 +7,24 @@
#pragma once
#endif
-#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/dll.h"
-#include "yaml-cpp/node/type.h"
-#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/node/detail/node_ref.h"
+#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/type.h"
#include <set>
+#include <atomic>
namespace YAML {
namespace detail {
class node {
+ private:
+ struct less {
+ bool operator ()(const node* l, const node* r) const {return l->m_index < r->m_index;}
+ };
+
public:
- node() : m_pRef(new node_ref) {}
+ node() : m_pRef(new node_ref), m_dependencies{}, m_index{} {}
node(const node&) = delete;
node& operator=(const node&) = delete;
@@ -42,9 +48,8 @@ class node {
return;
m_pRef->mark_defined();
- for (nodes::iterator it = m_dependencies.begin();
- it != m_dependencies.end(); ++it)
- (*it)->mark_defined();
+ for (node* dependency : m_dependencies)
+ dependency->mark_defined();
m_dependencies.clear();
}
@@ -109,6 +114,7 @@ class node {
void push_back(node& input, shared_memory_holder pMemory) {
m_pRef->push_back(input, pMemory);
input.add_dependency(*this);
+ m_index = m_amount.fetch_add(1);
}
void insert(node& key, node& value, shared_memory_holder pMemory) {
m_pRef->insert(key, value, pMemory);
@@ -120,7 +126,7 @@ class node {
template <typename Key>
node* get(const Key& key, shared_memory_holder pMemory) const {
// NOTE: this returns a non-const node so that the top-level Node can wrap
- // it, and returns a pointer so that it can be NULL (if there is no such
+ // it, and returns a pointer so that it can be nullptr (if there is no such
// key).
return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
}
@@ -137,7 +143,7 @@ class node {
node* get(node& key, shared_memory_holder pMemory) const {
// NOTE: this returns a non-const node so that the top-level Node can wrap
- // it, and returns a pointer so that it can be NULL (if there is no such
+ // it, and returns a pointer so that it can be nullptr (if there is no such
// key).
return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
}
@@ -160,10 +166,12 @@ class node {
private:
shared_node_ref m_pRef;
- typedef std::set<node*> nodes;
+ using nodes = std::set<node*, less>;
nodes m_dependencies;
+ size_t m_index;
+ static YAML_CPP_API std::atomic<size_t> m_amount;
};
-}
-}
+} // namespace detail
+} // namespace YAML
#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_data.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_data.h
index 50bcd74352d..07cf81aa099 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_data.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_data.h
@@ -60,8 +60,8 @@ class YAML_CPP_API node_data {
node_iterator end();
// sequence
- void push_back(node& node, shared_memory_holder pMemory);
- void insert(node& key, node& value, shared_memory_holder pMemory);
+ void push_back(node& node, const shared_memory_holder& pMemory);
+ void insert(node& key, node& value, const shared_memory_holder& pMemory);
// indexing
template <typename Key>
@@ -71,9 +71,9 @@ class YAML_CPP_API node_data {
template <typename Key>
bool remove(const Key& key, shared_memory_holder pMemory);
- node* get(node& key, shared_memory_holder pMemory) const;
- node& get(node& key, shared_memory_holder pMemory);
- bool remove(node& key, shared_memory_holder pMemory);
+ node* get(node& key, const shared_memory_holder& pMemory) const;
+ node& get(node& key, const shared_memory_holder& pMemory);
+ bool remove(node& key, const shared_memory_holder& pMemory);
// map
template <typename Key, typename Value>
@@ -81,7 +81,7 @@ class YAML_CPP_API node_data {
shared_memory_holder pMemory);
public:
- static std::string empty_scalar;
+ static const std::string& empty_scalar();
private:
void compute_seq_size() const;
@@ -91,8 +91,8 @@ class YAML_CPP_API node_data {
void reset_map();
void insert_map_pair(node& key, node& value);
- void convert_to_map(shared_memory_holder pMemory);
- void convert_sequence_to_map(shared_memory_holder pMemory);
+ void convert_to_map(const shared_memory_holder& pMemory);
+ void convert_sequence_to_map(const shared_memory_holder& pMemory);
template <typename T>
static node& convert_to_node(const T& rhs, shared_memory_holder pMemory);
@@ -108,17 +108,17 @@ class YAML_CPP_API node_data {
std::string m_scalar;
// sequence
- typedef std::vector<node*> node_seq;
+ using node_seq = std::vector<node *>;
node_seq m_sequence;
mutable std::size_t m_seqSize;
// map
- typedef std::vector<std::pair<node*, node*>> node_map;
+ using node_map = std::vector<std::pair<node*, node*>>;
node_map m_map;
- typedef std::pair<node*, node*> kv_pair;
- typedef std::list<kv_pair> kv_pairs;
+ using kv_pair = std::pair<node*, node*>;
+ using kv_pairs = std::list<kv_pair>;
mutable kv_pairs m_undefinedPairs;
};
}
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h
index 692afca3289..49dcf958dbb 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h
@@ -24,11 +24,11 @@ struct iterator_type {
template <typename V>
struct node_iterator_value : public std::pair<V*, V*> {
- typedef std::pair<V*, V*> kv;
+ using kv = std::pair<V*, V*>;
- node_iterator_value() : kv(), pNode(0) {}
+ node_iterator_value() : kv(), pNode(nullptr) {}
explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
- explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(0) {}
+ explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {}
V& operator*() const { return *pNode; }
V& operator->() const { return *pNode; }
@@ -36,19 +36,19 @@ struct node_iterator_value : public std::pair<V*, V*> {
V* pNode;
};
-typedef std::vector<node*> node_seq;
-typedef std::vector<std::pair<node*, node*>> node_map;
+using node_seq = std::vector<node *>;
+using node_map = std::vector<std::pair<node*, node*>>;
template <typename V>
struct node_iterator_type {
- typedef node_seq::iterator seq;
- typedef node_map::iterator map;
+ using seq = node_seq::iterator;
+ using map = node_map::iterator;
};
template <typename V>
struct node_iterator_type<const V> {
- typedef node_seq::const_iterator seq;
- typedef node_map::const_iterator map;
+ using seq = node_seq::const_iterator;
+ using map = node_map::const_iterator;
};
template <typename V>
@@ -65,13 +65,13 @@ class node_iterator_base {
};
public:
- typedef typename node_iterator_type<V>::seq SeqIter;
- typedef typename node_iterator_type<V>::map MapIter;
using iterator_category = std::forward_iterator_tag;
using value_type = node_iterator_value<V>;
using difference_type = std::ptrdiff_t;
using pointer = node_iterator_value<V>*;
- using reference = node_iterator_value<V>&;
+ using reference = node_iterator_value<V>;
+ using SeqIter = typename node_iterator_type<V>::seq;
+ using MapIter = typename node_iterator_type<V>::map;
node_iterator_base()
: m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}
@@ -173,8 +173,8 @@ class node_iterator_base {
MapIter m_mapIt, m_mapEnd;
};
-typedef node_iterator_base<node> node_iterator;
-typedef node_iterator_base<const node> const_node_iterator;
+using node_iterator = node_iterator_base<node>;
+using const_node_iterator = node_iterator_base<const node>;
}
}
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/impl.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/impl.h
index 20c487a687f..312281f18cc 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/impl.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/impl.h
@@ -7,18 +7,21 @@
#pragma once
#endif
-#include "yaml-cpp/node/node.h"
-#include "yaml-cpp/node/iterator.h"
+#include "yaml-cpp/exceptions.h"
#include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h"
-#include "yaml-cpp/exceptions.h"
+#include "yaml-cpp/node/iterator.h"
+#include "yaml-cpp/node/node.h"
+#include <sstream>
#include <string>
namespace YAML {
-inline Node::Node() : m_isValid(true), m_pNode(NULL) {}
+inline Node::Node()
+ : m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {}
inline Node::Node(NodeType::value type)
: m_isValid(true),
+ m_invalidKey{},
m_pMemory(new detail::memory_holder),
m_pNode(&m_pMemory->create_node()) {
m_pNode->set_type(type);
@@ -27,6 +30,7 @@ inline Node::Node(NodeType::value type)
template <typename T>
inline Node::Node(const T& rhs)
: m_isValid(true),
+ m_invalidKey{},
m_pMemory(new detail::memory_holder),
m_pNode(&m_pMemory->create_node()) {
Assign(rhs);
@@ -34,24 +38,26 @@ inline Node::Node(const T& rhs)
inline Node::Node(const detail::iterator_value& rhs)
: m_isValid(rhs.m_isValid),
+ m_invalidKey(rhs.m_invalidKey),
m_pMemory(rhs.m_pMemory),
m_pNode(rhs.m_pNode) {}
-inline Node::Node(const Node& rhs)
- : m_isValid(rhs.m_isValid),
- m_pMemory(rhs.m_pMemory),
- m_pNode(rhs.m_pNode) {}
+inline Node::Node(const Node&) = default;
+
+inline Node::Node(Zombie)
+ : m_isValid(false), m_invalidKey{}, m_pMemory{}, m_pNode(nullptr) {}
-inline Node::Node(Zombie) : m_isValid(false), m_pNode(NULL) {}
+inline Node::Node(Zombie, const std::string& key)
+ : m_isValid(false), m_invalidKey(key), m_pMemory{}, m_pNode(nullptr) {}
inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
- : m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {}
+ : m_isValid(true), m_invalidKey{}, m_pMemory(pMemory), m_pNode(&node) {}
-inline Node::~Node() {}
+inline Node::~Node() = default;
inline void Node::EnsureNodeExists() const {
if (!m_isValid)
- throw InvalidNode();
+ throw InvalidNode(m_invalidKey);
if (!m_pNode) {
m_pMemory.reset(new detail::memory_holder);
m_pNode = &m_pMemory->create_node();
@@ -68,14 +74,14 @@ inline bool Node::IsDefined() const {
inline Mark Node::Mark() const {
if (!m_isValid) {
- throw InvalidNode();
+ throw InvalidNode(m_invalidKey);
}
return m_pNode ? m_pNode->mark() : Mark::null_mark();
}
inline NodeType::value Node::Type() const {
if (!m_isValid)
- throw InvalidNode();
+ throw InvalidNode(m_invalidKey);
return m_pNode ? m_pNode->type() : NodeType::Null;
}
@@ -104,6 +110,8 @@ struct as_if<std::string, S> {
const Node& node;
std::string operator()(const S& fallback) const {
+ if (node.Type() == NodeType::Null)
+ return "null";
if (node.Type() != NodeType::Scalar)
return fallback;
return node.Scalar();
@@ -132,6 +140,8 @@ struct as_if<std::string, void> {
const Node& node;
std::string operator()() const {
+ if (node.Type() == NodeType::Null)
+ return "null";
if (node.Type() != NodeType::Scalar)
throw TypedBadConversion<std::string>(node.Mark());
return node.Scalar();
@@ -142,7 +152,7 @@ struct as_if<std::string, void> {
template <typename T>
inline T Node::as() const {
if (!m_isValid)
- throw InvalidNode();
+ throw InvalidNode(m_invalidKey);
return as_if<T, void>(*this)();
}
@@ -155,32 +165,28 @@ inline T Node::as(const S& fallback) const {
inline const std::string& Node::Scalar() const {
if (!m_isValid)
- throw InvalidNode();
- return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar;
+ throw InvalidNode(m_invalidKey);
+ return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar();
}
inline const std::string& Node::Tag() const {
if (!m_isValid)
- throw InvalidNode();
- return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar;
+ throw InvalidNode(m_invalidKey);
+ return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar();
}
inline void Node::SetTag(const std::string& tag) {
- if (!m_isValid)
- throw InvalidNode();
EnsureNodeExists();
m_pNode->set_tag(tag);
}
inline EmitterStyle::value Node::Style() const {
if (!m_isValid)
- throw InvalidNode();
+ throw InvalidNode(m_invalidKey);
return m_pNode ? m_pNode->style() : EmitterStyle::Default;
}
inline void Node::SetStyle(EmitterStyle::value style) {
- if (!m_isValid)
- throw InvalidNode();
EnsureNodeExists();
m_pNode->set_style(style);
}
@@ -188,7 +194,7 @@ inline void Node::SetStyle(EmitterStyle::value style) {
// assignment
inline bool Node::is(const Node& rhs) const {
if (!m_isValid || !rhs.m_isValid)
- throw InvalidNode();
+ throw InvalidNode(m_invalidKey);
if (!m_pNode || !rhs.m_pNode)
return false;
return m_pNode->is(*rhs.m_pNode);
@@ -196,15 +202,20 @@ inline bool Node::is(const Node& rhs) const {
template <typename T>
inline Node& Node::operator=(const T& rhs) {
- if (!m_isValid)
- throw InvalidNode();
Assign(rhs);
return *this;
}
+inline Node& Node::operator=(const Node& rhs) {
+ if (is(rhs))
+ return *this;
+ AssignNode(rhs);
+ return *this;
+}
+
inline void Node::reset(const YAML::Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
- throw InvalidNode();
+ throw InvalidNode(m_invalidKey);
m_pMemory = rhs.m_pMemory;
m_pNode = rhs.m_pNode;
}
@@ -212,44 +223,27 @@ inline void Node::reset(const YAML::Node& rhs) {
template <typename T>
inline void Node::Assign(const T& rhs) {
if (!m_isValid)
- throw InvalidNode();
+ throw InvalidNode(m_invalidKey);
AssignData(convert<T>::encode(rhs));
}
template <>
inline void Node::Assign(const std::string& rhs) {
- if (!m_isValid)
- throw InvalidNode();
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline void Node::Assign(const char* rhs) {
- if (!m_isValid)
- throw InvalidNode();
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline void Node::Assign(char* rhs) {
- if (!m_isValid)
- throw InvalidNode();
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
-inline Node& Node::operator=(const Node& rhs) {
- if (!m_isValid || !rhs.m_isValid)
- throw InvalidNode();
- if (is(rhs))
- return *this;
- AssignNode(rhs);
- return *this;
-}
-
inline void Node::AssignData(const Node& rhs) {
- if (!m_isValid || !rhs.m_isValid)
- throw InvalidNode();
EnsureNodeExists();
rhs.EnsureNodeExists();
@@ -258,8 +252,8 @@ inline void Node::AssignData(const Node& rhs) {
}
inline void Node::AssignNode(const Node& rhs) {
- if (!m_isValid || !rhs.m_isValid)
- throw InvalidNode();
+ if (!m_isValid)
+ throw InvalidNode(m_invalidKey);
rhs.EnsureNodeExists();
if (!m_pNode) {
@@ -276,7 +270,7 @@ inline void Node::AssignNode(const Node& rhs) {
// size/iterator
inline std::size_t Node::size() const {
if (!m_isValid)
- throw InvalidNode();
+ throw InvalidNode(m_invalidKey);
return m_pNode ? m_pNode->size() : 0;
}
@@ -309,13 +303,11 @@ inline iterator Node::end() {
template <typename T>
inline void Node::push_back(const T& rhs) {
if (!m_isValid)
- throw InvalidNode();
+ throw InvalidNode(m_invalidKey);
push_back(Node(rhs));
}
inline void Node::push_back(const Node& rhs) {
- if (!m_isValid || !rhs.m_isValid)
- throw InvalidNode();
EnsureNodeExists();
rhs.EnsureNodeExists();
@@ -323,99 +315,49 @@ inline void Node::push_back(const Node& rhs) {
m_pMemory->merge(*rhs.m_pMemory);
}
-// helpers for indexing
-namespace detail {
-template <typename T>
-struct to_value_t {
- explicit to_value_t(const T& t_) : t(t_) {}
- const T& t;
- typedef const T& return_type;
-
- const T& operator()() const { return t; }
-};
-
-template <>
-struct to_value_t<const char*> {
- explicit to_value_t(const char* t_) : t(t_) {}
- const char* t;
- typedef std::string return_type;
-
- const std::string operator()() const { return t; }
-};
-
-template <>
-struct to_value_t<char*> {
- explicit to_value_t(char* t_) : t(t_) {}
- const char* t;
- typedef std::string return_type;
-
- const std::string operator()() const { return t; }
-};
-
-template <std::size_t N>
-struct to_value_t<char[N]> {
- explicit to_value_t(const char* t_) : t(t_) {}
- const char* t;
- typedef std::string return_type;
-
- const std::string operator()() const { return t; }
-};
-
-// converts C-strings to std::strings so they can be copied
-template <typename T>
-inline typename to_value_t<T>::return_type to_value(const T& t) {
- return to_value_t<T>(t)();
-}
+template<typename Key>
+std::string key_to_string(const Key& key) {
+ return streamable_to_string<Key, is_streamable<std::stringstream, Key>::value>().impl(key);
}
// indexing
template <typename Key>
inline const Node Node::operator[](const Key& key) const {
- if (!m_isValid)
- throw InvalidNode();
EnsureNodeExists();
- detail::node* value = static_cast<const detail::node&>(*m_pNode)
- .get(detail::to_value(key), m_pMemory);
+ detail::node* value =
+ static_cast<const detail::node&>(*m_pNode).get(key, m_pMemory);
if (!value) {
- return Node(ZombieNode);
+ return Node(ZombieNode, key_to_string(key));
}
return Node(*value, m_pMemory);
}
template <typename Key>
inline Node Node::operator[](const Key& key) {
- if (!m_isValid)
- throw InvalidNode();
EnsureNodeExists();
- detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory);
+ detail::node& value = m_pNode->get(key, m_pMemory);
return Node(value, m_pMemory);
}
template <typename Key>
inline bool Node::remove(const Key& key) {
- if (!m_isValid)
- throw InvalidNode();
EnsureNodeExists();
- return m_pNode->remove(detail::to_value(key), m_pMemory);
+ return m_pNode->remove(key, m_pMemory);
}
inline const Node Node::operator[](const Node& key) const {
- if (!m_isValid || !key.m_isValid)
- throw InvalidNode();
EnsureNodeExists();
key.EnsureNodeExists();
m_pMemory->merge(*key.m_pMemory);
detail::node* value =
static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
if (!value) {
- return Node(ZombieNode);
+ return Node(ZombieNode, key_to_string(key));
}
return Node(*value, m_pMemory);
}
inline Node Node::operator[](const Node& key) {
- if (!m_isValid || !key.m_isValid)
- throw InvalidNode();
EnsureNodeExists();
key.EnsureNodeExists();
m_pMemory->merge(*key.m_pMemory);
@@ -424,8 +366,6 @@ inline Node Node::operator[](const Node& key) {
}
inline bool Node::remove(const Node& key) {
- if (!m_isValid || !key.m_isValid)
- throw InvalidNode();
EnsureNodeExists();
key.EnsureNodeExists();
return m_pNode->remove(*key.m_pNode, m_pMemory);
@@ -434,15 +374,12 @@ inline bool Node::remove(const Node& key) {
// map
template <typename Key, typename Value>
inline void Node::force_insert(const Key& key, const Value& value) {
- if (!m_isValid)
- throw InvalidNode();
EnsureNodeExists();
- m_pNode->force_insert(detail::to_value(key), detail::to_value(value),
- m_pMemory);
+ m_pNode->force_insert(key, value, m_pMemory);
}
// free functions
inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
-}
+} // namespace YAML
#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/iterator.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/iterator.h
index 366a9c807fe..1fcf6e400ff 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/iterator.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/iterator.h
@@ -15,10 +15,13 @@
#include <utility>
#include <vector>
+// Assert in place so gcc + libc++ combination properly builds
+static_assert(std::is_constructible<YAML::Node, const YAML::Node&>::value, "Node must be copy constructable");
+
namespace YAML {
namespace detail {
struct iterator_value : public Node, std::pair<Node, Node> {
- iterator_value() {}
+ iterator_value() = default;
explicit iterator_value(const Node& rhs)
: Node(rhs),
std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {}
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/node.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/node.h
index 1ded7d27b72..c9e9a0a4bc1 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/node.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/node.h
@@ -8,11 +8,11 @@
#endif
#include <stdexcept>
+#include <string>
#include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/mark.h"
-#include "yaml-cpp/node/detail/bool_type.h"
#include "yaml-cpp/node/detail/iterator_fwd.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h"
@@ -38,8 +38,8 @@ class YAML_CPP_API Node {
template <typename T, typename S>
friend struct as_if;
- typedef YAML::iterator iterator;
- typedef YAML::const_iterator const_iterator;
+ using iterator = YAML::iterator;
+ using const_iterator = YAML::const_iterator;
Node();
explicit Node(NodeType::value type);
@@ -58,7 +58,7 @@ class YAML_CPP_API Node {
bool IsMap() const { return Type() == NodeType::Map; }
// bool conversions
- YAML_CPP_OPERATOR_BOOL()
+ explicit operator bool() const { return IsDefined(); }
bool operator!() const { return !IsDefined(); }
// access
@@ -116,6 +116,7 @@ class YAML_CPP_API Node {
private:
enum Zombie { ZombieNode };
explicit Node(Zombie);
+ explicit Node(Zombie, const std::string&);
explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
void EnsureNodeExists() const;
@@ -130,6 +131,8 @@ class YAML_CPP_API Node {
private:
bool m_isValid;
+ // String representation of invalid key, if the node is invalid.
+ std::string m_invalidKey;
mutable detail::shared_memory_holder m_pMemory;
mutable detail::node* m_pNode;
};
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/ptr.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/ptr.h
index ce085dd5cd8..f55d95ed9ca 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/ptr.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/ptr.h
@@ -7,7 +7,6 @@
#pragma once
#endif
-#include "yaml-cpp/dll.h"
#include <memory>
namespace YAML {
@@ -18,11 +17,11 @@ class node_data;
class memory;
class memory_holder;
-typedef std::shared_ptr<node> shared_node;
-typedef std::shared_ptr<node_ref> shared_node_ref;
-typedef std::shared_ptr<node_data> shared_node_data;
-typedef std::shared_ptr<memory_holder> shared_memory_holder;
-typedef std::shared_ptr<memory> shared_memory;
+using shared_node = std::shared_ptr<node>;
+using shared_node_ref = std::shared_ptr<node_ref>;
+using shared_node_data = std::shared_ptr<node_data>;
+using shared_memory_holder = std::shared_ptr<memory_holder>;
+using shared_memory = std::shared_ptr<memory>;
}
}
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noexcept.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noexcept.h
new file mode 100644
index 00000000000..6aac63516f3
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noexcept.h
@@ -0,0 +1,18 @@
+#ifndef NOEXCEPT_H_768872DA_476C_11EA_88B8_90B11C0C0FF8
+#define NOEXCEPT_H_768872DA_476C_11EA_88B8_90B11C0C0FF8
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+// This is here for compatibility with older versions of Visual Studio
+// which don't support noexcept.
+#if defined(_MSC_VER) && _MSC_VER < 1900
+ #define YAML_CPP_NOEXCEPT _NOEXCEPT
+#else
+ #define YAML_CPP_NOEXCEPT noexcept
+#endif
+
+#endif
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noncopyable.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noncopyable.h
deleted file mode 100644
index a261040739b..00000000000
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noncopyable.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-#define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-
-#if defined(_MSC_VER) || \
- (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
- (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
-#pragma once
-#endif
-
-#include "yaml-cpp/dll.h"
-
-namespace YAML {
-// this is basically boost::noncopyable
-class YAML_CPP_API noncopyable {
- protected:
- noncopyable() {}
- ~noncopyable() {}
-
- private:
- noncopyable(const noncopyable&);
- const noncopyable& operator=(const noncopyable&);
-};
-}
-
-#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/ostream_wrapper.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/ostream_wrapper.h
index 09d45f39b78..cf89741d093 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/ostream_wrapper.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/ostream_wrapper.h
@@ -17,6 +17,10 @@ class YAML_CPP_API ostream_wrapper {
public:
ostream_wrapper();
explicit ostream_wrapper(std::ostream& stream);
+ ostream_wrapper(const ostream_wrapper&) = delete;
+ ostream_wrapper(ostream_wrapper&&) = delete;
+ ostream_wrapper& operator=(const ostream_wrapper&) = delete;
+ ostream_wrapper& operator=(ostream_wrapper&&) = delete;
~ostream_wrapper();
void write(const std::string& str);
@@ -26,7 +30,7 @@ class YAML_CPP_API ostream_wrapper {
const char* str() const {
if (m_pStream) {
- return 0;
+ return nullptr;
} else {
m_buffer[m_pos] = '\0';
return &m_buffer[0];
@@ -52,7 +56,7 @@ class YAML_CPP_API ostream_wrapper {
template <std::size_t N>
inline ostream_wrapper& operator<<(ostream_wrapper& stream,
- const char(&str)[N]) {
+ const char (&str)[N]) {
stream.write(str, N - 1);
return stream;
}
@@ -67,6 +71,6 @@ inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) {
stream.write(&ch, 1);
return stream;
}
-}
+} // namespace YAML
#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/parser.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/parser.h
index ceac22d0268..2f403c35048 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/parser.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/parser.h
@@ -11,7 +11,6 @@
#include <memory>
#include "yaml-cpp/dll.h"
-#include "yaml-cpp/noncopyable.h"
namespace YAML {
class EventHandler;
@@ -24,11 +23,16 @@ struct Token;
* A parser turns a stream of bytes into one stream of "events" per YAML
* document in the input stream.
*/
-class YAML_CPP_API Parser : private noncopyable {
+class YAML_CPP_API Parser {
public:
/** Constructs an empty parser (with no input. */
Parser();
+ Parser(const Parser&) = delete;
+ Parser(Parser&&) = delete;
+ Parser& operator=(const Parser&) = delete;
+ Parser& operator=(Parser&&) = delete;
+
/**
* Constructs a parser from the given input stream. The input stream must
* live as long as the parser.
@@ -81,6 +85,6 @@ class YAML_CPP_API Parser : private noncopyable {
std::unique_ptr<Scanner> m_pScanner;
std::unique_ptr<Directives> m_pDirectives;
};
-}
+} // namespace YAML
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/stlemitter.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/stlemitter.h
index 06780c861f1..210a2f64e6a 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/stlemitter.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/stlemitter.h
@@ -16,8 +16,8 @@ namespace YAML {
template <typename Seq>
inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) {
emitter << BeginSeq;
- for (typename Seq::const_iterator it = seq.begin(); it != seq.end(); ++it)
- emitter << *it;
+ for (const auto& v : seq)
+ emitter << v;
emitter << EndSeq;
return emitter;
}
@@ -39,10 +39,9 @@ inline Emitter& operator<<(Emitter& emitter, const std::set<T>& v) {
template <typename K, typename V>
inline Emitter& operator<<(Emitter& emitter, const std::map<K, V>& m) {
- typedef typename std::map<K, V> map;
emitter << BeginMap;
- for (typename map::const_iterator it = m.begin(); it != m.end(); ++it)
- emitter << Key << it->first << Value << it->second;
+ for (const auto& v : m)
+ emitter << Key << v.first << Value << v.second;
emitter << EndMap;
return emitter;
}
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/traits.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/traits.h
index f33d0e1f637..ffe9999f191 100644
--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/traits.h
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/traits.h
@@ -7,6 +7,11 @@
#pragma once
#endif
+#include <type_traits>
+#include <utility>
+#include <string>
+#include <sstream>
+
namespace YAML {
template <typename>
struct is_numeric {
@@ -79,7 +84,7 @@ struct is_numeric<long double> {
template <bool, class T = void>
struct enable_if_c {
- typedef T type;
+ using type = T;
};
template <class T>
@@ -90,7 +95,7 @@ struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool, class T = void>
struct disable_if_c {
- typedef T type;
+ using type = T;
};
template <class T>
@@ -100,4 +105,31 @@ template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {};
}
+template <typename S, typename T>
+struct is_streamable {
+ template <typename StreamT, typename ValueT>
+ static auto test(int)
+ -> decltype(std::declval<StreamT&>() << std::declval<ValueT>(), std::true_type());
+
+ template <typename, typename>
+ static auto test(...) -> std::false_type;
+
+ static const bool value = decltype(test<S, T>(0))::value;
+};
+
+template<typename Key, bool Streamable>
+struct streamable_to_string {
+ static std::string impl(const Key& key) {
+ std::stringstream ss;
+ ss << key;
+ return ss.str();
+ }
+};
+
+template<typename Key>
+struct streamable_to_string<Key, false> {
+ static std::string impl(const Key&) {
+ return "";
+ }
+};
#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/patches/0001-yaml-cpp-Strip-unneeded-sources.patch b/src/libs/3rdparty/yaml-cpp/patches/0001-yaml-cpp-Strip-unneeded-sources.patch
index 93bdc64f64f..218b9e1ef79 100644
--- a/src/libs/3rdparty/yaml-cpp/patches/0001-yaml-cpp-Strip-unneeded-sources.patch
+++ b/src/libs/3rdparty/yaml-cpp/patches/0001-yaml-cpp-Strip-unneeded-sources.patch
@@ -1,1667 +1,1556 @@
-From dd3d5fa32be556e54d2ee2247a06e1fc7e5c8026 Mon Sep 17 00:00:00 2001
-From: Nikolai Kosjar <nikolai.kosjar@qt.io>
-Date: Thu, 22 Aug 2019 15:00:03 +0200
+From 484b421d0004ce37d7abd63bd0043819ad3a9d9f Mon Sep 17 00:00:00 2001
+From: Eike Ziller <eike.ziller@qt.io>
+Date: Fri, 25 Aug 2023 13:00:39 +0200
Subject: [PATCH] yaml-cpp: Strip unneeded sources
-Change-Id: I2f863b06c1cd42abadc64897cd6282c4a2c8a8e3
---
- src/libs/3rdparty/yaml-cpp/.codedocs | 50 -
- src/libs/3rdparty/yaml-cpp/.gitignore | 1 -
- src/libs/3rdparty/yaml-cpp/.travis.yml | 28 -
- src/libs/3rdparty/yaml-cpp/CMakeLists.txt | 365 -
- src/libs/3rdparty/yaml-cpp/CONTRIBUTING.md | 26 -
- .../include/yaml-cpp/contrib/anchordict.h | 39 -
- .../include/yaml-cpp/contrib/graphbuilder.h | 149 -
- src/libs/3rdparty/yaml-cpp/install.txt | 24 -
- .../yaml-cpp/src/contrib/graphbuilder.cpp | 17 -
- .../src/contrib/graphbuilderadapter.cpp | 94 -
- .../src/contrib/graphbuilderadapter.h | 79 -
- .../3rdparty/yaml-cpp/test/CMakeLists.txt | 44 -
- .../yaml-cpp/test/create-emitter-tests.py | 211 -
- .../yaml-cpp/test/gtest-1.8.0/.gitignore | 2 -
- .../yaml-cpp/test/gtest-1.8.0/.travis.yml | 46 -
- .../yaml-cpp/test/gtest-1.8.0/CMakeLists.txt | 16 -
- .../yaml-cpp/test/gtest-1.8.0/README.md | 142 -
- .../yaml-cpp/test/gtest-1.8.0/appveyor.yml | 71 -
- .../test/gtest-1.8.0/googlemock/CHANGES | 126 -
- .../gtest-1.8.0/googlemock/CMakeLists.txt | 202 -
- .../test/gtest-1.8.0/googlemock/CONTRIBUTORS | 40 -
- .../test/gtest-1.8.0/googlemock/LICENSE | 28 -
- .../test/gtest-1.8.0/googlemock/README.md | 333 -
- .../gtest-1.8.0/googlemock/build-aux/.keep | 0
- .../test/gtest-1.8.0/googlemock/configure.ac | 146 -
- .../gtest-1.8.0/googlemock/docs/CheatSheet.md | 562 -
- .../gtest-1.8.0/googlemock/docs/CookBook.md | 3675 -------
- .../gtest-1.8.0/googlemock/docs/DesignDoc.md | 280 -
- .../gtest-1.8.0/googlemock/docs/DevGuide.md | 132 -
- .../googlemock/docs/Documentation.md | 12 -
- .../gtest-1.8.0/googlemock/docs/ForDummies.md | 439 -
- .../docs/FrequentlyAskedQuestions.md | 628 --
- .../googlemock/docs/KnownIssues.md | 19 -
- .../googlemock/docs/v1_5/CheatSheet.md | 525 -
- .../googlemock/docs/v1_5/CookBook.md | 3250 ------
- .../googlemock/docs/v1_5/Documentation.md | 11 -
- .../googlemock/docs/v1_5/ForDummies.md | 439 -
- .../docs/v1_5/FrequentlyAskedQuestions.md | 624 --
- .../googlemock/docs/v1_6/CheatSheet.md | 534 -
- .../googlemock/docs/v1_6/CookBook.md | 3342 ------
- .../googlemock/docs/v1_6/Documentation.md | 12 -
- .../googlemock/docs/v1_6/ForDummies.md | 439 -
- .../docs/v1_6/FrequentlyAskedQuestions.md | 628 --
- .../googlemock/docs/v1_7/CheatSheet.md | 556 -
- .../googlemock/docs/v1_7/CookBook.md | 3432 ------
- .../googlemock/docs/v1_7/Documentation.md | 12 -
- .../googlemock/docs/v1_7/ForDummies.md | 439 -
- .../docs/v1_7/FrequentlyAskedQuestions.md | 628 --
- .../googlemock/include/gmock/gmock-actions.h | 1205 --
- .../include/gmock/gmock-cardinalities.h | 147 -
- .../include/gmock/gmock-generated-actions.h | 2377 ----
- .../gmock/gmock-generated-actions.h.pump | 794 --
- .../gmock/gmock-generated-function-mockers.h | 1095 --
- .../gmock-generated-function-mockers.h.pump | 291 -
- .../include/gmock/gmock-generated-matchers.h | 2179 ----
- .../gmock/gmock-generated-matchers.h.pump | 672 --
- .../gmock/gmock-generated-nice-strict.h | 397 -
- .../gmock/gmock-generated-nice-strict.h.pump | 161 -
- .../googlemock/include/gmock/gmock-matchers.h | 4399 --------
- .../include/gmock/gmock-more-actions.h | 246 -
- .../include/gmock/gmock-more-matchers.h | 58 -
- .../include/gmock/gmock-spec-builders.h | 1847 ----
- .../googlemock/include/gmock/gmock.h | 94 -
- .../internal/custom/gmock-generated-actions.h | 8 -
- .../custom/gmock-generated-actions.h.pump | 10 -
- .../gmock/internal/custom/gmock-matchers.h | 39 -
- .../gmock/internal/custom/gmock-port.h | 46 -
- .../internal/gmock-generated-internal-utils.h | 279 -
- .../gmock-generated-internal-utils.h.pump | 136 -
- .../gmock/internal/gmock-internal-utils.h | 511 -
- .../include/gmock/internal/gmock-port.h | 91 -
- .../googlemock/msvc/2005/gmock_config.vsprops | 15 -
- .../googlemock/msvc/2010/gmock_config.props | 19 -
- .../googlemock/msvc/2015/gmock_config.props | 19 -
- .../googlemock/scripts/fuse_gmock_files.py | 240 -
+ .codedocs | 50 -
+ .github/workflows/build.yml | 72 -
+ .gitignore | 3 -
+ BUILD.bazel | 21 -
+ CMakeLists.txt | 207 -
+ CONTRIBUTING.md | 26 -
+ SECURITY.md | 13 -
+ WORKSPACE | 10 -
+ cmake_uninstall.cmake.in | 21 -
+ docs/Breaking-Changes.md | 52 -
+ docs/How-To-Emit-YAML.md | 230 -
+ docs/How-To-Parse-A-Document-(Old-API).md | 265 -
+ docs/Strings.md | 18 -
+ docs/Tutorial.md | 201 -
+ docs/_config.yml | 1 -
+ docs/index.md | 1 -
+ include/yaml-cpp/contrib/anchordict.h | 40 -
+ include/yaml-cpp/contrib/graphbuilder.h | 149 -
+ install.txt | 24 -
+ src/contrib/graphbuilder.cpp | 16 -
+ src/contrib/graphbuilderadapter.cpp | 94 -
+ src/contrib/graphbuilderadapter.h | 86 -
+ src/contrib/yaml-cpp.natvis | 32 -
+ src/contrib/yaml-cpp.natvis.md | 9 -
+ test/BUILD.bazel | 14 -
+ test/CMakeLists.txt | 56 -
+ test/binary_test.cpp | 14 -
+ test/create-emitter-tests.py | 223 -
+ test/gtest-1.11.0/.clang-format | 4 -
+ .../.github/ISSUE_TEMPLATE/00-bug_report.md | 43 -
+ .../ISSUE_TEMPLATE/10-feature_request.md | 24 -
+ .../.github/ISSUE_TEMPLATE/config.yml | 1 -
+ test/gtest-1.11.0/.gitignore | 84 -
+ test/gtest-1.11.0/BUILD.bazel | 190 -
+ test/gtest-1.11.0/CMakeLists.txt | 32 -
+ test/gtest-1.11.0/CONTRIBUTING.md | 130 -
+ test/gtest-1.11.0/CONTRIBUTORS | 63 -
+ test/gtest-1.11.0/LICENSE | 28 -
+ test/gtest-1.11.0/README.md | 140 -
+ test/gtest-1.11.0/WORKSPACE | 24 -
+ test/gtest-1.11.0/ci/linux-presubmit.sh | 126 -
+ test/gtest-1.11.0/ci/macos-presubmit.sh | 73 -
+ test/gtest-1.11.0/docs/_config.yml | 1 -
+ test/gtest-1.11.0/docs/_data/navigation.yml | 43 -
+ test/gtest-1.11.0/docs/_layouts/default.html | 58 -
+ test/gtest-1.11.0/docs/_sass/main.scss | 200 -
+ test/gtest-1.11.0/docs/advanced.md | 2318 ----
+ test/gtest-1.11.0/docs/assets/css/style.scss | 5 -
+ .../docs/community_created_documentation.md | 7 -
+ test/gtest-1.11.0/docs/faq.md | 693 --
+ test/gtest-1.11.0/docs/gmock_cheat_sheet.md | 241 -
+ test/gtest-1.11.0/docs/gmock_cook_book.md | 4301 -------
+ test/gtest-1.11.0/docs/gmock_faq.md | 390 -
+ test/gtest-1.11.0/docs/gmock_for_dummies.md | 700 --
+ test/gtest-1.11.0/docs/index.md | 22 -
+ test/gtest-1.11.0/docs/pkgconfig.md | 148 -
+ test/gtest-1.11.0/docs/platforms.md | 35 -
+ test/gtest-1.11.0/docs/primer.md | 482 -
+ test/gtest-1.11.0/docs/quickstart-bazel.md | 161 -
+ test/gtest-1.11.0/docs/quickstart-cmake.md | 156 -
+ test/gtest-1.11.0/docs/reference/actions.md | 115 -
+ .../gtest-1.11.0/docs/reference/assertions.md | 633 --
+ test/gtest-1.11.0/docs/reference/matchers.md | 283 -
+ test/gtest-1.11.0/docs/reference/mocking.md | 587 -
+ test/gtest-1.11.0/docs/reference/testing.md | 1431 ---
+ test/gtest-1.11.0/docs/samples.md | 22 -
+ test/gtest-1.11.0/googlemock/CMakeLists.txt | 218 -
+ test/gtest-1.11.0/googlemock/README.md | 44 -
+ .../gtest-1.11.0/googlemock/cmake/gmock.pc.in | 10 -
+ .../googlemock/cmake/gmock_main.pc.in | 10 -
+ test/gtest-1.11.0/googlemock/docs/README.md | 4 -
+ .../googlemock/include/gmock/gmock-actions.h | 1687 ---
+ .../include/gmock/gmock-cardinalities.h | 157 -
+ .../include/gmock/gmock-function-mocker.h | 479 -
+ .../googlemock/include/gmock/gmock-matchers.h | 5392 ---------
+ .../include/gmock/gmock-more-actions.h | 573 -
+ .../include/gmock/gmock-more-matchers.h | 92 -
+ .../include/gmock/gmock-nice-strict.h | 261 -
+ .../include/gmock/gmock-spec-builders.h | 2038 ----
+ .../googlemock/include/gmock/gmock.h | 98 -
+ .../include/gmock/internal/custom/README.md | 16 -
+ .../internal/custom/gmock-generated-actions.h | 6 -
+ .../gmock/internal/custom/gmock-matchers.h | 36 -
+ .../gmock/internal/custom/gmock-port.h | 39 -
+ .../gmock/internal/gmock-internal-utils.h | 459 -
+ .../include/gmock/internal/gmock-port.h | 87 -
+ .../include/gmock/internal/gmock-pp.h | 279 -
+ .../gtest-1.11.0/googlemock/scripts/README.md | 5 -
+ .../googlemock/scripts/fuse_gmock_files.py | 256 -
.../googlemock/scripts/generator/LICENSE | 203 -
- .../googlemock/scripts/generator/README | 35 -
+ .../googlemock/scripts/generator/README | 34 -
.../scripts/generator/README.cppclean | 115 -
.../scripts/generator/cpp/__init__.py | 0
- .../googlemock/scripts/generator/cpp/ast.py | 1733 ---
- .../scripts/generator/cpp/gmock_class.py | 227 -
- .../scripts/generator/cpp/gmock_class_test.py | 448 -
- .../scripts/generator/cpp/keywords.py | 59 -
- .../scripts/generator/cpp/tokenize.py | 287 -
- .../googlemock/scripts/generator/cpp/utils.py | 41 -
- .../googlemock/scripts/generator/gmock_gen.py | 31 -
- .../googlemock/scripts/gmock-config.in | 303 -
- .../googlemock/scripts/gmock_doctor.py | 640 --
- .../gtest-1.8.0/googlemock/scripts/upload.py | 1387 ---
- .../googlemock/scripts/upload_gmock.py | 78 -
- .../gtest-1.8.0/googlemock/src/gmock-all.cc | 47 -
- .../googlemock/src/gmock-cardinalities.cc | 156 -
- .../googlemock/src/gmock-internal-utils.cc | 174 -
- .../googlemock/src/gmock-matchers.cc | 498 -
- .../googlemock/src/gmock-spec-builders.cc | 823 --
- .../test/gtest-1.8.0/googlemock/src/gmock.cc | 183 -
- .../gtest-1.8.0/googlemock/src/gmock_main.cc | 54 -
- .../googlemock/test/gmock-actions_test.cc | 1411 ---
- .../test/gmock-cardinalities_test.cc | 428 -
- .../test/gmock-generated-actions_test.cc | 1228 ---
- .../gmock-generated-function-mockers_test.cc | 622 --
- .../gmock-generated-internal-utils_test.cc | 127 -
- .../test/gmock-generated-matchers_test.cc | 1286 ---
- .../test/gmock-internal-utils_test.cc | 699 --
- .../googlemock/test/gmock-matchers_test.cc | 5652 ----------
- .../test/gmock-more-actions_test.cc | 708 --
- .../googlemock/test/gmock-nice-strict_test.cc | 424 -
- .../googlemock/test/gmock-port_test.cc | 43 -
- .../test/gmock-spec-builders_test.cc | 2644 -----
- .../googlemock/test/gmock_all_test.cc | 51 -
- .../googlemock/test/gmock_ex_test.cc | 81 -
- .../googlemock/test/gmock_leak_test.py | 108 -
- .../googlemock/test/gmock_leak_test_.cc | 100 -
- .../googlemock/test/gmock_link2_test.cc | 40 -
- .../googlemock/test/gmock_link_test.cc | 40 -
- .../googlemock/test/gmock_link_test.h | 669 --
- .../googlemock/test/gmock_output_test.py | 180 -
- .../googlemock/test/gmock_output_test_.cc | 291 -
- .../test/gmock_output_test_golden.txt | 310 -
- .../googlemock/test/gmock_stress_test.cc | 322 -
- .../gtest-1.8.0/googlemock/test/gmock_test.cc | 220 -
- .../googlemock/test/gmock_test_utils.py | 112 -
- .../test/gtest-1.8.0/googletest/.gitignore | 2 -
- .../test/gtest-1.8.0/googletest/CHANGES | 157 -
- .../gtest-1.8.0/googletest/CMakeLists.txt | 286 -
- .../test/gtest-1.8.0/googletest/CONTRIBUTORS | 37 -
- .../test/gtest-1.8.0/googletest/LICENSE | 28 -
- .../test/gtest-1.8.0/googletest/README.md | 280 -
- .../gtest-1.8.0/googletest/build-aux/.keep | 0
- .../googletest/cmake/internal_utils.cmake | 254 -
- .../googletest/codegear/gtest.cbproj | 138 -
- .../googletest/codegear/gtest.groupproj | 54 -
- .../googletest/codegear/gtest_all.cc | 38 -
- .../googletest/codegear/gtest_link.cc | 40 -
- .../googletest/codegear/gtest_main.cbproj | 82 -
- .../googletest/codegear/gtest_unittest.cbproj | 88 -
- .../test/gtest-1.8.0/googletest/configure.ac | 68 -
- .../googletest/docs/AdvancedGuide.md | 2182 ----
- .../gtest-1.8.0/googletest/docs/DevGuide.md | 126 -
- .../googletest/docs/Documentation.md | 14 -
- .../test/gtest-1.8.0/googletest/docs/FAQ.md | 1087 --
- .../gtest-1.8.0/googletest/docs/Primer.md | 502 -
- .../gtest-1.8.0/googletest/docs/PumpManual.md | 177 -
- .../gtest-1.8.0/googletest/docs/Samples.md | 14 -
- .../googletest/docs/V1_5_AdvancedGuide.md | 2096 ----
- .../googletest/docs/V1_5_Documentation.md | 12 -
- .../gtest-1.8.0/googletest/docs/V1_5_FAQ.md | 886 --
- .../googletest/docs/V1_5_Primer.md | 497 -
- .../googletest/docs/V1_5_PumpManual.md | 177 -
- .../googletest/docs/V1_5_XcodeGuide.md | 93 -
- .../googletest/docs/V1_6_AdvancedGuide.md | 2178 ----
- .../googletest/docs/V1_6_Documentation.md | 14 -
- .../gtest-1.8.0/googletest/docs/V1_6_FAQ.md | 1038 --
- .../googletest/docs/V1_6_Primer.md | 501 -
- .../googletest/docs/V1_6_PumpManual.md | 177 -
- .../googletest/docs/V1_6_Samples.md | 14 -
- .../googletest/docs/V1_6_XcodeGuide.md | 93 -
- .../googletest/docs/V1_7_AdvancedGuide.md | 2181 ----
- .../googletest/docs/V1_7_Documentation.md | 14 -
- .../gtest-1.8.0/googletest/docs/V1_7_FAQ.md | 1082 --
- .../googletest/docs/V1_7_Primer.md | 501 -
- .../googletest/docs/V1_7_PumpManual.md | 177 -
- .../googletest/docs/V1_7_Samples.md | 14 -
- .../googletest/docs/V1_7_XcodeGuide.md | 93 -
- .../gtest-1.8.0/googletest/docs/XcodeGuide.md | 93 -
- .../include/gtest/gtest-death-test.h | 294 -
- .../googletest/include/gtest/gtest-message.h | 250 -
- .../include/gtest/gtest-param-test.h | 1444 ---
- .../include/gtest/gtest-param-test.h.pump | 510 -
- .../googletest/include/gtest/gtest-printers.h | 993 --
- .../googletest/include/gtest/gtest-spi.h | 232 -
- .../include/gtest/gtest-test-part.h | 179 -
- .../include/gtest/gtest-typed-test.h | 263 -
- .../googletest/include/gtest/gtest.h | 2236 ----
- .../include/gtest/gtest_pred_impl.h | 358 -
- .../googletest/include/gtest/gtest_prod.h | 58 -
- .../gtest/internal/custom/gtest-port.h | 69 -
+ .../googlemock/scripts/generator/cpp/ast.py | 1773 ---
+ .../scripts/generator/cpp/gmock_class.py | 247 -
+ .../scripts/generator/cpp/gmock_class_test.py | 570 -
+ .../scripts/generator/cpp/keywords.py | 56 -
+ .../scripts/generator/cpp/tokenize.py | 284 -
+ .../googlemock/scripts/generator/cpp/utils.py | 37 -
+ .../googlemock/scripts/generator/gmock_gen.py | 30 -
+ test/gtest-1.11.0/googlemock/src/gmock-all.cc | 46 -
+ .../googlemock/src/gmock-cardinalities.cc | 155 -
+ .../googlemock/src/gmock-internal-utils.cc | 200 -
+ .../googlemock/src/gmock-matchers.cc | 459 -
+ .../googlemock/src/gmock-spec-builders.cc | 908 --
+ test/gtest-1.11.0/googlemock/src/gmock.cc | 213 -
+ .../gtest-1.11.0/googlemock/src/gmock_main.cc | 72 -
+ test/gtest-1.11.0/googlemock/test/BUILD.bazel | 118 -
+ .../googlemock/test/gmock-actions_test.cc | 1583 ---
+ .../test/gmock-cardinalities_test.cc | 429 -
+ .../test/gmock-function-mocker_test.cc | 986 --
+ .../test/gmock-internal-utils_test.cc | 720 --
+ .../googlemock/test/gmock-matchers_test.cc | 8562 --------------
+ .../test/gmock-more-actions_test.cc | 1547 ---
+ .../googlemock/test/gmock-nice-strict_test.cc | 539 -
+ .../googlemock/test/gmock-port_test.cc | 42 -
+ .../googlemock/test/gmock-pp-string_test.cc | 206 -
+ .../googlemock/test/gmock-pp_test.cc | 83 -
+ .../test/gmock-spec-builders_test.cc | 2775 -----
+ .../googlemock/test/gmock_all_test.cc | 46 -
+ .../googlemock/test/gmock_ex_test.cc | 80 -
+ .../googlemock/test/gmock_leak_test.py | 104 -
+ .../googlemock/test/gmock_leak_test_.cc | 99 -
+ .../googlemock/test/gmock_link2_test.cc | 39 -
+ .../googlemock/test/gmock_link_test.cc | 39 -
+ .../googlemock/test/gmock_link_test.h | 690 --
+ .../googlemock/test/gmock_output_test.py | 183 -
+ .../googlemock/test/gmock_output_test_.cc | 309 -
+ .../test/gmock_output_test_golden.txt | 317 -
+ .../googlemock/test/gmock_stress_test.cc | 240 -
+ .../googlemock/test/gmock_test.cc | 181 -
+ .../googlemock/test/gmock_test_utils.py | 108 -
+ test/gtest-1.11.0/googletest/CMakeLists.txt | 323 -
+ test/gtest-1.11.0/googletest/README.md | 215 -
+ .../googletest/cmake/Config.cmake.in | 9 -
+ .../gtest-1.11.0/googletest/cmake/gtest.pc.in | 9 -
+ .../googletest/cmake/gtest_main.pc.in | 10 -
+ .../googletest/cmake/internal_utils.cmake | 344 -
+ .../googletest/cmake/libgtest.la.in | 21 -
+ test/gtest-1.11.0/googletest/docs/README.md | 4 -
+ .../include/gtest/gtest-death-test.h | 346 -
+ .../googletest/include/gtest/gtest-matchers.h | 930 --
+ .../googletest/include/gtest/gtest-message.h | 219 -
+ .../include/gtest/gtest-param-test.h | 507 -
+ .../googletest/include/gtest/gtest-printers.h | 1029 --
+ .../googletest/include/gtest/gtest-spi.h | 238 -
+ .../include/gtest/gtest-test-part.h | 184 -
+ .../include/gtest/gtest-typed-test.h | 329 -
+ .../googletest/include/gtest/gtest.h | 2495 -----
+ .../include/gtest/gtest_pred_impl.h | 359 -
+ .../googletest/include/gtest/gtest_prod.h | 61 -
+ .../include/gtest/internal/custom/README.md | 56 -
+ .../gtest/internal/custom/gtest-port.h | 37 -
.../gtest/internal/custom/gtest-printers.h | 42 -
- .../include/gtest/internal/custom/gtest.h | 41 -
- .../internal/gtest-death-test-internal.h | 319 -
- .../include/gtest/internal/gtest-filepath.h | 206 -
- .../include/gtest/internal/gtest-internal.h | 1238 ---
- .../include/gtest/internal/gtest-linked_ptr.h | 243 -
- .../internal/gtest-param-util-generated.h | 5146 ---------
- .../gtest-param-util-generated.h.pump | 286 -
- .../include/gtest/internal/gtest-param-util.h | 731 --
- .../include/gtest/internal/gtest-port-arch.h | 93 -
- .../include/gtest/internal/gtest-port.h | 2554 -----
- .../include/gtest/internal/gtest-string.h | 167 -
- .../include/gtest/internal/gtest-tuple.h | 1020 --
- .../include/gtest/internal/gtest-tuple.h.pump | 347 -
- .../include/gtest/internal/gtest-type-util.h | 3331 ------
- .../gtest/internal/gtest-type-util.h.pump | 297 -
- .../gtest-1.8.0/googletest/m4/acx_pthread.m4 | 363 -
- .../test/gtest-1.8.0/googletest/m4/gtest.m4 | 74 -
- .../googletest/samples/prime_tables.h | 123 -
- .../gtest-1.8.0/googletest/samples/sample1.cc | 68 -
- .../gtest-1.8.0/googletest/samples/sample1.h | 43 -
- .../googletest/samples/sample10_unittest.cc | 144 -
- .../googletest/samples/sample1_unittest.cc | 153 -
- .../gtest-1.8.0/googletest/samples/sample2.cc | 56 -
- .../gtest-1.8.0/googletest/samples/sample2.h | 85 -
- .../googletest/samples/sample2_unittest.cc | 109 -
+ .../include/gtest/internal/custom/gtest.h | 37 -
+ .../internal/gtest-death-test-internal.h | 304 -
+ .../include/gtest/internal/gtest-filepath.h | 211 -
+ .../include/gtest/internal/gtest-internal.h | 1560 ---
+ .../include/gtest/internal/gtest-param-util.h | 947 --
+ .../include/gtest/internal/gtest-port-arch.h | 114 -
+ .../include/gtest/internal/gtest-port.h | 2389 ----
+ .../include/gtest/internal/gtest-string.h | 175 -
+ .../include/gtest/internal/gtest-type-util.h | 183 -
+ .../googletest/samples/prime_tables.h | 126 -
+ .../googletest/samples/sample1.cc | 66 -
+ .../gtest-1.11.0/googletest/samples/sample1.h | 41 -
+ .../googletest/samples/sample10_unittest.cc | 139 -
+ .../googletest/samples/sample1_unittest.cc | 151 -
+ .../googletest/samples/sample2.cc | 54 -
+ .../gtest-1.11.0/googletest/samples/sample2.h | 80 -
+ .../googletest/samples/sample2_unittest.cc | 107 -
.../googletest/samples/sample3-inl.h | 172 -
- .../googletest/samples/sample3_unittest.cc | 151 -
- .../gtest-1.8.0/googletest/samples/sample4.cc | 46 -
- .../gtest-1.8.0/googletest/samples/sample4.h | 53 -
- .../googletest/samples/sample4_unittest.cc | 45 -
- .../googletest/samples/sample5_unittest.cc | 199 -
- .../googletest/samples/sample6_unittest.cc | 224 -
- .../googletest/samples/sample7_unittest.cc | 130 -
- .../googletest/samples/sample8_unittest.cc | 173 -
- .../googletest/samples/sample9_unittest.cc | 160 -
- .../gtest-1.8.0/googletest/scripts/common.py | 83 -
+ .../googletest/samples/sample3_unittest.cc | 149 -
+ .../googletest/samples/sample4.cc | 54 -
+ .../gtest-1.11.0/googletest/samples/sample4.h | 53 -
+ .../googletest/samples/sample4_unittest.cc | 53 -
+ .../googletest/samples/sample5_unittest.cc | 196 -
+ .../googletest/samples/sample6_unittest.cc | 217 -
+ .../googletest/samples/sample7_unittest.cc | 117 -
+ .../googletest/samples/sample8_unittest.cc | 154 -
+ .../googletest/samples/sample9_unittest.cc | 156 -
+ .../gtest-1.11.0/googletest/scripts/README.md | 5 -
+ .../gtest-1.11.0/googletest/scripts/common.py | 83 -
.../googletest/scripts/fuse_gtest_files.py | 253 -
- .../googletest/scripts/gen_gtest_pred_impl.py | 730 --
+ .../googletest/scripts/gen_gtest_pred_impl.py | 733 --
.../googletest/scripts/gtest-config.in | 274 -
- .../gtest-1.8.0/googletest/scripts/pump.py | 855 --
.../googletest/scripts/release_docs.py | 158 -
- .../gtest-1.8.0/googletest/scripts/upload.py | 1387 ---
+ .../googletest/scripts/run_with_path.py | 32 -
+ .../gtest-1.11.0/googletest/scripts/upload.py | 1402 ---
.../googletest/scripts/upload_gtest.py | 78 -
- .../gtest-1.8.0/googletest/src/gtest-all.cc | 48 -
- .../googletest/src/gtest-death-test.cc | 1342 ---
- .../googletest/src/gtest-filepath.cc | 387 -
- .../googletest/src/gtest-internal-inl.h | 1183 --
- .../gtest-1.8.0/googletest/src/gtest-port.cc | 1259 ---
- .../googletest/src/gtest-printers.cc | 373 -
- .../googletest/src/gtest-test-part.cc | 110 -
- .../googletest/src/gtest-typed-test.cc | 118 -
- .../test/gtest-1.8.0/googletest/src/gtest.cc | 5388 ---------
- .../gtest-1.8.0/googletest/src/gtest_main.cc | 38 -
- .../test/gtest-death-test_ex_test.cc | 93 -
- .../googletest/test/gtest-death-test_test.cc | 1427 ---
- .../googletest/test/gtest-filepath_test.cc | 662 --
- .../googletest/test/gtest-linked_ptr_test.cc | 154 -
- .../googletest/test/gtest-listener_test.cc | 311 -
- .../googletest/test/gtest-message_test.cc | 159 -
- .../googletest/test/gtest-options_test.cc | 215 -
- .../googletest/test/gtest-param-test2_test.cc | 65 -
- .../googletest/test/gtest-param-test_test.cc | 1055 --
- .../googletest/test/gtest-param-test_test.h | 57 -
- .../googletest/test/gtest-port_test.cc | 1304 ---
- .../googletest/test/gtest-printers_test.cc | 1635 ---
- .../googletest/test/gtest-test-part_test.cc | 208 -
- .../googletest/test/gtest-tuple_test.cc | 320 -
- .../googletest/test/gtest-typed-test2_test.cc | 45 -
- .../googletest/test/gtest-typed-test_test.cc | 380 -
- .../googletest/test/gtest-typed-test_test.h | 66 -
- .../test/gtest-unittest-api_test.cc | 341 -
- .../googletest/test/gtest_all_test.cc | 47 -
- .../test/gtest_break_on_failure_unittest.py | 212 -
- .../test/gtest_break_on_failure_unittest_.cc | 88 -
- .../test/gtest_catch_exceptions_test.py | 237 -
- .../test/gtest_catch_exceptions_test_.cc | 311 -
- .../googletest/test/gtest_color_test.py | 130 -
- .../googletest/test/gtest_color_test_.cc | 71 -
- .../googletest/test/gtest_env_var_test.py | 117 -
- .../googletest/test/gtest_env_var_test_.cc | 126 -
- .../googletest/test/gtest_environment_test.cc | 192 -
- .../googletest/test/gtest_filter_unittest.py | 636 --
- .../googletest/test/gtest_filter_unittest_.cc | 140 -
+ test/gtest-1.11.0/googletest/src/gtest-all.cc | 48 -
+ .../googletest/src/gtest-death-test.cc | 1644 ---
+ .../googletest/src/gtest-filepath.cc | 369 -
+ .../googletest/src/gtest-internal-inl.h | 1221 --
+ .../googletest/src/gtest-matchers.cc | 97 -
+ .../gtest-1.11.0/googletest/src/gtest-port.cc | 1433 ---
+ .../googletest/src/gtest-printers.cc | 533 -
+ .../googletest/src/gtest-test-part.cc | 108 -
+ .../googletest/src/gtest-typed-test.cc | 107 -
+ test/gtest-1.11.0/googletest/src/gtest.cc | 6746 -----------
+ .../gtest-1.11.0/googletest/src/gtest_main.cc | 54 -
+ test/gtest-1.11.0/googletest/test/BUILD.bazel | 590 -
+ .../googletest-break-on-failure-unittest.py | 208 -
+ .../googletest-break-on-failure-unittest_.cc | 86 -
+ .../test/googletest-catch-exceptions-test.py | 236 -
+ .../test/googletest-catch-exceptions-test_.cc | 293 -
+ .../googletest/test/googletest-color-test.py | 127 -
+ .../googletest/test/googletest-color-test_.cc | 62 -
+ .../test/googletest-death-test-test.cc | 1542 ---
+ .../test/googletest-death-test_ex_test.cc | 92 -
+ .../test/googletest-env-var-test.py | 120 -
+ .../test/googletest-env-var-test_.cc | 132 -
+ .../test/googletest-failfast-unittest.py | 410 -
+ .../test/googletest-failfast-unittest_.cc | 167 -
+ .../test/googletest-filepath-test.cc | 649 --
+ .../test/googletest-filter-unittest.py | 639 --
+ .../test/googletest-filter-unittest_.cc | 137 -
+ .../googletest-global-environment-unittest.py | 72 -
+ ...googletest-global-environment-unittest_.cc | 58 -
+ .../test/googletest-json-outfiles-test.py | 191 -
+ .../test/googletest-json-output-unittest.py | 848 --
+ .../test/googletest-list-tests-unittest.py | 205 -
+ .../test/googletest-list-tests-unittest_.cc | 156 -
+ .../test/googletest-listener-test.cc | 518 -
+ .../test/googletest-message-test.cc | 158 -
+ .../test/googletest-options-test.cc | 219 -
+ .../googletest-output-test-golden-lin.txt | 1180 --
+ .../googletest/test/googletest-output-test.py | 346 -
+ .../test/googletest-output-test_.cc | 1108 --
+ ...oogletest-param-test-invalid-name1-test.py | 63 -
+ ...ogletest-param-test-invalid-name1-test_.cc | 50 -
+ ...oogletest-param-test-invalid-name2-test.py | 62 -
+ ...ogletest-param-test-invalid-name2-test_.cc | 55 -
+ .../test/googletest-param-test-test.cc | 1119 --
+ .../test/googletest-param-test-test.h | 51 -
+ .../test/googletest-param-test2-test.cc | 61 -
+ .../googletest/test/googletest-port-test.cc | 1276 ---
+ .../test/googletest-printers-test.cc | 1962 ----
+ .../test/googletest-setuptestsuite-test.py | 54 -
+ .../test/googletest-setuptestsuite-test_.cc | 49 -
+ .../test/googletest-shuffle-test.py | 323 -
+ .../test/googletest-shuffle-test_.cc | 101 -
+ .../test/googletest-test-part-test.cc | 230 -
+ .../test/googletest-throw-on-failure-test.py | 168 -
+ .../test/googletest-throw-on-failure-test_.cc | 71 -
+ .../test/googletest-uninitialized-test.py | 67 -
+ .../test/googletest-uninitialized-test_.cc | 42 -
+ .../googletest/test/gtest-typed-test2_test.cc | 40 -
+ .../googletest/test/gtest-typed-test_test.cc | 437 -
+ .../googletest/test/gtest-typed-test_test.h | 60 -
+ .../test/gtest-unittest-api_test.cc | 328 -
+ .../googletest/test/gtest_all_test.cc | 46 -
+ .../test/gtest_assert_by_exception_test.cc | 116 -
+ .../googletest/test/gtest_environment_test.cc | 188 -
.../googletest/test/gtest_help_test.py | 172 -
- .../googletest/test/gtest_help_test_.cc | 46 -
- .../test/gtest_list_tests_unittest.py | 207 -
- .../test/gtest_list_tests_unittest_.cc | 157 -
- .../googletest/test/gtest_main_unittest.cc | 45 -
- .../googletest/test/gtest_no_test_unittest.cc | 56 -
- .../googletest/test/gtest_output_test.py | 340 -
- .../googletest/test/gtest_output_test_.cc | 1062 --
- .../test/gtest_output_test_golden_lin.txt | 743 --
- .../test/gtest_pred_impl_unittest.cc | 2427 ----
- .../test/gtest_premature_exit_test.cc | 127 -
- .../googletest/test/gtest_prod_test.cc | 57 -
- .../googletest/test/gtest_repeat_test.cc | 253 -
- .../googletest/test/gtest_shuffle_test.py | 325 -
- .../googletest/test/gtest_shuffle_test_.cc | 103 -
- .../googletest/test/gtest_sole_header_test.cc | 57 -
- .../googletest/test/gtest_stress_test.cc | 256 -
- .../googletest/test/gtest_test_utils.py | 320 -
- .../test/gtest_throw_on_failure_ex_test.cc | 92 -
- .../test/gtest_throw_on_failure_test.py | 171 -
- .../test/gtest_throw_on_failure_test_.cc | 72 -
- .../test/gtest_uninitialized_test.py | 70 -
- .../test/gtest_uninitialized_test_.cc | 43 -
- .../googletest/test/gtest_unittest.cc | 7706 -------------
- .../test/gtest_xml_outfile1_test_.cc | 49 -
- .../test/gtest_xml_outfile2_test_.cc | 49 -
- .../test/gtest_xml_outfiles_test.py | 132 -
- .../test/gtest_xml_output_unittest.py | 308 -
- .../test/gtest_xml_output_unittest_.cc | 181 -
- .../googletest/test/gtest_xml_test_utils.py | 194 -
- .../gtest-1.8.0/googletest/test/production.cc | 36 -
- .../gtest-1.8.0/googletest/test/production.h | 55 -
- .../xcode/Config/DebugProject.xcconfig | 30 -
- .../xcode/Config/FrameworkTarget.xcconfig | 17 -
- .../googletest/xcode/Config/General.xcconfig | 41 -
- .../xcode/Config/ReleaseProject.xcconfig | 32 -
- .../xcode/Config/StaticLibraryTarget.xcconfig | 18 -
- .../xcode/Config/TestTarget.xcconfig | 8 -
- .../googletest/xcode/Resources/Info.plist | 30 -
- .../xcode/Samples/FrameworkSample/Info.plist | 28 -
- .../WidgetFramework.xcodeproj/project.pbxproj | 457 -
- .../xcode/Samples/FrameworkSample/runtests.sh | 62 -
- .../xcode/Samples/FrameworkSample/widget.cc | 63 -
- .../xcode/Samples/FrameworkSample/widget.h | 59 -
- .../Samples/FrameworkSample/widget_test.cc | 68 -
- .../googletest/xcode/Scripts/runtests.sh | 65 -
- .../xcode/Scripts/versiongenerate.py | 100 -
- .../xcode/gtest.xcodeproj/project.pbxproj | 1135 --
- .../yaml-cpp/test/gtest-1.8.0/travis.sh | 15 -
- .../3rdparty/yaml-cpp/test/handler_test.h | 32 -
- .../test/integration/emitter_test.cpp | 1038 --
- .../test/integration/encoding_test.cpp | 182 -
- .../test/integration/gen_emitter_test.cpp | 9759 -----------------
- .../test/integration/handler_spec_test.cpp | 1611 ---
- .../test/integration/handler_test.cpp | 76 -
- .../test/integration/load_node_test.cpp | 241 -
- .../test/integration/node_spec_test.cpp | 1131 --
- src/libs/3rdparty/yaml-cpp/test/main.cpp | 6 -
- .../yaml-cpp/test/mock_event_handler.h | 26 -
- .../3rdparty/yaml-cpp/test/node/node_test.cpp | 517 -
- .../yaml-cpp/test/ostream_wrapper_test.cpp | 66 -
- .../3rdparty/yaml-cpp/test/regex_test.cpp | 177 -
- .../3rdparty/yaml-cpp/test/specexamples.h | 846 --
- .../3rdparty/yaml-cpp/util/CMakeLists.txt | 14 -
- src/libs/3rdparty/yaml-cpp/util/api.cpp | 137 -
- src/libs/3rdparty/yaml-cpp/util/parse.cpp | 61 -
- src/libs/3rdparty/yaml-cpp/util/read.cpp | 103 -
- src/libs/3rdparty/yaml-cpp/util/sandbox.cpp | 36 -
- .../yaml-cpp/yaml-cpp-config-version.cmake.in | 11 -
- .../yaml-cpp/yaml-cpp-config.cmake.in | 14 -
- 331 files changed, 167784 deletions(-)
- delete mode 100644 src/libs/3rdparty/yaml-cpp/.codedocs
- delete mode 100644 src/libs/3rdparty/yaml-cpp/.gitignore
- delete mode 100644 src/libs/3rdparty/yaml-cpp/.travis.yml
- delete mode 100644 src/libs/3rdparty/yaml-cpp/CMakeLists.txt
- delete mode 100644 src/libs/3rdparty/yaml-cpp/CONTRIBUTING.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/anchordict.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/install.txt
- delete mode 100644 src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilder.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/CMakeLists.txt
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/create-emitter-tests.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.gitignore
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.travis.yml
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/CMakeLists.txt
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/README.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/appveyor.yml
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CHANGES
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CMakeLists.txt
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CONTRIBUTORS
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/LICENSE
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/README.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/build-aux/.keep
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/configure.ac
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CheatSheet.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CookBook.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DesignDoc.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DevGuide.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/Documentation.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/ForDummies.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/FrequentlyAskedQuestions.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/KnownIssues.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CheatSheet.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CookBook.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/Documentation.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/ForDummies.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/FrequentlyAskedQuestions.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CheatSheet.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CookBook.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/Documentation.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/ForDummies.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/FrequentlyAskedQuestions.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CheatSheet.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CookBook.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/Documentation.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/ForDummies.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/FrequentlyAskedQuestions.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-actions.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-cardinalities.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h.pump
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h.pump
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h.pump
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h.pump
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-matchers.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-actions.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-matchers.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-spec-builders.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-matchers.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-port.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-internal-utils.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-port.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2005/gmock_config.vsprops
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2010/gmock_config.props
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2015/gmock_config.props
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/fuse_gmock_files.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/LICENSE
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README.cppclean
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/__init__.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/ast.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class_test.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/keywords.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/tokenize.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/utils.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/gmock_gen.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock-config.in
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock_doctor.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload_gmock.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-all.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-cardinalities.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-internal-utils.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-matchers.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-spec-builders.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock_main.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-actions_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-cardinalities_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-actions_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-function-mockers_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-internal-utils_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-matchers_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-internal-utils_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-matchers_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-more-actions_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-nice-strict_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-port_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-spec-builders_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_all_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_ex_test.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test_.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link2_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.h
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_golden.txt
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_stress_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test_utils.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/.gitignore
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CHANGES
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CMakeLists.txt
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CONTRIBUTORS
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/LICENSE
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/README.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/build-aux/.keep
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/cmake/internal_utils.cmake
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.cbproj
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.groupproj
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_all.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_link.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_main.cbproj
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_unittest.cbproj
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/configure.ac
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/AdvancedGuide.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/DevGuide.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Documentation.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/FAQ.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Primer.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/PumpManual.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Samples.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_AdvancedGuide.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Documentation.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_FAQ.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Primer.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_PumpManual.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_XcodeGuide.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_AdvancedGuide.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Documentation.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_FAQ.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Primer.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_PumpManual.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Samples.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_XcodeGuide.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_AdvancedGuide.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Documentation.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_FAQ.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Primer.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_PumpManual.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Samples.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_XcodeGuide.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/XcodeGuide.md
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-death-test.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-message.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h.pump
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-printers.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-spi.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-test-part.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-typed-test.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_pred_impl.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_prod.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-port.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-printers.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-death-test-internal.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-filepath.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-internal.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-linked_ptr.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h.pump
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port-arch.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-string.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h.pump
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h.pump
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/acx_pthread.m4
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/gtest.m4
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/prime_tables.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample10_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3-inl.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample5_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample6_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample7_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample8_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample9_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/common.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/fuse_gtest_files.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gen_gtest_pred_impl.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gtest-config.in
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/pump.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/release_docs.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload_gtest.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-all.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-death-test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-filepath.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-internal-inl.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-port.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-printers.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-test-part.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-typed-test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest_main.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_ex_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-filepath_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-linked_ptr_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-listener_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-message_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-options_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test2_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-port_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-printers_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-test-part_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-tuple_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test2_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-unittest-api_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_all_test.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest_.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test_.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test_.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test_.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_environment_test.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest_.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test_.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest_.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_main_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_no_test_unittest.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_golden_lin.txt
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_pred_impl_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_premature_exit_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_prod_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_repeat_test.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test_.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_sole_header_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_stress_test.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_test_utils.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_ex_test.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test_.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test_.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_unittest.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile1_test_.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile2_test_.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfiles_test.py
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest_.cc
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_test_utils.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/DebugProject.xcconfig
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/FrameworkTarget.xcconfig
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/General.xcconfig
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/ReleaseProject.xcconfig
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/StaticLibraryTarget.xcconfig
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/TestTarget.xcconfig
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Resources/Info.plist
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/Info.plist
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/runtests.sh
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget_test.cc
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/runtests.sh
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/versiongenerate.py
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/gtest.xcodeproj/project.pbxproj
- delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/travis.sh
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/handler_test.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/emitter_test.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/encoding_test.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/gen_emitter_test.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/handler_spec_test.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/handler_test.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/load_node_test.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/node_spec_test.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/main.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/mock_event_handler.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/node/node_test.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/ostream_wrapper_test.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/regex_test.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/test/specexamples.h
- delete mode 100644 src/libs/3rdparty/yaml-cpp/util/CMakeLists.txt
- delete mode 100644 src/libs/3rdparty/yaml-cpp/util/api.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/util/parse.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/util/read.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/util/sandbox.cpp
- delete mode 100644 src/libs/3rdparty/yaml-cpp/yaml-cpp-config-version.cmake.in
- delete mode 100644 src/libs/3rdparty/yaml-cpp/yaml-cpp-config.cmake.in
+ .../googletest/test/gtest_help_test_.cc | 45 -
+ .../googletest/test/gtest_json_test_utils.py | 60 -
+ .../test/gtest_list_output_unittest.py | 286 -
+ .../test/gtest_list_output_unittest_.cc | 77 -
+ .../googletest/test/gtest_main_unittest.cc | 44 -
+ .../googletest/test/gtest_no_test_unittest.cc | 54 -
+ .../test/gtest_pred_impl_unittest.cc | 2422 ----
+ .../test/gtest_premature_exit_test.cc | 126 -
+ .../googletest/test/gtest_prod_test.cc | 56 -
+ .../googletest/test/gtest_repeat_test.cc | 233 -
+ .../test/gtest_skip_check_output_test.py | 59 -
+ ...test_skip_environment_check_output_test.py | 54 -
+ .../gtest_skip_in_environment_setup_test.cc | 49 -
+ .../googletest/test/gtest_skip_test.cc | 55 -
+ .../googletest/test/gtest_sole_header_test.cc | 56 -
+ .../googletest/test/gtest_stress_test.cc | 248 -
+ .../gtest_test_macro_stack_footprint_test.cc | 89 -
+ .../googletest/test/gtest_test_utils.py | 312 -
+ .../googletest/test/gtest_testbridge_test.py | 63 -
+ .../googletest/test/gtest_testbridge_test_.cc | 43 -
+ .../test/gtest_throw_on_failure_ex_test.cc | 90 -
+ .../googletest/test/gtest_unittest.cc | 7784 -------------
+ .../test/gtest_xml_outfile1_test_.cc | 43 -
+ .../test/gtest_xml_outfile2_test_.cc | 43 -
+ .../test/gtest_xml_outfiles_test.py | 135 -
+ .../test/gtest_xml_output_unittest.py | 415 -
+ .../test/gtest_xml_output_unittest_.cc | 193 -
+ .../googletest/test/gtest_xml_test_utils.py | 197 -
+ .../googletest/test/production.cc | 35 -
+ .../gtest-1.11.0/googletest/test/production.h | 54 -
+ test/gtest-1.11.0/library.json | 62 -
+ test/handler_test.h | 32 -
+ test/integration/emitter_test.cpp | 1740 ---
+ test/integration/encoding_test.cpp | 182 -
+ test/integration/error_messages_test.cpp | 61 -
+ test/integration/gen_emitter_test.cpp | 9936 -----------------
+ test/integration/handler_spec_test.cpp | 1686 ---
+ test/integration/handler_test.cpp | 76 -
+ test/integration/load_node_test.cpp | 364 -
+ test/integration/node_spec_test.cpp | 1136 --
+ test/main.cpp | 6 -
+ test/mock_event_handler.h | 30 -
+ test/node/node_test.cpp | 853 --
+ test/ostream_wrapper_test.cpp | 66 -
+ test/parser_test.cpp | 64 -
+ test/regex_test.cpp | 177 -
+ test/specexamples.h | 868 --
+ util/CMakeLists.txt | 32 -
+ util/api.cpp | 137 -
+ util/parse.cpp | 46 -
+ util/read.cpp | 103 -
+ util/sandbox.cpp | 36 -
+ yaml-cpp-config.cmake.in | 22 -
+ yaml-cpp.pc.in | 11 -
+ 309 files changed, 133651 deletions(-)
+ delete mode 100644 .codedocs
+ delete mode 100644 .github/workflows/build.yml
+ delete mode 100644 .gitignore
+ delete mode 100644 BUILD.bazel
+ delete mode 100644 CMakeLists.txt
+ delete mode 100644 CONTRIBUTING.md
+ delete mode 100644 SECURITY.md
+ delete mode 100644 WORKSPACE
+ delete mode 100644 cmake_uninstall.cmake.in
+ delete mode 100644 docs/Breaking-Changes.md
+ delete mode 100644 docs/How-To-Emit-YAML.md
+ delete mode 100644 docs/How-To-Parse-A-Document-(Old-API).md
+ delete mode 100644 docs/Strings.md
+ delete mode 100644 docs/Tutorial.md
+ delete mode 100644 docs/_config.yml
+ delete mode 100644 docs/index.md
+ delete mode 100644 include/yaml-cpp/contrib/anchordict.h
+ delete mode 100644 include/yaml-cpp/contrib/graphbuilder.h
+ delete mode 100644 install.txt
+ delete mode 100644 src/contrib/graphbuilder.cpp
+ delete mode 100644 src/contrib/graphbuilderadapter.cpp
+ delete mode 100644 src/contrib/graphbuilderadapter.h
+ delete mode 100644 src/contrib/yaml-cpp.natvis
+ delete mode 100644 src/contrib/yaml-cpp.natvis.md
+ delete mode 100644 test/BUILD.bazel
+ delete mode 100644 test/CMakeLists.txt
+ delete mode 100644 test/binary_test.cpp
+ delete mode 100644 test/create-emitter-tests.py
+ delete mode 100644 test/gtest-1.11.0/.clang-format
+ delete mode 100644 test/gtest-1.11.0/.github/ISSUE_TEMPLATE/00-bug_report.md
+ delete mode 100644 test/gtest-1.11.0/.github/ISSUE_TEMPLATE/10-feature_request.md
+ delete mode 100644 test/gtest-1.11.0/.github/ISSUE_TEMPLATE/config.yml
+ delete mode 100644 test/gtest-1.11.0/.gitignore
+ delete mode 100644 test/gtest-1.11.0/BUILD.bazel
+ delete mode 100644 test/gtest-1.11.0/CMakeLists.txt
+ delete mode 100644 test/gtest-1.11.0/CONTRIBUTING.md
+ delete mode 100644 test/gtest-1.11.0/CONTRIBUTORS
+ delete mode 100644 test/gtest-1.11.0/LICENSE
+ delete mode 100644 test/gtest-1.11.0/README.md
+ delete mode 100644 test/gtest-1.11.0/WORKSPACE
+ delete mode 100644 test/gtest-1.11.0/ci/linux-presubmit.sh
+ delete mode 100644 test/gtest-1.11.0/ci/macos-presubmit.sh
+ delete mode 100644 test/gtest-1.11.0/docs/_config.yml
+ delete mode 100644 test/gtest-1.11.0/docs/_data/navigation.yml
+ delete mode 100644 test/gtest-1.11.0/docs/_layouts/default.html
+ delete mode 100644 test/gtest-1.11.0/docs/_sass/main.scss
+ delete mode 100644 test/gtest-1.11.0/docs/advanced.md
+ delete mode 100644 test/gtest-1.11.0/docs/assets/css/style.scss
+ delete mode 100644 test/gtest-1.11.0/docs/community_created_documentation.md
+ delete mode 100644 test/gtest-1.11.0/docs/faq.md
+ delete mode 100644 test/gtest-1.11.0/docs/gmock_cheat_sheet.md
+ delete mode 100644 test/gtest-1.11.0/docs/gmock_cook_book.md
+ delete mode 100644 test/gtest-1.11.0/docs/gmock_faq.md
+ delete mode 100644 test/gtest-1.11.0/docs/gmock_for_dummies.md
+ delete mode 100644 test/gtest-1.11.0/docs/index.md
+ delete mode 100644 test/gtest-1.11.0/docs/pkgconfig.md
+ delete mode 100644 test/gtest-1.11.0/docs/platforms.md
+ delete mode 100644 test/gtest-1.11.0/docs/primer.md
+ delete mode 100644 test/gtest-1.11.0/docs/quickstart-bazel.md
+ delete mode 100644 test/gtest-1.11.0/docs/quickstart-cmake.md
+ delete mode 100644 test/gtest-1.11.0/docs/reference/actions.md
+ delete mode 100644 test/gtest-1.11.0/docs/reference/assertions.md
+ delete mode 100644 test/gtest-1.11.0/docs/reference/matchers.md
+ delete mode 100644 test/gtest-1.11.0/docs/reference/mocking.md
+ delete mode 100644 test/gtest-1.11.0/docs/reference/testing.md
+ delete mode 100644 test/gtest-1.11.0/docs/samples.md
+ delete mode 100644 test/gtest-1.11.0/googlemock/CMakeLists.txt
+ delete mode 100644 test/gtest-1.11.0/googlemock/README.md
+ delete mode 100644 test/gtest-1.11.0/googlemock/cmake/gmock.pc.in
+ delete mode 100644 test/gtest-1.11.0/googlemock/cmake/gmock_main.pc.in
+ delete mode 100644 test/gtest-1.11.0/googlemock/docs/README.md
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/gmock-actions.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/gmock-cardinalities.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/gmock-function-mocker.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/gmock-matchers.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/gmock-more-actions.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/gmock-more-matchers.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/gmock-nice-strict.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/gmock-spec-builders.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/gmock.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/internal/custom/README.md
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/internal/custom/gmock-matchers.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/internal/custom/gmock-port.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/internal/gmock-internal-utils.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/internal/gmock-port.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/include/gmock/internal/gmock-pp.h
+ delete mode 100644 test/gtest-1.11.0/googlemock/scripts/README.md
+ delete mode 100755 test/gtest-1.11.0/googlemock/scripts/fuse_gmock_files.py
+ delete mode 100644 test/gtest-1.11.0/googlemock/scripts/generator/LICENSE
+ delete mode 100644 test/gtest-1.11.0/googlemock/scripts/generator/README
+ delete mode 100644 test/gtest-1.11.0/googlemock/scripts/generator/README.cppclean
+ delete mode 100755 test/gtest-1.11.0/googlemock/scripts/generator/cpp/__init__.py
+ delete mode 100755 test/gtest-1.11.0/googlemock/scripts/generator/cpp/ast.py
+ delete mode 100755 test/gtest-1.11.0/googlemock/scripts/generator/cpp/gmock_class.py
+ delete mode 100755 test/gtest-1.11.0/googlemock/scripts/generator/cpp/gmock_class_test.py
+ delete mode 100755 test/gtest-1.11.0/googlemock/scripts/generator/cpp/keywords.py
+ delete mode 100755 test/gtest-1.11.0/googlemock/scripts/generator/cpp/tokenize.py
+ delete mode 100755 test/gtest-1.11.0/googlemock/scripts/generator/cpp/utils.py
+ delete mode 100755 test/gtest-1.11.0/googlemock/scripts/generator/gmock_gen.py
+ delete mode 100644 test/gtest-1.11.0/googlemock/src/gmock-all.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/src/gmock-cardinalities.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/src/gmock-internal-utils.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/src/gmock-matchers.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/src/gmock-spec-builders.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/src/gmock.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/src/gmock_main.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/BUILD.bazel
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-actions_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-cardinalities_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-function-mocker_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-internal-utils_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-matchers_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-more-actions_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-nice-strict_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-port_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-pp-string_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-pp_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock-spec-builders_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock_all_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock_ex_test.cc
+ delete mode 100755 test/gtest-1.11.0/googlemock/test/gmock_leak_test.py
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock_leak_test_.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock_link2_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock_link_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock_link_test.h
+ delete mode 100755 test/gtest-1.11.0/googlemock/test/gmock_output_test.py
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock_output_test_.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock_output_test_golden.txt
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock_stress_test.cc
+ delete mode 100644 test/gtest-1.11.0/googlemock/test/gmock_test.cc
+ delete mode 100755 test/gtest-1.11.0/googlemock/test/gmock_test_utils.py
+ delete mode 100644 test/gtest-1.11.0/googletest/CMakeLists.txt
+ delete mode 100644 test/gtest-1.11.0/googletest/README.md
+ delete mode 100644 test/gtest-1.11.0/googletest/cmake/Config.cmake.in
+ delete mode 100644 test/gtest-1.11.0/googletest/cmake/gtest.pc.in
+ delete mode 100644 test/gtest-1.11.0/googletest/cmake/gtest_main.pc.in
+ delete mode 100644 test/gtest-1.11.0/googletest/cmake/internal_utils.cmake
+ delete mode 100644 test/gtest-1.11.0/googletest/cmake/libgtest.la.in
+ delete mode 100644 test/gtest-1.11.0/googletest/docs/README.md
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest-death-test.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest-matchers.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest-message.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest-param-test.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest-printers.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest-spi.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest-test-part.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest-typed-test.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest_pred_impl.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/gtest_prod.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/custom/README.md
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/custom/gtest-port.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/custom/gtest-printers.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/custom/gtest.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/gtest-death-test-internal.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/gtest-filepath.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/gtest-internal.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/gtest-param-util.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/gtest-port-arch.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/gtest-port.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/gtest-string.h
+ delete mode 100644 test/gtest-1.11.0/googletest/include/gtest/internal/gtest-type-util.h
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/prime_tables.h
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample1.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample1.h
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample10_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample1_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample2.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample2.h
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample2_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample3-inl.h
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample3_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample4.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample4.h
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample4_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample5_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample6_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample7_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample8_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/samples/sample9_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/scripts/README.md
+ delete mode 100644 test/gtest-1.11.0/googletest/scripts/common.py
+ delete mode 100755 test/gtest-1.11.0/googletest/scripts/fuse_gtest_files.py
+ delete mode 100755 test/gtest-1.11.0/googletest/scripts/gen_gtest_pred_impl.py
+ delete mode 100755 test/gtest-1.11.0/googletest/scripts/gtest-config.in
+ delete mode 100755 test/gtest-1.11.0/googletest/scripts/release_docs.py
+ delete mode 100755 test/gtest-1.11.0/googletest/scripts/run_with_path.py
+ delete mode 100755 test/gtest-1.11.0/googletest/scripts/upload.py
+ delete mode 100755 test/gtest-1.11.0/googletest/scripts/upload_gtest.py
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest-all.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest-death-test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest-filepath.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest-internal-inl.h
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest-matchers.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest-port.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest-printers.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest-test-part.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest-typed-test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/src/gtest_main.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/BUILD.bazel
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-break-on-failure-unittest.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-break-on-failure-unittest_.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-catch-exceptions-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-catch-exceptions-test_.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-color-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-color-test_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-death-test-test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-death-test_ex_test.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-env-var-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-env-var-test_.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-failfast-unittest.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-failfast-unittest_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-filepath-test.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-filter-unittest.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-filter-unittest_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-global-environment-unittest.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-global-environment-unittest_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-json-outfiles-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-json-output-unittest.py
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-list-tests-unittest.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-list-tests-unittest_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-listener-test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-message-test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-options-test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-output-test-golden-lin.txt
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-output-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-output-test_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name1-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name1-test_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name2-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name2-test_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-param-test-test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-param-test-test.h
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-param-test2-test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-port-test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-printers-test.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-setuptestsuite-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-setuptestsuite-test_.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-shuffle-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-shuffle-test_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-test-part-test.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-throw-on-failure-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-throw-on-failure-test_.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/googletest-uninitialized-test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/googletest-uninitialized-test_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest-typed-test2_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest-typed-test_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest-typed-test_test.h
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest-unittest-api_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_all_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_assert_by_exception_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_environment_test.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/gtest_help_test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_help_test_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_json_test_utils.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_list_output_unittest.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_list_output_unittest_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_main_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_no_test_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_pred_impl_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_premature_exit_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_prod_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_repeat_test.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/gtest_skip_check_output_test.py
+ delete mode 100755 test/gtest-1.11.0/googletest/test/gtest_skip_environment_check_output_test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_skip_in_environment_setup_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_skip_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_sole_header_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_stress_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_test_macro_stack_footprint_test.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/gtest_test_utils.py
+ delete mode 100755 test/gtest-1.11.0/googletest/test/gtest_testbridge_test.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_testbridge_test_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_throw_on_failure_ex_test.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_unittest.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_xml_outfile1_test_.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_xml_outfile2_test_.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/gtest_xml_outfiles_test.py
+ delete mode 100755 test/gtest-1.11.0/googletest/test/gtest_xml_output_unittest.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/gtest_xml_output_unittest_.cc
+ delete mode 100755 test/gtest-1.11.0/googletest/test/gtest_xml_test_utils.py
+ delete mode 100644 test/gtest-1.11.0/googletest/test/production.cc
+ delete mode 100644 test/gtest-1.11.0/googletest/test/production.h
+ delete mode 100644 test/gtest-1.11.0/library.json
+ delete mode 100644 test/handler_test.h
+ delete mode 100644 test/integration/emitter_test.cpp
+ delete mode 100644 test/integration/encoding_test.cpp
+ delete mode 100644 test/integration/error_messages_test.cpp
+ delete mode 100644 test/integration/gen_emitter_test.cpp
+ delete mode 100644 test/integration/handler_spec_test.cpp
+ delete mode 100644 test/integration/handler_test.cpp
+ delete mode 100644 test/integration/load_node_test.cpp
+ delete mode 100644 test/integration/node_spec_test.cpp
+ delete mode 100644 test/main.cpp
+ delete mode 100644 test/mock_event_handler.h
+ delete mode 100644 test/node/node_test.cpp
+ delete mode 100644 test/ostream_wrapper_test.cpp
+ delete mode 100644 test/parser_test.cpp
+ delete mode 100644 test/regex_test.cpp
+ delete mode 100644 test/specexamples.h
+ delete mode 100644 util/CMakeLists.txt
+ delete mode 100644 util/api.cpp
+ delete mode 100644 util/parse.cpp
+ delete mode 100644 util/read.cpp
+ delete mode 100644 util/sandbox.cpp
+ delete mode 100644 yaml-cpp-config.cmake.in
+ delete mode 100644 yaml-cpp.pc.in
-diff --git a/src/libs/3rdparty/yaml-cpp/.codedocs b/src/libs/3rdparty/yaml-cpp/.codedocs
+diff --git a/.codedocs b/.codedocs
deleted file mode 100644
-index 02e438213a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/.gitignore b/src/libs/3rdparty/yaml-cpp/.gitignore
+index 02e4382..0000000
+diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
-index 567609b123..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/.travis.yml b/src/libs/3rdparty/yaml-cpp/.travis.yml
+index a408a9d..0000000
+diff --git a/.gitignore b/.gitignore
deleted file mode 100644
-index d0b6a04efe..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/CMakeLists.txt
+index 2f9d10f..0000000
+diff --git a/BUILD.bazel b/BUILD.bazel
deleted file mode 100644
-index d2d8810288..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/CONTRIBUTING.md b/src/libs/3rdparty/yaml-cpp/CONTRIBUTING.md
+index 23e847e..0000000
+diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
-index cd09a1aca8..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/anchordict.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/anchordict.h
+index 46dc180..0000000
+diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
-index 78db9ec928..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h
+index 5705fe2..0000000
+diff --git a/SECURITY.md b/SECURITY.md
deleted file mode 100644
-index f0a38f2887..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/install.txt b/src/libs/3rdparty/yaml-cpp/install.txt
+index 06a1751..0000000
+diff --git a/WORKSPACE b/WORKSPACE
deleted file mode 100644
-index 939236249b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilder.cpp b/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilder.cpp
+index d5ecc0b..0000000
+diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in
deleted file mode 100644
-index 416c1359db..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.cpp b/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.cpp
+index c2d34d4..0000000
+diff --git a/docs/Breaking-Changes.md b/docs/Breaking-Changes.md
deleted file mode 100644
-index 02a3d972a5..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.h b/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.h
+index 959adea..0000000
+diff --git a/docs/How-To-Emit-YAML.md b/docs/How-To-Emit-YAML.md
deleted file mode 100644
-index 0d1e579208..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/test/CMakeLists.txt
+index 9340701..0000000
+diff --git a/docs/How-To-Parse-A-Document-(Old-API).md b/docs/How-To-Parse-A-Document-(Old-API).md
deleted file mode 100644
-index 3633da578b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/create-emitter-tests.py b/src/libs/3rdparty/yaml-cpp/test/create-emitter-tests.py
+index 82fac71..0000000
+diff --git a/docs/Strings.md b/docs/Strings.md
deleted file mode 100644
-index 7a03c41e1b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.gitignore b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.gitignore
+index f2328a1..0000000
+diff --git a/docs/Tutorial.md b/docs/Tutorial.md
deleted file mode 100644
-index ce310bc357..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.travis.yml b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.travis.yml
+index a7b0e21..0000000
+diff --git a/docs/_config.yml b/docs/_config.yml
deleted file mode 100644
-index 3204dfac17..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/CMakeLists.txt
+index c741881..0000000
+diff --git a/docs/index.md b/docs/index.md
deleted file mode 100644
-index 8d2b552ef7..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/README.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/README.md
+index 17f1315..0000000
+diff --git a/include/yaml-cpp/contrib/anchordict.h b/include/yaml-cpp/contrib/anchordict.h
deleted file mode 100644
-index 076484e4fa..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/appveyor.yml b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/appveyor.yml
+index 1b7809b..0000000
+diff --git a/include/yaml-cpp/contrib/graphbuilder.h b/include/yaml-cpp/contrib/graphbuilder.h
deleted file mode 100644
-index d613fd6027..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CHANGES b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CHANGES
+index dbffd92..0000000
+diff --git a/install.txt b/install.txt
deleted file mode 100644
-index d6f2f760e3..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CMakeLists.txt
+index 9392362..0000000
+diff --git a/src/contrib/graphbuilder.cpp b/src/contrib/graphbuilder.cpp
deleted file mode 100644
-index beb259a2e9..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CONTRIBUTORS b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CONTRIBUTORS
+index 0352054..0000000
+diff --git a/src/contrib/graphbuilderadapter.cpp b/src/contrib/graphbuilderadapter.cpp
deleted file mode 100644
-index 6e9ae362b6..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/LICENSE b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/LICENSE
+index c386a92..0000000
+diff --git a/src/contrib/graphbuilderadapter.h b/src/contrib/graphbuilderadapter.h
deleted file mode 100644
-index 1941a11f8c..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/README.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/README.md
+index c1cbcff..0000000
+diff --git a/src/contrib/yaml-cpp.natvis b/src/contrib/yaml-cpp.natvis
deleted file mode 100644
-index 332beab388..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/build-aux/.keep b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/build-aux/.keep
+index d5c222b..0000000
+diff --git a/src/contrib/yaml-cpp.natvis.md b/src/contrib/yaml-cpp.natvis.md
deleted file mode 100644
-index e69de29bb2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/configure.ac b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/configure.ac
+index f1d68a8..0000000
+diff --git a/test/BUILD.bazel b/test/BUILD.bazel
deleted file mode 100644
-index 3b740f205e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CheatSheet.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CheatSheet.md
+index d30fa73..0000000
+diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
deleted file mode 100644
-index ef4451b878..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CookBook.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CookBook.md
+index 351b03f..0000000
+diff --git a/test/binary_test.cpp b/test/binary_test.cpp
deleted file mode 100644
-index c52f1009d1..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DesignDoc.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DesignDoc.md
+index 7b17823..0000000
+diff --git a/test/create-emitter-tests.py b/test/create-emitter-tests.py
deleted file mode 100644
-index 3f515c3b6d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DevGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DevGuide.md
+index 7295544..0000000
+diff --git a/test/gtest-1.11.0/.clang-format b/test/gtest-1.11.0/.clang-format
deleted file mode 100644
-index f4bab75ca7..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/Documentation.md
+index 5b9bfe6..0000000
+diff --git a/test/gtest-1.11.0/.github/ISSUE_TEMPLATE/00-bug_report.md b/test/gtest-1.11.0/.github/ISSUE_TEMPLATE/00-bug_report.md
deleted file mode 100644
-index 444151ee9e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/ForDummies.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/ForDummies.md
+index 0f7e8b5..0000000
+diff --git a/test/gtest-1.11.0/.github/ISSUE_TEMPLATE/10-feature_request.md b/test/gtest-1.11.0/.github/ISSUE_TEMPLATE/10-feature_request.md
deleted file mode 100644
-index 0da4cbe27b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/FrequentlyAskedQuestions.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/FrequentlyAskedQuestions.md
+index 70a3a20..0000000
+diff --git a/test/gtest-1.11.0/.github/ISSUE_TEMPLATE/config.yml b/test/gtest-1.11.0/.github/ISSUE_TEMPLATE/config.yml
deleted file mode 100644
-index 5eac83f4b9..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/KnownIssues.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/KnownIssues.md
+index 3ba13e0..0000000
+diff --git a/test/gtest-1.11.0/.gitignore b/test/gtest-1.11.0/.gitignore
deleted file mode 100644
-index adadf5144b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CheatSheet.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CheatSheet.md
+index f08cb72..0000000
+diff --git a/test/gtest-1.11.0/BUILD.bazel b/test/gtest-1.11.0/BUILD.bazel
deleted file mode 100644
-index 3c7bed4c6f..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CookBook.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CookBook.md
+index 965c518..0000000
+diff --git a/test/gtest-1.11.0/CMakeLists.txt b/test/gtest-1.11.0/CMakeLists.txt
deleted file mode 100644
-index 26e153c6ba..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/Documentation.md
+index ea81ab1..0000000
+diff --git a/test/gtest-1.11.0/CONTRIBUTING.md b/test/gtest-1.11.0/CONTRIBUTING.md
deleted file mode 100644
-index 315b0a2989..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/ForDummies.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/ForDummies.md
+index da45e44..0000000
+diff --git a/test/gtest-1.11.0/CONTRIBUTORS b/test/gtest-1.11.0/CONTRIBUTORS
deleted file mode 100644
-index fcc3b56174..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/FrequentlyAskedQuestions.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/FrequentlyAskedQuestions.md
+index 76db0b4..0000000
+diff --git a/test/gtest-1.11.0/LICENSE b/test/gtest-1.11.0/LICENSE
deleted file mode 100644
-index 7593243c3a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CheatSheet.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CheatSheet.md
+index 1941a11..0000000
+diff --git a/test/gtest-1.11.0/README.md b/test/gtest-1.11.0/README.md
deleted file mode 100644
-index 91de1d210e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CookBook.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CookBook.md
+index 7d872a5..0000000
+diff --git a/test/gtest-1.11.0/WORKSPACE b/test/gtest-1.11.0/WORKSPACE
deleted file mode 100644
-index f5975a0035..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/Documentation.md
+index 614f557..0000000
+diff --git a/test/gtest-1.11.0/ci/linux-presubmit.sh b/test/gtest-1.11.0/ci/linux-presubmit.sh
deleted file mode 100644
-index dcc9156c2a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/ForDummies.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/ForDummies.md
+index 6bea1cd..0000000
+diff --git a/test/gtest-1.11.0/ci/macos-presubmit.sh b/test/gtest-1.11.0/ci/macos-presubmit.sh
deleted file mode 100644
-index 19ee63ab0c..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/FrequentlyAskedQuestions.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/FrequentlyAskedQuestions.md
+index d6423fa..0000000
+diff --git a/test/gtest-1.11.0/docs/_config.yml b/test/gtest-1.11.0/docs/_config.yml
deleted file mode 100644
-index f74715d2e3..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CheatSheet.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CheatSheet.md
+index d12867e..0000000
+diff --git a/test/gtest-1.11.0/docs/_data/navigation.yml b/test/gtest-1.11.0/docs/_data/navigation.yml
deleted file mode 100644
-index db421e51be..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CookBook.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CookBook.md
+index 9f33327..0000000
+diff --git a/test/gtest-1.11.0/docs/_layouts/default.html b/test/gtest-1.11.0/docs/_layouts/default.html
deleted file mode 100644
-index 419a001071..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/Documentation.md
+index dcb42d9..0000000
+diff --git a/test/gtest-1.11.0/docs/_sass/main.scss b/test/gtest-1.11.0/docs/_sass/main.scss
deleted file mode 100644
-index d9181f28e1..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/ForDummies.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/ForDummies.md
+index 92edc87..0000000
+diff --git a/test/gtest-1.11.0/docs/advanced.md b/test/gtest-1.11.0/docs/advanced.md
deleted file mode 100644
-index ee03c5b989..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/FrequentlyAskedQuestions.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/FrequentlyAskedQuestions.md
+index 8dff5ba..0000000
+diff --git a/test/gtest-1.11.0/docs/assets/css/style.scss b/test/gtest-1.11.0/docs/assets/css/style.scss
deleted file mode 100644
-index fa21233aa2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-actions.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-actions.h
+index bb30f41..0000000
+diff --git a/test/gtest-1.11.0/docs/community_created_documentation.md b/test/gtest-1.11.0/docs/community_created_documentation.md
deleted file mode 100644
-index b3f654af34..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-cardinalities.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-cardinalities.h
+index 4569075..0000000
+diff --git a/test/gtest-1.11.0/docs/faq.md b/test/gtest-1.11.0/docs/faq.md
deleted file mode 100644
-index fc315f92ab..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h
+index 9042da1..0000000
+diff --git a/test/gtest-1.11.0/docs/gmock_cheat_sheet.md b/test/gtest-1.11.0/docs/gmock_cheat_sheet.md
deleted file mode 100644
-index b5a889c0c3..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h.pump
+index 17ed7a5..0000000
+diff --git a/test/gtest-1.11.0/docs/gmock_cook_book.md b/test/gtest-1.11.0/docs/gmock_cook_book.md
deleted file mode 100644
-index 66d9f9d551..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h
+index c08958e..0000000
+diff --git a/test/gtest-1.11.0/docs/gmock_faq.md b/test/gtest-1.11.0/docs/gmock_faq.md
deleted file mode 100644
-index 4fa5ca9484..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h.pump
+index 2cd9b3f..0000000
+diff --git a/test/gtest-1.11.0/docs/gmock_for_dummies.md b/test/gtest-1.11.0/docs/gmock_for_dummies.md
deleted file mode 100644
-index 811502d0ce..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h
+index 1f4cc24..0000000
+diff --git a/test/gtest-1.11.0/docs/index.md b/test/gtest-1.11.0/docs/index.md
deleted file mode 100644
-index 57056fd91d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h.pump
+index b162c74..0000000
+diff --git a/test/gtest-1.11.0/docs/pkgconfig.md b/test/gtest-1.11.0/docs/pkgconfig.md
deleted file mode 100644
-index de30c2c92b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h
+index 768e9b4..0000000
+diff --git a/test/gtest-1.11.0/docs/platforms.md b/test/gtest-1.11.0/docs/platforms.md
deleted file mode 100644
-index 4095f4d5bc..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h.pump
+index eba6ef8..0000000
+diff --git a/test/gtest-1.11.0/docs/primer.md b/test/gtest-1.11.0/docs/primer.md
deleted file mode 100644
-index 3ee1ce7f30..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-matchers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-matchers.h
+index 6d8fdf4..0000000
+diff --git a/test/gtest-1.11.0/docs/quickstart-bazel.md b/test/gtest-1.11.0/docs/quickstart-bazel.md
deleted file mode 100644
-index 33b37a7a5d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-actions.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-actions.h
+index 362ee6d..0000000
+diff --git a/test/gtest-1.11.0/docs/quickstart-cmake.md b/test/gtest-1.11.0/docs/quickstart-cmake.md
deleted file mode 100644
-index 3d387b6b7d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-matchers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-matchers.h
+index 420f1d3..0000000
+diff --git a/test/gtest-1.11.0/docs/reference/actions.md b/test/gtest-1.11.0/docs/reference/actions.md
deleted file mode 100644
-index 3db899f429..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-spec-builders.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-spec-builders.h
+index 166d2a8..0000000
+diff --git a/test/gtest-1.11.0/docs/reference/assertions.md b/test/gtest-1.11.0/docs/reference/assertions.md
deleted file mode 100644
-index fed7de66bc..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock.h
+index 7bf03a3..0000000
+diff --git a/test/gtest-1.11.0/docs/reference/matchers.md b/test/gtest-1.11.0/docs/reference/matchers.md
deleted file mode 100644
-index 6735c71bf8..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h
+index 9e40cab..0000000
+diff --git a/test/gtest-1.11.0/docs/reference/mocking.md b/test/gtest-1.11.0/docs/reference/mocking.md
deleted file mode 100644
-index 7dc3b1ad54..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump
+index c29f716..0000000
+diff --git a/test/gtest-1.11.0/docs/reference/testing.md b/test/gtest-1.11.0/docs/reference/testing.md
deleted file mode 100644
-index d26c8a08a4..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-matchers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-matchers.h
+index 554d6c9..0000000
+diff --git a/test/gtest-1.11.0/docs/samples.md b/test/gtest-1.11.0/docs/samples.md
deleted file mode 100644
-index f2efef91db..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-port.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-port.h
+index 2d97ca5..0000000
+diff --git a/test/gtest-1.11.0/googlemock/CMakeLists.txt b/test/gtest-1.11.0/googlemock/CMakeLists.txt
deleted file mode 100644
-index 9ce8bfe06b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h
+index e7df8ec..0000000
+diff --git a/test/gtest-1.11.0/googlemock/README.md b/test/gtest-1.11.0/googlemock/README.md
deleted file mode 100644
-index 7811e43f87..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump
+index ead6883..0000000
+diff --git a/test/gtest-1.11.0/googlemock/cmake/gmock.pc.in b/test/gtest-1.11.0/googlemock/cmake/gmock.pc.in
deleted file mode 100644
-index 800af17c1d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-internal-utils.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-internal-utils.h
+index 23c67b5..0000000
+diff --git a/test/gtest-1.11.0/googlemock/cmake/gmock_main.pc.in b/test/gtest-1.11.0/googlemock/cmake/gmock_main.pc.in
deleted file mode 100644
-index e2ddb05c91..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-port.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-port.h
+index 66ffea7..0000000
+diff --git a/test/gtest-1.11.0/googlemock/docs/README.md b/test/gtest-1.11.0/googlemock/docs/README.md
deleted file mode 100644
-index 63f4a6802e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2005/gmock_config.vsprops b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2005/gmock_config.vsprops
+index 1bc57b7..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/gmock-actions.h b/test/gtest-1.11.0/googlemock/include/gmock/gmock-actions.h
deleted file mode 100644
-index 9b5ff7f38a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2010/gmock_config.props b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2010/gmock_config.props
+index f2393bd..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/gmock-cardinalities.h b/test/gtest-1.11.0/googlemock/include/gmock/gmock-cardinalities.h
deleted file mode 100644
-index 77bc95b192..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2015/gmock_config.props b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2015/gmock_config.props
+index fc7f803..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/gmock-function-mocker.h b/test/gtest-1.11.0/googlemock/include/gmock/gmock-function-mocker.h
deleted file mode 100644
-index 77bc95b192..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/fuse_gmock_files.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/fuse_gmock_files.py
-deleted file mode 100755
-index cb7fdf2f78..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/LICENSE b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/LICENSE
-deleted file mode 100644
-index 87ea063651..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README
-deleted file mode 100644
-index d6f95974b6..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README.cppclean b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README.cppclean
-deleted file mode 100644
-index 65431b6175..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/__init__.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/__init__.py
-deleted file mode 100755
-index e69de29bb2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/ast.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/ast.py
-deleted file mode 100755
-index 11cbe9126a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class.py
-deleted file mode 100755
-index f9966cbb4b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class_test.py
-deleted file mode 100755
-index 018f90a650..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/keywords.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/keywords.py
-deleted file mode 100755
-index f694450e37..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/tokenize.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/tokenize.py
-deleted file mode 100755
-index 359d5562d7..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/utils.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/utils.py
-deleted file mode 100755
-index eab36eec33..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/gmock_gen.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/gmock_gen.py
-deleted file mode 100755
-index 8cc0d135d6..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock-config.in b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock-config.in
-deleted file mode 100755
-index 2baefe94d6..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock_doctor.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock_doctor.py
-deleted file mode 100755
-index 74992bc744..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload.py
-deleted file mode 100755
-index 6e6f9a1471..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload_gmock.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload_gmock.py
-deleted file mode 100755
-index 5dc484b391..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-all.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-all.cc
-deleted file mode 100644
-index 7aebce7afe..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-cardinalities.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-cardinalities.cc
-deleted file mode 100644
-index 50ec7286ee..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-internal-utils.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-internal-utils.cc
-deleted file mode 100644
-index fb5308018a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-matchers.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-matchers.cc
-deleted file mode 100644
-index e7424510fc..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-spec-builders.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-spec-builders.cc
+index 0fc6f6f..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/gmock-matchers.h b/test/gtest-1.11.0/googlemock/include/gmock/gmock-matchers.h
deleted file mode 100644
-index 9551342070..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock.cc
+index 86be9c1..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/gmock-more-actions.h b/test/gtest-1.11.0/googlemock/include/gmock/gmock-more-actions.h
deleted file mode 100644
-index eac3d842ba..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock_main.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock_main.cc
+index fd29335..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/gmock-more-matchers.h b/test/gtest-1.11.0/googlemock/include/gmock/gmock-more-matchers.h
deleted file mode 100644
-index bd5be03be2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-actions_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-actions_test.cc
+index dfc77e3..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/gmock-nice-strict.h b/test/gtest-1.11.0/googlemock/include/gmock/gmock-nice-strict.h
deleted file mode 100644
-index f470de4c55..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-cardinalities_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-cardinalities_test.cc
+index b03b770..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/gmock-spec-builders.h b/test/gtest-1.11.0/googlemock/include/gmock/gmock-spec-builders.h
deleted file mode 100644
-index 64815e57a3..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-actions_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-actions_test.cc
+index 41323c1..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/gmock.h b/test/gtest-1.11.0/googlemock/include/gmock/gmock.h
deleted file mode 100644
-index 5ca5bc7892..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-function-mockers_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-function-mockers_test.cc
+index 12469bc..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/internal/custom/README.md b/test/gtest-1.11.0/googlemock/include/gmock/internal/custom/README.md
deleted file mode 100644
-index a86a613578..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-internal-utils_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-internal-utils_test.cc
+index f6c93f6..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h b/test/gtest-1.11.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h
deleted file mode 100644
-index e0a535a346..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-matchers_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-matchers_test.cc
+index 63f8999..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/internal/custom/gmock-matchers.h b/test/gtest-1.11.0/googlemock/include/gmock/internal/custom/gmock-matchers.h
deleted file mode 100644
-index 0e9f77f5eb..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-internal-utils_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-internal-utils_test.cc
+index 6384294..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/internal/custom/gmock-port.h b/test/gtest-1.11.0/googlemock/include/gmock/internal/custom/gmock-port.h
deleted file mode 100644
-index 9d5ec60927..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-matchers_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-matchers_test.cc
+index 1437869..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/internal/gmock-internal-utils.h b/test/gtest-1.11.0/googlemock/include/gmock/internal/gmock-internal-utils.h
deleted file mode 100644
-index 9f62c3d826..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-more-actions_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-more-actions_test.cc
+index 317544a..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/internal/gmock-port.h b/test/gtest-1.11.0/googlemock/include/gmock/internal/gmock-port.h
deleted file mode 100644
-index 77e15bd586..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-nice-strict_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-nice-strict_test.cc
+index 367a44d..0000000
+diff --git a/test/gtest-1.11.0/googlemock/include/gmock/internal/gmock-pp.h b/test/gtest-1.11.0/googlemock/include/gmock/internal/gmock-pp.h
deleted file mode 100644
-index d0adcbbed8..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-port_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-port_test.cc
+index 94d61c0..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/README.md b/test/gtest-1.11.0/googlemock/scripts/README.md
deleted file mode 100644
-index d6a8d44466..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-spec-builders_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-spec-builders_test.cc
-deleted file mode 100644
-index 59ea87c894..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_all_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_all_test.cc
-deleted file mode 100644
-index 56d6c49ccc..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_ex_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_ex_test.cc
-deleted file mode 100644
-index 3afed86ab9..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test.py
+index a3301e5..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/fuse_gmock_files.py b/test/gtest-1.11.0/googlemock/scripts/fuse_gmock_files.py
deleted file mode 100755
-index 997680ce1a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test_.cc
+index 7fa9b3a..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/LICENSE b/test/gtest-1.11.0/googlemock/scripts/generator/LICENSE
deleted file mode 100644
-index 1d27d22f62..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link2_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link2_test.cc
+index 87ea063..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/README b/test/gtest-1.11.0/googlemock/scripts/generator/README
deleted file mode 100644
-index 4c310c3d83..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.cc
+index 01fd463..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/README.cppclean b/test/gtest-1.11.0/googlemock/scripts/generator/README.cppclean
deleted file mode 100644
-index 61e97d10ca..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.h
-deleted file mode 100644
-index 1f55f5bd7f..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test.py
+index 65431b6..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/cpp/__init__.py b/test/gtest-1.11.0/googlemock/scripts/generator/cpp/__init__.py
deleted file mode 100755
-index eced8a81f2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_.cc
-deleted file mode 100644
-index 44cba342ad..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_golden.txt b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_golden.txt
-deleted file mode 100644
-index 689d5eeb03..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_stress_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_stress_test.cc
-deleted file mode 100644
-index 0e97aeed0b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test.cc
-deleted file mode 100644
-index d8d0c57b16..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test_utils.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test_utils.py
+index e69de29..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/cpp/ast.py b/test/gtest-1.11.0/googlemock/scripts/generator/cpp/ast.py
+deleted file mode 100755
+index 0e77016..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/cpp/gmock_class.py b/test/gtest-1.11.0/googlemock/scripts/generator/cpp/gmock_class.py
+deleted file mode 100755
+index 3e21022..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/cpp/gmock_class_test.py b/test/gtest-1.11.0/googlemock/scripts/generator/cpp/gmock_class_test.py
deleted file mode 100755
-index 20e3d3d446..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/.gitignore b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/.gitignore
+index eff475f..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/cpp/keywords.py b/test/gtest-1.11.0/googlemock/scripts/generator/cpp/keywords.py
+deleted file mode 100755
+index e428271..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/cpp/tokenize.py b/test/gtest-1.11.0/googlemock/scripts/generator/cpp/tokenize.py
+deleted file mode 100755
+index a75edcb..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/cpp/utils.py b/test/gtest-1.11.0/googlemock/scripts/generator/cpp/utils.py
+deleted file mode 100755
+index 6f5fc09..0000000
+diff --git a/test/gtest-1.11.0/googlemock/scripts/generator/gmock_gen.py b/test/gtest-1.11.0/googlemock/scripts/generator/gmock_gen.py
+deleted file mode 100755
+index 9d528a5..0000000
+diff --git a/test/gtest-1.11.0/googlemock/src/gmock-all.cc b/test/gtest-1.11.0/googlemock/src/gmock-all.cc
deleted file mode 100644
-index 4b7be4b91b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CHANGES b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CHANGES
+index e43c9b7..0000000
+diff --git a/test/gtest-1.11.0/googlemock/src/gmock-cardinalities.cc b/test/gtest-1.11.0/googlemock/src/gmock-cardinalities.cc
deleted file mode 100644
-index 0552132421..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CMakeLists.txt
+index 7463f43..0000000
+diff --git a/test/gtest-1.11.0/googlemock/src/gmock-internal-utils.cc b/test/gtest-1.11.0/googlemock/src/gmock-internal-utils.cc
deleted file mode 100644
-index 621d0f0421..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CONTRIBUTORS b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CONTRIBUTORS
+index e5b5479..0000000
+diff --git a/test/gtest-1.11.0/googlemock/src/gmock-matchers.cc b/test/gtest-1.11.0/googlemock/src/gmock-matchers.cc
deleted file mode 100644
-index feae2fc044..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/LICENSE b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/LICENSE
+index dded437..0000000
+diff --git a/test/gtest-1.11.0/googlemock/src/gmock-spec-builders.cc b/test/gtest-1.11.0/googlemock/src/gmock-spec-builders.cc
deleted file mode 100644
-index 1941a11f8c..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/README.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/README.md
+index c7266a3..0000000
+diff --git a/test/gtest-1.11.0/googlemock/src/gmock.cc b/test/gtest-1.11.0/googlemock/src/gmock.cc
deleted file mode 100644
-index edd4408054..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/build-aux/.keep b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/build-aux/.keep
+index 7bcdb0b..0000000
+diff --git a/test/gtest-1.11.0/googlemock/src/gmock_main.cc b/test/gtest-1.11.0/googlemock/src/gmock_main.cc
deleted file mode 100644
-index e69de29bb2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/cmake/internal_utils.cmake b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/cmake/internal_utils.cmake
+index 18c500f..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/BUILD.bazel b/test/gtest-1.11.0/googlemock/test/BUILD.bazel
deleted file mode 100644
-index 777b91ed4b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.cbproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.cbproj
+index efb7306..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-actions_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-actions_test.cc
deleted file mode 100644
-index 285bb2a87b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.groupproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.groupproj
+index e1ca7fe..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-cardinalities_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-cardinalities_test.cc
deleted file mode 100644
-index 849f4c4b81..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_all.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_all.cc
+index ca97cae..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-function-mocker_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-function-mocker_test.cc
deleted file mode 100644
-index ba7ad68ad1..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_link.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_link.cc
+index cf76fa9..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-internal-utils_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-internal-utils_test.cc
deleted file mode 100644
-index b955ebf2f9..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_main.cbproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_main.cbproj
+index 0d15e8f..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-matchers_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-matchers_test.cc
deleted file mode 100644
-index fae32cb29b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_unittest.cbproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_unittest.cbproj
+index 1f48a76..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-more-actions_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-more-actions_test.cc
deleted file mode 100644
-index 33f7056346..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/configure.ac b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/configure.ac
+index 53bb029..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-nice-strict_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-nice-strict_test.cc
deleted file mode 100644
-index cc592e1583..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/AdvancedGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/AdvancedGuide.md
+index 25558eb..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-port_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-port_test.cc
deleted file mode 100644
-index 93a65200da..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/DevGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/DevGuide.md
+index a2c2be2..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-pp-string_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-pp-string_test.cc
deleted file mode 100644
-index 06467a3277..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Documentation.md
+index 6f66cf1..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-pp_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-pp_test.cc
deleted file mode 100644
-index 8ca1aac759..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/FAQ.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/FAQ.md
+index 5d1566e..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock-spec-builders_test.cc b/test/gtest-1.11.0/googlemock/test/gmock-spec-builders_test.cc
deleted file mode 100644
-index 5fd6cb7238..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Primer.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Primer.md
+index fa97411..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_all_test.cc b/test/gtest-1.11.0/googlemock/test/gmock_all_test.cc
deleted file mode 100644
-index 474c1d2ab6..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/PumpManual.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/PumpManual.md
+index fffbb8b..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_ex_test.cc b/test/gtest-1.11.0/googlemock/test/gmock_ex_test.cc
deleted file mode 100644
-index 8184f153ca..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Samples.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Samples.md
+index 72eb43f..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_leak_test.py b/test/gtest-1.11.0/googlemock/test/gmock_leak_test.py
+deleted file mode 100755
+index 7e4b1ee..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_leak_test_.cc b/test/gtest-1.11.0/googlemock/test/gmock_leak_test_.cc
deleted file mode 100644
-index f21d200567..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_AdvancedGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_AdvancedGuide.md
+index 2e095ab..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_link2_test.cc b/test/gtest-1.11.0/googlemock/test/gmock_link2_test.cc
deleted file mode 100644
-index 34e19c26fd..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Documentation.md
+index d27ce17..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_link_test.cc b/test/gtest-1.11.0/googlemock/test/gmock_link_test.cc
deleted file mode 100644
-index 46bba2ec86..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_FAQ.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_FAQ.md
+index e7c54cc..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_link_test.h b/test/gtest-1.11.0/googlemock/test/gmock_link_test.h
deleted file mode 100644
-index e870aff000..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Primer.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Primer.md
+index 5734b2e..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_output_test.py b/test/gtest-1.11.0/googlemock/test/gmock_output_test.py
+deleted file mode 100755
+index 25f99f2..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_output_test_.cc b/test/gtest-1.11.0/googlemock/test/gmock_output_test_.cc
deleted file mode 100644
-index 6960d2ce4c..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_PumpManual.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_PumpManual.md
+index 3955c73..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_output_test_golden.txt b/test/gtest-1.11.0/googlemock/test/gmock_output_test_golden.txt
deleted file mode 100644
-index 15710789dd..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_XcodeGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_XcodeGuide.md
+index 4846c12..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_stress_test.cc b/test/gtest-1.11.0/googlemock/test/gmock_stress_test.cc
deleted file mode 100644
-index bf24bf51bf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_AdvancedGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_AdvancedGuide.md
+index 20725d6..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_test.cc b/test/gtest-1.11.0/googlemock/test/gmock_test.cc
deleted file mode 100644
-index 78864b1667..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Documentation.md
+index e9840a3..0000000
+diff --git a/test/gtest-1.11.0/googlemock/test/gmock_test_utils.py b/test/gtest-1.11.0/googlemock/test/gmock_test_utils.py
+deleted file mode 100755
+index 7dc4e11..0000000
+diff --git a/test/gtest-1.11.0/googletest/CMakeLists.txt b/test/gtest-1.11.0/googletest/CMakeLists.txt
deleted file mode 100644
-index ca924660a3..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_FAQ.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_FAQ.md
+index abdd98b..0000000
+diff --git a/test/gtest-1.11.0/googletest/README.md b/test/gtest-1.11.0/googletest/README.md
deleted file mode 100644
-index 2b7f784077..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Primer.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Primer.md
+index 1f8b349..0000000
+diff --git a/test/gtest-1.11.0/googletest/cmake/Config.cmake.in b/test/gtest-1.11.0/googletest/cmake/Config.cmake.in
deleted file mode 100644
-index 8d840ef45b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_PumpManual.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_PumpManual.md
+index 12be449..0000000
+diff --git a/test/gtest-1.11.0/googletest/cmake/gtest.pc.in b/test/gtest-1.11.0/googletest/cmake/gtest.pc.in
deleted file mode 100644
-index 8184f153ca..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Samples.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Samples.md
+index b4148fa..0000000
+diff --git a/test/gtest-1.11.0/googletest/cmake/gtest_main.pc.in b/test/gtest-1.11.0/googletest/cmake/gtest_main.pc.in
deleted file mode 100644
-index f21d200567..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_XcodeGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_XcodeGuide.md
+index 38c88c5..0000000
+diff --git a/test/gtest-1.11.0/googletest/cmake/internal_utils.cmake b/test/gtest-1.11.0/googletest/cmake/internal_utils.cmake
deleted file mode 100644
-index bf24bf51bf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_AdvancedGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_AdvancedGuide.md
+index 8d8d60a..0000000
+diff --git a/test/gtest-1.11.0/googletest/cmake/libgtest.la.in b/test/gtest-1.11.0/googletest/cmake/libgtest.la.in
deleted file mode 100644
-index dd4af8f366..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Documentation.md
+index 840c838..0000000
+diff --git a/test/gtest-1.11.0/googletest/docs/README.md b/test/gtest-1.11.0/googletest/docs/README.md
deleted file mode 100644
-index 282697a50b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_FAQ.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_FAQ.md
+index 1bc57b7..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest-death-test.h b/test/gtest-1.11.0/googletest/include/gtest/gtest-death-test.h
deleted file mode 100644
-index 3dd914dcf1..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Primer.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Primer.md
+index 9b4d4d1..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest-matchers.h b/test/gtest-1.11.0/googletest/include/gtest/gtest-matchers.h
deleted file mode 100644
-index b1827c7355..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_PumpManual.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_PumpManual.md
+index 9fa34a0..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest-message.h b/test/gtest-1.11.0/googletest/include/gtest/gtest-message.h
deleted file mode 100644
-index 8184f153ca..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Samples.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Samples.md
+index becfd49..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest-param-test.h b/test/gtest-1.11.0/googletest/include/gtest/gtest-param-test.h
deleted file mode 100644
-index f21d200567..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_XcodeGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_XcodeGuide.md
+index 804e702..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest-printers.h b/test/gtest-1.11.0/googletest/include/gtest/gtest-printers.h
deleted file mode 100644
-index bf24bf51bf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/XcodeGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/XcodeGuide.md
+index 076c9de..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest-spi.h b/test/gtest-1.11.0/googletest/include/gtest/gtest-spi.h
deleted file mode 100644
-index bf24bf51bf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-death-test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-death-test.h
+index eacef44..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest-test-part.h b/test/gtest-1.11.0/googletest/include/gtest/gtest-test-part.h
deleted file mode 100644
-index 957a69c6a9..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-message.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-message.h
+index 203fdf9..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest-typed-test.h b/test/gtest-1.11.0/googletest/include/gtest/gtest-typed-test.h
deleted file mode 100644
-index fe879bca79..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h
+index 9fdc6be..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest.h b/test/gtest-1.11.0/googletest/include/gtest/gtest.h
deleted file mode 100644
-index 038f9ba79e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h.pump
+index 7a5d057..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest_pred_impl.h b/test/gtest-1.11.0/googletest/include/gtest/gtest_pred_impl.h
deleted file mode 100644
-index 3078d6d2a1..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-printers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-printers.h
+index 5029a9b..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/gtest_prod.h b/test/gtest-1.11.0/googletest/include/gtest/gtest_prod.h
deleted file mode 100644
-index 8a33164cb3..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-spi.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-spi.h
+index 38b9d85..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/custom/README.md b/test/gtest-1.11.0/googletest/include/gtest/internal/custom/README.md
deleted file mode 100644
-index f63fa9a1b2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-test-part.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-test-part.h
+index ff391fb..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/custom/gtest-port.h b/test/gtest-1.11.0/googletest/include/gtest/internal/custom/gtest-port.h
deleted file mode 100644
-index 77eb844839..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-typed-test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-typed-test.h
+index db02881..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/custom/gtest-printers.h b/test/gtest-1.11.0/googletest/include/gtest/internal/custom/gtest-printers.h
deleted file mode 100644
-index 5f69d5678e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest.h
+index b9495d8..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/custom/gtest.h b/test/gtest-1.11.0/googletest/include/gtest/internal/custom/gtest.h
deleted file mode 100644
-index f846c5bd66..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_pred_impl.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_pred_impl.h
+index afaaf17..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-death-test-internal.h b/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-death-test-internal.h
deleted file mode 100644
-index 30ae712f50..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_prod.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_prod.h
+index 490296d..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-filepath.h b/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-filepath.h
deleted file mode 100644
-index da80ddc6c7..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-port.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-port.h
+index 0c033ab..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-internal.h b/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-internal.h
deleted file mode 100644
-index 7e744bd3bb..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-printers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-printers.h
+index f8cbdbd..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-param-util.h b/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-param-util.h
deleted file mode 100644
-index 60c1ea050b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest.h
+index c2ef6e3..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-port-arch.h b/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-port-arch.h
deleted file mode 100644
-index c27412a898..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-death-test-internal.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-death-test-internal.h
+index dd84591..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-port.h b/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-port.h
deleted file mode 100644
-index 2b3a78f5bf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-filepath.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-filepath.h
+index 0953a78..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-string.h b/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-string.h
deleted file mode 100644
-index 7a13b4b0de..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-internal.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-internal.h
+index 10f774f..0000000
+diff --git a/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-type-util.h b/test/gtest-1.11.0/googletest/include/gtest/internal/gtest-type-util.h
deleted file mode 100644
-index ebd1cf615d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-linked_ptr.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-linked_ptr.h
+index b87a2e2..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/prime_tables.h b/test/gtest-1.11.0/googletest/samples/prime_tables.h
deleted file mode 100644
-index 3602942217..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h
+index 3a10352..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample1.cc b/test/gtest-1.11.0/googletest/samples/sample1.cc
deleted file mode 100644
-index 4d1d81d20f..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h.pump
+index 1d42759..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample1.h b/test/gtest-1.11.0/googletest/samples/sample1.h
deleted file mode 100644
-index 5c7c47af0b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util.h
+index ba392cf..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample10_unittest.cc b/test/gtest-1.11.0/googletest/samples/sample10_unittest.cc
deleted file mode 100644
-index 82cab9b020..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port-arch.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port-arch.h
+index 36cdac2..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample1_unittest.cc b/test/gtest-1.11.0/googletest/samples/sample1_unittest.cc
deleted file mode 100644
-index 74ab949057..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port.h
+index cb08b61..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample2.cc b/test/gtest-1.11.0/googletest/samples/sample2.cc
deleted file mode 100644
-index 0094ed5077..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-string.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-string.h
+index d8e8723..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample2.h b/test/gtest-1.11.0/googletest/samples/sample2.h
deleted file mode 100644
-index 97f1a7fdd2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h
+index 0f98689..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample2_unittest.cc b/test/gtest-1.11.0/googletest/samples/sample2_unittest.cc
deleted file mode 100644
-index e9b405340a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h.pump
+index 41e31c1..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample3-inl.h b/test/gtest-1.11.0/googletest/samples/sample3-inl.h
deleted file mode 100644
-index 429ddfeeca..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h
+index 659e0f0..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample3_unittest.cc b/test/gtest-1.11.0/googletest/samples/sample3_unittest.cc
deleted file mode 100644
-index e46f7cfcb4..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h.pump
+index b19416d..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample4.cc b/test/gtest-1.11.0/googletest/samples/sample4.cc
deleted file mode 100644
-index 251fdf025b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/acx_pthread.m4 b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/acx_pthread.m4
+index b0ee609..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample4.h b/test/gtest-1.11.0/googletest/samples/sample4.h
deleted file mode 100644
-index 2cf20de144..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/gtest.m4 b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/gtest.m4
+index 0c4ed92..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample4_unittest.cc b/test/gtest-1.11.0/googletest/samples/sample4_unittest.cc
deleted file mode 100644
-index 6598ba75a4..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/prime_tables.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/prime_tables.h
+index d5144c0..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample5_unittest.cc b/test/gtest-1.11.0/googletest/samples/sample5_unittest.cc
deleted file mode 100644
-index 92ce16a014..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.cc
+index 0a21dd2..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample6_unittest.cc b/test/gtest-1.11.0/googletest/samples/sample6_unittest.cc
deleted file mode 100644
-index f171e2609d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.h
+index da317ee..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample7_unittest.cc b/test/gtest-1.11.0/googletest/samples/sample7_unittest.cc
deleted file mode 100644
-index 3dfeb98c45..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample10_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample10_unittest.cc
+index e0efc29..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample8_unittest.cc b/test/gtest-1.11.0/googletest/samples/sample8_unittest.cc
deleted file mode 100644
-index 0051cd5dcd..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1_unittest.cc
+index 10488b0..0000000
+diff --git a/test/gtest-1.11.0/googletest/samples/sample9_unittest.cc b/test/gtest-1.11.0/googletest/samples/sample9_unittest.cc
deleted file mode 100644
-index aefc4f1d86..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.cc
+index e502d08..0000000
+diff --git a/test/gtest-1.11.0/googletest/scripts/README.md b/test/gtest-1.11.0/googletest/scripts/README.md
deleted file mode 100644
-index 5f763b9bdf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.h
+index fa359fe..0000000
+diff --git a/test/gtest-1.11.0/googletest/scripts/common.py b/test/gtest-1.11.0/googletest/scripts/common.py
deleted file mode 100644
-index cb485c70fb..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2_unittest.cc
+index 3c0347a..0000000
+diff --git a/test/gtest-1.11.0/googletest/scripts/fuse_gtest_files.py b/test/gtest-1.11.0/googletest/scripts/fuse_gtest_files.py
+deleted file mode 100755
+index d0dd464..0000000
+diff --git a/test/gtest-1.11.0/googletest/scripts/gen_gtest_pred_impl.py b/test/gtest-1.11.0/googletest/scripts/gen_gtest_pred_impl.py
+deleted file mode 100755
+index e09a6e0..0000000
+diff --git a/test/gtest-1.11.0/googletest/scripts/gtest-config.in b/test/gtest-1.11.0/googletest/scripts/gtest-config.in
+deleted file mode 100755
+index 780f843..0000000
+diff --git a/test/gtest-1.11.0/googletest/scripts/release_docs.py b/test/gtest-1.11.0/googletest/scripts/release_docs.py
+deleted file mode 100755
+index 8d24f28..0000000
+diff --git a/test/gtest-1.11.0/googletest/scripts/run_with_path.py b/test/gtest-1.11.0/googletest/scripts/run_with_path.py
+deleted file mode 100755
+index d46ab4d..0000000
+diff --git a/test/gtest-1.11.0/googletest/scripts/upload.py b/test/gtest-1.11.0/googletest/scripts/upload.py
+deleted file mode 100755
+index eba5711..0000000
+diff --git a/test/gtest-1.11.0/googletest/scripts/upload_gtest.py b/test/gtest-1.11.0/googletest/scripts/upload_gtest.py
+deleted file mode 100755
+index be19ae8..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest-all.cc b/test/gtest-1.11.0/googletest/src/gtest-all.cc
deleted file mode 100644
-index 4fa19b71c7..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3-inl.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3-inl.h
+index ad29290..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest-death-test.cc b/test/gtest-1.11.0/googletest/src/gtest-death-test.cc
deleted file mode 100644
-index 7e3084d638..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3_unittest.cc
+index bf4f633..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest-filepath.cc b/test/gtest-1.11.0/googletest/src/gtest-filepath.cc
deleted file mode 100644
-index bf3877d013..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.cc
+index 0b56294..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest-internal-inl.h b/test/gtest-1.11.0/googletest/src/gtest-internal-inl.h
deleted file mode 100644
-index ae44bda6f1..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.h
+index 6d8cecb..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest-matchers.cc b/test/gtest-1.11.0/googletest/src/gtest-matchers.cc
deleted file mode 100644
-index cd60f0dd2d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4_unittest.cc
+index 65104eb..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest-port.cc b/test/gtest-1.11.0/googletest/src/gtest-port.cc
deleted file mode 100644
-index fa5afc7d5a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample5_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample5_unittest.cc
+index 53a4d37..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest-printers.cc b/test/gtest-1.11.0/googletest/src/gtest-printers.cc
deleted file mode 100644
-index 43d8e57775..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample6_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample6_unittest.cc
+index 1b68fcb..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest-test-part.cc b/test/gtest-1.11.0/googletest/src/gtest-test-part.cc
deleted file mode 100644
-index 8f2036a516..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample7_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample7_unittest.cc
+index a938683..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest-typed-test.cc b/test/gtest-1.11.0/googletest/src/gtest-typed-test.cc
deleted file mode 100644
-index 1b651a21d6..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample8_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample8_unittest.cc
+index c02c3df..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest.cc b/test/gtest-1.11.0/googletest/src/gtest.cc
deleted file mode 100644
-index 7274334067..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample9_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample9_unittest.cc
+index 21c611a..0000000
+diff --git a/test/gtest-1.11.0/googletest/src/gtest_main.cc b/test/gtest-1.11.0/googletest/src/gtest_main.cc
deleted file mode 100644
-index b2e2079bf3..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/common.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/common.py
+index 46b27c3..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/BUILD.bazel b/test/gtest-1.11.0/googletest/test/BUILD.bazel
deleted file mode 100644
-index 3c0347a75b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/fuse_gtest_files.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/fuse_gtest_files.py
-deleted file mode 100755
-index 3f3e9f36d6..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gen_gtest_pred_impl.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gen_gtest_pred_impl.py
-deleted file mode 100755
-index 3e7ab042ea..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gtest-config.in b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gtest-config.in
-deleted file mode 100755
-index 780f8432ef..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/pump.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/pump.py
-deleted file mode 100755
-index 5efb653c20..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/release_docs.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/release_docs.py
-deleted file mode 100755
-index 1291347f67..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload.py
-deleted file mode 100755
-index 6e6f9a1471..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload_gtest.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload_gtest.py
+index b06a00a..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-break-on-failure-unittest.py b/test/gtest-1.11.0/googletest/test/googletest-break-on-failure-unittest.py
deleted file mode 100755
-index be19ae8091..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-all.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-all.cc
+index a5dfbc6..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-break-on-failure-unittest_.cc b/test/gtest-1.11.0/googletest/test/googletest-break-on-failure-unittest_.cc
deleted file mode 100644
-index 0a9cee5223..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-death-test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-death-test.cc
-deleted file mode 100644
-index a01a369830..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-filepath.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-filepath.cc
-deleted file mode 100644
-index 0292dc1195..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-internal-inl.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-internal-inl.h
-deleted file mode 100644
-index ed8a682a96..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-port.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-port.cc
+index f84957a..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-catch-exceptions-test.py b/test/gtest-1.11.0/googletest/test/googletest-catch-exceptions-test.py
+deleted file mode 100755
+index 94a5b33..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-catch-exceptions-test_.cc b/test/gtest-1.11.0/googletest/test/googletest-catch-exceptions-test_.cc
deleted file mode 100644
-index e5bf3dd2be..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-printers.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-printers.cc
+index 8c127d4..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-color-test.py b/test/gtest-1.11.0/googletest/test/googletest-color-test.py
+deleted file mode 100755
+index f3b7c99..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-color-test_.cc b/test/gtest-1.11.0/googletest/test/googletest-color-test_.cc
deleted file mode 100644
-index a2df412f8a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-test-part.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-test-part.cc
+index 220a3a0..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-death-test-test.cc b/test/gtest-1.11.0/googletest/test/googletest-death-test-test.cc
deleted file mode 100644
-index fb0e35425e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-typed-test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-typed-test.cc
+index c0b3d1f..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-death-test_ex_test.cc b/test/gtest-1.11.0/googletest/test/googletest-death-test_ex_test.cc
deleted file mode 100644
-index df1eef4754..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest.cc
+index 7219680..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-env-var-test.py b/test/gtest-1.11.0/googletest/test/googletest-env-var-test.py
+deleted file mode 100755
+index 02c3655..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-env-var-test_.cc b/test/gtest-1.11.0/googletest/test/googletest-env-var-test_.cc
deleted file mode 100644
-index d882ab2e36..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest_main.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest_main.cc
+index 52f9586..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-failfast-unittest.py b/test/gtest-1.11.0/googletest/test/googletest-failfast-unittest.py
+deleted file mode 100755
+index 3aeb2df..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-failfast-unittest_.cc b/test/gtest-1.11.0/googletest/test/googletest-failfast-unittest_.cc
deleted file mode 100644
-index f302822552..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_ex_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_ex_test.cc
+index 0b2c951..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-filepath-test.cc b/test/gtest-1.11.0/googletest/test/googletest-filepath-test.cc
deleted file mode 100644
-index b50a13d5e2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_test.cc
+index aafad36..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-filter-unittest.py b/test/gtest-1.11.0/googletest/test/googletest-filter-unittest.py
+deleted file mode 100755
+index 6b32f2d..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-filter-unittest_.cc b/test/gtest-1.11.0/googletest/test/googletest-filter-unittest_.cc
deleted file mode 100644
-index bb4a3d1b38..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-filepath_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-filepath_test.cc
+index d30ec9c..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-global-environment-unittest.py b/test/gtest-1.11.0/googletest/test/googletest-global-environment-unittest.py
deleted file mode 100644
-index da72986926..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-linked_ptr_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-linked_ptr_test.cc
+index 32ba628..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-global-environment-unittest_.cc b/test/gtest-1.11.0/googletest/test/googletest-global-environment-unittest_.cc
deleted file mode 100644
-index 6fcf5124a8..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-listener_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-listener_test.cc
+index f401b2f..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-json-outfiles-test.py b/test/gtest-1.11.0/googletest/test/googletest-json-outfiles-test.py
deleted file mode 100644
-index 90747685f0..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-message_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-message_test.cc
+index 8ef47b8..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-json-output-unittest.py b/test/gtest-1.11.0/googletest/test/googletest-json-output-unittest.py
deleted file mode 100644
-index 175238ef4e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-options_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-options_test.cc
+index 41c8565..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-list-tests-unittest.py b/test/gtest-1.11.0/googletest/test/googletest-list-tests-unittest.py
+deleted file mode 100755
+index 81423a3..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-list-tests-unittest_.cc b/test/gtest-1.11.0/googletest/test/googletest-list-tests-unittest_.cc
deleted file mode 100644
-index 5586dc3b1b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test2_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test2_test.cc
+index 493c6f0..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-listener-test.cc b/test/gtest-1.11.0/googletest/test/googletest-listener-test.cc
deleted file mode 100644
-index 4a782fe708..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.cc
+index 10457af..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-message-test.cc b/test/gtest-1.11.0/googletest/test/googletest-message-test.cc
deleted file mode 100644
-index 8b278bb94b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.h
+index 962d519..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-options-test.cc b/test/gtest-1.11.0/googletest/test/googletest-options-test.cc
deleted file mode 100644
-index 26ea122b10..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-port_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-port_test.cc
+index 11fb1f2..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-output-test-golden-lin.txt b/test/gtest-1.11.0/googletest/test/googletest-output-test-golden-lin.txt
deleted file mode 100644
-index 6ea607bc70..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-printers_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-printers_test.cc
+index 3fab3b9..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-output-test.py b/test/gtest-1.11.0/googletest/test/googletest-output-test.py
+deleted file mode 100755
+index 09028f6..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-output-test_.cc b/test/gtest-1.11.0/googletest/test/googletest-output-test_.cc
deleted file mode 100644
-index 3e97cc24ab..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-test-part_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-test-part_test.cc
+index 074f64e..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name1-test.py b/test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name1-test.py
deleted file mode 100644
-index ca8ba933ae..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-tuple_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-tuple_test.cc
+index 2a08477..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name1-test_.cc b/test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name1-test_.cc
deleted file mode 100644
-index bfaa3e0ac4..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test2_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test2_test.cc
+index 955d699..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name2-test.py b/test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name2-test.py
deleted file mode 100644
-index c284700b02..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.cc
+index ab838f4..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name2-test_.cc b/test/gtest-1.11.0/googletest/test/googletest-param-test-invalid-name2-test_.cc
deleted file mode 100644
-index 93628ba080..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.h
+index 76371df..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-param-test-test.cc b/test/gtest-1.11.0/googletest/test/googletest-param-test-test.cc
deleted file mode 100644
-index 41d75704cf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-unittest-api_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-unittest-api_test.cc
+index 023aa46..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-param-test-test.h b/test/gtest-1.11.0/googletest/test/googletest-param-test-test.h
deleted file mode 100644
-index b1f51688af..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_all_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_all_test.cc
+index 8919375..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-param-test2-test.cc b/test/gtest-1.11.0/googletest/test/googletest-param-test2-test.cc
deleted file mode 100644
-index 955aa62828..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest.py
-deleted file mode 100755
-index 78f3e0f53b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest_.cc
+index 2a29fb1..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-port-test.cc b/test/gtest-1.11.0/googletest/test/googletest-port-test.cc
deleted file mode 100644
-index dd07478c07..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test.py
-deleted file mode 100755
-index e6fc22fd1f..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test_.cc
+index 1e0c861..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-printers-test.cc b/test/gtest-1.11.0/googletest/test/googletest-printers-test.cc
deleted file mode 100644
-index d0fc82c998..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test.py
+index e1e8e1c..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-setuptestsuite-test.py b/test/gtest-1.11.0/googletest/test/googletest-setuptestsuite-test.py
deleted file mode 100755
-index d02a53ed85..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test_.cc
+index c82162f..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-setuptestsuite-test_.cc b/test/gtest-1.11.0/googletest/test/googletest-setuptestsuite-test_.cc
deleted file mode 100644
-index f61ebb89b8..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test.py
+index a4bc4ef..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-shuffle-test.py b/test/gtest-1.11.0/googletest/test/googletest-shuffle-test.py
deleted file mode 100755
-index 424075cfa3..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test_.cc
+index 573cc5e..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-shuffle-test_.cc b/test/gtest-1.11.0/googletest/test/googletest-shuffle-test_.cc
deleted file mode 100644
-index 539afc9683..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_environment_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_environment_test.cc
+index 4505663..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-test-part-test.cc b/test/gtest-1.11.0/googletest/test/googletest-test-part-test.cc
deleted file mode 100644
-index 3cff19e70e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest.py
+index 44cf7ca..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-throw-on-failure-test.py b/test/gtest-1.11.0/googletest/test/googletest-throw-on-failure-test.py
deleted file mode 100755
-index ec0b151b11..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest_.cc
+index ea627c4..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-throw-on-failure-test_.cc b/test/gtest-1.11.0/googletest/test/googletest-throw-on-failure-test_.cc
deleted file mode 100644
-index 77deffc38f..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test.py
+index 83bb914..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-uninitialized-test.py b/test/gtest-1.11.0/googletest/test/googletest-uninitialized-test.py
deleted file mode 100755
-index 093c838d9e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test_.cc
-deleted file mode 100644
-index 31f78c2441..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest.py
-deleted file mode 100755
-index f2d2fd1b1c..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest_.cc
-deleted file mode 100644
-index 907c176ba9..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_main_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_main_unittest.cc
+index 69595a0..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/googletest-uninitialized-test_.cc b/test/gtest-1.11.0/googletest/test/googletest-uninitialized-test_.cc
deleted file mode 100644
-index ecd9bb876f..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_no_test_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_no_test_unittest.cc
+index b4434d5..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest-typed-test2_test.cc b/test/gtest-1.11.0/googletest/test/gtest-typed-test2_test.cc
deleted file mode 100644
-index 292599af8d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test.py
-deleted file mode 100755
-index 06dbee0980..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_.cc
+index e83ca2e..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest-typed-test_test.cc b/test/gtest-1.11.0/googletest/test/gtest-typed-test_test.cc
deleted file mode 100644
-index 1070a9f26f..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_golden_lin.txt b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_golden_lin.txt
+index 5fc678c..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest-typed-test_test.h b/test/gtest-1.11.0/googletest/test/gtest-typed-test_test.h
deleted file mode 100644
-index 2223d560e2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_pred_impl_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_pred_impl_unittest.cc
+index 8ce559c..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest-unittest-api_test.cc b/test/gtest-1.11.0/googletest/test/gtest-unittest-api_test.cc
deleted file mode 100644
-index a84eff860a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_premature_exit_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_premature_exit_test.cc
+index 8ef5058..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_all_test.cc b/test/gtest-1.11.0/googletest/test/gtest_all_test.cc
deleted file mode 100644
-index 3b4dc7d43f..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_prod_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_prod_test.cc
+index 615b29b..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_assert_by_exception_test.cc b/test/gtest-1.11.0/googletest/test/gtest_assert_by_exception_test.cc
deleted file mode 100644
-index 060abce187..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_repeat_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_repeat_test.cc
+index ada4cb3..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_environment_test.cc b/test/gtest-1.11.0/googletest/test/gtest_environment_test.cc
deleted file mode 100644
-index 481012adc2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test.py
+index 064bfc5..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_help_test.py b/test/gtest-1.11.0/googletest/test/gtest_help_test.py
deleted file mode 100755
-index 30d0303d19..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test_.cc
+index 8d953bb..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_help_test_.cc b/test/gtest-1.11.0/googletest/test/gtest_help_test_.cc
deleted file mode 100644
-index 6fb441bd4d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_sole_header_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_sole_header_test.cc
+index 750ae6c..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_json_test_utils.py b/test/gtest-1.11.0/googletest/test/gtest_json_test_utils.py
deleted file mode 100644
-index ccd091a281..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_stress_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_stress_test.cc
+index 62bbfc2..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_list_output_unittest.py b/test/gtest-1.11.0/googletest/test/gtest_list_output_unittest.py
deleted file mode 100644
-index e7daa430df..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_test_utils.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_test_utils.py
-deleted file mode 100755
-index 4acd36c975..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_ex_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_ex_test.cc
+index a442fc1..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_list_output_unittest_.cc b/test/gtest-1.11.0/googletest/test/gtest_list_output_unittest_.cc
deleted file mode 100644
-index 8d46c76f16..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test.py
-deleted file mode 100755
-index 3e7740cabb..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test_.cc
+index 92b9d4f..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_main_unittest.cc b/test/gtest-1.11.0/googletest/test/gtest_main_unittest.cc
deleted file mode 100644
-index 2b88fe3d9b..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test.py
-deleted file mode 100755
-index 4358370097..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test_.cc
+index eddedea..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_no_test_unittest.cc b/test/gtest-1.11.0/googletest/test/gtest_no_test_unittest.cc
deleted file mode 100644
-index 44316987fb..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_unittest.cc
+index d4f88db..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_pred_impl_unittest.cc b/test/gtest-1.11.0/googletest/test/gtest_pred_impl_unittest.cc
deleted file mode 100644
-index 88e94134b9..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile1_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile1_test_.cc
+index bbef994..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_premature_exit_test.cc b/test/gtest-1.11.0/googletest/test/gtest_premature_exit_test.cc
deleted file mode 100644
-index 531ced49d4..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile2_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile2_test_.cc
+index 1d1187e..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_prod_test.cc b/test/gtest-1.11.0/googletest/test/gtest_prod_test.cc
deleted file mode 100644
-index 7b400b2760..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfiles_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfiles_test.py
-deleted file mode 100755
-index 524e437e6c..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest.py
-deleted file mode 100755
-index bcd5975991..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest_.cc
+index ede81a0..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_repeat_test.cc b/test/gtest-1.11.0/googletest/test/gtest_repeat_test.cc
deleted file mode 100644
-index 48b8771b52..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_test_utils.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_test_utils.py
+index 7da4a15..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_skip_check_output_test.py b/test/gtest-1.11.0/googletest/test/gtest_skip_check_output_test.py
deleted file mode 100755
-index 341956b54d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.cc
-deleted file mode 100644
-index 8b8a40b44e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.h
+index 14e63ab..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_skip_environment_check_output_test.py b/test/gtest-1.11.0/googletest/test/gtest_skip_environment_check_output_test.py
+deleted file mode 100755
+index 6e79155..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_skip_in_environment_setup_test.cc b/test/gtest-1.11.0/googletest/test/gtest_skip_in_environment_setup_test.cc
deleted file mode 100644
-index 98fd5e476c..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/DebugProject.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/DebugProject.xcconfig
+index 9372310..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_skip_test.cc b/test/gtest-1.11.0/googletest/test/gtest_skip_test.cc
deleted file mode 100644
-index 3d68157d5d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/FrameworkTarget.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/FrameworkTarget.xcconfig
+index 4a23004..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_sole_header_test.cc b/test/gtest-1.11.0/googletest/test/gtest_sole_header_test.cc
deleted file mode 100644
-index 357b1c8fbf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/General.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/General.xcconfig
+index 1d94ac6..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_stress_test.cc b/test/gtest-1.11.0/googletest/test/gtest_stress_test.cc
deleted file mode 100644
-index f23e322272..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/ReleaseProject.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/ReleaseProject.xcconfig
+index 8434819..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_test_macro_stack_footprint_test.cc b/test/gtest-1.11.0/googletest/test/gtest_test_macro_stack_footprint_test.cc
deleted file mode 100644
-index 5349f0a04a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/StaticLibraryTarget.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/StaticLibraryTarget.xcconfig
+index a48db05..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_test_utils.py b/test/gtest-1.11.0/googletest/test/gtest_test_utils.py
+deleted file mode 100755
+index d0c2446..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_testbridge_test.py b/test/gtest-1.11.0/googletest/test/gtest_testbridge_test.py
+deleted file mode 100755
+index 87ffad7..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_testbridge_test_.cc b/test/gtest-1.11.0/googletest/test/gtest_testbridge_test_.cc
deleted file mode 100644
-index 3922fa51d5..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/TestTarget.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/TestTarget.xcconfig
+index 24617b2..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_throw_on_failure_ex_test.cc b/test/gtest-1.11.0/googletest/test/gtest_throw_on_failure_ex_test.cc
deleted file mode 100644
-index e6652ba859..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Resources/Info.plist b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Resources/Info.plist
+index 1d95adb..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_unittest.cc b/test/gtest-1.11.0/googletest/test/gtest_unittest.cc
deleted file mode 100644
-index 9dd28ea148..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/Info.plist b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/Info.plist
+index 1730e8b..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_xml_outfile1_test_.cc b/test/gtest-1.11.0/googletest/test/gtest_xml_outfile1_test_.cc
deleted file mode 100644
-index f3852edea2..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
+index 19aa252..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_xml_outfile2_test_.cc b/test/gtest-1.11.0/googletest/test/gtest_xml_outfile2_test_.cc
deleted file mode 100644
-index 497617eb68..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/runtests.sh b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/runtests.sh
+index f9a2a6e..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_xml_outfiles_test.py b/test/gtest-1.11.0/googletest/test/gtest_xml_outfiles_test.py
+deleted file mode 100755
+index ac66feb..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_xml_output_unittest.py b/test/gtest-1.11.0/googletest/test/gtest_xml_output_unittest.py
+deleted file mode 100755
+index eade7aa..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_xml_output_unittest_.cc b/test/gtest-1.11.0/googletest/test/gtest_xml_output_unittest_.cc
deleted file mode 100644
-index 4a0d413e52..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.cc
+index c0036aa..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/gtest_xml_test_utils.py b/test/gtest-1.11.0/googletest/test/gtest_xml_test_utils.py
+deleted file mode 100755
+index ec42c62..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/production.cc b/test/gtest-1.11.0/googletest/test/production.cc
deleted file mode 100644
-index bfc4e7fcfd..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.h
+index 0f69f6d..0000000
+diff --git a/test/gtest-1.11.0/googletest/test/production.h b/test/gtest-1.11.0/googletest/test/production.h
deleted file mode 100644
-index 0c55cdc8cf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget_test.cc
+index 41a5472..0000000
+diff --git a/test/gtest-1.11.0/library.json b/test/gtest-1.11.0/library.json
deleted file mode 100644
-index 8725994218..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/runtests.sh b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/runtests.sh
+index f61bf00..0000000
+diff --git a/test/handler_test.h b/test/handler_test.h
deleted file mode 100644
-index 3fc229f1d4..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/versiongenerate.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/versiongenerate.py
-deleted file mode 100755
-index 81de8c96ac..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/gtest.xcodeproj/project.pbxproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/gtest.xcodeproj/project.pbxproj
+index 668a58d..0000000
+diff --git a/test/integration/emitter_test.cpp b/test/integration/emitter_test.cpp
deleted file mode 100644
-index aefaa88b05..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/travis.sh b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/travis.sh
-deleted file mode 100755
-index bdecbd964d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/handler_test.h b/src/libs/3rdparty/yaml-cpp/test/handler_test.h
+index b277d57..0000000
+diff --git a/test/integration/encoding_test.cpp b/test/integration/encoding_test.cpp
deleted file mode 100644
-index 668a58d01e..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/emitter_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/emitter_test.cpp
+index 9bd6586..0000000
+diff --git a/test/integration/error_messages_test.cpp b/test/integration/error_messages_test.cpp
deleted file mode 100644
-index 27808380d5..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/encoding_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/encoding_test.cpp
+index 64ab6b9..0000000
+diff --git a/test/integration/gen_emitter_test.cpp b/test/integration/gen_emitter_test.cpp
deleted file mode 100644
-index 9bd6586378..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/gen_emitter_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/gen_emitter_test.cpp
+index 3536144..0000000
+diff --git a/test/integration/handler_spec_test.cpp b/test/integration/handler_spec_test.cpp
deleted file mode 100644
-index e44eee6da7..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/handler_spec_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/handler_spec_test.cpp
+index 8cba902..0000000
+diff --git a/test/integration/handler_test.cpp b/test/integration/handler_test.cpp
deleted file mode 100644
-index d142a0d302..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/handler_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/handler_test.cpp
+index 6011460..0000000
+diff --git a/test/integration/load_node_test.cpp b/test/integration/load_node_test.cpp
deleted file mode 100644
-index 6011460713..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/load_node_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/load_node_test.cpp
+index 9d0c790..0000000
+diff --git a/test/integration/node_spec_test.cpp b/test/integration/node_spec_test.cpp
deleted file mode 100644
-index 02bb8fe58d..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/node_spec_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/node_spec_test.cpp
+index bfc8578..0000000
+diff --git a/test/main.cpp b/test/main.cpp
deleted file mode 100644
-index aedf38b2bf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/main.cpp b/src/libs/3rdparty/yaml-cpp/test/main.cpp
+index 443e2db..0000000
+diff --git a/test/mock_event_handler.h b/test/mock_event_handler.h
deleted file mode 100644
-index 443e2dbb3f..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/mock_event_handler.h b/src/libs/3rdparty/yaml-cpp/test/mock_event_handler.h
+index 0b7e7da..0000000
+diff --git a/test/node/node_test.cpp b/test/node/node_test.cpp
deleted file mode 100644
-index 49d1f0c334..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/node/node_test.cpp b/src/libs/3rdparty/yaml-cpp/test/node/node_test.cpp
+index 5f41ef2..0000000
+diff --git a/test/ostream_wrapper_test.cpp b/test/ostream_wrapper_test.cpp
deleted file mode 100644
-index 485ad09e1a..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/ostream_wrapper_test.cpp b/src/libs/3rdparty/yaml-cpp/test/ostream_wrapper_test.cpp
+index ff4f635..0000000
+diff --git a/test/parser_test.cpp b/test/parser_test.cpp
deleted file mode 100644
-index cdc1f05083..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/regex_test.cpp b/src/libs/3rdparty/yaml-cpp/test/regex_test.cpp
+index e5002a4..0000000
+diff --git a/test/regex_test.cpp b/test/regex_test.cpp
deleted file mode 100644
-index 7589d2e4bf..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/test/specexamples.h b/src/libs/3rdparty/yaml-cpp/test/specexamples.h
+index 658db9e..0000000
+diff --git a/test/specexamples.h b/test/specexamples.h
deleted file mode 100644
-index 3c81c77791..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/util/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/util/CMakeLists.txt
+index 46e2c4c..0000000
+diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt
deleted file mode 100644
-index 22866273c7..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/util/api.cpp b/src/libs/3rdparty/yaml-cpp/util/api.cpp
+index 87ea4f9..0000000
+diff --git a/util/api.cpp b/util/api.cpp
deleted file mode 100644
-index 8ae5ff2978..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/util/parse.cpp b/src/libs/3rdparty/yaml-cpp/util/parse.cpp
+index 8ae5ff2..0000000
+diff --git a/util/parse.cpp b/util/parse.cpp
deleted file mode 100644
-index f3f0279ce5..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/util/read.cpp b/src/libs/3rdparty/yaml-cpp/util/read.cpp
+index ea4295a..0000000
+diff --git a/util/read.cpp b/util/read.cpp
deleted file mode 100644
-index fc88f1f9b9..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/util/sandbox.cpp b/src/libs/3rdparty/yaml-cpp/util/sandbox.cpp
+index 3455ea3..0000000
+diff --git a/util/sandbox.cpp b/util/sandbox.cpp
deleted file mode 100644
-index 1df25bb242..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp-config-version.cmake.in b/src/libs/3rdparty/yaml-cpp/yaml-cpp-config-version.cmake.in
+index f21490e..0000000
+diff --git a/yaml-cpp-config.cmake.in b/yaml-cpp-config.cmake.in
deleted file mode 100644
-index 80b9c79add..0000000000
-diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp-config.cmake.in b/src/libs/3rdparty/yaml-cpp/yaml-cpp-config.cmake.in
+index 799b9b4..0000000
+diff --git a/yaml-cpp.pc.in b/yaml-cpp.pc.in
deleted file mode 100644
-index 7b41e3f30c..0000000000
+index d02dc9e..0000000
--
-2.17.1
+2.42.0
diff --git a/src/libs/3rdparty/yaml-cpp/patches/0002-yaml-cpp-Make-dll.h-compatible-with-fvisibility-hidd.patch b/src/libs/3rdparty/yaml-cpp/patches/0002-yaml-cpp-Make-dll.h-compatible-with-fvisibility-hidd.patch
deleted file mode 100644
index 90d684b9c1d..00000000000
--- a/src/libs/3rdparty/yaml-cpp/patches/0002-yaml-cpp-Make-dll.h-compatible-with-fvisibility-hidd.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 72546402c08fc548efb248761870a83e78eb5ea3 Mon Sep 17 00:00:00 2001
-From: Nikolai Kosjar <nikolai.kosjar@qt.io>
-Date: Wed, 31 Jul 2019 09:08:55 +0200
-Subject: [PATCH] yaml-cpp: Make dll.h compatible with -fvisibility=hidden
-
-Change-Id: Ic09ace43e37102294d290768b3a7994c7a6b42c6
----
- src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h | 13 +++++++++++--
- 1 file changed, 11 insertions(+), 2 deletions(-)
-
-diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
-index a32c06b2e3..897f1533df 100644
---- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
-+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
-@@ -18,13 +18,22 @@
-
- #ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined
- // manually)
-+
-+#if defined(_WIN32) || defined(WIN32)
-+# define YAML_CPP_API_IMPORT __declspec(dllimport)
-+# define YAML_CPP_API_EXPORT __declspec(dllexport)
-+#else
-+# define YAML_CPP_API_IMPORT __attribute__((visibility("default")))
-+# define YAML_CPP_API_EXPORT __attribute__((visibility("default")))
-+#endif
-+
- #ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake
- // or defined manually)
- // #pragma message( "Defining YAML_CPP_API for DLL export" )
--#define YAML_CPP_API __declspec(dllexport)
-+#define YAML_CPP_API YAML_CPP_API_EXPORT
- #else // yaml_cpp_EXPORTS
- // #pragma message( "Defining YAML_CPP_API for DLL import" )
--#define YAML_CPP_API __declspec(dllimport)
-+#define YAML_CPP_API YAML_CPP_API_IMPORT
- #endif // yaml_cpp_EXPORTS
- #else // YAML_CPP_DLL
- #define YAML_CPP_API
---
-2.17.1
-
diff --git a/src/libs/3rdparty/yaml-cpp/patches/0003-yaml-cpp-MSVC-Fix-unknown-override-specifier-for-_NO.patch b/src/libs/3rdparty/yaml-cpp/patches/0003-yaml-cpp-MSVC-Fix-unknown-override-specifier-for-_NO.patch
deleted file mode 100644
index ab7929f964e..00000000000
--- a/src/libs/3rdparty/yaml-cpp/patches/0003-yaml-cpp-MSVC-Fix-unknown-override-specifier-for-_NO.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From b6f98df7d1ebdd788e7b5029c3884dcf38a6f17d Mon Sep 17 00:00:00 2001
-From: Nikolai Kosjar <nikolai.kosjar@qt.io>
-Date: Tue, 27 Aug 2019 12:01:03 +0200
-Subject: [PATCH] yaml-cpp: MSVC: Fix "unknown override specifier" for
- _NOEXCEPT
-
-Change-Id: If07000f7b3e8c4c1b87b683ff9cd29e57d43ab60
----
- src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h | 8 +-------
- src/libs/3rdparty/yaml-cpp/src/exceptions.cpp | 8 +-------
- 2 files changed, 2 insertions(+), 14 deletions(-)
-
-diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
-index 9c96859b2c..eae31968b7 100644
---- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
-+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
-@@ -13,13 +13,7 @@
- #include <stdexcept>
- #include <string>
-
--// This is here for compatibility with older versions of Visual Studio
--// which don't support noexcept
--#ifdef _MSC_VER
-- #define YAML_CPP_NOEXCEPT _NOEXCEPT
--#else
-- #define YAML_CPP_NOEXCEPT noexcept
--#endif
-+#define YAML_CPP_NOEXCEPT noexcept
-
- namespace YAML {
- // error messages
-diff --git a/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp b/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
-index 9b6d8912c1..d5e10b23c1 100644
---- a/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
-+++ b/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
-@@ -1,12 +1,6 @@
- #include "yaml-cpp/exceptions.h"
-
--// This is here for compatibility with older versions of Visual Studio
--// which don't support noexcept
--#ifdef _MSC_VER
-- #define YAML_CPP_NOEXCEPT _NOEXCEPT
--#else
-- #define YAML_CPP_NOEXCEPT noexcept
--#endif
-+#define YAML_CPP_NOEXCEPT noexcept
-
- namespace YAML {
-
---
-2.17.1
-
diff --git a/src/libs/3rdparty/yaml-cpp/src/binary.cpp b/src/libs/3rdparty/yaml-cpp/src/binary.cpp
index a7e51301b82..d27762a2436 100644
--- a/src/libs/3rdparty/yaml-cpp/src/binary.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/binary.cpp
@@ -1,5 +1,7 @@
#include "yaml-cpp/binary.h"
+#include <cctype>
+
namespace YAML {
static const char encoding[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -64,7 +66,7 @@ static const unsigned char decoding[] = {
};
std::vector<unsigned char> DecodeBase64(const std::string &input) {
- typedef std::vector<unsigned char> ret_type;
+ using ret_type = std::vector<unsigned char>;
if (input.empty())
return ret_type();
@@ -72,22 +74,27 @@ std::vector<unsigned char> DecodeBase64(const std::string &input) {
unsigned char *out = &ret[0];
unsigned value = 0;
- for (std::size_t i = 0; i < input.size(); i++) {
- unsigned char d = decoding[static_cast<unsigned>(input[i])];
+ for (std::size_t i = 0, cnt = 0; i < input.size(); i++) {
+ if (std::isspace(static_cast<unsigned char>(input[i]))) {
+ // skip newlines
+ continue;
+ }
+ unsigned char d = decoding[static_cast<unsigned char>(input[i])];
if (d == 255)
return ret_type();
value = (value << 6) | d;
- if (i % 4 == 3) {
+ if (cnt % 4 == 3) {
*out++ = value >> 16;
if (i > 0 && input[i - 1] != '=')
*out++ = value >> 8;
if (input[i] != '=')
*out++ = value;
}
+ ++cnt;
}
ret.resize(out - &ret[0]);
return ret;
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/collectionstack.h b/src/libs/3rdparty/yaml-cpp/src/collectionstack.h
index 2302786e037..9feba967951 100644
--- a/src/libs/3rdparty/yaml-cpp/src/collectionstack.h
+++ b/src/libs/3rdparty/yaml-cpp/src/collectionstack.h
@@ -7,8 +7,8 @@
#pragma once
#endif
-#include <stack>
#include <cassert>
+#include <stack>
namespace YAML {
struct CollectionType {
@@ -17,6 +17,7 @@ struct CollectionType {
class CollectionStack {
public:
+ CollectionStack() : collectionStack{} {}
CollectionType::value GetCurCollectionType() const {
if (collectionStack.empty())
return CollectionType::NoCollection;
@@ -28,12 +29,13 @@ class CollectionStack {
}
void PopCollectionType(CollectionType::value type) {
assert(type == GetCurCollectionType());
+ (void)type;
collectionStack.pop();
}
private:
std::stack<CollectionType::value> collectionStack;
};
-}
+} // namespace YAML
#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/convert.cpp b/src/libs/3rdparty/yaml-cpp/src/convert.cpp
index ec05b77826b..9658b360355 100644
--- a/src/libs/3rdparty/yaml-cpp/src/convert.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/convert.cpp
@@ -16,11 +16,7 @@ std::string tolower(const std::string& str) {
template <typename T>
bool IsEntirely(const std::string& str, T func) {
- for (std::size_t i = 0; i < str.size(); i++)
- if (!func(str[i]))
- return false;
-
- return true;
+ return std::all_of(str.begin(), str.end(), [=](char ch) { return func(ch); });
}
// IsFlexibleCase
@@ -39,7 +35,7 @@ bool IsFlexibleCase(const std::string& str) {
std::string rest = str.substr(1);
return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
}
-}
+} // namespace
namespace YAML {
bool convert<bool>::decode(const Node& node, bool& rhs) {
@@ -52,19 +48,22 @@ bool convert<bool>::decode(const Node& node, bool& rhs) {
static const struct {
std::string truename, falsename;
} names[] = {
- {"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"},
+ {"y", "n"},
+ {"yes", "no"},
+ {"true", "false"},
+ {"on", "off"},
};
if (!IsFlexibleCase(node.Scalar()))
return false;
- for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
- if (names[i].truename == tolower(node.Scalar())) {
+ for (const auto& name : names) {
+ if (name.truename == tolower(node.Scalar())) {
rhs = true;
return true;
}
- if (names[i].falsename == tolower(node.Scalar())) {
+ if (name.falsename == tolower(node.Scalar())) {
rhs = false;
return true;
}
@@ -72,4 +71,4 @@ bool convert<bool>::decode(const Node& node, bool& rhs) {
return false;
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/depthguard.cpp b/src/libs/3rdparty/yaml-cpp/src/depthguard.cpp
new file mode 100644
index 00000000000..5bf6cdf03bf
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/depthguard.cpp
@@ -0,0 +1,9 @@
+#include "yaml-cpp/depthguard.h"
+
+namespace YAML {
+
+DeepRecursion::DeepRecursion(int depth, const Mark& mark_,
+ const std::string& msg_)
+ : ParserException(mark_, msg_), m_depth(depth) {}
+
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/directives.cpp b/src/libs/3rdparty/yaml-cpp/src/directives.cpp
index 963bd2cd379..4c1dc201d7f 100644
--- a/src/libs/3rdparty/yaml-cpp/src/directives.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/directives.cpp
@@ -1,16 +1,11 @@
#include "directives.h"
namespace YAML {
-Directives::Directives() {
- // version
- version.isDefault = true;
- version.major = 1;
- version.minor = 2;
-}
+Directives::Directives() : version{true, 1, 2}, tags{} {}
-const std::string Directives::TranslateTagHandle(
+std::string Directives::TranslateTagHandle(
const std::string& handle) const {
- std::map<std::string, std::string>::const_iterator it = tags.find(handle);
+ auto it = tags.find(handle);
if (it == tags.end()) {
if (handle == "!!")
return "tag:yaml.org,2002:";
@@ -19,4 +14,4 @@ const std::string Directives::TranslateTagHandle(
return it->second;
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/directives.h b/src/libs/3rdparty/yaml-cpp/src/directives.h
index 333af26e374..18d14c9c0b7 100644
--- a/src/libs/3rdparty/yaml-cpp/src/directives.h
+++ b/src/libs/3rdparty/yaml-cpp/src/directives.h
@@ -19,7 +19,7 @@ struct Version {
struct Directives {
Directives();
- const std::string TranslateTagHandle(const std::string& handle) const;
+ std::string TranslateTagHandle(const std::string& handle) const;
Version version;
std::map<std::string, std::string> tags;
diff --git a/src/libs/3rdparty/yaml-cpp/src/emit.cpp b/src/libs/3rdparty/yaml-cpp/src/emit.cpp
index 51bc791533d..b0efb8401cc 100644
--- a/src/libs/3rdparty/yaml-cpp/src/emit.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/emit.cpp
@@ -1,7 +1,7 @@
#include "yaml-cpp/node/emit.h"
+#include "nodeevents.h"
#include "yaml-cpp/emitfromevents.h"
#include "yaml-cpp/emitter.h"
-#include "nodeevents.h"
namespace YAML {
Emitter& operator<<(Emitter& out, const Node& node) {
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitfromevents.cpp b/src/libs/3rdparty/yaml-cpp/src/emitfromevents.cpp
index 4832649f3c7..2e97187b900 100644
--- a/src/libs/3rdparty/yaml-cpp/src/emitfromevents.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/emitfromevents.cpp
@@ -16,10 +16,11 @@ std::string ToString(YAML::anchor_t anchor) {
stream << anchor;
return stream.str();
}
-}
+} // namespace
namespace YAML {
-EmitFromEvents::EmitFromEvents(Emitter& emitter) : m_emitter(emitter) {}
+EmitFromEvents::EmitFromEvents(Emitter& emitter)
+ : m_emitter(emitter), m_stateStack{} {}
void EmitFromEvents::OnDocumentStart(const Mark&) {}
@@ -58,6 +59,8 @@ void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag,
default:
break;
}
+ // Restore the global settings to eliminate the override from node style
+ m_emitter.RestoreGlobalModifiedSettings();
m_emitter << BeginSeq;
m_stateStack.push(State::WaitingForSequenceEntry);
}
@@ -82,6 +85,8 @@ void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag,
default:
break;
}
+ // Restore the global settings to eliminate the override from node style
+ m_emitter.RestoreGlobalModifiedSettings();
m_emitter << BeginMap;
m_stateStack.push(State::WaitingForKey);
}
@@ -116,4 +121,4 @@ void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) {
if (anchor)
m_emitter << Anchor(ToString(anchor));
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitter.cpp b/src/libs/3rdparty/yaml-cpp/src/emitter.cpp
index ebeb059554e..4d483075bde 100644
--- a/src/libs/3rdparty/yaml-cpp/src/emitter.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/emitter.cpp
@@ -11,12 +11,12 @@ namespace YAML {
class Binary;
struct _Null;
-Emitter::Emitter() : m_pState(new EmitterState) {}
+Emitter::Emitter() : m_pState(new EmitterState), m_stream{} {}
Emitter::Emitter(std::ostream& stream)
: m_pState(new EmitterState), m_stream(stream) {}
-Emitter::~Emitter() {}
+Emitter::~Emitter() = default;
const char* Emitter::c_str() const { return m_stream.str(); }
@@ -49,6 +49,10 @@ bool Emitter::SetBoolFormat(EMITTER_MANIP value) {
return ok;
}
+bool Emitter::SetNullFormat(EMITTER_MANIP value) {
+ return m_pState->SetNullFormat(value, FmtScope::Global);
+}
+
bool Emitter::SetIntBase(EMITTER_MANIP value) {
return m_pState->SetIntFormat(value, FmtScope::Global);
}
@@ -86,6 +90,10 @@ bool Emitter::SetDoublePrecision(std::size_t n) {
return m_pState->SetDoublePrecision(n, FmtScope::Global);
}
+void Emitter::RestoreGlobalModifiedSettings() {
+ m_pState->RestoreGlobalModifiedSettings();
+}
+
// SetLocalValue
// . Either start/end a group, or set a modifier locally
Emitter& Emitter::SetLocalValue(EMITTER_MANIP value) {
@@ -197,6 +205,7 @@ void Emitter::EmitBeginSeq() {
void Emitter::EmitEndSeq() {
if (!good())
return;
+ FlowType::value originalType = m_pState->CurGroupFlowType();
if (m_pState->CurGroupChildCount() == 0)
m_pState->ForceFlow();
@@ -205,8 +214,12 @@ void Emitter::EmitEndSeq() {
if (m_stream.comment())
m_stream << "\n";
m_stream << IndentTo(m_pState->CurIndent());
- if (m_pState->CurGroupChildCount() == 0)
+ if (originalType == FlowType::Block) {
m_stream << "[";
+ } else {
+ if (m_pState->CurGroupChildCount() == 0 && !m_pState->HasBegunNode())
+ m_stream << "[";
+ }
m_stream << "]";
}
@@ -227,6 +240,7 @@ void Emitter::EmitBeginMap() {
void Emitter::EmitEndMap() {
if (!good())
return;
+ FlowType::value originalType = m_pState->CurGroupFlowType();
if (m_pState->CurGroupChildCount() == 0)
m_pState->ForceFlow();
@@ -235,8 +249,12 @@ void Emitter::EmitEndMap() {
if (m_stream.comment())
m_stream << "\n";
m_stream << IndentTo(m_pState->CurIndent());
- if (m_pState->CurGroupChildCount() == 0)
+ if (originalType == FlowType::Block) {
m_stream << "{";
+ } else {
+ if (m_pState->CurGroupChildCount() == 0 && !m_pState->HasBegunNode())
+ m_stream << "{";
+ }
m_stream << "}";
}
@@ -285,10 +303,8 @@ void Emitter::PrepareTopNode(EmitterNodeType::value child) {
if (child == EmitterNodeType::NoType)
return;
- if (m_pState->CurGroupChildCount() > 0 && m_stream.col() > 0) {
- if (child != EmitterNodeType::NoType)
- EmitBeginDoc();
- }
+ if (m_pState->CurGroupChildCount() > 0 && m_stream.col() > 0)
+ EmitBeginDoc();
switch (child) {
case EmitterNodeType::NoType:
@@ -488,6 +504,9 @@ void Emitter::FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child) {
if (m_stream.comment())
m_stream << "\n";
m_stream << IndentTo(lastIndent);
+ if (m_pState->HasAlias()) {
+ m_stream << " ";
+ }
m_stream << ":";
}
@@ -514,7 +533,8 @@ void Emitter::BlockMapPrepareNode(EmitterNodeType::value child) {
if (m_pState->GetMapKeyFormat() == LongKey)
m_pState->SetLongKey();
if (child == EmitterNodeType::BlockSeq ||
- child == EmitterNodeType::BlockMap)
+ child == EmitterNodeType::BlockMap ||
+ child == EmitterNodeType::Property)
m_pState->SetLongKey();
if (m_pState->CurGroupLongKey())
@@ -558,6 +578,8 @@ void Emitter::BlockMapPrepareLongKey(EmitterNodeType::value child) {
break;
case EmitterNodeType::BlockSeq:
case EmitterNodeType::BlockMap:
+ if (m_pState->HasBegunContent())
+ m_stream << "\n";
break;
}
}
@@ -581,8 +603,12 @@ void Emitter::BlockMapPrepareLongKeyValue(EmitterNodeType::value child) {
case EmitterNodeType::Scalar:
case EmitterNodeType::FlowSeq:
case EmitterNodeType::FlowMap:
+ SpaceOrIndentTo(true, curIndent + 1);
+ break;
case EmitterNodeType::BlockSeq:
case EmitterNodeType::BlockMap:
+ if (m_pState->HasBegunContent())
+ m_stream << "\n";
SpaceOrIndentTo(true, curIndent + 1);
break;
}
@@ -621,6 +647,9 @@ void Emitter::BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child) {
const std::size_t nextIndent = curIndent + m_pState->CurGroupIndent();
if (!m_pState->HasBegunNode()) {
+ if (m_pState->HasAlias()) {
+ m_stream << " ";
+ }
m_stream << ":";
}
@@ -674,16 +703,29 @@ void Emitter::StartedScalar() { m_pState->StartedScalar(); }
// *******************************************************************************************
// overloads of Write
+StringEscaping::value GetStringEscapingStyle(const EMITTER_MANIP emitterManip) {
+ switch (emitterManip) {
+ case EscapeNonAscii:
+ return StringEscaping::NonAscii;
+ case EscapeAsJson:
+ return StringEscaping::JSON;
+ default:
+ return StringEscaping::None;
+ break;
+ }
+}
+
Emitter& Emitter::Write(const std::string& str) {
if (!good())
return *this;
- const bool escapeNonAscii = m_pState->GetOutputCharset() == EscapeNonAscii;
+ StringEscaping::value stringEscaping = GetStringEscapingStyle(m_pState->GetOutputCharset());
+
const StringFormat::value strFormat =
Utils::ComputeStringFormat(str, m_pState->GetStringFormat(),
- m_pState->CurGroupFlowType(), escapeNonAscii);
+ m_pState->CurGroupFlowType(), stringEscaping == StringEscaping::NonAscii);
- if (strFormat == StringFormat::Literal)
+ if (strFormat == StringFormat::Literal || str.size() > 1024)
m_pState->SetMapKeyFormat(YAML::LongKey, FmtScope::Local);
PrepareNode(EmitterNodeType::Scalar);
@@ -696,7 +738,7 @@ Emitter& Emitter::Write(const std::string& str) {
Utils::WriteSingleQuotedString(m_stream, str);
break;
case StringFormat::DoubleQuoted:
- Utils::WriteDoubleQuotedString(m_stream, str, escapeNonAscii);
+ Utils::WriteDoubleQuotedString(m_stream, str, stringEscaping);
break;
case StringFormat::Literal:
Utils::WriteLiteralString(m_stream, str,
@@ -766,6 +808,21 @@ const char* Emitter::ComputeFullBoolName(bool b) const {
// these answers
}
+const char* Emitter::ComputeNullName() const {
+ switch (m_pState->GetNullFormat()) {
+ case LowerNull:
+ return "null";
+ case UpperNull:
+ return "NULL";
+ case CamelNull:
+ return "Null";
+ case TildeNull:
+ // fallthrough
+ default:
+ return "~";
+ }
+}
+
Emitter& Emitter::Write(bool b) {
if (!good())
return *this;
@@ -787,8 +844,10 @@ Emitter& Emitter::Write(char ch) {
if (!good())
return *this;
+
+
PrepareNode(EmitterNodeType::Scalar);
- Utils::WriteChar(m_stream, ch);
+ Utils::WriteChar(m_stream, ch, GetStringEscapingStyle(m_pState->GetOutputCharset()));
StartedScalar();
return *this;
@@ -812,6 +871,8 @@ Emitter& Emitter::Write(const _Alias& alias) {
StartedScalar();
+ m_pState->SetAlias();
+
return *this;
}
@@ -889,7 +950,7 @@ Emitter& Emitter::Write(const _Null& /*null*/) {
PrepareNode(EmitterNodeType::Scalar);
- m_stream << "~";
+ m_stream << ComputeNullName();
StartedScalar();
@@ -908,4 +969,4 @@ Emitter& Emitter::Write(const Binary& binary) {
return *this;
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitterstate.cpp b/src/libs/3rdparty/yaml-cpp/src/emitterstate.cpp
index 3542aaf5071..3dbe4011084 100644
--- a/src/libs/3rdparty/yaml-cpp/src/emitterstate.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/emitterstate.cpp
@@ -6,29 +6,35 @@
namespace YAML {
EmitterState::EmitterState()
: m_isGood(true),
+ m_lastError{},
+ // default global manipulators
+ m_charset(EmitNonAscii),
+ m_strFmt(Auto),
+ m_boolFmt(TrueFalseBool),
+ m_boolLengthFmt(LongBool),
+ m_boolCaseFmt(LowerCase),
+ m_nullFmt(TildeNull),
+ m_intFmt(Dec),
+ m_indent(2),
+ m_preCommentIndent(2),
+ m_postCommentIndent(1),
+ m_seqFmt(Block),
+ m_mapFmt(Block),
+ m_mapKeyFmt(Auto),
+ m_floatPrecision(std::numeric_limits<float>::max_digits10),
+ m_doublePrecision(std::numeric_limits<double>::max_digits10),
+ //
+ m_modifiedSettings{},
+ m_globalModifiedSettings{},
+ m_groups{},
m_curIndent(0),
m_hasAnchor(false),
+ m_hasAlias(false),
m_hasTag(false),
m_hasNonContent(false),
- m_docCount(0) {
- // set default global manipulators
- m_charset.set(EmitNonAscii);
- m_strFmt.set(Auto);
- m_boolFmt.set(TrueFalseBool);
- m_boolLengthFmt.set(LongBool);
- m_boolCaseFmt.set(LowerCase);
- m_intFmt.set(Dec);
- m_indent.set(2);
- m_preCommentIndent.set(2);
- m_postCommentIndent.set(1);
- m_seqFmt.set(Block);
- m_mapFmt.set(Block);
- m_mapKeyFmt.set(Auto);
- m_floatPrecision.set(std::numeric_limits<float>::digits10 + 1);
- m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1);
-}
-
-EmitterState::~EmitterState() {}
+ m_docCount(0) {}
+
+EmitterState::~EmitterState() = default;
// SetLocalValue
// . We blindly tries to set all possible formatters to this value
@@ -39,6 +45,7 @@ void EmitterState::SetLocalValue(EMITTER_MANIP value) {
SetBoolFormat(value, FmtScope::Local);
SetBoolCaseFormat(value, FmtScope::Local);
SetBoolLengthFormat(value, FmtScope::Local);
+ SetNullFormat(value, FmtScope::Local);
SetIntFormat(value, FmtScope::Local);
SetFlowType(GroupType::Seq, value, FmtScope::Local);
SetFlowType(GroupType::Map, value, FmtScope::Local);
@@ -47,6 +54,8 @@ void EmitterState::SetLocalValue(EMITTER_MANIP value) {
void EmitterState::SetAnchor() { m_hasAnchor = true; }
+void EmitterState::SetAlias() { m_hasAlias = true; }
+
void EmitterState::SetTag() { m_hasTag = true; }
void EmitterState::SetNonContent() { m_hasNonContent = true; }
@@ -81,6 +90,7 @@ void EmitterState::StartedNode() {
}
m_hasAnchor = false;
+ m_hasAlias = false;
m_hasTag = false;
m_hasNonContent = false;
}
@@ -90,15 +100,13 @@ EmitterNodeType::value EmitterState::NextGroupType(
if (type == GroupType::Seq) {
if (GetFlowType(type) == Block)
return EmitterNodeType::BlockSeq;
- else
- return EmitterNodeType::FlowSeq;
- } else {
- if (GetFlowType(type) == Block)
- return EmitterNodeType::BlockMap;
- else
- return EmitterNodeType::FlowMap;
+ return EmitterNodeType::FlowSeq;
}
+ if (GetFlowType(type) == Block)
+ return EmitterNodeType::BlockMap;
+ return EmitterNodeType::FlowMap;
+
// can't happen
assert(false);
return EmitterNodeType::NoType;
@@ -152,9 +160,15 @@ void EmitterState::EndedGroup(GroupType::value type) {
if (m_groups.empty()) {
if (type == GroupType::Seq) {
return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
- } else {
- return SetError(ErrorMsg::UNEXPECTED_END_MAP);
}
+ return SetError(ErrorMsg::UNEXPECTED_END_MAP);
+ }
+
+ if (m_hasTag) {
+ SetError(ErrorMsg::INVALID_TAG);
+ }
+ if (m_hasAnchor) {
+ SetError(ErrorMsg::INVALID_ANCHOR);
}
// get rid of the current group
@@ -176,6 +190,9 @@ void EmitterState::EndedGroup(GroupType::value type) {
m_globalModifiedSettings.restore();
ClearModifiedSettings();
+ m_hasAnchor = false;
+ m_hasTag = false;
+ m_hasNonContent = false;
}
EmitterNodeType::value EmitterState::CurGroupNodeType() const {
@@ -216,11 +233,16 @@ std::size_t EmitterState::LastIndent() const {
void EmitterState::ClearModifiedSettings() { m_modifiedSettings.clear(); }
+void EmitterState::RestoreGlobalModifiedSettings() {
+ m_globalModifiedSettings.restore();
+}
+
bool EmitterState::SetOutputCharset(EMITTER_MANIP value,
FmtScope::value scope) {
switch (value) {
case EmitNonAscii:
case EscapeNonAscii:
+ case EscapeAsJson:
_Set(m_charset, value, scope);
return true;
default:
@@ -278,6 +300,19 @@ bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value,
}
}
+bool EmitterState::SetNullFormat(EMITTER_MANIP value, FmtScope::value scope) {
+ switch (value) {
+ case LowerNull:
+ case UpperNull:
+ case CamelNull:
+ case TildeNull:
+ _Set(m_nullFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+}
+
bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) {
switch (value) {
case Dec:
@@ -349,7 +384,7 @@ bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) {
}
bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) {
- if (value > std::numeric_limits<float>::digits10 + 1)
+ if (value > std::numeric_limits<float>::max_digits10)
return false;
_Set(m_floatPrecision, value, scope);
return true;
@@ -357,9 +392,9 @@ bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) {
bool EmitterState::SetDoublePrecision(std::size_t value,
FmtScope::value scope) {
- if (value > std::numeric_limits<double>::digits10 + 1)
+ if (value > std::numeric_limits<double>::max_digits10)
return false;
_Set(m_doublePrecision, value, scope);
return true;
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitterstate.h b/src/libs/3rdparty/yaml-cpp/src/emitterstate.h
index 0937f000d9f..8f379ca9524 100644
--- a/src/libs/3rdparty/yaml-cpp/src/emitterstate.h
+++ b/src/libs/3rdparty/yaml-cpp/src/emitterstate.h
@@ -43,6 +43,7 @@ class EmitterState {
// node handling
void SetAnchor();
+ void SetAlias();
void SetTag();
void SetNonContent();
void SetLongKey();
@@ -65,6 +66,7 @@ class EmitterState {
std::size_t LastIndent() const;
std::size_t CurIndent() const { return m_curIndent; }
bool HasAnchor() const { return m_hasAnchor; }
+ bool HasAlias() const { return m_hasAlias; }
bool HasTag() const { return m_hasTag; }
bool HasBegunNode() const {
return m_hasAnchor || m_hasTag || m_hasNonContent;
@@ -72,6 +74,7 @@ class EmitterState {
bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
void ClearModifiedSettings();
+ void RestoreGlobalModifiedSettings();
// formatters
void SetLocalValue(EMITTER_MANIP value);
@@ -91,6 +94,9 @@ class EmitterState {
bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
+ bool SetNullFormat(EMITTER_MANIP value, FmtScope::value scope);
+ EMITTER_MANIP GetNullFormat() const { return m_nullFmt.get(); }
+
bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
@@ -131,6 +137,7 @@ class EmitterState {
Setting<EMITTER_MANIP> m_boolFmt;
Setting<EMITTER_MANIP> m_boolLengthFmt;
Setting<EMITTER_MANIP> m_boolCaseFmt;
+ Setting<EMITTER_MANIP> m_nullFmt;
Setting<EMITTER_MANIP> m_intFmt;
Setting<std::size_t> m_indent;
Setting<std::size_t> m_preCommentIndent, m_postCommentIndent;
@@ -145,7 +152,12 @@ class EmitterState {
struct Group {
explicit Group(GroupType::value type_)
- : type(type_), indent(0), childCount(0), longKey(false) {}
+ : type(type_),
+ flowType{},
+ indent(0),
+ childCount(0),
+ longKey(false),
+ modifiedSettings{} {}
GroupType::value type;
FlowType::value flowType;
@@ -177,6 +189,7 @@ class EmitterState {
std::vector<std::unique_ptr<Group>> m_groups;
std::size_t m_curIndent;
bool m_hasAnchor;
+ bool m_hasAlias;
bool m_hasTag;
bool m_hasNonContent;
std::size_t m_docCount;
@@ -198,6 +211,6 @@ void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
assert(false);
}
}
-}
+} // namespace YAML
#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitterutils.cpp b/src/libs/3rdparty/yaml-cpp/src/emitterutils.cpp
index 147738ad8a1..6cdf6de7e29 100644
--- a/src/libs/3rdparty/yaml-cpp/src/emitterutils.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/emitterutils.cpp
@@ -1,3 +1,4 @@
+#include <algorithm>
#include <iomanip>
#include <sstream>
@@ -8,8 +9,8 @@
#include "regeximpl.h"
#include "stringsource.h"
#include "yaml-cpp/binary.h" // IWYU pragma: keep
-#include "yaml-cpp/ostream_wrapper.h"
#include "yaml-cpp/null.h"
+#include "yaml-cpp/ostream_wrapper.h"
namespace YAML {
namespace Utils {
@@ -134,12 +135,12 @@ void WriteCodePoint(ostream_wrapper& out, int codePoint) {
if (codePoint < 0 || codePoint > 0x10FFFF) {
codePoint = REPLACEMENT_CHARACTER;
}
- if (codePoint < 0x7F) {
+ if (codePoint <= 0x7F) {
out << static_cast<char>(codePoint);
- } else if (codePoint < 0x7FF) {
+ } else if (codePoint <= 0x7FF) {
out << static_cast<char>(0xC0 | (codePoint >> 6))
<< static_cast<char>(0x80 | (codePoint & 0x3F));
- } else if (codePoint < 0xFFFF) {
+ } else if (codePoint <= 0xFFFF) {
out << static_cast<char>(0xE0 | (codePoint >> 12))
<< static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
<< static_cast<char>(0x80 | (codePoint & 0x3F));
@@ -173,13 +174,13 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
// then check until something is disallowed
static const RegEx& disallowed_flow =
- Exp::EndScalarInFlow() || (Exp::BlankOrBreak() + Exp::Comment()) ||
- Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() ||
- Exp::Tab();
+ Exp::EndScalarInFlow() | (Exp::BlankOrBreak() + Exp::Comment()) |
+ Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
+ Exp::Tab() | Exp::Ampersand();
static const RegEx& disallowed_block =
- Exp::EndScalar() || (Exp::BlankOrBreak() + Exp::Comment()) ||
- Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() ||
- Exp::Tab();
+ Exp::EndScalar() | (Exp::BlankOrBreak() + Exp::Comment()) |
+ Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
+ Exp::Tab() | Exp::Ampersand();
const RegEx& disallowed =
flowType == FlowType::Flow ? disallowed_flow : disallowed_block;
@@ -199,15 +200,10 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) {
// TODO: check for non-printable characters?
- for (std::size_t i = 0; i < str.size(); i++) {
- if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) {
- return false;
- }
- if (str[i] == '\n') {
- return false;
- }
- }
- return true;
+ return std::none_of(str.begin(), str.end(), [=](char ch) {
+ return (escapeNonAscii && (0x80 <= static_cast<unsigned char>(ch))) ||
+ (ch == '\n');
+ });
}
bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType,
@@ -217,28 +213,39 @@ bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType,
}
// TODO: check for non-printable characters?
- for (std::size_t i = 0; i < str.size(); i++) {
- if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) {
- return false;
- }
- }
- return true;
+ return std::none_of(str.begin(), str.end(), [=](char ch) {
+ return (escapeNonAscii && (0x80 <= static_cast<unsigned char>(ch)));
+ });
+}
+
+std::pair<uint16_t, uint16_t> EncodeUTF16SurrogatePair(int codePoint) {
+ const uint32_t leadOffset = 0xD800 - (0x10000 >> 10);
+
+ return {
+ leadOffset | (codePoint >> 10),
+ 0xDC00 | (codePoint & 0x3FF),
+ };
}
-void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) {
+void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint, StringEscaping::value stringEscapingStyle) {
static const char hexDigits[] = "0123456789abcdef";
out << "\\";
int digits = 8;
- if (codePoint < 0xFF) {
+ if (codePoint < 0xFF && stringEscapingStyle != StringEscaping::JSON) {
out << "x";
digits = 2;
} else if (codePoint < 0xFFFF) {
out << "u";
digits = 4;
- } else {
+ } else if (stringEscapingStyle != StringEscaping::JSON) {
out << "U";
digits = 8;
+ } else {
+ auto surrogatePair = EncodeUTF16SurrogatePair(codePoint);
+ WriteDoubleQuoteEscapeSequence(out, surrogatePair.first, stringEscapingStyle);
+ WriteDoubleQuoteEscapeSequence(out, surrogatePair.second, stringEscapingStyle);
+ return;
}
// Write digits into the escape sequence
@@ -258,7 +265,7 @@ bool WriteAliasName(ostream_wrapper& out, const std::string& str) {
}
return true;
}
-}
+} // namespace
StringFormat::value ComputeStringFormat(const std::string& str,
EMITTER_MANIP strFormat,
@@ -310,7 +317,7 @@ bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) {
}
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
- bool escapeNonAscii) {
+ StringEscaping::value stringEscaping) {
out << "\"";
int codePoint;
for (std::string::const_iterator i = str.begin();
@@ -334,16 +341,19 @@ bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
case '\b':
out << "\\b";
break;
+ case '\f':
+ out << "\\f";
+ break;
default:
if (codePoint < 0x20 ||
(codePoint >= 0x80 &&
codePoint <= 0xA0)) { // Control characters and non-breaking space
- WriteDoubleQuoteEscapeSequence(out, codePoint);
+ WriteDoubleQuoteEscapeSequence(out, codePoint, stringEscaping);
} else if (codePoint == 0xFEFF) { // Byte order marks (ZWNS) should be
// escaped (YAML 1.2, sec. 5.2)
- WriteDoubleQuoteEscapeSequence(out, codePoint);
- } else if (escapeNonAscii && codePoint > 0x7E) {
- WriteDoubleQuoteEscapeSequence(out, codePoint);
+ WriteDoubleQuoteEscapeSequence(out, codePoint, stringEscaping);
+ } else if (stringEscaping == StringEscaping::NonAscii && codePoint > 0x7E) {
+ WriteDoubleQuoteEscapeSequence(out, codePoint, stringEscaping);
} else {
WriteCodePoint(out, codePoint);
}
@@ -356,37 +366,41 @@ bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
std::size_t indent) {
out << "|\n";
- out << IndentTo(indent);
int codePoint;
for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
if (codePoint == '\n') {
- out << "\n" << IndentTo(indent);
+ out << "\n";
} else {
+ out<< IndentTo(indent);
WriteCodePoint(out, codePoint);
}
}
return true;
}
-bool WriteChar(ostream_wrapper& out, char ch) {
+bool WriteChar(ostream_wrapper& out, char ch, StringEscaping::value stringEscapingStyle) {
if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) {
out << ch;
} else if (ch == '\"') {
- out << "\"\\\"\"";
+ out << R"("\"")";
} else if (ch == '\t') {
- out << "\"\\t\"";
+ out << R"("\t")";
} else if (ch == '\n') {
- out << "\"\\n\"";
+ out << R"("\n")";
} else if (ch == '\b') {
- out << "\"\\b\"";
+ out << R"("\b")";
+ } else if (ch == '\r') {
+ out << R"("\r")";
+ } else if (ch == '\f') {
+ out << R"("\f")";
} else if (ch == '\\') {
- out << "\"\\\\\"";
- } else if ((0x20 <= ch && ch <= 0x7e) || ch == ' ') {
+ out << R"("\\")";
+ } else if (0x20 <= ch && ch <= 0x7e) {
out << "\"" << ch << "\"";
} else {
out << "\"";
- WriteDoubleQuoteEscapeSequence(out, ch);
+ WriteDoubleQuoteEscapeSequence(out, ch, stringEscapingStyle);
out << "\"";
}
return true;
@@ -401,8 +415,8 @@ bool WriteComment(ostream_wrapper& out, const std::string& str,
for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
if (codePoint == '\n') {
- out << "\n" << IndentTo(curIndent) << "#"
- << Indentation(postCommentIndent);
+ out << "\n"
+ << IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
out.set_comment();
} else {
WriteCodePoint(out, codePoint);
@@ -476,8 +490,8 @@ bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
bool WriteBinary(ostream_wrapper& out, const Binary& binary) {
WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()),
- false);
+ StringEscaping::None);
return true;
}
-}
-}
+} // namespace Utils
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitterutils.h b/src/libs/3rdparty/yaml-cpp/src/emitterutils.h
index 6cc73191476..3a7d5982521 100644
--- a/src/libs/3rdparty/yaml-cpp/src/emitterutils.h
+++ b/src/libs/3rdparty/yaml-cpp/src/emitterutils.h
@@ -24,6 +24,10 @@ struct StringFormat {
enum value { Plain, SingleQuoted, DoubleQuoted, Literal };
};
+struct StringEscaping {
+ enum value { None, NonAscii, JSON };
+};
+
namespace Utils {
StringFormat::value ComputeStringFormat(const std::string& str,
EMITTER_MANIP strFormat,
@@ -32,10 +36,11 @@ StringFormat::value ComputeStringFormat(const std::string& str,
bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str);
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
- bool escapeNonAscii);
+ StringEscaping::value stringEscaping);
bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
std::size_t indent);
-bool WriteChar(ostream_wrapper& out, char ch);
+bool WriteChar(ostream_wrapper& out, char ch,
+ StringEscaping::value stringEscapingStyle);
bool WriteComment(ostream_wrapper& out, const std::string& str,
std::size_t postCommentIndent);
bool WriteAlias(ostream_wrapper& out, const std::string& str);
diff --git a/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp b/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
index d5e10b23c1c..43a7976e907 100644
--- a/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
@@ -1,25 +1,20 @@
#include "yaml-cpp/exceptions.h"
-
-#define YAML_CPP_NOEXCEPT noexcept
+#include "yaml-cpp/noexcept.h"
namespace YAML {
// These destructors are defined out-of-line so the vtable is only emitted once.
-Exception::~Exception() YAML_CPP_NOEXCEPT {}
-ParserException::~ParserException() YAML_CPP_NOEXCEPT {}
-RepresentationException::~RepresentationException() YAML_CPP_NOEXCEPT {}
-InvalidScalar::~InvalidScalar() YAML_CPP_NOEXCEPT {}
-KeyNotFound::~KeyNotFound() YAML_CPP_NOEXCEPT {}
-InvalidNode::~InvalidNode() YAML_CPP_NOEXCEPT {}
-BadConversion::~BadConversion() YAML_CPP_NOEXCEPT {}
-BadDereference::~BadDereference() YAML_CPP_NOEXCEPT {}
-BadSubscript::~BadSubscript() YAML_CPP_NOEXCEPT {}
-BadPushback::~BadPushback() YAML_CPP_NOEXCEPT {}
-BadInsert::~BadInsert() YAML_CPP_NOEXCEPT {}
-EmitterException::~EmitterException() YAML_CPP_NOEXCEPT {}
-BadFile::~BadFile() YAML_CPP_NOEXCEPT {}
-}
-
-#undef YAML_CPP_NOEXCEPT
-
-
+Exception::~Exception() YAML_CPP_NOEXCEPT = default;
+ParserException::~ParserException() YAML_CPP_NOEXCEPT = default;
+RepresentationException::~RepresentationException() YAML_CPP_NOEXCEPT = default;
+InvalidScalar::~InvalidScalar() YAML_CPP_NOEXCEPT = default;
+KeyNotFound::~KeyNotFound() YAML_CPP_NOEXCEPT = default;
+InvalidNode::~InvalidNode() YAML_CPP_NOEXCEPT = default;
+BadConversion::~BadConversion() YAML_CPP_NOEXCEPT = default;
+BadDereference::~BadDereference() YAML_CPP_NOEXCEPT = default;
+BadSubscript::~BadSubscript() YAML_CPP_NOEXCEPT = default;
+BadPushback::~BadPushback() YAML_CPP_NOEXCEPT = default;
+BadInsert::~BadInsert() YAML_CPP_NOEXCEPT = default;
+EmitterException::~EmitterException() YAML_CPP_NOEXCEPT = default;
+BadFile::~BadFile() YAML_CPP_NOEXCEPT = default;
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/exp.cpp b/src/libs/3rdparty/yaml-cpp/src/exp.cpp
index 695440aec0e..992620ff94b 100644
--- a/src/libs/3rdparty/yaml-cpp/src/exp.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/exp.cpp
@@ -12,8 +12,7 @@ namespace YAML {
namespace Exp {
unsigned ParseHex(const std::string& str, const Mark& mark) {
unsigned value = 0;
- for (std::size_t i = 0; i < str.size(); i++) {
- char ch = str[i];
+ for (char ch : str) {
int digit = 0;
if ('a' <= ch && ch <= 'f')
digit = ch - 'a' + 10;
@@ -55,14 +54,16 @@ std::string Escape(Stream& in, int codeLength) {
// now break it up into chars
if (value <= 0x7F)
return Str(value);
- else if (value <= 0x7FF)
+
+ if (value <= 0x7FF)
return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
- else if (value <= 0xFFFF)
+
+ if (value <= 0xFFFF)
return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) +
Str(0x80 + (value & 0x3F));
- else
- return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
- Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
+
+ return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
+ Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
}
// Escape
@@ -104,7 +105,7 @@ std::string Escape(Stream& in) {
case 'e':
return "\x1B";
case ' ':
- return "\x20";
+ return R"( )";
case '\"':
return "\"";
case '\'':
@@ -132,5 +133,5 @@ std::string Escape(Stream& in) {
std::stringstream msg;
throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
}
-}
-}
+} // namespace Exp
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/exp.h b/src/libs/3rdparty/yaml-cpp/src/exp.h
index 7c02cf6e451..c8837f0f825 100644
--- a/src/libs/3rdparty/yaml-cpp/src/exp.h
+++ b/src/libs/3rdparty/yaml-cpp/src/exp.h
@@ -33,15 +33,15 @@ inline const RegEx& Tab() {
return e;
}
inline const RegEx& Blank() {
- static const RegEx e = Space() || Tab();
+ static const RegEx e = Space() | Tab();
return e;
}
inline const RegEx& Break() {
- static const RegEx e = RegEx('\n') || RegEx("\r\n");
+ static const RegEx e = RegEx('\n') | RegEx("\r\n") | RegEx('\r');
return e;
}
inline const RegEx& BlankOrBreak() {
- static const RegEx e = Blank() || Break();
+ static const RegEx e = Blank() | Break();
return e;
}
inline const RegEx& Digit() {
@@ -49,29 +49,29 @@ inline const RegEx& Digit() {
return e;
}
inline const RegEx& Alpha() {
- static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z');
+ static const RegEx e = RegEx('a', 'z') | RegEx('A', 'Z');
return e;
}
inline const RegEx& AlphaNumeric() {
- static const RegEx e = Alpha() || Digit();
+ static const RegEx e = Alpha() | Digit();
return e;
}
inline const RegEx& Word() {
- static const RegEx e = AlphaNumeric() || RegEx('-');
+ static const RegEx e = AlphaNumeric() | RegEx('-');
return e;
}
inline const RegEx& Hex() {
- static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f');
+ static const RegEx e = Digit() | RegEx('A', 'F') | RegEx('a', 'f');
return e;
}
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec.
// 5.1)
inline const RegEx& NotPrintable() {
static const RegEx e =
- RegEx(0) ||
- RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
- RegEx(0x0E, 0x1F) ||
- (RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
+ RegEx(0) |
+ RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) |
+ RegEx(0x0E, 0x1F) |
+ (RegEx('\xC2') + (RegEx('\x80', '\x84') | RegEx('\x86', '\x9F')));
return e;
}
inline const RegEx& Utf8_ByteOrderMark() {
@@ -82,19 +82,19 @@ inline const RegEx& Utf8_ByteOrderMark() {
// actual tags
inline const RegEx& DocStart() {
- static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx());
+ static const RegEx e = RegEx("---") + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& DocEnd() {
- static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx());
+ static const RegEx e = RegEx("...") + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& DocIndicator() {
- static const RegEx e = DocStart() || DocEnd();
+ static const RegEx e = DocStart() | DocEnd();
return e;
}
inline const RegEx& BlockEntry() {
- static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx());
+ static const RegEx e = RegEx('-') + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& Key() {
@@ -106,36 +106,40 @@ inline const RegEx& KeyInFlow() {
return e;
}
inline const RegEx& Value() {
- static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
+ static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& ValueInFlow() {
- static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR));
+ static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx(",]}", REGEX_OR));
return e;
}
inline const RegEx& ValueInJSONFlow() {
static const RegEx e = RegEx(':');
return e;
}
+inline const RegEx& Ampersand() {
+ static const RegEx e = RegEx('&');
+ return e;
+}
inline const RegEx Comment() {
static const RegEx e = RegEx('#');
return e;
}
inline const RegEx& Anchor() {
- static const RegEx e = !(RegEx("[]{},", REGEX_OR) || BlankOrBreak());
+ static const RegEx e = !(RegEx("[]{},", REGEX_OR) | BlankOrBreak());
return e;
}
inline const RegEx& AnchorEnd() {
- static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak();
+ static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) | BlankOrBreak();
return e;
}
inline const RegEx& URI() {
- static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) ||
+ static const RegEx e = Word() | RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) |
(RegEx('%') + Hex() + Hex());
return e;
}
inline const RegEx& Tag() {
- static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) ||
+ static const RegEx e = Word() | RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) |
(RegEx('%') + Hex() + Hex());
return e;
}
@@ -148,34 +152,34 @@ inline const RegEx& Tag() {
// space.
inline const RegEx& PlainScalar() {
static const RegEx e =
- !(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) ||
- (RegEx("-?:", REGEX_OR) + (BlankOrBreak() || RegEx())));
+ !(BlankOrBreak() | RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) |
+ (RegEx("-?:", REGEX_OR) + (BlankOrBreak() | RegEx())));
return e;
}
inline const RegEx& PlainScalarInFlow() {
static const RegEx e =
- !(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) ||
- (RegEx("-:", REGEX_OR) + Blank()));
+ !(BlankOrBreak() | RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) |
+ (RegEx("-:", REGEX_OR) + (Blank() | RegEx())));
return e;
}
inline const RegEx& EndScalar() {
- static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
+ static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& EndScalarInFlow() {
static const RegEx e =
- (RegEx(':') + (BlankOrBreak() || RegEx() || RegEx(",]}", REGEX_OR))) ||
+ (RegEx(':') + (BlankOrBreak() | RegEx() | RegEx(",]}", REGEX_OR))) |
RegEx(",?[]{}", REGEX_OR);
return e;
}
inline const RegEx& ScanScalarEndInFlow() {
- static const RegEx e = (EndScalarInFlow() || (BlankOrBreak() + Comment()));
+ static const RegEx e = (EndScalarInFlow() | (BlankOrBreak() + Comment()));
return e;
}
inline const RegEx& ScanScalarEnd() {
- static const RegEx e = EndScalar() || (BlankOrBreak() + Comment());
+ static const RegEx e = EndScalar() | (BlankOrBreak() + Comment());
return e;
}
inline const RegEx& EscSingleQuote() {
@@ -192,8 +196,8 @@ inline const RegEx& ChompIndicator() {
return e;
}
inline const RegEx& Chomp() {
- static const RegEx e = (ChompIndicator() + Digit()) ||
- (Digit() + ChompIndicator()) || ChompIndicator() ||
+ static const RegEx e = (ChompIndicator() + Digit()) |
+ (Digit() + ChompIndicator()) | ChompIndicator() |
Digit();
return e;
}
diff --git a/src/libs/3rdparty/yaml-cpp/src/memory.cpp b/src/libs/3rdparty/yaml-cpp/src/memory.cpp
index e5f8a9d3f8c..676e4c7f152 100644
--- a/src/libs/3rdparty/yaml-cpp/src/memory.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/memory.cpp
@@ -22,5 +22,5 @@ node& memory::create_node() {
void memory::merge(const memory& rhs) {
m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
}
-}
-}
+} // namespace detail
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/node.cpp b/src/libs/3rdparty/yaml-cpp/src/node.cpp
index 2088e13c9ae..badc3110ecc 100644
--- a/src/libs/3rdparty/yaml-cpp/src/node.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/node.cpp
@@ -9,4 +9,4 @@ Node Clone(const Node& node) {
events.Emit(builder);
return builder.Root();
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/node_data.cpp b/src/libs/3rdparty/yaml-cpp/src/node_data.cpp
index 77cd4657806..8f5422ae6e1 100644
--- a/src/libs/3rdparty/yaml-cpp/src/node_data.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/node_data.cpp
@@ -1,4 +1,5 @@
-#include <assert.h>
+#include <algorithm>
+#include <cassert>
#include <iterator>
#include <sstream>
@@ -12,15 +13,24 @@
namespace YAML {
namespace detail {
+YAML_CPP_API std::atomic<size_t> node::m_amount{0};
-std::string node_data::empty_scalar;
+const std::string& node_data::empty_scalar() {
+ static const std::string svalue;
+ return svalue;
+}
node_data::node_data()
: m_isDefined(false),
m_mark(Mark::null_mark()),
m_type(NodeType::Null),
+ m_tag{},
m_style(EmitterStyle::Default),
- m_seqSize(0) {}
+ m_scalar{},
+ m_sequence{},
+ m_seqSize(0),
+ m_map{},
+ m_undefinedPairs{} {}
void node_data::mark_defined() {
if (m_type == NodeType::Undefined)
@@ -100,9 +110,9 @@ void node_data::compute_seq_size() const {
}
void node_data::compute_map_size() const {
- kv_pairs::iterator it = m_undefinedPairs.begin();
+ auto it = m_undefinedPairs.begin();
while (it != m_undefinedPairs.end()) {
- kv_pairs::iterator jt = std::next(it);
+ auto jt = std::next(it);
if (it->first->is_defined() && it->second->is_defined())
m_undefinedPairs.erase(it);
it = jt;
@@ -111,7 +121,7 @@ void node_data::compute_map_size() const {
const_node_iterator node_data::begin() const {
if (!m_isDefined)
- return const_node_iterator();
+ return {};
switch (m_type) {
case NodeType::Sequence:
@@ -119,13 +129,13 @@ const_node_iterator node_data::begin() const {
case NodeType::Map:
return const_node_iterator(m_map.begin(), m_map.end());
default:
- return const_node_iterator();
+ return {};
}
}
node_iterator node_data::begin() {
if (!m_isDefined)
- return node_iterator();
+ return {};
switch (m_type) {
case NodeType::Sequence:
@@ -133,13 +143,13 @@ node_iterator node_data::begin() {
case NodeType::Map:
return node_iterator(m_map.begin(), m_map.end());
default:
- return node_iterator();
+ return {};
}
}
const_node_iterator node_data::end() const {
if (!m_isDefined)
- return const_node_iterator();
+ return {};
switch (m_type) {
case NodeType::Sequence:
@@ -147,13 +157,13 @@ const_node_iterator node_data::end() const {
case NodeType::Map:
return const_node_iterator(m_map.end(), m_map.end());
default:
- return const_node_iterator();
+ return {};
}
}
node_iterator node_data::end() {
if (!m_isDefined)
- return node_iterator();
+ return {};
switch (m_type) {
case NodeType::Sequence:
@@ -161,12 +171,13 @@ node_iterator node_data::end() {
case NodeType::Map:
return node_iterator(m_map.end(), m_map.end());
default:
- return node_iterator();
+ return {};
}
}
// sequence
-void node_data::push_back(node& node, shared_memory_holder /* pMemory */) {
+void node_data::push_back(node& node,
+ const shared_memory_holder& /* pMemory */) {
if (m_type == NodeType::Undefined || m_type == NodeType::Null) {
m_type = NodeType::Sequence;
reset_sequence();
@@ -178,7 +189,8 @@ void node_data::push_back(node& node, shared_memory_holder /* pMemory */) {
m_sequence.push_back(&node);
}
-void node_data::insert(node& key, node& value, shared_memory_holder pMemory) {
+void node_data::insert(node& key, node& value,
+ const shared_memory_holder& pMemory) {
switch (m_type) {
case NodeType::Map:
break;
@@ -188,27 +200,28 @@ void node_data::insert(node& key, node& value, shared_memory_holder pMemory) {
convert_to_map(pMemory);
break;
case NodeType::Scalar:
- throw BadSubscript();
+ throw BadSubscript(m_mark, key);
}
insert_map_pair(key, value);
}
// indexing
-node* node_data::get(node& key, shared_memory_holder /* pMemory */) const {
+node* node_data::get(node& key,
+ const shared_memory_holder& /* pMemory */) const {
if (m_type != NodeType::Map) {
- return NULL;
+ return nullptr;
}
- for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
- if (it->first->is(key))
- return it->second;
+ for (const auto& it : m_map) {
+ if (it.first->is(key))
+ return it.second;
}
- return NULL;
+ return nullptr;
}
-node& node_data::get(node& key, shared_memory_holder pMemory) {
+node& node_data::get(node& key, const shared_memory_holder& pMemory) {
switch (m_type) {
case NodeType::Map:
break;
@@ -218,12 +231,12 @@ node& node_data::get(node& key, shared_memory_holder pMemory) {
convert_to_map(pMemory);
break;
case NodeType::Scalar:
- throw BadSubscript();
+ throw BadSubscript(m_mark, key);
}
- for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
- if (it->first->is(key))
- return *it->second;
+ for (const auto& it : m_map) {
+ if (it.first->is(key))
+ return *it.second;
}
node& value = pMemory->create_node();
@@ -231,15 +244,26 @@ node& node_data::get(node& key, shared_memory_holder pMemory) {
return value;
}
-bool node_data::remove(node& key, shared_memory_holder /* pMemory */) {
+bool node_data::remove(node& key, const shared_memory_holder& /* pMemory */) {
if (m_type != NodeType::Map)
return false;
- for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
- if (it->first->is(key)) {
- m_map.erase(it);
- return true;
- }
+ for (auto it = m_undefinedPairs.begin(); it != m_undefinedPairs.end();) {
+ auto jt = std::next(it);
+ if (it->first->is(key))
+ m_undefinedPairs.erase(it);
+ it = jt;
+ }
+
+ auto it =
+ std::find_if(m_map.begin(), m_map.end(),
+ [&](std::pair<YAML::detail::node*, YAML::detail::node*> j) {
+ return (j.first->is(key));
+ });
+
+ if (it != m_map.end()) {
+ m_map.erase(it);
+ return true;
}
return false;
@@ -262,7 +286,7 @@ void node_data::insert_map_pair(node& key, node& value) {
m_undefinedPairs.emplace_back(&key, &value);
}
-void node_data::convert_to_map(shared_memory_holder pMemory) {
+void node_data::convert_to_map(const shared_memory_holder& pMemory) {
switch (m_type) {
case NodeType::Undefined:
case NodeType::Null:
@@ -280,7 +304,7 @@ void node_data::convert_to_map(shared_memory_holder pMemory) {
}
}
-void node_data::convert_sequence_to_map(shared_memory_holder pMemory) {
+void node_data::convert_sequence_to_map(const shared_memory_holder& pMemory) {
assert(m_type == NodeType::Sequence);
reset_map();
@@ -296,5 +320,5 @@ void node_data::convert_sequence_to_map(shared_memory_holder pMemory) {
reset_sequence();
m_type = NodeType::Map;
}
-}
-}
+} // namespace detail
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp b/src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp
index 093d2efeb77..bbaefac8a60 100644
--- a/src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp
@@ -1,4 +1,3 @@
-#include <assert.h>
#include <cassert>
#include "nodebuilder.h"
@@ -11,11 +10,16 @@ namespace YAML {
struct Mark;
NodeBuilder::NodeBuilder()
- : m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) {
- m_anchors.push_back(0); // since the anchors start at 1
+ : m_pMemory(new detail::memory_holder),
+ m_pRoot(nullptr),
+ m_stack{},
+ m_anchors{},
+ m_keys{},
+ m_mapDepth(0) {
+ m_anchors.push_back(nullptr); // since the anchors start at 1
}
-NodeBuilder::~NodeBuilder() {}
+NodeBuilder::~NodeBuilder() = default;
Node NodeBuilder::Root() {
if (!m_pRoot)
@@ -88,7 +92,7 @@ void NodeBuilder::Push(detail::node& node) {
m_stack.push_back(&node);
if (needsKey)
- m_keys.push_back(PushedKey(&node, false));
+ m_keys.emplace_back(&node, false);
}
void NodeBuilder::Pop() {
@@ -127,4 +131,4 @@ void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) {
m_anchors.push_back(&node);
}
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/nodebuilder.h b/src/libs/3rdparty/yaml-cpp/src/nodebuilder.h
index a6a47f007bb..c580d40e29b 100644
--- a/src/libs/3rdparty/yaml-cpp/src/nodebuilder.h
+++ b/src/libs/3rdparty/yaml-cpp/src/nodebuilder.h
@@ -27,25 +27,29 @@ class Node;
class NodeBuilder : public EventHandler {
public:
NodeBuilder();
- virtual ~NodeBuilder();
+ NodeBuilder(const NodeBuilder&) = delete;
+ NodeBuilder(NodeBuilder&&) = delete;
+ NodeBuilder& operator=(const NodeBuilder&) = delete;
+ NodeBuilder& operator=(NodeBuilder&&) = delete;
+ ~NodeBuilder() override;
Node Root();
- virtual void OnDocumentStart(const Mark& mark);
- virtual void OnDocumentEnd();
+ void OnDocumentStart(const Mark& mark) override;
+ void OnDocumentEnd() override;
- virtual void OnNull(const Mark& mark, anchor_t anchor);
- virtual void OnAlias(const Mark& mark, anchor_t anchor);
- virtual void OnScalar(const Mark& mark, const std::string& tag,
- anchor_t anchor, const std::string& value);
+ void OnNull(const Mark& mark, anchor_t anchor) override;
+ void OnAlias(const Mark& mark, anchor_t anchor) override;
+ void OnScalar(const Mark& mark, const std::string& tag,
+ anchor_t anchor, const std::string& value) override;
- virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
- anchor_t anchor, EmitterStyle::value style);
- virtual void OnSequenceEnd();
+ void OnSequenceStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style) override;
+ void OnSequenceEnd() override;
- virtual void OnMapStart(const Mark& mark, const std::string& tag,
- anchor_t anchor, EmitterStyle::value style);
- virtual void OnMapEnd();
+ void OnMapStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style) override;
+ void OnMapEnd() override;
private:
detail::node& Push(const Mark& mark, anchor_t anchor);
@@ -57,14 +61,14 @@ class NodeBuilder : public EventHandler {
detail::shared_memory_holder m_pMemory;
detail::node* m_pRoot;
- typedef std::vector<detail::node*> Nodes;
+ using Nodes = std::vector<detail::node *>;
Nodes m_stack;
Nodes m_anchors;
- typedef std::pair<detail::node*, bool> PushedKey;
+ using PushedKey = std::pair<detail::node*, bool>;
std::vector<PushedKey> m_keys;
std::size_t m_mapDepth;
};
-}
+} // namespace YAML
#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/nodeevents.cpp b/src/libs/3rdparty/yaml-cpp/src/nodeevents.cpp
index 82261feb058..b1774fef3e4 100644
--- a/src/libs/3rdparty/yaml-cpp/src/nodeevents.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/nodeevents.cpp
@@ -13,14 +13,14 @@ void NodeEvents::AliasManager::RegisterReference(const detail::node& node) {
anchor_t NodeEvents::AliasManager::LookupAnchor(
const detail::node& node) const {
- AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref());
+ auto it = m_anchorByIdentity.find(node.ref());
if (it == m_anchorByIdentity.end())
return 0;
return it->second;
}
NodeEvents::NodeEvents(const Node& node)
- : m_pMemory(node.m_pMemory), m_root(node.m_pNode) {
+ : m_pMemory(node.m_pMemory), m_root(node.m_pNode), m_refCount{} {
if (m_root)
Setup(*m_root);
}
@@ -32,13 +32,12 @@ void NodeEvents::Setup(const detail::node& node) {
return;
if (node.type() == NodeType::Sequence) {
- for (detail::const_node_iterator it = node.begin(); it != node.end(); ++it)
- Setup(**it);
+ for (auto element : node)
+ Setup(*element);
} else if (node.type() == NodeType::Map) {
- for (detail::const_node_iterator it = node.begin(); it != node.end();
- ++it) {
- Setup(*it->first);
- Setup(*it->second);
+ for (auto element : node) {
+ Setup(*element.first);
+ Setup(*element.second);
}
}
}
@@ -77,17 +76,15 @@ void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
break;
case NodeType::Sequence:
handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style());
- for (detail::const_node_iterator it = node.begin(); it != node.end();
- ++it)
- Emit(**it, handler, am);
+ for (auto element : node)
+ Emit(*element, handler, am);
handler.OnSequenceEnd();
break;
case NodeType::Map:
handler.OnMapStart(Mark(), node.tag(), anchor, node.style());
- for (detail::const_node_iterator it = node.begin(); it != node.end();
- ++it) {
- Emit(*it->first, handler, am);
- Emit(*it->second, handler, am);
+ for (auto element : node) {
+ Emit(*element.first, handler, am);
+ Emit(*element.second, handler, am);
}
handler.OnMapEnd();
break;
@@ -95,7 +92,7 @@ void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
}
bool NodeEvents::IsAliased(const detail::node& node) const {
- RefCount::const_iterator it = m_refCount.find(node.ref());
+ auto it = m_refCount.find(node.ref());
return it != m_refCount.end() && it->second > 1;
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/nodeevents.h b/src/libs/3rdparty/yaml-cpp/src/nodeevents.h
index 49c18eb854a..efca9149ed3 100644
--- a/src/libs/3rdparty/yaml-cpp/src/nodeevents.h
+++ b/src/libs/3rdparty/yaml-cpp/src/nodeevents.h
@@ -26,13 +26,17 @@ class Node;
class NodeEvents {
public:
explicit NodeEvents(const Node& node);
+ NodeEvents(const NodeEvents&) = delete;
+ NodeEvents(NodeEvents&&) = delete;
+ NodeEvents& operator=(const NodeEvents&) = delete;
+ NodeEvents& operator=(NodeEvents&&) = delete;
void Emit(EventHandler& handler);
private:
class AliasManager {
public:
- AliasManager() : m_curAnchor(0) {}
+ AliasManager() : m_anchorByIdentity{}, m_curAnchor(0) {}
void RegisterReference(const detail::node& node);
anchor_t LookupAnchor(const detail::node& node) const;
@@ -41,7 +45,7 @@ class NodeEvents {
anchor_t _CreateNewAnchor() { return ++m_curAnchor; }
private:
- typedef std::map<const detail::node_ref*, anchor_t> AnchorByIdentity;
+ using AnchorByIdentity = std::map<const detail::node_ref*, anchor_t>;
AnchorByIdentity m_anchorByIdentity;
anchor_t m_curAnchor;
@@ -56,9 +60,9 @@ class NodeEvents {
detail::shared_memory_holder m_pMemory;
detail::node* m_root;
- typedef std::map<const detail::node_ref*, int> RefCount;
+ using RefCount = std::map<const detail::node_ref*, int>;
RefCount m_refCount;
};
-}
+} // namespace YAML
#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/null.cpp b/src/libs/3rdparty/yaml-cpp/src/null.cpp
index d12dd08ce4b..db7daebf1d2 100644
--- a/src/libs/3rdparty/yaml-cpp/src/null.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/null.cpp
@@ -7,4 +7,4 @@ bool IsNullString(const std::string& str) {
return str.empty() || str == "~" || str == "null" || str == "Null" ||
str == "NULL";
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/ostream_wrapper.cpp b/src/libs/3rdparty/yaml-cpp/src/ostream_wrapper.cpp
index 357fc0094c4..047a9f7c8ea 100644
--- a/src/libs/3rdparty/yaml-cpp/src/ostream_wrapper.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/ostream_wrapper.cpp
@@ -7,16 +7,21 @@
namespace YAML {
ostream_wrapper::ostream_wrapper()
: m_buffer(1, '\0'),
- m_pStream(0),
+ m_pStream(nullptr),
m_pos(0),
m_row(0),
m_col(0),
m_comment(false) {}
ostream_wrapper::ostream_wrapper(std::ostream& stream)
- : m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) {}
+ : m_buffer{},
+ m_pStream(&stream),
+ m_pos(0),
+ m_row(0),
+ m_col(0),
+ m_comment(false) {}
-ostream_wrapper::~ostream_wrapper() {}
+ostream_wrapper::~ostream_wrapper() = default;
void ostream_wrapper::write(const std::string& str) {
if (m_pStream) {
@@ -26,8 +31,8 @@ void ostream_wrapper::write(const std::string& str) {
std::copy(str.begin(), str.end(), m_buffer.begin() + m_pos);
}
- for (std::size_t i = 0; i < str.size(); i++) {
- update_pos(str[i]);
+ for (char ch : str) {
+ update_pos(ch);
}
}
@@ -54,4 +59,4 @@ void ostream_wrapper::update_pos(char ch) {
m_comment = false;
}
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/parse.cpp b/src/libs/3rdparty/yaml-cpp/src/parse.cpp
index 0b2ae4a4f6e..262536b85a4 100644
--- a/src/libs/3rdparty/yaml-cpp/src/parse.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/parse.cpp
@@ -3,10 +3,10 @@
#include <fstream>
#include <sstream>
-#include "yaml-cpp/node/node.h"
+#include "nodebuilder.h"
#include "yaml-cpp/node/impl.h"
+#include "yaml-cpp/node/node.h"
#include "yaml-cpp/parser.h"
-#include "nodebuilder.h"
namespace YAML {
Node Load(const std::string& input) {
@@ -30,9 +30,9 @@ Node Load(std::istream& input) {
}
Node LoadFile(const std::string& filename) {
- std::ifstream fin(filename.c_str());
+ std::ifstream fin(filename);
if (!fin) {
- throw BadFile();
+ throw BadFile(filename);
}
return Load(fin);
}
@@ -51,7 +51,7 @@ std::vector<Node> LoadAll(std::istream& input) {
std::vector<Node> docs;
Parser parser(input);
- while (1) {
+ while (true) {
NodeBuilder builder;
if (!parser.HandleNextDocument(builder)) {
break;
@@ -63,9 +63,9 @@ std::vector<Node> LoadAll(std::istream& input) {
}
std::vector<Node> LoadAllFromFile(const std::string& filename) {
- std::ifstream fin(filename.c_str());
+ std::ifstream fin(filename);
if (!fin) {
- throw BadFile();
+ throw BadFile(filename);
}
return LoadAll(fin);
}
diff --git a/src/libs/3rdparty/yaml-cpp/src/parser.cpp b/src/libs/3rdparty/yaml-cpp/src/parser.cpp
index cd69f39fcec..b8b78ebabc5 100644
--- a/src/libs/3rdparty/yaml-cpp/src/parser.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/parser.cpp
@@ -11,15 +11,13 @@
namespace YAML {
class EventHandler;
-Parser::Parser() {}
+Parser::Parser() : m_pScanner{}, m_pDirectives{} {}
-Parser::Parser(std::istream& in) { Load(in); }
+Parser::Parser(std::istream& in) : Parser() { Load(in); }
-Parser::~Parser() {}
+Parser::~Parser() = default;
-Parser::operator bool() const {
- return m_pScanner.get() && !m_pScanner->empty();
-}
+Parser::operator bool() const { return m_pScanner && !m_pScanner->empty(); }
void Parser::Load(std::istream& in) {
m_pScanner.reset(new Scanner(in));
@@ -27,7 +25,7 @@ void Parser::Load(std::istream& in) {
}
bool Parser::HandleNextDocument(EventHandler& eventHandler) {
- if (!m_pScanner.get())
+ if (!m_pScanner)
return false;
ParseDirectives();
@@ -43,11 +41,7 @@ bool Parser::HandleNextDocument(EventHandler& eventHandler) {
void Parser::ParseDirectives() {
bool readDirective = false;
- while (1) {
- if (m_pScanner->empty()) {
- break;
- }
-
+ while (!m_pScanner->empty()) {
Token& token = m_pScanner->peek();
if (token.type != Token::DIRECTIVE) {
break;
@@ -113,17 +107,13 @@ void Parser::HandleTagDirective(const Token& token) {
}
void Parser::PrintTokens(std::ostream& out) {
- if (!m_pScanner.get()) {
+ if (!m_pScanner) {
return;
}
- while (1) {
- if (m_pScanner->empty()) {
- break;
- }
-
+ while (!m_pScanner->empty()) {
out << m_pScanner->peek() << "\n";
m_pScanner->pop();
}
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/ptr_vector.h b/src/libs/3rdparty/yaml-cpp/src/ptr_vector.h
index 955aebd8d56..d58de04cb62 100644
--- a/src/libs/3rdparty/yaml-cpp/src/ptr_vector.h
+++ b/src/libs/3rdparty/yaml-cpp/src/ptr_vector.h
@@ -12,15 +12,17 @@
#include <memory>
#include <vector>
-#include "yaml-cpp/noncopyable.h"
-
namespace YAML {
// TODO: This class is no longer needed
template <typename T>
-class ptr_vector : private YAML::noncopyable {
+class ptr_vector {
public:
- ptr_vector() {}
+ ptr_vector() : m_data{} {}
+ ptr_vector(const ptr_vector&) = delete;
+ ptr_vector(ptr_vector&&) = default;
+ ptr_vector& operator=(const ptr_vector&) = delete;
+ ptr_vector& operator=(ptr_vector&&) = default;
void clear() { m_data.clear(); }
@@ -38,6 +40,6 @@ class ptr_vector : private YAML::noncopyable {
private:
std::vector<std::unique_ptr<T>> m_data;
};
-}
+} // namespace YAML
#endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/regex_yaml.cpp b/src/libs/3rdparty/yaml-cpp/src/regex_yaml.cpp
index 20b772051d2..bf1784b41d5 100644
--- a/src/libs/3rdparty/yaml-cpp/src/regex_yaml.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/regex_yaml.cpp
@@ -2,18 +2,16 @@
namespace YAML {
// constructors
-RegEx::RegEx() : m_op(REGEX_EMPTY) {}
-RegEx::RegEx(REGEX_OP op) : m_op(op) {}
+RegEx::RegEx(REGEX_OP op) : m_op(op), m_a(0), m_z(0), m_params{} {}
+RegEx::RegEx() : RegEx(REGEX_EMPTY) {}
-RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch) {}
+RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch), m_z(0), m_params{} {}
-RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z) {}
+RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z), m_params{} {}
-RegEx::RegEx(const std::string& str, REGEX_OP op) : m_op(op) {
- for (std::size_t i = 0; i < str.size(); i++)
- m_params.push_back(RegEx(str[i]));
-}
+RegEx::RegEx(const std::string& str, REGEX_OP op)
+ : m_op(op), m_a(0), m_z(0), m_params(str.begin(), str.end()) {}
// combination constructors
RegEx operator!(const RegEx& ex) {
@@ -22,14 +20,14 @@ RegEx operator!(const RegEx& ex) {
return ret;
}
-RegEx operator||(const RegEx& ex1, const RegEx& ex2) {
+RegEx operator|(const RegEx& ex1, const RegEx& ex2) {
RegEx ret(REGEX_OR);
ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2);
return ret;
}
-RegEx operator&&(const RegEx& ex1, const RegEx& ex2) {
+RegEx operator&(const RegEx& ex1, const RegEx& ex2) {
RegEx ret(REGEX_AND);
ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2);
@@ -42,4 +40,4 @@ RegEx operator+(const RegEx& ex1, const RegEx& ex2) {
ret.m_params.push_back(ex2);
return ret;
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/regex_yaml.h b/src/libs/3rdparty/yaml-cpp/src/regex_yaml.h
index 8f28b852a29..c70ab60dcc1 100644
--- a/src/libs/3rdparty/yaml-cpp/src/regex_yaml.h
+++ b/src/libs/3rdparty/yaml-cpp/src/regex_yaml.h
@@ -31,14 +31,14 @@ enum REGEX_OP {
class YAML_CPP_API RegEx {
public:
RegEx();
- RegEx(char ch);
+ explicit RegEx(char ch);
RegEx(char a, char z);
RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ);
- ~RegEx() {}
+ ~RegEx() = default;
friend YAML_CPP_API RegEx operator!(const RegEx& ex);
- friend YAML_CPP_API RegEx operator||(const RegEx& ex1, const RegEx& ex2);
- friend YAML_CPP_API RegEx operator&&(const RegEx& ex1, const RegEx& ex2);
+ friend YAML_CPP_API RegEx operator|(const RegEx& ex1, const RegEx& ex2);
+ friend YAML_CPP_API RegEx operator&(const RegEx& ex1, const RegEx& ex2);
friend YAML_CPP_API RegEx operator+(const RegEx& ex1, const RegEx& ex2);
bool Matches(char ch) const;
@@ -53,7 +53,7 @@ class YAML_CPP_API RegEx {
int Match(const Source& source) const;
private:
- RegEx(REGEX_OP op);
+ explicit RegEx(REGEX_OP op);
template <typename Source>
bool IsValidSource(const Source& source) const;
@@ -77,10 +77,11 @@ class YAML_CPP_API RegEx {
private:
REGEX_OP m_op;
- char m_a, m_z;
+ char m_a{};
+ char m_z{};
std::vector<RegEx> m_params;
};
-}
+} // namespace YAML
#include "regeximpl.h"
diff --git a/src/libs/3rdparty/yaml-cpp/src/regeximpl.h b/src/libs/3rdparty/yaml-cpp/src/regeximpl.h
index 709124f0088..a742cdc3050 100644
--- a/src/libs/3rdparty/yaml-cpp/src/regeximpl.h
+++ b/src/libs/3rdparty/yaml-cpp/src/regeximpl.h
@@ -8,8 +8,8 @@
#endif
#include "stream.h"
-#include "stringsource.h"
#include "streamcharsource.h"
+#include "stringsource.h"
namespace YAML {
// query matches
@@ -106,9 +106,8 @@ inline int RegEx::MatchOpEmpty(const Source& source) const {
template <>
inline int RegEx::MatchOpEmpty<StringCharSource>(
const StringCharSource& source) const {
- return !source
- ? 0
- : -1; // the empty regex only is successful on the empty string
+ return !source ? 0 : -1; // the empty regex only is successful on the empty
+ // string
}
// MatchOperator
@@ -130,8 +129,8 @@ inline int RegEx::MatchOpRange(const Source& source) const {
// OrOperator
template <typename Source>
inline int RegEx::MatchOpOr(const Source& source) const {
- for (std::size_t i = 0; i < m_params.size(); i++) {
- int n = m_params[i].MatchUnchecked(source);
+ for (const RegEx& param : m_params) {
+ int n = param.MatchUnchecked(source);
if (n >= 0)
return n;
}
@@ -169,11 +168,11 @@ inline int RegEx::MatchOpNot(const Source& source) const {
template <typename Source>
inline int RegEx::MatchOpSeq(const Source& source) const {
int offset = 0;
- for (std::size_t i = 0; i < m_params.size(); i++) {
- int n = m_params[i].Match(source + offset); // note Match, not
- // MatchUnchecked because we
- // need to check validity after
- // the offset
+ for (const RegEx& param : m_params) {
+ int n = param.Match(source + offset); // note Match, not
+ // MatchUnchecked because we
+ // need to check validity after
+ // the offset
if (n == -1)
return -1;
offset += n;
@@ -181,6 +180,6 @@ inline int RegEx::MatchOpSeq(const Source& source) const {
return offset;
}
-}
+} // namespace YAML
#endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/scanner.cpp b/src/libs/3rdparty/yaml-cpp/src/scanner.cpp
index b5cfcc12b22..ea5511a114c 100644
--- a/src/libs/3rdparty/yaml-cpp/src/scanner.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/scanner.cpp
@@ -9,12 +9,17 @@
namespace YAML {
Scanner::Scanner(std::istream& in)
: INPUT(in),
+ m_tokens{},
m_startedStream(false),
m_endedStream(false),
m_simpleKeyAllowed(false),
- m_canBeJSONFlow(false) {}
+ m_canBeJSONFlow(false),
+ m_simpleKeys{},
+ m_indents{},
+ m_indentRefs{},
+ m_flows{} {}
-Scanner::~Scanner() {}
+Scanner::~Scanner() = default;
bool Scanner::empty() {
EnsureTokensInQueue();
@@ -46,7 +51,7 @@ Token& Scanner::peek() {
Mark Scanner::mark() const { return INPUT.mark(); }
void Scanner::EnsureTokensInQueue() {
- while (1) {
+ while (true) {
if (!m_tokens.empty()) {
Token& token = m_tokens.front();
@@ -83,7 +88,7 @@ void Scanner::ScanNextToken() {
return StartStream();
}
- // get rid of whitespace, etc. (in between tokens it should be irrelevent)
+ // get rid of whitespace, etc. (in between tokens it should be irrelevant)
ScanToNextToken();
// maybe need to end some blocks
@@ -169,7 +174,7 @@ void Scanner::ScanNextToken() {
}
void Scanner::ScanToNextToken() {
- while (1) {
+ while (true) {
// first eat whitespace
while (INPUT && IsWhitespaceToBeEaten(INPUT.peek())) {
if (InBlockContext() && Exp::Tab().Matches(INPUT)) {
@@ -282,7 +287,7 @@ Scanner::IndentMarker* Scanner::PushIndentTo(int column,
IndentMarker::INDENT_TYPE type) {
// are we in flow?
if (InFlowContext()) {
- return 0;
+ return nullptr;
}
std::unique_ptr<IndentMarker> pIndent(new IndentMarker(column, type));
@@ -291,12 +296,12 @@ Scanner::IndentMarker* Scanner::PushIndentTo(int column,
// is this actually an indentation?
if (indent.column < lastIndent.column) {
- return 0;
+ return nullptr;
}
if (indent.column == lastIndent.column &&
!(indent.type == IndentMarker::SEQ &&
lastIndent.type == IndentMarker::MAP)) {
- return 0;
+ return nullptr;
}
// push a start token
diff --git a/src/libs/3rdparty/yaml-cpp/src/scanner.h b/src/libs/3rdparty/yaml-cpp/src/scanner.h
index 7bb2ccc71a5..4af938e69c3 100644
--- a/src/libs/3rdparty/yaml-cpp/src/scanner.h
+++ b/src/libs/3rdparty/yaml-cpp/src/scanner.h
@@ -9,9 +9,7 @@
#include <cstddef>
#include <ios>
-#include <map>
#include <queue>
-#include <set>
#include <stack>
#include <string>
@@ -49,7 +47,7 @@ class Scanner {
enum INDENT_TYPE { MAP, SEQ, NONE };
enum STATUS { VALID, INVALID, UNKNOWN };
IndentMarker(int column_, INDENT_TYPE type_)
- : column(column_), type(type_), status(VALID), pStartToken(0) {}
+ : column(column_), type(type_), status(VALID), pStartToken(nullptr) {}
int column;
INDENT_TYPE type;
diff --git a/src/libs/3rdparty/yaml-cpp/src/scanscalar.cpp b/src/libs/3rdparty/yaml-cpp/src/scanscalar.cpp
index 10e359d4466..be57b1cd5d5 100644
--- a/src/libs/3rdparty/yaml-cpp/src/scanscalar.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/scanscalar.cpp
@@ -47,7 +47,8 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
if (INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) {
if (params.onDocIndicator == BREAK) {
break;
- } else if (params.onDocIndicator == THROW) {
+ }
+ if (params.onDocIndicator == THROW) {
throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR);
}
}
@@ -183,7 +184,7 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
case FOLD_FLOW:
if (nextEmptyLine) {
scalar += "\n";
- } else if (!emptyLine && !nextEmptyLine && !escapedNewline) {
+ } else if (!emptyLine && !escapedNewline) {
scalar += " ";
}
break;
@@ -203,7 +204,7 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
// post-processing
if (params.trimTrailingSpaces) {
- std::size_t pos = scalar.find_last_not_of(' ');
+ std::size_t pos = scalar.find_last_not_of(" \t");
if (lastEscapedChar != std::string::npos) {
if (pos < lastEscapedChar || pos == std::string::npos) {
pos = lastEscapedChar;
@@ -247,4 +248,4 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
return scalar;
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/scanscalar.h b/src/libs/3rdparty/yaml-cpp/src/scanscalar.h
index c3a574ad9b6..296b885a515 100644
--- a/src/libs/3rdparty/yaml-cpp/src/scanscalar.h
+++ b/src/libs/3rdparty/yaml-cpp/src/scanscalar.h
@@ -57,7 +57,7 @@ struct ScanScalarParams {
bool leadingSpaces;
};
-std::string ScanScalar(Stream& INPUT, ScanScalarParams& info);
+std::string ScanScalar(Stream& INPUT, ScanScalarParams& params);
}
#endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/scantag.cpp b/src/libs/3rdparty/yaml-cpp/src/scantag.cpp
index c5b39652ad0..176cc5c711c 100644
--- a/src/libs/3rdparty/yaml-cpp/src/scantag.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/scantag.cpp
@@ -78,4 +78,4 @@ const std::string ScanTagSuffix(Stream& INPUT) {
return tag;
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/scantoken.cpp b/src/libs/3rdparty/yaml-cpp/src/scantoken.cpp
index fd8758d7815..1a94ab1d7d0 100644
--- a/src/libs/3rdparty/yaml-cpp/src/scantoken.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/scantoken.cpp
@@ -37,7 +37,7 @@ void Scanner::ScanDirective() {
token.value += INPUT.get();
// read parameters
- while (1) {
+ while (true) {
// first get rid of whitespace
while (Exp::Blank().Matches(INPUT))
INPUT.eat(1);
@@ -171,7 +171,7 @@ void Scanner::ScanBlockEntry() {
// Key
void Scanner::ScanKey() {
- // handle keys diffently in the block context (and manage indents)
+ // handle keys differently in the block context (and manage indents)
if (InBlockContext()) {
if (!m_simpleKeyAllowed)
throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY);
@@ -199,7 +199,7 @@ void Scanner::ScanValue() {
// seems fine)
m_simpleKeyAllowed = false;
} else {
- // handle values diffently in the block context (and manage indents)
+ // handle values differently in the block context (and manage indents)
if (InBlockContext()) {
if (!m_simpleKeyAllowed)
throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE);
@@ -338,7 +338,7 @@ void Scanner::ScanQuotedScalar() {
// setup the scanning parameters
ScanScalarParams params;
- RegEx end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote));
+ RegEx end = (single ? RegEx(quote) & !Exp::EscSingleQuote() : RegEx(quote));
params.end = &end;
params.eatEnd = true;
params.escape = (single ? '\'' : '\\');
@@ -434,4 +434,4 @@ void Scanner::ScanBlockScalar() {
token.value = scalar;
m_tokens.push(token);
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/setting.h b/src/libs/3rdparty/yaml-cpp/src/setting.h
index b78d40e2e85..4960bbf75c4 100644
--- a/src/libs/3rdparty/yaml-cpp/src/setting.h
+++ b/src/libs/3rdparty/yaml-cpp/src/setting.h
@@ -7,17 +7,24 @@
#pragma once
#endif
+#include "yaml-cpp/noexcept.h"
#include <memory>
+#include <utility>
#include <vector>
-#include "yaml-cpp/noncopyable.h"
namespace YAML {
-class SettingChangeBase;
+
+class SettingChangeBase {
+ public:
+ virtual ~SettingChangeBase() = default;
+ virtual void pop() = 0;
+};
template <typename T>
class Setting {
public:
Setting() : m_value() {}
+ Setting(const T& value) : m_value() { set(value); }
const T get() const { return m_value; }
std::unique_ptr<SettingChangeBase> set(const T& value);
@@ -27,21 +34,19 @@ class Setting {
T m_value;
};
-class SettingChangeBase {
- public:
- virtual ~SettingChangeBase() {}
- virtual void pop() = 0;
-};
-
template <typename T>
class SettingChange : public SettingChangeBase {
public:
- SettingChange(Setting<T>* pSetting) : m_pCurSetting(pSetting) {
- // copy old setting to save its state
- m_oldSetting = *pSetting;
- }
+ SettingChange(Setting<T>* pSetting)
+ : m_pCurSetting(pSetting),
+ m_oldSetting(*pSetting) // copy old setting to save its state
+ {}
+ SettingChange(const SettingChange&) = delete;
+ SettingChange(SettingChange&&) = delete;
+ SettingChange& operator=(const SettingChange&) = delete;
+ SettingChange& operator=(SettingChange&&) = delete;
- virtual void pop() { m_pCurSetting->restore(m_oldSetting); }
+ void pop() override { m_pCurSetting->restore(m_oldSetting); }
private:
Setting<T>* m_pCurSetting;
@@ -55,41 +60,41 @@ inline std::unique_ptr<SettingChangeBase> Setting<T>::set(const T& value) {
return pChange;
}
-class SettingChanges : private noncopyable {
+class SettingChanges {
public:
- SettingChanges() {}
+ SettingChanges() : m_settingChanges{} {}
+ SettingChanges(const SettingChanges&) = delete;
+ SettingChanges(SettingChanges&&) YAML_CPP_NOEXCEPT = default;
+ SettingChanges& operator=(const SettingChanges&) = delete;
+ SettingChanges& operator=(SettingChanges&& rhs) YAML_CPP_NOEXCEPT {
+ if (this == &rhs)
+ return *this;
+
+ clear();
+ std::swap(m_settingChanges, rhs.m_settingChanges);
+
+ return *this;
+ }
~SettingChanges() { clear(); }
- void clear() {
+ void clear() YAML_CPP_NOEXCEPT {
restore();
m_settingChanges.clear();
}
- void restore() {
- for (setting_changes::const_iterator it = m_settingChanges.begin();
- it != m_settingChanges.end(); ++it)
- (*it)->pop();
+ void restore() YAML_CPP_NOEXCEPT {
+ for (const auto& setting : m_settingChanges)
+ setting->pop();
}
void push(std::unique_ptr<SettingChangeBase> pSettingChange) {
m_settingChanges.push_back(std::move(pSettingChange));
}
- // like std::unique_ptr - assignment is transfer of ownership
- SettingChanges& operator=(SettingChanges&& rhs) {
- if (this == &rhs)
- return *this;
-
- clear();
- std::swap(m_settingChanges, rhs.m_settingChanges);
-
- return *this;
- }
-
private:
- typedef std::vector<std::unique_ptr<SettingChangeBase>> setting_changes;
+ using setting_changes = std::vector<std::unique_ptr<SettingChangeBase>>;
setting_changes m_settingChanges;
};
-}
+} // namespace YAML
#endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/simplekey.cpp b/src/libs/3rdparty/yaml-cpp/src/simplekey.cpp
index 70f56b6ae42..67c2d712efe 100644
--- a/src/libs/3rdparty/yaml-cpp/src/simplekey.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/simplekey.cpp
@@ -5,7 +5,11 @@ namespace YAML {
struct Mark;
Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_)
- : mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0) {}
+ : mark(mark_),
+ flowLevel(flowLevel_),
+ pIndent(nullptr),
+ pMapStart(nullptr),
+ pKey(nullptr) {}
void Scanner::SimpleKey::Validate() {
// Note: pIndent will *not* be garbage here;
@@ -125,4 +129,4 @@ void Scanner::PopAllSimpleKeys() {
while (!m_simpleKeys.empty())
m_simpleKeys.pop();
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/singledocparser.cpp b/src/libs/3rdparty/yaml-cpp/src/singledocparser.cpp
index a27c1c3b04d..22913d198c2 100644
--- a/src/libs/3rdparty/yaml-cpp/src/singledocparser.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/singledocparser.cpp
@@ -7,6 +7,7 @@
#include "singledocparser.h"
#include "tag.h"
#include "token.h"
+#include "yaml-cpp/depthguard.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
@@ -18,9 +19,10 @@ SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives)
: m_scanner(scanner),
m_directives(directives),
m_pCollectionStack(new CollectionStack),
+ m_anchors{},
m_curAnchor(0) {}
-SingleDocParser::~SingleDocParser() {}
+SingleDocParser::~SingleDocParser() = default;
// HandleDocument
// . Handles the next document
@@ -46,6 +48,8 @@ void SingleDocParser::HandleDocument(EventHandler& eventHandler) {
}
void SingleDocParser::HandleNode(EventHandler& eventHandler) {
+ DepthGuard<500> depthguard(depth, m_scanner.mark(), ErrorMsg::BAD_FILE);
+
// an empty node *is* a possibility
if (m_scanner.empty()) {
eventHandler.OnNull(m_scanner.mark(), NullAnchor);
@@ -71,20 +75,31 @@ void SingleDocParser::HandleNode(EventHandler& eventHandler) {
}
std::string tag;
+ std::string anchor_name;
anchor_t anchor;
- ParseProperties(tag, anchor);
+ ParseProperties(tag, anchor, anchor_name);
- const Token& token = m_scanner.peek();
+ if (!anchor_name.empty())
+ eventHandler.OnAnchor(mark, anchor_name);
- if (token.type == Token::PLAIN_SCALAR && IsNullString(token.value)) {
+ // after parsing properties, an empty node is again a possibility
+ if (m_scanner.empty()) {
eventHandler.OnNull(mark, anchor);
- m_scanner.pop();
return;
}
+ const Token& token = m_scanner.peek();
+
// add non-specific tags
if (tag.empty())
tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
+
+ if (token.type == Token::PLAIN_SCALAR
+ && tag.compare("?") == 0 && IsNullString(token.value)) {
+ eventHandler.OnNull(mark, anchor);
+ m_scanner.pop();
+ return;
+ }
// now split based on what kind of node we should be
switch (token.type) {
@@ -152,7 +167,7 @@ void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) {
m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq);
- while (1) {
+ while (true) {
if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ);
@@ -166,10 +181,10 @@ void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) {
// check for null
if (!m_scanner.empty()) {
- const Token& token = m_scanner.peek();
- if (token.type == Token::BLOCK_ENTRY ||
- token.type == Token::BLOCK_SEQ_END) {
- eventHandler.OnNull(token.mark, NullAnchor);
+ const Token& nextToken = m_scanner.peek();
+ if (nextToken.type == Token::BLOCK_ENTRY ||
+ nextToken.type == Token::BLOCK_SEQ_END) {
+ eventHandler.OnNull(nextToken.mark, NullAnchor);
continue;
}
}
@@ -185,7 +200,7 @@ void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler) {
m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq);
- while (1) {
+ while (true) {
if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
@@ -238,7 +253,7 @@ void SingleDocParser::HandleBlockMap(EventHandler& eventHandler) {
m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::BlockMap);
- while (1) {
+ while (true) {
if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP);
@@ -277,7 +292,7 @@ void SingleDocParser::HandleFlowMap(EventHandler& eventHandler) {
m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::FlowMap);
- while (1) {
+ while (true) {
if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
@@ -356,11 +371,13 @@ void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler) {
// ParseProperties
// . Grabs any tag or anchor tokens and deals with them.
-void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor) {
+void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor,
+ std::string& anchor_name) {
tag.clear();
+ anchor_name.clear();
anchor = NullAnchor;
- while (1) {
+ while (true) {
if (m_scanner.empty())
return;
@@ -369,7 +386,7 @@ void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor) {
ParseTag(tag);
break;
case Token::ANCHOR:
- ParseAnchor(anchor);
+ ParseAnchor(anchor, anchor_name);
break;
default:
return;
@@ -387,11 +404,12 @@ void SingleDocParser::ParseTag(std::string& tag) {
m_scanner.pop();
}
-void SingleDocParser::ParseAnchor(anchor_t& anchor) {
+void SingleDocParser::ParseAnchor(anchor_t& anchor, std::string& anchor_name) {
Token& token = m_scanner.peek();
if (anchor)
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
+ anchor_name = token.value;
anchor = RegisterAnchor(token.value);
m_scanner.pop();
}
@@ -405,10 +423,13 @@ anchor_t SingleDocParser::RegisterAnchor(const std::string& name) {
anchor_t SingleDocParser::LookupAnchor(const Mark& mark,
const std::string& name) const {
- Anchors::const_iterator it = m_anchors.find(name);
- if (it == m_anchors.end())
- throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR);
+ auto it = m_anchors.find(name);
+ if (it == m_anchors.end()) {
+ std::stringstream ss;
+ ss << ErrorMsg::UNKNOWN_ANCHOR << name;
+ throw ParserException(mark, ss.str());
+ }
return it->second;
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/singledocparser.h b/src/libs/3rdparty/yaml-cpp/src/singledocparser.h
index 2b92067cddb..f484eb1f957 100644
--- a/src/libs/3rdparty/yaml-cpp/src/singledocparser.h
+++ b/src/libs/3rdparty/yaml-cpp/src/singledocparser.h
@@ -12,10 +12,10 @@
#include <string>
#include "yaml-cpp/anchor.h"
-#include "yaml-cpp/noncopyable.h"
namespace YAML {
class CollectionStack;
+template <int> class DepthGuard; // depthguard.h
class EventHandler;
class Node;
class Scanner;
@@ -23,9 +23,13 @@ struct Directives;
struct Mark;
struct Token;
-class SingleDocParser : private noncopyable {
+class SingleDocParser {
public:
SingleDocParser(Scanner& scanner, const Directives& directives);
+ SingleDocParser(const SingleDocParser&) = delete;
+ SingleDocParser(SingleDocParser&&) = delete;
+ SingleDocParser& operator=(const SingleDocParser&) = delete;
+ SingleDocParser& operator=(SingleDocParser&&) = delete;
~SingleDocParser();
void HandleDocument(EventHandler& eventHandler);
@@ -43,23 +47,25 @@ class SingleDocParser : private noncopyable {
void HandleCompactMap(EventHandler& eventHandler);
void HandleCompactMapWithNoKey(EventHandler& eventHandler);
- void ParseProperties(std::string& tag, anchor_t& anchor);
+ void ParseProperties(std::string& tag, anchor_t& anchor,
+ std::string& anchor_name);
void ParseTag(std::string& tag);
- void ParseAnchor(anchor_t& anchor);
+ void ParseAnchor(anchor_t& anchor, std::string& anchor_name);
anchor_t RegisterAnchor(const std::string& name);
anchor_t LookupAnchor(const Mark& mark, const std::string& name) const;
private:
+ int depth = 0;
Scanner& m_scanner;
const Directives& m_directives;
std::unique_ptr<CollectionStack> m_pCollectionStack;
- typedef std::map<std::string, anchor_t> Anchors;
+ using Anchors = std::map<std::string, anchor_t>;
Anchors m_anchors;
anchor_t m_curAnchor;
};
-}
+} // namespace YAML
#endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/stream.cpp b/src/libs/3rdparty/yaml-cpp/src/stream.cpp
index 3b013cfa7d3..b1aa092f693 100644
--- a/src/libs/3rdparty/yaml-cpp/src/stream.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/stream.cpp
@@ -111,24 +111,15 @@ static UtfIntroState s_introTransitions[][uictMax] = {
static char s_introUngetCount[][uictMax] = {
// uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther
- {0, 1, 1, 0, 0, 0, 0, 1},
- {0, 2, 2, 2, 2, 2, 2, 2},
- {3, 3, 3, 3, 0, 3, 3, 3},
- {4, 4, 4, 4, 4, 0, 4, 4},
- {1, 1, 1, 1, 1, 1, 1, 1},
- {1, 1, 1, 1, 1, 1, 1, 1},
- {2, 2, 2, 2, 2, 0, 2, 2},
- {2, 2, 2, 2, 0, 2, 2, 2},
- {0, 1, 1, 1, 1, 1, 1, 1},
- {0, 2, 2, 2, 2, 2, 2, 2},
- {1, 1, 1, 1, 1, 1, 1, 1},
- {1, 1, 1, 1, 1, 1, 1, 1},
- {0, 2, 2, 2, 2, 2, 2, 2},
- {0, 3, 3, 3, 3, 3, 3, 3},
- {4, 4, 4, 4, 4, 4, 4, 4},
- {2, 0, 2, 2, 2, 2, 2, 2},
- {3, 3, 0, 3, 3, 3, 3, 3},
- {1, 1, 1, 1, 1, 1, 1, 1},
+ {0, 1, 1, 0, 0, 0, 0, 1}, {0, 2, 2, 2, 2, 2, 2, 2},
+ {3, 3, 3, 3, 0, 3, 3, 3}, {4, 4, 4, 4, 4, 0, 4, 4},
+ {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1},
+ {2, 2, 2, 2, 2, 0, 2, 2}, {2, 2, 2, 2, 0, 2, 2, 2},
+ {0, 1, 1, 1, 1, 1, 1, 1}, {0, 2, 2, 2, 2, 2, 2, 2},
+ {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1},
+ {0, 2, 2, 2, 2, 2, 2, 2}, {0, 3, 3, 3, 3, 3, 3, 3},
+ {4, 4, 4, 4, 4, 4, 4, 4}, {2, 0, 2, 2, 2, 2, 2, 2},
+ {3, 3, 0, 3, 3, 3, 3, 3}, {1, 1, 1, 1, 1, 1, 1, 1},
};
inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) {
@@ -160,7 +151,8 @@ inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) {
inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits,
unsigned char rshift) {
- const unsigned char header = ((1 << lead_bits) - 1) << (8 - lead_bits);
+ const unsigned char header =
+ static_cast<unsigned char>(((1 << lead_bits) - 1) << (8 - lead_bits));
const unsigned char mask = (0xFF >> (lead_bits + 1));
return static_cast<char>(
static_cast<unsigned char>(header | ((ch >> rshift) & mask)));
@@ -192,17 +184,20 @@ inline void QueueUnicodeCodepoint(std::deque<char>& q, unsigned long ch) {
Stream::Stream(std::istream& input)
: m_input(input),
+ m_mark{},
+ m_charSet{},
+ m_readahead{},
m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]),
m_nPrefetchedAvailable(0),
m_nPrefetchedUsed(0) {
- typedef std::istream::traits_type char_traits;
+ using char_traits = std::istream::traits_type;
if (!input)
return;
// Determine (or guess) the character-set by reading the BOM, if any. See
// the YAML specification for the determination algorithm.
- char_traits::int_type intro[4];
+ char_traits::int_type intro[4]{};
int nIntroUsed = 0;
UtfIntroState state = uis_start;
for (; !s_introFinalState[state];) {
@@ -279,9 +274,11 @@ char Stream::get() {
// . Extracts 'n' characters from the stream and updates our position
std::string Stream::get(int n) {
std::string ret;
- ret.reserve(n);
- for (int i = 0; i < n; i++)
- ret += get();
+ if (n > 0) {
+ ret.reserve(static_cast<std::string::size_type>(n));
+ for (int i = 0; i < n; i++)
+ ret += get();
+ }
return ret;
}
@@ -332,7 +329,7 @@ bool Stream::_ReadAheadTo(size_t i) const {
void Stream::StreamInUtf8() const {
unsigned char b = GetNextByte();
if (m_input.good()) {
- m_readahead.push_back(b);
+ m_readahead.push_back(static_cast<char>(b));
}
}
@@ -353,7 +350,9 @@ void Stream::StreamInUtf16() const {
// Trailing (low) surrogate...ugh, wrong order
QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
return;
- } else if (ch >= 0xD800 && ch < 0xDC00) {
+ }
+
+ if (ch >= 0xD800 && ch < 0xDC00) {
// ch is a leading (high) surrogate
// Four byte UTF-8 code point
@@ -378,11 +377,10 @@ void Stream::StreamInUtf16() const {
// Easiest case: queue the codepoint and return
QueueUnicodeCodepoint(m_readahead, ch);
return;
- } else {
- // Start the loop over with the new high surrogate
- ch = chLow;
- continue;
}
+ // Start the loop over with the new high surrogate
+ ch = chLow;
+ continue;
}
// Select the payload bits from the high surrogate
@@ -445,4 +443,4 @@ void Stream::StreamInUtf32() const {
QueueUnicodeCodepoint(m_readahead, ch);
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/stream.h b/src/libs/3rdparty/yaml-cpp/src/stream.h
index 42d542d5b16..2bc7a152165 100644
--- a/src/libs/3rdparty/yaml-cpp/src/stream.h
+++ b/src/libs/3rdparty/yaml-cpp/src/stream.h
@@ -7,7 +7,6 @@
#pragma once
#endif
-#include "yaml-cpp/noncopyable.h"
#include "yaml-cpp/mark.h"
#include <cstddef>
#include <deque>
@@ -17,11 +16,18 @@
#include <string>
namespace YAML {
-class Stream : private noncopyable {
+
+class StreamCharSource;
+
+class Stream {
public:
friend class StreamCharSource;
Stream(std::istream& input);
+ Stream(const Stream&) = delete;
+ Stream(Stream&&) = delete;
+ Stream& operator=(const Stream&) = delete;
+ Stream& operator=(Stream&&) = delete;
~Stream();
operator bool() const;
@@ -71,6 +77,6 @@ inline bool Stream::ReadAheadTo(size_t i) const {
return true;
return _ReadAheadTo(i);
}
-}
+} // namespace YAML
#endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/streamcharsource.h b/src/libs/3rdparty/yaml-cpp/src/streamcharsource.h
index 624599e65da..826ba5347ee 100644
--- a/src/libs/3rdparty/yaml-cpp/src/streamcharsource.h
+++ b/src/libs/3rdparty/yaml-cpp/src/streamcharsource.h
@@ -7,16 +7,20 @@
#pragma once
#endif
-#include "yaml-cpp/noncopyable.h"
+#include "yaml-cpp/noexcept.h"
+#include "stream.h"
#include <cstddef>
namespace YAML {
+
class StreamCharSource {
public:
StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {}
- StreamCharSource(const StreamCharSource& source)
- : m_offset(source.m_offset), m_stream(source.m_stream) {}
- ~StreamCharSource() {}
+ StreamCharSource(const StreamCharSource& source) = default;
+ StreamCharSource(StreamCharSource&&) YAML_CPP_NOEXCEPT = default;
+ StreamCharSource& operator=(const StreamCharSource&) = delete;
+ StreamCharSource& operator=(StreamCharSource&&) = delete;
+ ~StreamCharSource() = default;
operator bool() const;
char operator[](std::size_t i) const { return m_stream.CharAt(m_offset + i); }
@@ -27,8 +31,6 @@ class StreamCharSource {
private:
std::size_t m_offset;
const Stream& m_stream;
-
- StreamCharSource& operator=(const StreamCharSource&); // non-assignable
};
inline StreamCharSource::operator bool() const {
@@ -38,11 +40,11 @@ inline StreamCharSource::operator bool() const {
inline const StreamCharSource StreamCharSource::operator+(int i) const {
StreamCharSource source(*this);
if (static_cast<int>(source.m_offset) + i >= 0)
- source.m_offset += i;
+ source.m_offset += static_cast<std::size_t>(i);
else
source.m_offset = 0;
return source;
}
-}
+} // namespace YAML
#endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/tag.cpp b/src/libs/3rdparty/yaml-cpp/src/tag.cpp
index 51435520e46..35a1b465604 100644
--- a/src/libs/3rdparty/yaml-cpp/src/tag.cpp
+++ b/src/libs/3rdparty/yaml-cpp/src/tag.cpp
@@ -6,7 +6,8 @@
#include "token.h"
namespace YAML {
-Tag::Tag(const Token& token) : type(static_cast<TYPE>(token.data)) {
+Tag::Tag(const Token& token)
+ : type(static_cast<TYPE>(token.data)), handle{}, value{} {
switch (type) {
case VERBATIM:
value = token.value;
@@ -28,7 +29,7 @@ Tag::Tag(const Token& token) : type(static_cast<TYPE>(token.data)) {
}
}
-const std::string Tag::Translate(const Directives& directives) {
+std::string Tag::Translate(const Directives& directives) {
switch (type) {
case VERBATIM:
return value;
@@ -46,4 +47,4 @@ const std::string Tag::Translate(const Directives& directives) {
}
throw std::runtime_error("yaml-cpp: internal error, bad tag type");
}
-}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/tag.h b/src/libs/3rdparty/yaml-cpp/src/tag.h
index ac30673b9e8..c811f395597 100644
--- a/src/libs/3rdparty/yaml-cpp/src/tag.h
+++ b/src/libs/3rdparty/yaml-cpp/src/tag.h
@@ -23,7 +23,7 @@ struct Tag {
};
Tag(const Token& token);
- const std::string Translate(const Directives& directives);
+ std::string Translate(const Directives& directives);
TYPE type;
std::string handle, value;
diff --git a/src/libs/3rdparty/yaml-cpp/src/token.h b/src/libs/3rdparty/yaml-cpp/src/token.h
index ad0b7d0a005..9c9a5b77982 100644
--- a/src/libs/3rdparty/yaml-cpp/src/token.h
+++ b/src/libs/3rdparty/yaml-cpp/src/token.h
@@ -14,10 +14,11 @@
namespace YAML {
const std::string TokenNames[] = {
- "DIRECTIVE", "DOC_START", "DOC_END", "BLOCK_SEQ_START", "BLOCK_MAP_START",
- "BLOCK_SEQ_END", "BLOCK_MAP_END", "BLOCK_ENTRY", "FLOW_SEQ_START",
- "FLOW_MAP_START", "FLOW_SEQ_END", "FLOW_MAP_END", "FLOW_MAP_COMPACT",
- "FLOW_ENTRY", "KEY", "VALUE", "ANCHOR", "ALIAS", "TAG", "SCALAR"};
+ "DIRECTIVE", "DOC_START", "DOC_END", "BLOCK_SEQ_START",
+ "BLOCK_MAP_START", "BLOCK_SEQ_END", "BLOCK_MAP_END", "BLOCK_ENTRY",
+ "FLOW_SEQ_START", "FLOW_MAP_START", "FLOW_SEQ_END", "FLOW_MAP_END",
+ "FLOW_MAP_COMPACT", "FLOW_ENTRY", "KEY", "VALUE",
+ "ANCHOR", "ALIAS", "TAG", "SCALAR"};
struct Token {
// enums
@@ -48,12 +49,12 @@ struct Token {
// data
Token(TYPE type_, const Mark& mark_)
- : status(VALID), type(type_), mark(mark_), data(0) {}
+ : status(VALID), type(type_), mark(mark_), value{}, params{}, data(0) {}
friend std::ostream& operator<<(std::ostream& out, const Token& token) {
out << TokenNames[token.type] << std::string(": ") << token.value;
- for (std::size_t i = 0; i < token.params.size(); i++)
- out << std::string(" ") << token.params[i];
+ for (const std::string& param : token.params)
+ out << std::string(" ") << param;
return out;
}
@@ -64,6 +65,6 @@ struct Token {
std::vector<std::string> params;
int data;
};
-}
+} // namespace YAML
#endif // TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp.pc.cmake b/src/libs/3rdparty/yaml-cpp/yaml-cpp.pc.cmake
deleted file mode 100644
index 3db7962eaf5..00000000000
--- a/src/libs/3rdparty/yaml-cpp/yaml-cpp.pc.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-includedir=${prefix}/@INCLUDE_INSTALL_ROOT_DIR@
-libdir=${exec_prefix}/@LIB_INSTALL_DIR@
-
-Name: Yaml-cpp
-Description: A YAML parser and emitter for C++
-Version: @YAML_CPP_VERSION@
-Requires:
-Libs: -L${libdir} -lyaml-cpp
-Cflags: -I${includedir}
diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp.qbs b/src/libs/3rdparty/yaml-cpp/yaml-cpp.qbs
index ca39a4864f9..d6558880f8e 100644
--- a/src/libs/3rdparty/yaml-cpp/yaml-cpp.qbs
+++ b/src/libs/3rdparty/yaml-cpp/yaml-cpp.qbs
@@ -1,105 +1,102 @@
-import qbs 1.0
+QtcLibrary {
+ name: "yaml-cpp"
-Project {
- QtcLibrary {
- name: "yaml-cpp"
+ cpp.defines: base.concat(["YAML_CPP_DLL", "yaml_cpp_EXPORTS"])
+ cpp.includePaths: [product.sourceDirectory + "/include/"]
- cpp.defines: base.concat(["YAML_CPP_DLL", "yaml_cpp_EXPORTS"])
- cpp.includePaths: [product.sourceDirectory + "/include/"]
+ files: [
+ "include/yaml-cpp/anchor.h",
+ "include/yaml-cpp/binary.h",
+ "include/yaml-cpp/depthguard.h",
+ "include/yaml-cpp/dll.h",
+ "include/yaml-cpp/emitfromevents.h",
+ "include/yaml-cpp/emitter.h",
+ "include/yaml-cpp/emitterdef.h",
+ "include/yaml-cpp/emittermanip.h",
+ "include/yaml-cpp/emitterstyle.h",
+ "include/yaml-cpp/eventhandler.h",
+ "include/yaml-cpp/exceptions.h",
+ "include/yaml-cpp/mark.h",
+ "include/yaml-cpp/noexcept.h",
+ "include/yaml-cpp/node",
+ "include/yaml-cpp/node/convert.h",
+ "include/yaml-cpp/node/detail",
+ "include/yaml-cpp/node/detail/impl.h",
+ "include/yaml-cpp/node/detail/iterator.h",
+ "include/yaml-cpp/node/detail/iterator_fwd.h",
+ "include/yaml-cpp/node/detail/memory.h",
+ "include/yaml-cpp/node/detail/node.h",
+ "include/yaml-cpp/node/detail/node_data.h",
+ "include/yaml-cpp/node/detail/node_iterator.h",
+ "include/yaml-cpp/node/detail/node_ref.h",
+ "include/yaml-cpp/node/emit.h",
+ "include/yaml-cpp/node/impl.h",
+ "include/yaml-cpp/node/iterator.h",
+ "include/yaml-cpp/node/node.h",
+ "include/yaml-cpp/node/parse.h",
+ "include/yaml-cpp/node/ptr.h",
+ "include/yaml-cpp/node/type.h",
+ "include/yaml-cpp/null.h",
+ "include/yaml-cpp/ostream_wrapper.h",
+ "include/yaml-cpp/parser.h",
+ "include/yaml-cpp/stlemitter.h",
+ "include/yaml-cpp/traits.h",
+ "include/yaml-cpp/yaml.h",
+ "src/binary.cpp",
+ "src/collectionstack.h",
+ "src/convert.cpp",
+ "src/depthguard.cpp",
+ "src/directives.cpp",
+ "src/directives.h",
+ "src/emit.cpp",
+ "src/emitfromevents.cpp",
+ "src/emitter.cpp",
+ "src/emitterstate.cpp",
+ "src/emitterstate.h",
+ "src/emitterutils.cpp",
+ "src/emitterutils.h",
+ "src/exceptions.cpp",
+ "src/exp.cpp",
+ "src/exp.h",
+ "src/indentation.h",
+ "src/memory.cpp",
+ "src/node.cpp",
+ "src/node_data.cpp",
+ "src/nodebuilder.cpp",
+ "src/nodebuilder.h",
+ "src/nodeevents.cpp",
+ "src/nodeevents.h",
+ "src/null.cpp",
+ "src/ostream_wrapper.cpp",
+ "src/parse.cpp",
+ "src/parser.cpp",
+ "src/ptr_vector.h",
+ "src/regex_yaml.cpp",
+ "src/regex_yaml.h",
+ "src/regeximpl.h",
+ "src/scanner.cpp",
+ "src/scanner.h",
+ "src/scanscalar.cpp",
+ "src/scanscalar.h",
+ "src/scantag.cpp",
+ "src/scantag.h",
+ "src/scantoken.cpp",
+ "src/setting.h",
+ "src/simplekey.cpp",
+ "src/singledocparser.cpp",
+ "src/singledocparser.h",
+ "src/stream.cpp",
+ "src/stream.h",
+ "src/streamcharsource.h",
+ "src/stringsource.h",
+ "src/tag.cpp",
+ "src/tag.h",
+ "src/token.h",
+ ]
- files: [
- "include/yaml-cpp/anchor.h",
- "include/yaml-cpp/binary.h",
- "include/yaml-cpp/dll.h",
- "include/yaml-cpp/emitfromevents.h",
- "include/yaml-cpp/emitter.h",
- "include/yaml-cpp/emitterdef.h",
- "include/yaml-cpp/emittermanip.h",
- "include/yaml-cpp/emitterstyle.h",
- "include/yaml-cpp/eventhandler.h",
- "include/yaml-cpp/exceptions.h",
- "include/yaml-cpp/mark.h",
- "include/yaml-cpp/node",
- "include/yaml-cpp/node/convert.h",
- "include/yaml-cpp/node/detail",
- "include/yaml-cpp/node/detail/bool_type.h",
- "include/yaml-cpp/node/detail/impl.h",
- "include/yaml-cpp/node/detail/iterator.h",
- "include/yaml-cpp/node/detail/iterator_fwd.h",
- "include/yaml-cpp/node/detail/memory.h",
- "include/yaml-cpp/node/detail/node.h",
- "include/yaml-cpp/node/detail/node_data.h",
- "include/yaml-cpp/node/detail/node_iterator.h",
- "include/yaml-cpp/node/detail/node_ref.h",
- "include/yaml-cpp/node/emit.h",
- "include/yaml-cpp/node/impl.h",
- "include/yaml-cpp/node/iterator.h",
- "include/yaml-cpp/node/node.h",
- "include/yaml-cpp/node/parse.h",
- "include/yaml-cpp/node/ptr.h",
- "include/yaml-cpp/node/type.h",
- "include/yaml-cpp/noncopyable.h",
- "include/yaml-cpp/null.h",
- "include/yaml-cpp/ostream_wrapper.h",
- "include/yaml-cpp/parser.h",
- "include/yaml-cpp/stlemitter.h",
- "include/yaml-cpp/traits.h",
- "include/yaml-cpp/yaml.h",
- "src/binary.cpp",
- "src/collectionstack.h",
- "src/convert.cpp",
- "src/directives.cpp",
- "src/directives.h",
- "src/emit.cpp",
- "src/emitfromevents.cpp",
- "src/emitter.cpp",
- "src/emitterstate.cpp",
- "src/emitterstate.h",
- "src/emitterutils.cpp",
- "src/emitterutils.h",
- "src/exceptions.cpp",
- "src/exp.cpp",
- "src/exp.h",
- "src/indentation.h",
- "src/memory.cpp",
- "src/node.cpp",
- "src/node_data.cpp",
- "src/nodebuilder.cpp",
- "src/nodebuilder.h",
- "src/nodeevents.cpp",
- "src/nodeevents.h",
- "src/null.cpp",
- "src/ostream_wrapper.cpp",
- "src/parse.cpp",
- "src/parser.cpp",
- "src/ptr_vector.h",
- "src/regex_yaml.cpp",
- "src/regex_yaml.h",
- "src/regeximpl.h",
- "src/scanner.cpp",
- "src/scanner.h",
- "src/scanscalar.cpp",
- "src/scanscalar.h",
- "src/scantag.cpp",
- "src/scantag.h",
- "src/scantoken.cpp",
- "src/setting.h",
- "src/simplekey.cpp",
- "src/singledocparser.cpp",
- "src/singledocparser.h",
- "src/stream.cpp",
- "src/stream.h",
- "src/streamcharsource.h",
- "src/stringsource.h",
- "src/tag.cpp",
- "src/tag.h",
- "src/token.h",
- ]
-
- Export {
- Depends { name: "cpp" }
- cpp.includePaths: [exportingProduct.sourceDirectory + "/include/"]
- cpp.defines: base.concat(["YAML_CPP_DLL"])
- }
+ Export {
+ Depends { name: "cpp" }
+ cpp.includePaths: [exportingProduct.sourceDirectory + "/include/"]
+ cpp.defines: "YAML_CPP_DLL"
}
}
diff --git a/src/libs/CMakeLists.txt b/src/libs/CMakeLists.txt
index 73a554bae8b..536e3734949 100644
--- a/src/libs/CMakeLists.txt
+++ b/src/libs/CMakeLists.txt
@@ -1,5 +1,6 @@
add_subdirectory(3rdparty)
+add_subdirectory(nanotrace)
add_subdirectory(advanceddockingsystem)
add_subdirectory(aggregation)
add_subdirectory(cplusplus)
@@ -8,7 +9,6 @@ add_subdirectory(glsl)
add_subdirectory(languageserverprotocol)
add_subdirectory(languageutils)
add_subdirectory(modelinglib)
-add_subdirectory(nanotrace)
add_subdirectory(qmldebug)
add_subdirectory(qmleditorwidgets)
add_subdirectory(qmljs)
diff --git a/src/libs/advanceddockingsystem/CMakeLists.txt b/src/libs/advanceddockingsystem/CMakeLists.txt
index 66608852137..f993a9f1431 100644
--- a/src/libs/advanceddockingsystem/CMakeLists.txt
+++ b/src/libs/advanceddockingsystem/CMakeLists.txt
@@ -1,4 +1,5 @@
add_qtc_library(AdvancedDockingSystem
+ CONDITION TARGET Qt::QuickWidgets
DEPENDS Qt::Widgets Qt::Core Qt::Gui Qt::Xml Qt::QuickWidgets Utils
SOURCES
ads_globals.cpp ads_globals.h
diff --git a/src/libs/advanceddockingsystem/ads_globals.cpp b/src/libs/advanceddockingsystem/ads_globals.cpp
index 664f10ca8a5..5642651e717 100644
--- a/src/libs/advanceddockingsystem/ads_globals.cpp
+++ b/src/libs/advanceddockingsystem/ads_globals.cpp
@@ -17,7 +17,6 @@
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
#include <QApplication>
#include <QFile>
-#include <QSettings>
#endif
namespace ADS {
diff --git a/src/libs/advanceddockingsystem/advanceddockingsystem.qbs b/src/libs/advanceddockingsystem/advanceddockingsystem.qbs
index e603a039827..c04b8e0fe33 100644
--- a/src/libs/advanceddockingsystem/advanceddockingsystem.qbs
+++ b/src/libs/advanceddockingsystem/advanceddockingsystem.qbs
@@ -7,7 +7,7 @@ QtcLibrary {
cpp.defines: base.concat("ADVANCEDDOCKINGSYSTEM_LIBRARY")
cpp.includePaths: base.concat([".", linux.prefix])
- Depends { name: "Qt"; submodules: ["widgets", "xml"] }
+ Depends { name: "Qt"; submodules: ["quickwidgets", "widgets", "xml"] }
Depends { name: "Utils" }
Group {
diff --git a/src/libs/advanceddockingsystem/autohidetab.cpp b/src/libs/advanceddockingsystem/autohidetab.cpp
index 1d8f7a50a65..dd3f3f6c820 100644
--- a/src/libs/advanceddockingsystem/autohidetab.cpp
+++ b/src/libs/advanceddockingsystem/autohidetab.cpp
@@ -4,6 +4,7 @@
#include "autohidetab.h"
#include "ads_globals_p.h"
+#include "advanceddockingsystemtr.h"
#include "autohidedockcontainer.h"
#include "autohidesidebar.h"
#include "dockareawidget.h"
@@ -335,7 +336,7 @@ void AutoHideTab::contextMenuEvent(QContextMenuEvent *event)
const bool isFloatable = d->m_dockWidget->features().testFlag(DockWidget::DockWidgetFloatable);
QMenu menu(this);
- QAction *detachAction = menu.addAction(tr("Detach"));
+ QAction *detachAction = menu.addAction(Tr::tr("Detach"));
detachAction->connect(detachAction,
&QAction::triggered,
this,
@@ -345,17 +346,17 @@ void AutoHideTab::contextMenuEvent(QContextMenuEvent *event)
auto isPinnable = d->m_dockWidget->features().testFlag(DockWidget::DockWidgetPinnable);
detachAction->setEnabled(isPinnable);
- auto pinToMenu = menu.addMenu(tr("Pin To..."));
+ auto pinToMenu = menu.addMenu(Tr::tr("Pin To..."));
pinToMenu->setEnabled(isPinnable);
- d->createAutoHideToAction(tr("Top"), SideBarTop, pinToMenu);
- d->createAutoHideToAction(tr("Left"), SideBarLeft, pinToMenu);
- d->createAutoHideToAction(tr("Right"), SideBarRight, pinToMenu);
- d->createAutoHideToAction(tr("Bottom"), SideBarBottom, pinToMenu);
+ d->createAutoHideToAction(Tr::tr("Top"), SideBarTop, pinToMenu);
+ d->createAutoHideToAction(Tr::tr("Left"), SideBarLeft, pinToMenu);
+ d->createAutoHideToAction(Tr::tr("Right"), SideBarRight, pinToMenu);
+ d->createAutoHideToAction(Tr::tr("Bottom"), SideBarBottom, pinToMenu);
- QAction *unpinAction = menu.addAction(tr("Unpin (Dock)"));
+ QAction *unpinAction = menu.addAction(Tr::tr("Unpin (Dock)"));
unpinAction->connect(unpinAction, &QAction::triggered, this, &AutoHideTab::unpinDockWidget);
menu.addSeparator();
- QAction *closeAction = menu.addAction(tr("Close"));
+ QAction *closeAction = menu.addAction(Tr::tr("Close"));
closeAction->connect(closeAction,
&QAction::triggered,
this,
diff --git a/src/libs/advanceddockingsystem/dockareatitlebar.cpp b/src/libs/advanceddockingsystem/dockareatitlebar.cpp
index 234916d530d..7a2e6770621 100644
--- a/src/libs/advanceddockingsystem/dockareatitlebar.cpp
+++ b/src/libs/advanceddockingsystem/dockareatitlebar.cpp
@@ -656,7 +656,8 @@ void DockAreaTitleBar::contextMenuEvent(QContextMenuEvent *event)
QMenu menu(this);
if (!isTopLevelArea) {
- QAction *detachAction = menu.addAction(isAutoHide ? tr("Detach") : tr("Detach Group"));
+ QAction *detachAction = menu.addAction(isAutoHide ? Tr::tr("Detach")
+ : Tr::tr("Detach Group"));
detachAction->connect(detachAction,
&QAction::triggered,
this,
@@ -665,7 +666,8 @@ void DockAreaTitleBar::contextMenuEvent(QContextMenuEvent *event)
d->m_dockArea->features().testFlag(DockWidget::DockWidgetFloatable));
if (DockManager::testAutoHideConfigFlag(DockManager::AutoHideFeatureEnabled)) {
- QAction *pinAction = menu.addAction(isAutoHide ? tr("Unpin (Dock)") : tr("Pin Group"));
+ QAction *pinAction = menu.addAction(isAutoHide ? Tr::tr("Unpin (Dock)")
+ : Tr::tr("Pin Group"));
pinAction->connect(pinAction,
&QAction::triggered,
this,
@@ -674,17 +676,17 @@ void DockAreaTitleBar::contextMenuEvent(QContextMenuEvent *event)
auto areaIsPinnable = d->m_dockArea->features().testFlag(DockWidget::DockWidgetPinnable);
pinAction->setEnabled(areaIsPinnable);
if (!isAutoHide) {
- auto tmp = menu.addMenu(tr("Pin Group To..."));
+ auto tmp = menu.addMenu(Tr::tr("Pin Group To..."));
tmp->setEnabled(areaIsPinnable);
- d->createAutoHideToAction(tr("Top"), SideBarTop, tmp);
- d->createAutoHideToAction(tr("Left"), SideBarLeft, tmp);
- d->createAutoHideToAction(tr("Right"), SideBarRight, tmp);
- d->createAutoHideToAction(tr("Bottom"), SideBarBottom, tmp);
+ d->createAutoHideToAction(Tr::tr("Top"), SideBarTop, tmp);
+ d->createAutoHideToAction(Tr::tr("Left"), SideBarLeft, tmp);
+ d->createAutoHideToAction(Tr::tr("Right"), SideBarRight, tmp);
+ d->createAutoHideToAction(Tr::tr("Bottom"), SideBarBottom, tmp);
}
}
menu.addSeparator();
}
- QAction *closeAction = menu.addAction(isAutoHide ? tr("Close") : tr("Close Group"));
+ QAction *closeAction = menu.addAction(isAutoHide ? Tr::tr("Close") : Tr::tr("Close Group"));
closeAction->connect(closeAction,
&QAction::triggered,
this,
@@ -692,7 +694,7 @@ void DockAreaTitleBar::contextMenuEvent(QContextMenuEvent *event)
closeAction->setEnabled(d->m_dockArea->features().testFlag(DockWidget::DockWidgetClosable));
if (!isAutoHide && !isTopLevelArea) {
- QAction *closeOthersAction = menu.addAction(tr("Close Other Groups"));
+ QAction *closeOthersAction = menu.addAction(Tr::tr("Close Other Groups"));
closeOthersAction->connect(closeOthersAction,
&QAction::triggered,
d->m_dockArea,
@@ -717,22 +719,22 @@ QString DockAreaTitleBar::titleBarButtonToolTip(eTitleBarButton button) const
switch (button) {
case TitleBarButtonAutoHide:
if (d->m_dockArea->isAutoHide())
- return tr("Unpin (Dock)");
+ return Tr::tr("Unpin (Dock)");
if (DockManager::testAutoHideConfigFlag(DockManager::AutoHideButtonTogglesArea))
- return tr("Pin Group");
+ return Tr::tr("Pin Group");
else
- return tr("Pin Active Tab (Press Ctrl to Pin Group)");
+ return Tr::tr("Pin Active Tab (Press Ctrl to Pin Group)");
break;
case TitleBarButtonClose:
if (d->m_dockArea->isAutoHide())
- return tr("Close");
+ return Tr::tr("Close");
if (DockManager::testConfigFlag(DockManager::DockAreaCloseButtonClosesTab))
- return tr("Close Active Tab");
+ return Tr::tr("Close Active Tab");
else
- return tr("Close Group");
+ return Tr::tr("Close Group");
break;
default:
diff --git a/src/libs/advanceddockingsystem/dockmanager.cpp b/src/libs/advanceddockingsystem/dockmanager.cpp
index 088db38fbdf..15e7a9dbb15 100644
--- a/src/libs/advanceddockingsystem/dockmanager.cpp
+++ b/src/libs/advanceddockingsystem/dockmanager.cpp
@@ -21,6 +21,7 @@
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
+#include <utils/qtcsettings.h>
#include <algorithm>
#include <iostream>
@@ -91,7 +92,7 @@ public:
Workspace m_workspace;
bool m_workspaceLocked = false;
- QSettings *m_settings = nullptr;
+ QtcSettings *m_settings = nullptr;
bool m_modeChangeState = false;
bool m_workspaceOrderDirty = false;
@@ -441,7 +442,7 @@ int DockManager::startDragDistance()
return static_cast<int>(QApplication::startDragDistance() * 1.5);
}
-void DockManager::setSettings(QSettings *settings)
+void DockManager::setSettings(QtcSettings *settings)
{
d->m_settings = settings;
}
@@ -739,7 +740,7 @@ QList<int> DockManager::splitterSizes(DockAreaWidget *containedArea) const
return splitter->sizes();
}
- return QList<int>();
+ return {};
}
void DockManager::setSplitterSizes(DockAreaWidget *containedArea, const QList<int> &sizes)
@@ -1372,13 +1373,13 @@ expected_str<QString> DockManager::exportWorkspace(const QString &targetFilePath
// Check if the target directory exists
if (!targetFile.parentDir().exists())
return make_unexpected(
- Tr::tr("Directory does not exist\"%1\".").arg(targetFile.parentDir().toUserOutput()));
+ Tr::tr("The directory \"%1\" does not exist.").arg(targetFile.parentDir().toUserOutput()));
// Check if the workspace exists
const FilePath workspaceFile = userDirectory().pathAppended(sourceFileName);
if (!workspaceFile.exists())
return make_unexpected(
- Tr::tr("Workspace does not exist \"%1\"").arg(workspaceFile.toUserOutput()));
+ Tr::tr("The workspace \"%1\" does not exist ").arg(workspaceFile.toUserOutput()));
// Finally copy the workspace to the target
const expected_str<void> copyResult = workspaceFile.copyFile(targetFile);
@@ -1573,7 +1574,7 @@ void DockManager::syncWorkspacePresets()
// Try do create the 'workspaces' directory if it doesn't exist already
if (!userDirectory().ensureWritableDir()) {
- qWarning() << QString("Could not make directory '%1')").arg(userDirectory().toString());
+ qWarning() << QString("Could not make directory '%1')").arg(userDirectory().toUserOutput());
return;
}
@@ -1601,8 +1602,8 @@ void DockManager::syncWorkspacePresets()
userDirectory().pathAppended(filePath.fileName()));
if (!copyResult)
qWarning() << QString("Could not copy '%1' to '%2' due to %3")
- .arg(filePath.toString(),
- userDirectory().toString(),
+ .arg(filePath.toUserOutput(),
+ userDirectory().toUserOutput(),
copyResult.error());
}
}
diff --git a/src/libs/advanceddockingsystem/dockmanager.h b/src/libs/advanceddockingsystem/dockmanager.h
index 31621449d58..c11bd6ebb16 100644
--- a/src/libs/advanceddockingsystem/dockmanager.h
+++ b/src/libs/advanceddockingsystem/dockmanager.h
@@ -23,9 +23,10 @@
QT_BEGIN_NAMESPACE
class QMenu;
-class QSettings;
QT_END_NAMESPACE
+namespace Utils { class QtcSettings; }
+
namespace ADS {
namespace Constants {
@@ -277,7 +278,7 @@ public:
/**
* Set the QtCreator settings.
*/
- void setSettings(QSettings *settings);
+ void setSettings(Utils::QtcSettings *settings);
/**
* Set the path to the workspace presets folder.
diff --git a/src/libs/advanceddockingsystem/dockwidgettab.cpp b/src/libs/advanceddockingsystem/dockwidgettab.cpp
index aa4aba6aee3..efea3d0b202 100644
--- a/src/libs/advanceddockingsystem/dockwidgettab.cpp
+++ b/src/libs/advanceddockingsystem/dockwidgettab.cpp
@@ -473,7 +473,7 @@ void DockWidgetTab::contextMenuEvent(QContextMenuEvent *event)
QMenu menu(this);
if (!isTopLevelArea) {
- QAction *detachAction = menu.addAction(tr("Detach"));
+ QAction *detachAction = menu.addAction(Tr::tr("Detach"));
detachAction->connect(detachAction,
&QAction::triggered,
this,
@@ -481,7 +481,7 @@ void DockWidgetTab::contextMenuEvent(QContextMenuEvent *event)
detachAction->setEnabled(isDetachable);
if (DockManager::testAutoHideConfigFlag(DockManager::AutoHideFeatureEnabled)) {
- QAction *pinAction = menu.addAction(tr("Pin"));
+ QAction *pinAction = menu.addAction(Tr::tr("Pin"));
pinAction->connect(pinAction,
&QAction::triggered,
this,
@@ -490,23 +490,23 @@ void DockWidgetTab::contextMenuEvent(QContextMenuEvent *event)
auto isPinnable = d->m_dockWidget->features().testFlag(DockWidget::DockWidgetPinnable);
pinAction->setEnabled(isPinnable);
- auto subMenu = menu.addMenu(tr("Pin To..."));
+ auto subMenu = menu.addMenu(Tr::tr("Pin To..."));
subMenu->setEnabled(isPinnable);
- d->createAutoHideToAction(tr("Top"), SideBarTop, subMenu);
- d->createAutoHideToAction(tr("Left"), SideBarLeft, subMenu);
- d->createAutoHideToAction(tr("Right"), SideBarRight, subMenu);
- d->createAutoHideToAction(tr("Bottom"), SideBarBottom, subMenu);
+ d->createAutoHideToAction(Tr::tr("Top"), SideBarTop, subMenu);
+ d->createAutoHideToAction(Tr::tr("Left"), SideBarLeft, subMenu);
+ d->createAutoHideToAction(Tr::tr("Right"), SideBarRight, subMenu);
+ d->createAutoHideToAction(Tr::tr("Bottom"), SideBarBottom, subMenu);
}
}
menu.addSeparator();
- QAction *closeAction = menu.addAction(tr("Close"));
+ QAction *closeAction = menu.addAction(Tr::tr("Close"));
closeAction->connect(closeAction, &QAction::triggered, this, &DockWidgetTab::closeRequested);
closeAction->setEnabled(isClosable());
if (d->m_dockArea->openDockWidgetsCount() > 1) {
- QAction *closeOthersAction = menu.addAction(tr("Close Others"));
+ QAction *closeOthersAction = menu.addAction(Tr::tr("Close Others"));
closeOthersAction->connect(closeOthersAction,
&QAction::triggered,
this,
diff --git a/src/libs/advanceddockingsystem/linux/floatingwidgettitlebar.cpp b/src/libs/advanceddockingsystem/linux/floatingwidgettitlebar.cpp
index 699a0086fb9..1e02e47ebdc 100644
--- a/src/libs/advanceddockingsystem/linux/floatingwidgettitlebar.cpp
+++ b/src/libs/advanceddockingsystem/linux/floatingwidgettitlebar.cpp
@@ -174,7 +174,7 @@ void FloatingWidgetTitleBar::mouseMoveEvent(QMouseEvent *event)
// Move floating window
if (DraggingFloatingWidget == d->m_dragState) {
if (d->m_floatingWidget->isMaximized())
- d->m_floatingWidget->showNormal(true);
+ d->m_floatingWidget->showNormal();
d->m_floatingWidget->moveFloating();
Super::mouseMoveEvent(event);
diff --git a/src/libs/advanceddockingsystem/workspaceview.cpp b/src/libs/advanceddockingsystem/workspaceview.cpp
index 1b4cfc7e270..26983c2bcd7 100644
--- a/src/libs/advanceddockingsystem/workspaceview.cpp
+++ b/src/libs/advanceddockingsystem/workspaceview.cpp
@@ -46,6 +46,7 @@ WorkspaceView::WorkspaceView(DockManager *manager, QWidget *parent)
, m_manager(manager)
, m_workspaceModel(manager)
{
+ setUniformRowHeights(false);
setItemDelegate(new RemoveItemFocusDelegate(this));
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::SingleSelection);
diff --git a/src/libs/aggregation/aggregate.h b/src/libs/aggregation/aggregate.h
index 4934191d444..0e210451e71 100644
--- a/src/libs/aggregation/aggregate.h
+++ b/src/libs/aggregation/aggregate.h
@@ -83,14 +83,14 @@ template <typename T> T *query(QObject *obj)
template <typename T> QList<T *> query_all(Aggregate *obj)
{
if (!obj)
- return QList<T *>();
+ return {};
return obj->template components<T>();
}
template <typename T> QList<T *> query_all(QObject *obj)
{
if (!obj)
- return QList<T *>();
+ return {};
QReadLocker locker(&Aggregate::lock());
Aggregate *parentAggregation = Aggregate::parentAggregate(obj);
QList<T *> results;
diff --git a/src/libs/aggregation/aggregation.qbs b/src/libs/aggregation/aggregation.qbs
index d8f1097f756..873294e92f5 100644
--- a/src/libs/aggregation/aggregation.qbs
+++ b/src/libs/aggregation/aggregation.qbs
@@ -1,17 +1,12 @@
-import qbs 1.0
-
-Project {
+QtcLibrary {
name: "Aggregation"
-
- QtcLibrary {
- Depends { name: "Qt.core" }
- cpp.defines: base.concat("AGGREGATION_LIBRARY")
-
- files: [
- "aggregate.cpp",
- "aggregate.h",
- "aggregation_global.h",
- ]
- }
+ Depends { name: "Qt.core" }
+ cpp.defines: base.concat("AGGREGATION_LIBRARY")
+
+ files: [
+ "aggregate.cpp",
+ "aggregate.h",
+ "aggregation_global.h",
+ ]
}
diff --git a/src/libs/cplusplus/CMakeLists.txt b/src/libs/cplusplus/CMakeLists.txt
index c99a66c1f89..2fe5c63fe17 100644
--- a/src/libs/cplusplus/CMakeLists.txt
+++ b/src/libs/cplusplus/CMakeLists.txt
@@ -32,6 +32,7 @@ add_qtc_library(CPlusPlus
TypeOfExpression.cpp TypeOfExpression.h
TypePrettyPrinter.cpp TypePrettyPrinter.h
cppmodelmanagerbase.cpp cppmodelmanagerbase.h
+ declarationcomments.cpp declarationcomments.h
findcdbbreakpoint.cpp findcdbbreakpoint.h
pp-cctype.h pp-engine.cpp
pp-engine.h pp-scanner.cpp
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index 07714c0fe2f..6dc59bf1bf1 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -774,10 +774,8 @@ QSet<FilePath> Snapshot::allIncludesForDocument(const FilePath &filePath) const
if (Document::Ptr doc = document(file)) {
const FilePaths includedFiles = doc->includedFiles(Document::Duplicates::Keep);
for (const FilePath &inc : includedFiles) {
- if (!result.contains(inc)) {
- result.insert(inc);
+ if (Utils::insert(result, inc))
files.push(inc);
- }
}
}
}
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index 00bebf277d9..8834c7538a7 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -14,7 +14,6 @@
#include <QSharedPointer>
#include <QDateTime>
#include <QHash>
-#include <QFileInfo>
#include <QFuture>
#include <QAtomicInt>
diff --git a/src/libs/cplusplus/FastPreprocessor.cpp b/src/libs/cplusplus/FastPreprocessor.cpp
index b66d214ed27..580334d0744 100644
--- a/src/libs/cplusplus/FastPreprocessor.cpp
+++ b/src/libs/cplusplus/FastPreprocessor.cpp
@@ -6,6 +6,8 @@
#include <cplusplus/Literals.h>
#include <cplusplus/TranslationUnit.h>
+#include <utils/algorithm.h>
+
#include <QDir>
using namespace Utils;
@@ -65,9 +67,7 @@ void FastPreprocessor::sourceNeeded(int line, const FilePath &filePath, IncludeT
void FastPreprocessor::mergeEnvironment(const FilePath &filePath)
{
- if (! _merged.contains(filePath)) {
- _merged.insert(filePath);
-
+ if (Utils::insert(_merged, filePath)) {
if (Document::Ptr doc = _snapshot.document(filePath)) {
const QList<Document::Include> includes = doc->resolvedIncludes();
for (const Document::Include &i : includes)
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index 64669409b52..d4bf5b970d5 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -78,8 +78,7 @@ static bool isNestedInstantiationEnclosingTemplate(
{
QSet<ClassOrNamespace *> processed;
while (enclosingTemplateClassInstantiation
- && !processed.contains(enclosingTemplateClassInstantiation)) {
- processed.insert(enclosingTemplateClassInstantiation);
+ && Utils::insert(processed, enclosingTemplateClassInstantiation)) {
if (enclosingTemplateClassInstantiation == nestedClassOrNamespaceInstantiation)
return false;
enclosingTemplateClassInstantiation = enclosingTemplateClassInstantiation->parent();
@@ -389,11 +388,10 @@ ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope,
}
if (const NamedType *namedTy = d->type()->asNamedType()) {
// Stop on recursive typedef declarations
- if (typedefsBeingResolved.contains(d))
+ if (!Utils::insert(typedefsBeingResolved, d))
return nullptr;
return lookupType(namedTy->name(), scope, nullptr,
- QSet<const Declaration *>(typedefsBeingResolved)
- << d);
+ typedefsBeingResolved);
}
}
}
@@ -504,9 +502,8 @@ QList<LookupItem> LookupContext::lookup(const Name *name, Scope *scope) const
// try find this name in parent class
QSet<ClassOrNamespace *> processed;
while (candidates.isEmpty() && (binding = binding->parent())) {
- if (processed.contains(binding))
+ if (!Utils::insert(processed, binding))
break;
- processed.insert(binding);
candidates = binding->find(name);
}
@@ -683,9 +680,8 @@ QList<LookupItem> ClassOrNamespace::lookup_helper(const Name *name, bool searchI
for (ClassOrNamespace *parentBinding = binding->parent();
parentBinding && !match;
parentBinding = parentBinding->parent()) {
- if (processed.contains(parentBinding))
+ if (!Utils::insert(processed, parentBinding))
break;
- processed.insert(parentBinding);
match = parentBinding->lookupInScope(fullName);
}
@@ -704,9 +700,8 @@ QList<LookupItem> ClassOrNamespace::lookup_helper(const Name *name, bool searchI
QSet<ClassOrNamespace *> processedOwnParents;
ClassOrNamespace *binding = this;
do {
- if (processedOwnParents.contains(binding))
+ if (!Utils::insert(processedOwnParents, binding))
break;
- processedOwnParents.insert(binding);
lookup_helper(name, binding, &result, &processed, /*templateId = */ nullptr);
binding = binding->_parent;
} while (searchInEnclosingScope && binding);
@@ -720,9 +715,7 @@ void ClassOrNamespace::lookup_helper(const Name *name, ClassOrNamespace *binding
QSet<ClassOrNamespace *> *processed,
const TemplateNameId *templateId)
{
- if (binding && ! processed->contains(binding)) {
- processed->insert(binding);
-
+ if (binding && Utils::insert(*processed, binding)) {
const Identifier *nameId = name->identifier();
const QList<Symbol *> symbols = binding->symbols();
@@ -902,9 +895,8 @@ ClassOrNamespace *ClassOrNamespace::findBlock_helper(Block *block,
bool searchInEnclosingScope)
{
for (ClassOrNamespace *binding = this; binding; binding = binding->_parent) {
- if (processed->contains(binding))
+ if (!Utils::insert(*processed, binding))
break;
- processed->insert(binding);
binding->flush();
auto end = binding->_blocks.end();
auto citBlock = binding->_blocks.find(block);
@@ -977,9 +969,7 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
return nullptr;
- } else if (! processed->contains(this)) {
- processed->insert(this);
-
+ } else if (Utils::insert(*processed, this)) {
if (name->asNameId() || name->asTemplateNameId() || name->asAnonymousNameId()) {
flush();
@@ -1260,9 +1250,8 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name,
QSet<ClassOrNamespace *> otherProcessed;
while (!origin->_symbols.isEmpty() && origin->_symbols[0]->asBlock()) {
- if (otherProcessed.contains(origin))
+ if (!Utils::insert(otherProcessed, origin))
break;
- otherProcessed.insert(origin);
origin = origin->parent();
}
@@ -1489,9 +1478,8 @@ void ClassOrNamespace::NestedClassInstantiator::instantiate(ClassOrNamespace *en
{
if (_alreadyConsideredNestedClassInstantiations.size() >= 3)
return;
- if (_alreadyConsideredNestedClassInstantiations.contains(enclosingTemplateClass))
+ if (!Utils::insert(_alreadyConsideredNestedClassInstantiations, enclosingTemplateClass))
return;
- _alreadyConsideredNestedClassInstantiations.insert(enclosingTemplateClass);
ClassOrNamespace::Table::const_iterator cit = enclosingTemplateClass->_classOrNamespaces.begin();
for (; cit != enclosingTemplateClass->_classOrNamespaces.end(); ++cit) {
const Name *nestedName = cit->first;
@@ -1720,9 +1708,7 @@ void CreateBindings::process(Document::Ptr doc)
return;
if (Namespace *globalNamespace = doc->globalNamespace()) {
- if (! _processed.contains(globalNamespace)) {
- _processed.insert(globalNamespace);
-
+ if (Utils::insert(_processed, globalNamespace)) {
const QList<Document::Include> includes = doc->resolvedIncludes();
for (const Document::Include &i : includes) {
if (Document::Ptr incl = _snapshot.document(i.resolvedFileName()))
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 7d9ccf6891b..a120d5b736f 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -6,7 +6,6 @@
#include "LookupContext.h"
#include "Overview.h"
#include "DeprecatedGenTemplateInstance.h"
-#include "CppRewriter.h"
#include "TypeOfExpression.h"
#include <cplusplus/Control.h>
@@ -20,6 +19,8 @@
#include <cplusplus/NameVisitor.h>
#include <cplusplus/Templates.h>
+#include <utils/algorithm.h>
+
#include <QList>
#include <QDebug>
#include <QSet>
@@ -142,9 +143,8 @@ private:
for (const LookupItem &it : namedTypeItems) {
Symbol *declaration = it.declaration();
if (declaration && declaration->isTypedef()) {
- if (visited.contains(declaration))
+ if (!Utils::insert(visited, declaration))
break;
- visited.insert(declaration);
// continue working with the typedefed type and scope
if (type->type()->asPointerType()) {
@@ -231,7 +231,7 @@ QList<LookupItem> ResolveExpression::reference(ExpressionAST *ast, Scope *scope)
QList<LookupItem> ResolveExpression::resolve(ExpressionAST *ast, Scope *scope, bool ref)
{
if (! scope)
- return QList<LookupItem>();
+ return {};
std::swap(_scope, scope);
std::swap(_reference, ref);
diff --git a/src/libs/cplusplus/SnapshotSymbolVisitor.cpp b/src/libs/cplusplus/SnapshotSymbolVisitor.cpp
index 452c61531ad..512a4cffe7d 100644
--- a/src/libs/cplusplus/SnapshotSymbolVisitor.cpp
+++ b/src/libs/cplusplus/SnapshotSymbolVisitor.cpp
@@ -5,6 +5,8 @@
#include <cplusplus/Symbols.h>
+#include <utils/algorithm.h>
+
using namespace CPlusPlus;
SnapshotSymbolVisitor::SnapshotSymbolVisitor(const Snapshot &snapshot)
@@ -20,9 +22,7 @@ void SnapshotSymbolVisitor::accept(Document::Ptr doc)
void SnapshotSymbolVisitor::accept(Document::Ptr doc, QSet<QString> *processed)
{
- if (doc && doc->globalNamespace() && ! processed->contains(doc->filePath().path())) {
- processed->insert(doc->filePath().path());
-
+ if (doc && doc->globalNamespace() && Utils::insert(*processed, doc->filePath().path())) {
const QList<Document::Include> includes = doc->resolvedIncludes();
for (const Document::Include &i : includes) {
if (Document::Ptr incl = _snapshot.document(i.resolvedFileName()))
diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp
index 2776c19dd04..0cedec36b23 100644
--- a/src/libs/cplusplus/TypeOfExpression.cpp
+++ b/src/libs/cplusplus/TypeOfExpression.cpp
@@ -11,6 +11,8 @@
#include <cplusplus/Symbol.h>
#include <cplusplus/TranslationUnit.h>
+#include <utils/algorithm.h>
+
#include <QSet>
using namespace Utils;
@@ -134,9 +136,7 @@ ExpressionAST *TypeOfExpression::expressionAST() const
void TypeOfExpression::processEnvironment(Document::Ptr doc, Environment *env,
QSet<QString> *processed) const
{
- if (doc && ! processed->contains(doc->filePath().path())) {
- processed->insert(doc->filePath().path());
-
+ if (doc && Utils::insert(*processed, doc->filePath().path())) {
const QList<Document::Include> includes = doc->resolvedIncludes();
for (const Document::Include &incl : includes)
processEnvironment(m_snapshot.document(incl.resolvedFileName()), env, processed);
diff --git a/src/libs/cplusplus/cplusplus.qbs b/src/libs/cplusplus/cplusplus.qbs
index 0aed0ab438f..7e230504530 100644
--- a/src/libs/cplusplus/cplusplus.qbs
+++ b/src/libs/cplusplus/cplusplus.qbs
@@ -1,134 +1,131 @@
-import qbs 1.0
-
-Project {
+QtcLibrary {
name: "CPlusPlus"
- QtcLibrary {
- cpp.includePaths: base.concat("../3rdparty")
- cpp.defines: base.concat([
- "NDEBUG",
- "CPLUSPLUS_BUILD_LIB"
- ])
- cpp.optimization: "fast"
+ cpp.includePaths: base.concat("../3rdparty")
+ cpp.defines: base.concat([
+ "NDEBUG",
+ "CPLUSPLUS_BUILD_LIB"
+ ])
+ cpp.optimization: "fast"
- Depends { name: "Qt.widgets" }
- Depends { name: "Utils" }
+ Depends { name: "Qt.widgets" }
+ Depends { name: "Utils" }
- Group {
- name: "ThirdPartyCPlusPlus"
- prefix: "../3rdparty/cplusplus/"
- files: [
- "AST.cpp",
- "AST.h",
- "ASTClone.cpp",
- "ASTMatch0.cpp",
- "ASTMatcher.cpp",
- "ASTMatcher.h",
- "ASTPatternBuilder.h",
- "ASTVisit.cpp",
- "ASTVisitor.cpp",
- "ASTVisitor.h",
- "ASTfwd.h",
- "Bind.cpp",
- "Bind.h",
- "CPlusPlus.h",
- "Control.cpp",
- "Control.h",
- "CoreTypes.cpp",
- "CoreTypes.h",
- "DiagnosticClient.cpp",
- "DiagnosticClient.h",
- "FullySpecifiedType.cpp",
- "FullySpecifiedType.h",
- "Keywords.cpp",
- "Keywords.kwgen",
- "Lexer.cpp",
- "Lexer.h",
- "LiteralTable.h",
- "Literals.cpp",
- "Literals.h",
- "Matcher.cpp",
- "Matcher.h",
- "MemoryPool.cpp",
- "MemoryPool.h",
- "Name.cpp",
- "Name.h",
- "NameVisitor.cpp",
- "NameVisitor.h",
- "Names.cpp",
- "Names.h",
- "ObjectiveCAtKeywords.cpp",
- "ObjectiveCTypeQualifiers.cpp",
- "ObjectiveCTypeQualifiers.h",
- "Parser.cpp",
- "Parser.h",
- "QtContextKeywords.cpp",
- "QtContextKeywords.h",
- "SafeMatcher.cpp",
- "SafeMatcher.h",
- "Scope.cpp",
- "Scope.h",
- "Symbol.cpp",
- "Symbol.h",
- "SymbolVisitor.h",
- "Symbols.cpp",
- "Symbols.h",
- "Templates.cpp",
- "Templates.h",
- "Token.cpp",
- "Token.h",
- "TranslationUnit.cpp",
- "TranslationUnit.h",
- "Type.cpp",
- "Type.h",
- "TypeVisitor.cpp",
- "TypeVisitor.h",
- ]
- }
+ Group {
+ name: "ThirdPartyCPlusPlus"
+ prefix: "../3rdparty/cplusplus/"
+ files: [
+ "AST.cpp",
+ "AST.h",
+ "ASTClone.cpp",
+ "ASTMatch0.cpp",
+ "ASTMatcher.cpp",
+ "ASTMatcher.h",
+ "ASTPatternBuilder.h",
+ "ASTVisit.cpp",
+ "ASTVisitor.cpp",
+ "ASTVisitor.h",
+ "ASTfwd.h",
+ "Bind.cpp",
+ "Bind.h",
+ "CPlusPlus.h",
+ "Control.cpp",
+ "Control.h",
+ "CoreTypes.cpp",
+ "CoreTypes.h",
+ "DiagnosticClient.cpp",
+ "DiagnosticClient.h",
+ "FullySpecifiedType.cpp",
+ "FullySpecifiedType.h",
+ "Keywords.cpp",
+ "Keywords.kwgen",
+ "Lexer.cpp",
+ "Lexer.h",
+ "LiteralTable.h",
+ "Literals.cpp",
+ "Literals.h",
+ "Matcher.cpp",
+ "Matcher.h",
+ "MemoryPool.cpp",
+ "MemoryPool.h",
+ "Name.cpp",
+ "Name.h",
+ "NameVisitor.cpp",
+ "NameVisitor.h",
+ "Names.cpp",
+ "Names.h",
+ "ObjectiveCAtKeywords.cpp",
+ "ObjectiveCTypeQualifiers.cpp",
+ "ObjectiveCTypeQualifiers.h",
+ "Parser.cpp",
+ "Parser.h",
+ "QtContextKeywords.cpp",
+ "QtContextKeywords.h",
+ "SafeMatcher.cpp",
+ "SafeMatcher.h",
+ "Scope.cpp",
+ "Scope.h",
+ "Symbol.cpp",
+ "Symbol.h",
+ "SymbolVisitor.h",
+ "Symbols.cpp",
+ "Symbols.h",
+ "Templates.cpp",
+ "Templates.h",
+ "Token.cpp",
+ "Token.h",
+ "TranslationUnit.cpp",
+ "TranslationUnit.h",
+ "Type.cpp",
+ "Type.h",
+ "TypeVisitor.cpp",
+ "TypeVisitor.h",
+ ]
+ }
- Group {
- name: "General"
- files: [
- "AlreadyConsideredClassContainer.h",
- "ASTParent.cpp", "ASTParent.h",
- "ASTPath.cpp", "ASTPath.h",
- "BackwardsScanner.cpp", "BackwardsScanner.h",
- "CppDocument.cpp", "CppDocument.h",
- "CppRewriter.cpp", "CppRewriter.h",
- "cppmodelmanagerbase.cpp", "cppmodelmanagerbase.h",
- "DependencyTable.cpp", "DependencyTable.h",
- "DeprecatedGenTemplateInstance.cpp", "DeprecatedGenTemplateInstance.h",
- "ExpressionUnderCursor.cpp", "ExpressionUnderCursor.h",
- "FastPreprocessor.cpp", "FastPreprocessor.h",
- "FindUsages.cpp", "FindUsages.h",
- "Icons.cpp", "Icons.h",
- "LookupContext.cpp", "LookupContext.h",
- "LookupItem.cpp", "LookupItem.h",
- "Macro.cpp", "Macro.h",
- "MatchingText.cpp", "MatchingText.h",
- "NamePrettyPrinter.cpp", "NamePrettyPrinter.h",
- "Overview.cpp", "Overview.h",
- "PPToken.cpp", "PPToken.h",
- "PreprocessorClient.cpp", "PreprocessorClient.h",
- "PreprocessorEnvironment.cpp", "PreprocessorEnvironment.h",
- "ResolveExpression.cpp", "ResolveExpression.h",
- "SimpleLexer.cpp", "SimpleLexer.h",
- "SnapshotSymbolVisitor.cpp", "SnapshotSymbolVisitor.h",
- "SymbolNameVisitor.cpp", "SymbolNameVisitor.h",
- "TypeOfExpression.cpp", "TypeOfExpression.h",
- "TypePrettyPrinter.cpp", "TypePrettyPrinter.h",
- "findcdbbreakpoint.cpp", "findcdbbreakpoint.h",
- "pp-cctype.h",
- "pp-engine.cpp", "pp-engine.h",
- "pp-scanner.cpp", "pp-scanner.h",
- "pp.h",
- ]
- }
+ Group {
+ name: "General"
+ files: [
+ "AlreadyConsideredClassContainer.h",
+ "ASTParent.cpp", "ASTParent.h",
+ "ASTPath.cpp", "ASTPath.h",
+ "BackwardsScanner.cpp", "BackwardsScanner.h",
+ "CppDocument.cpp", "CppDocument.h",
+ "CppRewriter.cpp", "CppRewriter.h",
+ "cppmodelmanagerbase.cpp", "cppmodelmanagerbase.h",
+ "declarationcomments.cpp", "declarationcomments.h",
+ "DependencyTable.cpp", "DependencyTable.h",
+ "DeprecatedGenTemplateInstance.cpp", "DeprecatedGenTemplateInstance.h",
+ "ExpressionUnderCursor.cpp", "ExpressionUnderCursor.h",
+ "FastPreprocessor.cpp", "FastPreprocessor.h",
+ "FindUsages.cpp", "FindUsages.h",
+ "Icons.cpp", "Icons.h",
+ "LookupContext.cpp", "LookupContext.h",
+ "LookupItem.cpp", "LookupItem.h",
+ "Macro.cpp", "Macro.h",
+ "MatchingText.cpp", "MatchingText.h",
+ "NamePrettyPrinter.cpp", "NamePrettyPrinter.h",
+ "Overview.cpp", "Overview.h",
+ "PPToken.cpp", "PPToken.h",
+ "PreprocessorClient.cpp", "PreprocessorClient.h",
+ "PreprocessorEnvironment.cpp", "PreprocessorEnvironment.h",
+ "ResolveExpression.cpp", "ResolveExpression.h",
+ "SimpleLexer.cpp", "SimpleLexer.h",
+ "SnapshotSymbolVisitor.cpp", "SnapshotSymbolVisitor.h",
+ "SymbolNameVisitor.cpp", "SymbolNameVisitor.h",
+ "TypeOfExpression.cpp", "TypeOfExpression.h",
+ "TypePrettyPrinter.cpp", "TypePrettyPrinter.h",
+ "findcdbbreakpoint.cpp", "findcdbbreakpoint.h",
+ "pp-cctype.h",
+ "pp-engine.cpp", "pp-engine.h",
+ "pp-scanner.cpp", "pp-scanner.h",
+ "pp.h",
+ ]
+ }
- Export {
- cpp.includePaths: [
- exportingProduct.sourceDirectory + "/../3rdparty"
- ]
- }
+ Export {
+ cpp.includePaths: [
+ exportingProduct.sourceDirectory + "/../3rdparty"
+ ]
}
}
diff --git a/src/libs/cplusplus/cppmodelmanagerbase.cpp b/src/libs/cplusplus/cppmodelmanagerbase.cpp
index c869fd61a0f..410244ab96f 100644
--- a/src/libs/cplusplus/cppmodelmanagerbase.cpp
+++ b/src/libs/cplusplus/cppmodelmanagerbase.cpp
@@ -3,48 +3,60 @@
#include "cppmodelmanagerbase.h"
-namespace CPlusPlus {
+#include <utils/filepath.h>
+#include <utils/qtcassert.h>
-static CppModelManagerBase *g_instance = nullptr;
+using namespace Utils;
-CppModelManagerBase::CppModelManagerBase(QObject *parent)
- : QObject(parent)
+namespace CPlusPlus::CppModelManagerBase {
+
+static bool (*setExtraDiagnosticsCallback)
+ (const FilePath &, const QString &, const QList<Document::DiagnosticMessage> &) = nullptr;
+
+static CPlusPlus::Snapshot (*snapshotCallback)() = nullptr;
+
+
+bool trySetExtraDiagnostics(const FilePath &filePath, const QString &kind,
+ const QList<Document::DiagnosticMessage> &diagnostics)
{
- Q_ASSERT(!g_instance);
- g_instance = this;
+ if (!setExtraDiagnosticsCallback)
+ return false;
+ return setExtraDiagnosticsCallback(filePath, kind, diagnostics);
}
-CppModelManagerBase::~CppModelManagerBase()
+bool setExtraDiagnostics(const FilePath &filePath, const QString &kind,
+ const QList<Document::DiagnosticMessage> &diagnostics)
{
- Q_ASSERT(g_instance == this);
- g_instance = nullptr;
+ QTC_ASSERT(setExtraDiagnosticsCallback, return false);
+ return setExtraDiagnosticsCallback(filePath, kind, diagnostics);
}
-CppModelManagerBase *CppModelManagerBase::instance()
+Snapshot snapshot()
{
- return g_instance;
+ QTC_ASSERT(snapshotCallback, return {});
+ return snapshotCallback();
}
-bool CppModelManagerBase::trySetExtraDiagnostics(const QString &fileName, const QString &kind,
- const QList<CPlusPlus::Document::DiagnosticMessage> &diagnostics)
+bool hasSnapshots()
{
- if (CppModelManagerBase *mm = instance())
- return mm->setExtraDiagnostics(fileName, kind, diagnostics);
- return false;
+ return snapshotCallback;
}
-bool CppModelManagerBase::setExtraDiagnostics(const QString &fileName, const QString &kind,
- const QList<CPlusPlus::Document::DiagnosticMessage> &diagnostics)
+// Installation
+
+void registerSetExtraDiagnosticsCallback(
+ bool (*callback)(const FilePath &, const QString &, const QList<Document::DiagnosticMessage> &))
{
- Q_UNUSED(fileName)
- Q_UNUSED(kind)
- Q_UNUSED(diagnostics)
- return false;
+ QTC_ASSERT(callback, return);
+ QTC_CHECK(!setExtraDiagnosticsCallback); // bark when used twice
+ setExtraDiagnosticsCallback = callback;
}
-CPlusPlus::Snapshot CppModelManagerBase::snapshot() const
+void registerSnapshotCallback(Snapshot (*callback)())
{
- return CPlusPlus::Snapshot();
+ QTC_ASSERT(callback, return);
+ QTC_CHECK(!snapshotCallback); // bark when used twice
+ snapshotCallback = callback;
}
-} // namespace CPlusPlus
+} // CPlusPlus::CppModelManagerBase
diff --git a/src/libs/cplusplus/cppmodelmanagerbase.h b/src/libs/cplusplus/cppmodelmanagerbase.h
index d003fcf1dec..0a8e18e733f 100644
--- a/src/libs/cplusplus/cppmodelmanagerbase.h
+++ b/src/libs/cplusplus/cppmodelmanagerbase.h
@@ -5,29 +5,26 @@
#include <cplusplus/CppDocument.h>
-#include <QObject>
-#include <QList>
+namespace Utils { class FilePath; }
-QT_BEGIN_NAMESPACE
-class QString;
-QT_END_NAMESPACE
+namespace CPlusPlus::CppModelManagerBase {
-namespace CPlusPlus {
+CPLUSPLUS_EXPORT bool trySetExtraDiagnostics
+ (const Utils::FilePath &filePath, const QString &, const QList<Document::DiagnosticMessage> &);
-class CPLUSPLUS_EXPORT CppModelManagerBase : public QObject
-{
- Q_OBJECT
-public:
- CppModelManagerBase(QObject *parent = nullptr);
- ~CppModelManagerBase();
+CPLUSPLUS_EXPORT bool setSetExtraDiagnostics
+ (const Utils::FilePath &, const QString &, const QList<Document::DiagnosticMessage> &);
- static CppModelManagerBase *instance();
- static bool trySetExtraDiagnostics(const QString &fileName, const QString &kind,
- const QList<Document::DiagnosticMessage> &diagnostics);
+CPLUSPLUS_EXPORT bool hasSnapshots();
- virtual bool setExtraDiagnostics(const QString &fileName, const QString &kind,
- const QList<Document::DiagnosticMessage> &diagnostics);
- virtual CPlusPlus::Snapshot snapshot() const;
-};
+CPLUSPLUS_EXPORT CPlusPlus::Snapshot snapshot();
-} // namespace CPlusPlus
+
+// These callback are provided by the CppEditor plugin.
+
+CPLUSPLUS_EXPORT void registerSnapshotCallback(CPlusPlus::Snapshot (*)(void));
+
+CPLUSPLUS_EXPORT void registerSetExtraDiagnosticsCallback(
+ bool(*)(const Utils::FilePath &, const QString &, const QList<Document::DiagnosticMessage> &));
+
+} // CPlusPlus::CppModelManagerBase
diff --git a/src/libs/cplusplus/declarationcomments.cpp b/src/libs/cplusplus/declarationcomments.cpp
new file mode 100644
index 00000000000..f67ac1be9d5
--- /dev/null
+++ b/src/libs/cplusplus/declarationcomments.cpp
@@ -0,0 +1,175 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "declarationcomments.h"
+
+#include <cplusplus/ASTPath.h>
+#include <cplusplus/CppDocument.h>
+#include <cplusplus/Overview.h>
+
+#include <utils/algorithm.h>
+#include <utils/textutils.h>
+
+#include <QRegularExpression>
+#include <QStringList>
+#include <QTextBlock>
+#include <QTextDocument>
+
+namespace CPlusPlus {
+
+static QString nameFromSymbol(const Symbol *symbol)
+{
+ const QStringList symbolParts = Overview().prettyName(symbol->name())
+ .split("::", Qt::SkipEmptyParts);
+ if (symbolParts.isEmpty())
+ return {};
+ return symbolParts.last();
+}
+
+static QList<Token> commentsForDeclaration(
+ const AST *decl, const QString &symbolName, const QTextDocument &textDoc,
+ const Document::Ptr &cppDoc, bool isParameter)
+{
+ if (symbolName.isEmpty())
+ return {};
+
+ // Get the list of all tokens (including comments) and find the declaration start token there.
+ TranslationUnit * const tu = cppDoc->translationUnit();
+ QTC_ASSERT(tu && tu->isParsed(), return {});
+ const Token &declToken = tu->tokenAt(decl->firstToken());
+ std::vector<Token> allTokens = tu->allTokens();
+ QTC_ASSERT(!allTokens.empty(), return {});
+ int tokenPos = -1;
+ for (int i = 0; i < int(allTokens.size()); ++i) {
+ if (allTokens.at(i).byteOffset == declToken.byteOffset) {
+ tokenPos = i;
+ break;
+ }
+ }
+ if (tokenPos == -1)
+ return {};
+
+ // Go backwards in the token list and collect all associated comments.
+ struct Comment {
+ Token token;
+ QTextBlock startBlock;
+ QTextBlock endBlock;
+ };
+ QList<Comment> comments;
+ Kind commentKind = T_EOF_SYMBOL;
+ const auto blockForTokenStart = [&](const Token &tok) {
+ return textDoc.findBlock(tu->getTokenPositionInDocument(tok, &textDoc));
+ };
+ const auto blockForTokenEnd = [&](const Token &tok) {
+ return textDoc.findBlock(tu->getTokenEndPositionInDocument(tok, &textDoc));
+ };
+ bool needsSymbolReference = isParameter;
+ for (int i = tokenPos - 1; i >= 0; --i) {
+ const Token &tok = allTokens.at(i);
+ if (!tok.isComment())
+ break;
+ const QTextBlock tokenEndBlock = blockForTokenEnd(tok);
+ if (commentKind == T_EOF_SYMBOL) {
+ if (tokenEndBlock.next() != blockForTokenStart(declToken))
+ needsSymbolReference = true;
+ commentKind = tok.kind();
+ } else {
+ // If it's not the same kind of comment, it's not part of our comment block.
+ if (tok.kind() != commentKind)
+ break;
+
+ // If there are empty lines between the comments, we don't consider them as
+ // belonging together.
+ if (tokenEndBlock.next() != comments.first().startBlock)
+ break;
+ }
+
+ comments.push_front({tok, blockForTokenStart(tok), tokenEndBlock});
+ }
+
+ if (comments.isEmpty())
+ return {};
+
+ const auto tokenList = [&] {
+ return Utils::transform<QList<Token>>(comments, &Comment::token);
+ };
+
+ // We consider the comment block as associated with the symbol if it
+ // a) precedes it directly, without any empty lines in between or
+ // b) the symbol name occurs in it.
+ // Obviously, this heuristic can yield false positives in the case of very short names,
+ // but if a symbol is important enough to get documented, it should also have a proper name.
+ // Note that for function parameters, we always require the name to occur in the comment.
+
+ if (!needsSymbolReference) // a)
+ return tokenList();
+
+ // b)
+ const Kind tokenKind = comments.first().token.kind();
+ const bool isDoxygenComment = tokenKind == T_DOXY_COMMENT || tokenKind == T_CPP_DOXY_COMMENT;
+ const QRegularExpression symbolRegExp(QString("%1\\b%2\\b").arg(
+ isParameter && isDoxygenComment ? "[\\@]param\\s+" : QString(), symbolName));
+ for (const Comment &c : std::as_const(comments)) {
+ for (QTextBlock b = c.startBlock; b.blockNumber() <= c.endBlock.blockNumber();
+ b = b.next()) {
+ if (b.text().contains(symbolRegExp))
+ return tokenList();
+ }
+ }
+ return {};
+}
+
+
+QList<Token> commentsForDeclaration(const Symbol *symbol, const QTextDocument &textDoc,
+ const Document::Ptr &cppDoc)
+{
+ QTC_ASSERT(cppDoc->translationUnit() && cppDoc->translationUnit()->isParsed(), return {});
+ Utils::Text::Position pos;
+ cppDoc->translationUnit()->getTokenPosition(symbol->sourceLocation(), &pos.line, &pos.column);
+ --pos.column;
+ return commentsForDeclaration(nameFromSymbol(symbol), pos, textDoc, cppDoc);
+}
+
+QList<Token> commentsForDeclaration(const QString &symbolName, const Utils::Text::Position &pos,
+ const QTextDocument &textDoc, const Document::Ptr &cppDoc)
+{
+ if (symbolName.isEmpty())
+ return {};
+
+ // Find the symbol declaration's AST node.
+ // We stop at the last declaration node that precedes the symbol, except:
+ // - For parameter declarations, we just continue, because we are interested in the function.
+ // - If the declaration node is preceded directly by another one, we choose that one instead,
+ // because with nested declarations we want the outer one (e.g. templates).
+ const QList<AST *> astPath = ASTPath(cppDoc)(pos.line, pos.column + 1);
+ if (astPath.isEmpty())
+ return {};
+ const AST *declAst = nullptr;
+ bool isParameter = false;
+ for (auto it = std::next(std::rbegin(astPath)); it != std::rend(astPath); ++it) {
+ AST * const node = *it;
+ if (node->asParameterDeclaration()) {
+ isParameter = true;
+ continue;
+ }
+ if (node->asDeclaration()) {
+ declAst = node;
+ continue;
+ }
+ if (declAst)
+ break;
+ }
+ if (!declAst)
+ return {};
+
+ return commentsForDeclaration(declAst, symbolName, textDoc, cppDoc, isParameter);
+}
+
+QList<Token> commentsForDeclaration(const Symbol *symbol, const AST *decl,
+ const QTextDocument &textDoc, const Document::Ptr &cppDoc)
+{
+ return commentsForDeclaration(decl, nameFromSymbol(symbol), textDoc, cppDoc,
+ symbol->asArgument());
+}
+
+} // namespace CPlusPlus
diff --git a/src/libs/cplusplus/declarationcomments.h b/src/libs/cplusplus/declarationcomments.h
new file mode 100644
index 00000000000..7b775ad7549
--- /dev/null
+++ b/src/libs/cplusplus/declarationcomments.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include <cplusplus/CppDocument.h>
+#include <cplusplus/Token.h>
+
+#include <QList>
+
+QT_BEGIN_NAMESPACE
+class QTextDocument;
+QT_END_NAMESPACE
+
+namespace Utils { namespace Text { class Position; } }
+
+namespace CPlusPlus {
+class AST;
+class Symbol;
+
+QList<Token> CPLUSPLUS_EXPORT commentsForDeclaration(const Symbol *symbol,
+ const QTextDocument &textDoc,
+ const Document::Ptr &cppDoc);
+
+QList<Token> CPLUSPLUS_EXPORT commentsForDeclaration(const Symbol *symbol,
+ const AST *decl,
+ const QTextDocument &textDoc,
+ const Document::Ptr &cppDoc);
+
+QList<Token> CPLUSPLUS_EXPORT commentsForDeclaration(const QString &symbolName,
+ const Utils::Text::Position &pos,
+ const QTextDocument &textDoc,
+ const Document::Ptr &cppDoc);
+
+} // namespace CPlusPlus
diff --git a/src/libs/extensionsystem/CMakeLists.txt b/src/libs/extensionsystem/CMakeLists.txt
index 0e4e6607a55..edc1daa2455 100644
--- a/src/libs/extensionsystem/CMakeLists.txt
+++ b/src/libs/extensionsystem/CMakeLists.txt
@@ -26,3 +26,8 @@ extend_qtc_library(ExtensionSystem
DEPENDS Qt::Test
DEFINES WITH_TESTS
)
+
+extend_qtc_library(ExtensionSystem
+ CONDITION TARGET Nanotrace
+ PUBLIC_DEPENDS Nanotrace
+)
diff --git a/src/libs/extensionsystem/extensionsystem.qbs b/src/libs/extensionsystem/extensionsystem.qbs
index 39e8cbc57c6..8748c27ba69 100644
--- a/src/libs/extensionsystem/extensionsystem.qbs
+++ b/src/libs/extensionsystem/extensionsystem.qbs
@@ -1,45 +1,40 @@
-import qbs 1.0
-
-Project {
+QtcLibrary {
name: "ExtensionSystem"
- QtcLibrary {
- cpp.defines: base.concat([
- "EXTENSIONSYSTEM_LIBRARY",
- "IDE_TEST_DIR=\".\""
- ])
+ cpp.defines: base.concat(["EXTENSIONSYSTEM_LIBRARY", "IDE_TEST_DIR=\".\""])
+
+ Depends { name: "Qt"; submodules: ["core", "widgets"] }
+ Depends { name: "Qt.testlib"; condition: qtc.withPluginTests }
- Depends { name: "Qt"; submodules: ["core", "widgets"] }
- Depends { name: "Aggregation" }
- Depends { name: "Utils" }
+ Depends { name: "Aggregation" }
+ Depends { name: "Utils" }
- files: [
- "extensionsystem_global.h",
- "extensionsystemtr.h",
- "invoker.cpp",
- "invoker.h",
- "iplugin.cpp",
- "iplugin.h",
- "optionsparser.cpp",
- "optionsparser.h",
- "plugindetailsview.cpp",
- "plugindetailsview.h",
- "pluginerroroverview.cpp",
- "pluginerroroverview.h",
- "pluginerrorview.cpp",
- "pluginerrorview.h",
- "pluginmanager.cpp",
- "pluginmanager.h",
- "pluginmanager_p.h",
- "pluginspec.cpp",
- "pluginspec.h",
- "pluginspec_p.h",
- "pluginview.cpp",
- "pluginview.h",
- ]
+ files: [
+ "extensionsystem_global.h",
+ "extensionsystemtr.h",
+ "invoker.cpp",
+ "invoker.h",
+ "iplugin.cpp",
+ "iplugin.h",
+ "optionsparser.cpp",
+ "optionsparser.h",
+ "plugindetailsview.cpp",
+ "plugindetailsview.h",
+ "pluginerroroverview.cpp",
+ "pluginerroroverview.h",
+ "pluginerrorview.cpp",
+ "pluginerrorview.h",
+ "pluginmanager.cpp",
+ "pluginmanager.h",
+ "pluginmanager_p.h",
+ "pluginspec.cpp",
+ "pluginspec.h",
+ "pluginspec_p.h",
+ "pluginview.cpp",
+ "pluginview.h",
+ ]
- Export {
- Depends { name: "Qt.core" }
- }
+ Export {
+ Depends { name: "Qt.core" }
}
}
diff --git a/src/libs/extensionsystem/extensionsystem_global.h b/src/libs/extensionsystem/extensionsystem_global.h
index 85fa8de831c..8e1c1ee463c 100644
--- a/src/libs/extensionsystem/extensionsystem_global.h
+++ b/src/libs/extensionsystem/extensionsystem_global.h
@@ -14,4 +14,16 @@
# define EXTENSIONSYSTEM_EXPORT Q_DECL_IMPORT
#endif
+#if defined(WITH_TESTS)
+# if defined(EXTENSIONSYSTEM_LIBRARY)
+# define EXTENSIONSYSTEM_TEST_EXPORT Q_DECL_EXPORT
+# elif defined(EXTENSIONSYSTEM_STATIC_LIBRARY)
+# define EXTENSIONSYSTEM_TEST_EXPORT
+# else
+# define EXTENSIONSYSTEM_TEST_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define EXTENSIONSYSTEM_TEST_EXPORT
+#endif
+
Q_DECLARE_LOGGING_CATEGORY(pluginLog)
diff --git a/src/libs/extensionsystem/iplugin.cpp b/src/libs/extensionsystem/iplugin.cpp
index 2af49255735..42ddd05bf68 100644
--- a/src/libs/extensionsystem/iplugin.cpp
+++ b/src/libs/extensionsystem/iplugin.cpp
@@ -161,47 +161,12 @@
namespace ExtensionSystem {
namespace Internal {
-class ObjectInitializer
-{
-public:
- ObjectCreator creator;
- ObjectDestructor destructor;
- ObjectCreationPolicy policy;
-};
-
class IPluginPrivate
{
public:
- void tryCreateObjects();
-
QList<TestCreator> testCreators;
-
- QList<ObjectInitializer> objectInitializers;
- QList<std::function<void()>> objectDestructors;
-
- // For debugging purposes:
- QList<void *> createdObjects; // Not owned.
};
-void IPluginPrivate::tryCreateObjects()
-{
- QList<ObjectInitializer> unhandledObjectInitializers;
-
- for (const ObjectInitializer &initializer : std::as_const(objectInitializers)) {
- if (!initializer.policy.dependsOn.isEmpty()) {
- qWarning("Initialization dependencies are not supported yet");
- unhandledObjectInitializers.append(initializer);
- continue;
- }
-
- void *object = initializer.creator();
- createdObjects.append(object);
- objectDestructors.append([initializer, object] { initializer.destructor(object); });
- }
-
- objectInitializers = unhandledObjectInitializers;
-}
-
} // Internal
/*!
@@ -217,20 +182,10 @@ IPlugin::IPlugin()
*/
IPlugin::~IPlugin()
{
- for (const std::function<void()> &dtor : std::as_const(d->objectDestructors))
- dtor();
-
delete d;
d = nullptr;
}
-void IPlugin::addManagedHelper(const ObjectCreator &creator,
- const ObjectDestructor &destructor,
- const ObjectCreationPolicy &policy)
-{
- d->objectInitializers.append({creator, destructor, policy});
-}
-
bool IPlugin::initialize(const QStringList &arguments, QString *errorString)
{
Q_UNUSED(arguments)
@@ -240,14 +195,6 @@ bool IPlugin::initialize(const QStringList &arguments, QString *errorString)
}
/*!
- \internal
-*/
-void IPlugin::tryCreateObjects()
-{
- d->tryCreateObjects();
-}
-
-/*!
Registers a function object that creates a test object with the owner
\a creator.
diff --git a/src/libs/extensionsystem/iplugin.h b/src/libs/extensionsystem/iplugin.h
index 3e477e42e81..5a8fceb3d6e 100644
--- a/src/libs/extensionsystem/iplugin.h
+++ b/src/libs/extensionsystem/iplugin.h
@@ -5,8 +5,6 @@
#include "extensionsystem_global.h"
-#include <utils/id.h>
-
#include <QObject>
#include <functional>
@@ -17,17 +15,6 @@ namespace Internal { class IPluginPrivate; }
using TestCreator = std::function<QObject *()>;
-using ObjectCreator = std::function<void *()>;
-using ObjectDestructor = std::function<void(void *)>;
-
-struct EXTENSIONSYSTEM_EXPORT ObjectCreationPolicy
-{
- // Can be empty if nothing depends on it.
- Utils::Id id;
- // Objects with empty dependencies are created as soon as possible.
- QList<Utils::Id> dependsOn;
-};
-
class EXTENSIONSYSTEM_EXPORT IPlugin : public QObject
{
Q_OBJECT
@@ -52,7 +39,6 @@ public:
// Deprecated in 10.0, use addTest()
virtual QVector<QObject *> createTestObjects() const;
- virtual void tryCreateObjects();
protected:
virtual void initialize() {}
@@ -61,17 +47,6 @@ protected:
void addTest(Args && ...args) { addTestCreator([args...] { return new Test(args...); }); }
void addTestCreator(const TestCreator &creator);
- template <typename Type>
- void addManaged(const ObjectCreationPolicy &policy = {}) {
- addManagedHelper([]() -> void * { return new Type(); },
- [](void *p) { delete static_cast<Type *>(p); },
- policy);
- }
-
- void addManagedHelper(const ObjectCreator &creator,
- const ObjectDestructor &destructor,
- const ObjectCreationPolicy &policy);
-
signals:
void asynchronousShutdownFinished();
diff --git a/src/libs/extensionsystem/optionsparser.cpp b/src/libs/extensionsystem/optionsparser.cpp
index 8e3a5d900e7..205442488e6 100644
--- a/src/libs/extensionsystem/optionsparser.cpp
+++ b/src/libs/extensionsystem/optionsparser.cpp
@@ -22,6 +22,7 @@ const char *OptionsParser::TEST_OPTION = "-test";
const char *OptionsParser::NOTEST_OPTION = "-notest";
const char *OptionsParser::SCENARIO_OPTION = "-scenario";
const char *OptionsParser::PROFILE_OPTION = "-profile";
+const char *OptionsParser::TRACE_OPTION = "-trace";
const char *OptionsParser::NO_CRASHCHECK_OPTION = "-no-crashcheck";
OptionsParser::OptionsParser(const QStringList &args,
@@ -60,6 +61,8 @@ bool OptionsParser::parse()
continue;
if (checkForProfilingOption())
continue;
+ if (checkForTraceOption())
+ continue;
if (checkForNoCrashcheckOption())
continue;
#ifdef WITH_TESTS
@@ -239,7 +242,17 @@ bool OptionsParser::checkForProfilingOption()
{
if (m_currentArg != QLatin1String(PROFILE_OPTION))
return false;
- m_pmPrivate->initProfiling();
+ m_pmPrivate->increaseProfilingVerbosity();
+ return true;
+}
+
+bool OptionsParser::checkForTraceOption()
+{
+ if (m_currentArg != QLatin1String(TRACE_OPTION))
+ return false;
+ if (nextToken(RequiredToken)) {
+ m_pmPrivate->enableTracing(m_currentArg);
+ }
return true;
}
diff --git a/src/libs/extensionsystem/optionsparser.h b/src/libs/extensionsystem/optionsparser.h
index ee11582c3b0..93f3812c8d3 100644
--- a/src/libs/extensionsystem/optionsparser.h
+++ b/src/libs/extensionsystem/optionsparser.h
@@ -28,6 +28,7 @@ public:
static const char *NOTEST_OPTION;
static const char *SCENARIO_OPTION;
static const char *PROFILE_OPTION;
+ static const char *TRACE_OPTION;
static const char *NO_CRASHCHECK_OPTION;
private:
@@ -41,6 +42,7 @@ private:
bool checkForAppOption();
bool checkForPluginOption();
bool checkForProfilingOption();
+ bool checkForTraceOption();
bool checkForNoCrashcheckOption();
bool checkForUnknownOption();
void forceDisableAllPluginsExceptTestedAndForceEnabled();
diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp
index 45b9807958e..1f86693f907 100644
--- a/src/libs/extensionsystem/pluginmanager.cpp
+++ b/src/libs/extensionsystem/pluginmanager.cpp
@@ -10,6 +10,8 @@
#include "pluginspec.h"
#include "pluginspec_p.h"
+#include <nanotrace/nanotrace.h>
+
#include <utils/algorithm.h>
#include <utils/benchmarker.h>
#include <utils/fileutils.h>
@@ -373,10 +375,8 @@ const QSet<PluginSpec *> PluginManager::pluginsRequiredByPlugin(PluginSpec *spec
if (depIt.key().type != PluginDependency::Required)
continue;
PluginSpec *depSpec = depIt.value();
- if (!recursiveDependencies.contains(depSpec)) {
- recursiveDependencies.insert(depSpec);
+ if (Utils::insert(recursiveDependencies, depSpec))
queue.push(depSpec);
- }
}
}
recursiveDependencies.remove(spec);
@@ -490,7 +490,7 @@ void PluginManager::setSettings(QtcSettings *settings)
default disabled plugins.
Needs to be set before the plugin search path is set with setPluginPaths().
*/
-void PluginManager::setGlobalSettings(QtcSettings *settings)
+void PluginManager::setInstallSettings(QtcSettings *settings)
{
d->setGlobalSettings(settings);
}
@@ -724,6 +724,12 @@ void PluginManager::formatOptions(QTextStream &str, int optionIndentation, int d
QString(), QLatin1String("Profile plugin loading"),
optionIndentation, descriptionIndentation);
formatOption(str,
+ QLatin1String(OptionsParser::TRACE_OPTION),
+ QLatin1String("file"),
+ QLatin1String("Write trace file (CTF) for plugin loading"),
+ optionIndentation,
+ descriptionIndentation);
+ formatOption(str,
QLatin1String(OptionsParser::NO_CRASHCHECK_OPTION),
QString(),
QLatin1String("Disable startup check for previously crashed instance"),
@@ -883,16 +889,6 @@ PluginManager::ProcessData PluginManager::creatorProcessData()
}
/*!
- \internal
-*/
-
-void PluginManager::profilingReport(const char *what, const PluginSpec *spec)
-{
- d->profilingReport(what, spec);
-}
-
-
-/*!
Returns a list of plugins in load order.
*/
QVector<PluginSpec *> PluginManager::loadQueue()
@@ -942,23 +938,30 @@ PluginSpecPrivate *PluginManagerPrivate::privateSpec(PluginSpec *spec)
return spec->d;
}
-void PluginManagerPrivate::nextDelayedInitialize()
+void PluginManagerPrivate::startDelayedInitialize()
{
- while (!delayedInitializeQueue.empty()) {
- PluginSpec *spec = delayedInitializeQueue.front();
- delayedInitializeQueue.pop();
- profilingReport(">delayedInitialize", spec);
- bool delay = spec->d->delayedInitialize();
- profilingReport("<delayedInitialize", spec);
- if (delay)
- break; // do next delayedInitialize after a delay
- }
- if (delayedInitializeQueue.empty()) {
+ Utils::setMimeStartupPhase(MimeStartupPhase::PluginsDelayedInitializing);
+ {
+ NANOTRACE_SCOPE("ExtensionSystem", "DelayedInitialize");
+ while (!delayedInitializeQueue.empty()) {
+ PluginSpec *spec = delayedInitializeQueue.front();
+ const std::string specName = spec->name().toStdString();
+ delayedInitializeQueue.pop();
+ NANOTRACE_SCOPE(specName, specName + "::delayedInitialized");
+ profilingReport(">delayedInitialize", spec);
+ bool delay = spec->d->delayedInitialize();
+ profilingReport("<delayedInitialize", spec, &spec->d->performanceData.delayedInitialize);
+ if (delay) // give UI a bit of breathing space, but prevent user interaction
+ QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ }
+ Utils::setMimeStartupPhase(MimeStartupPhase::UpAndRunning);
m_isInitializationDone = true;
- delete delayedInitializeTimer;
- delayedInitializeTimer = nullptr;
- profilingSummary();
- emit q->initializationDone();
+ if (m_profileTimer)
+ m_totalStartupMS = m_profileTimer->elapsed();
+ printProfilingSummary();
+ }
+ NANOTRACE_SHUTDOWN();
+ emit q->initializationDone();
#ifdef WITH_TESTS
if (PluginManager::testRunRequested())
startTests();
@@ -971,9 +974,6 @@ void PluginManagerPrivate::nextDelayedInitialize()
}
}
#endif
- } else {
- delayedInitializeTimer->start();
- }
}
/*!
@@ -1020,12 +1020,12 @@ void PluginManagerPrivate::writeSettings()
void PluginManagerPrivate::readSettings()
{
if (globalSettings) {
- defaultDisabledPlugins = globalSettings->value(QLatin1String(C_IGNORED_PLUGINS)).toStringList();
- defaultEnabledPlugins = globalSettings->value(QLatin1String(C_FORCEENABLED_PLUGINS)).toStringList();
+ defaultDisabledPlugins = globalSettings->value(C_IGNORED_PLUGINS).toStringList();
+ defaultEnabledPlugins = globalSettings->value(C_FORCEENABLED_PLUGINS).toStringList();
}
if (settings) {
- disabledPlugins = settings->value(QLatin1String(C_IGNORED_PLUGINS)).toStringList();
- forceEnabledPlugins = settings->value(QLatin1String(C_FORCEENABLED_PLUGINS)).toStringList();
+ disabledPlugins = settings->value(C_IGNORED_PLUGINS).toStringList();
+ forceEnabledPlugins = settings->value(C_FORCEENABLED_PLUGINS).toStringList();
}
}
@@ -1035,11 +1035,7 @@ void PluginManagerPrivate::readSettings()
void PluginManagerPrivate::stopAll()
{
m_isShuttingDown = true;
- if (delayedInitializeTimer && delayedInitializeTimer->isActive()) {
- delayedInitializeTimer->stop();
- delete delayedInitializeTimer;
- delayedInitializeTimer = nullptr;
- }
+ delayedInitializeTimer.stop();
const QVector<PluginSpec *> queue = loadQueue();
for (PluginSpec *spec : queue)
@@ -1305,7 +1301,7 @@ void PluginManagerPrivate::addObject(QObject *obj)
if (debugLeaks)
qDebug() << "PluginManagerPrivate::addObject" << obj << obj->objectName();
- if (m_profilingVerbosity && !m_profileTimer.isNull()) {
+ if (m_profilingVerbosity > 1 && m_profileTimer) {
// Report a timestamp when adding an object. Useful for profiling
// its initialization time.
const int absoluteElapsedMS = int(m_profileTimer->elapsed());
@@ -1345,34 +1341,45 @@ void PluginManagerPrivate::removeObject(QObject *obj)
*/
void PluginManagerPrivate::loadPlugins()
{
+ if (m_profilingVerbosity > 0)
+ qDebug("Profiling started");
+
const QVector<PluginSpec *> queue = loadQueue();
Utils::setMimeStartupPhase(MimeStartupPhase::PluginsLoading);
- for (PluginSpec *spec : queue)
- loadPlugin(spec, PluginSpec::Loaded);
+ {
+ NANOTRACE_SCOPE("ExtensionSystem", "Load");
+ for (PluginSpec *spec : queue)
+ loadPlugin(spec, PluginSpec::Loaded);
+ }
Utils::setMimeStartupPhase(MimeStartupPhase::PluginsInitializing);
- for (PluginSpec *spec : queue)
- loadPlugin(spec, PluginSpec::Initialized);
+ {
+ NANOTRACE_SCOPE("ExtensionSystem", "Initialize");
+ for (PluginSpec *spec : queue)
+ loadPlugin(spec, PluginSpec::Initialized);
+ }
- Utils::setMimeStartupPhase(MimeStartupPhase::PluginsDelayedInitializing);
- Utils::reverseForeach(queue, [this](PluginSpec *spec) {
- loadPlugin(spec, PluginSpec::Running);
- if (spec->state() == PluginSpec::Running) {
- delayedInitializeQueue.push(spec);
- } else {
- // Plugin initialization failed, so cleanup after it
- spec->d->kill();
- }
- });
+ {
+ NANOTRACE_SCOPE("ExtensionSystem", "ExtensionsInitialized");
+ Utils::reverseForeach(queue, [this](PluginSpec *spec) {
+ loadPlugin(spec, PluginSpec::Running);
+ if (spec->state() == PluginSpec::Running) {
+ delayedInitializeQueue.push(spec);
+ } else {
+ // Plugin initialization failed, so cleanup after it
+ spec->d->kill();
+ }
+ });
+ }
emit q->pluginsChanged();
- Utils::setMimeStartupPhase(MimeStartupPhase::UpAndRunning);
- delayedInitializeTimer = new QTimer;
- delayedInitializeTimer->setInterval(DELAYED_INITIALIZE_INTERVAL);
- delayedInitializeTimer->setSingleShot(true);
- connect(delayedInitializeTimer, &QTimer::timeout,
- this, &PluginManagerPrivate::nextDelayedInitialize);
- delayedInitializeTimer->start();
+ delayedInitializeTimer.setInterval(DELAYED_INITIALIZE_INTERVAL);
+ delayedInitializeTimer.setSingleShot(true);
+ connect(&delayedInitializeTimer,
+ &QTimer::timeout,
+ this,
+ &PluginManagerPrivate::startDelayedInitialize);
+ delayedInitializeTimer.start();
}
/*!
@@ -1482,7 +1489,7 @@ public:
static std::optional<QString> lockedPluginName(PluginManagerPrivate *pm)
{
const QString lockFilePath = LockFile::filePath(pm);
- if (QFile::exists(lockFilePath)) {
+ if (QFileInfo::exists(lockFilePath)) {
QFile f(lockFilePath);
if (f.open(QIODevice::ReadOnly)) {
const auto pluginName = QString::fromUtf8(f.readLine()).trimmed();
@@ -1533,8 +1540,7 @@ void PluginManagerPrivate::checkForProblematicPlugins()
: Tr::tr("Help > About Plugins");
const QString otherPluginsText
= Tr::tr("If you temporarily disable %1, the following plugins that depend on "
- "it are also disabled: %2.\n\n")
- .arg(spec->name(), dependentsList);
+ "it are also disabled: %2.").arg(spec->name(), dependentsList) + "\n\n";
const QString detailsText = (dependents.isEmpty() ? QString() : otherPluginsText)
+ Tr::tr("Disable plugins permanently in %1.").arg(pluginsMenu);
const QString text = Tr::tr("The last time you started %1, it seems to have closed because "
@@ -1589,12 +1595,18 @@ void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destSt
if (enableCrashCheck && destState < PluginSpec::Stopped)
lockFile.reset(new LockFile(this, spec));
+ const std::string specName = spec->name().toStdString();
+
switch (destState) {
- case PluginSpec::Running:
+ case PluginSpec::Running: {
+ NANOTRACE_SCOPE(specName, specName + "::extensionsInitialized");
profilingReport(">initializeExtensions", spec);
spec->d->initializeExtensions();
- profilingReport("<initializeExtensions", spec);
+ profilingReport("<initializeExtensions",
+ spec,
+ &spec->d->performanceData.extensionsInitialized);
return;
+ }
case PluginSpec::Deleted:
profilingReport(">delete", spec);
spec->d->kill();
@@ -1618,16 +1630,20 @@ void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destSt
}
}
switch (destState) {
- case PluginSpec::Loaded:
+ case PluginSpec::Loaded: {
+ NANOTRACE_SCOPE(specName, specName + "::load");
profilingReport(">loadLibrary", spec);
spec->d->loadLibrary();
- profilingReport("<loadLibrary", spec);
+ profilingReport("<loadLibrary", spec, &spec->d->performanceData.load);
break;
- case PluginSpec::Initialized:
+ }
+ case PluginSpec::Initialized: {
+ NANOTRACE_SCOPE(specName, specName + "::initialize");
profilingReport(">initializePlugin", spec);
spec->d->initializePlugin();
- profilingReport("<initializePlugin", spec);
+ profilingReport("<initializePlugin", spec, &spec->d->performanceData.initialize);
break;
+ }
case PluginSpec::Stopped:
profilingReport(">stop", spec);
if (spec->d->stop() == IPlugin::AsynchronousShutdown) {
@@ -1762,58 +1778,83 @@ PluginSpec *PluginManagerPrivate::pluginByName(const QString &name) const
return Utils::findOrDefault(pluginSpecs, [name](PluginSpec *spec) { return spec->name() == name; });
}
-void PluginManagerPrivate::initProfiling()
+void PluginManagerPrivate::increaseProfilingVerbosity()
{
- if (m_profileTimer.isNull()) {
- m_profileTimer.reset(new QElapsedTimer);
- m_profileTimer->start();
- m_profileElapsedMS = 0;
- qDebug("Profiling started");
- } else {
- m_profilingVerbosity++;
- }
+ m_profilingVerbosity++;
+ if (!m_profileTimer)
+ PluginManager::startProfiling();
+}
+
+void PluginManagerPrivate::enableTracing(const QString &filePath)
+{
+ const QString jsonFilePath = filePath.endsWith(".json") ? filePath : filePath + ".json";
+#ifdef NANOTRACE_ENABLED
+ qDebug() << "Trace event file (CTF) will be saved at" << qPrintable(jsonFilePath);
+#endif
+ NANOTRACE_INIT(QCoreApplication::applicationName().toStdString(),
+ "Main",
+ jsonFilePath.toStdString());
}
-void PluginManagerPrivate::profilingReport(const char *what, const PluginSpec *spec /* = 0 */)
+void PluginManagerPrivate::profilingReport(const char *what, const PluginSpec *spec, qint64 *target)
{
- if (!m_profileTimer.isNull()) {
- const int absoluteElapsedMS = int(m_profileTimer->elapsed());
- const int elapsedMS = absoluteElapsedMS - m_profileElapsedMS;
+ if (m_profileTimer) {
+ const qint64 absoluteElapsedMS = m_profileTimer->elapsed();
+ const qint64 elapsedMS = absoluteElapsedMS - m_profileElapsedMS;
m_profileElapsedMS = absoluteElapsedMS;
- if (spec)
- qDebug("%-22s %-22s %8dms (%8dms)", what, qPrintable(spec->name()), absoluteElapsedMS, elapsedMS);
- else
- qDebug("%-45s %8dms (%8dms)", what, absoluteElapsedMS, elapsedMS);
- if (what && *what == '<') {
+ if (m_profilingVerbosity > 0) {
+ qDebug("%-22s %-40s %8lldms (%8lldms)",
+ what,
+ qPrintable(spec->name()),
+ absoluteElapsedMS,
+ elapsedMS);
+ }
+ if (target) {
QString tc;
- if (spec) {
- m_profileTotal[spec] += elapsedMS;
- tc = spec->name() + '_';
- }
+ *target = elapsedMS;
+ tc = spec->name() + '_';
tc += QString::fromUtf8(QByteArray(what + 1));
Utils::Benchmarker::report("loadPlugins", tc, elapsedMS);
}
}
}
-void PluginManagerPrivate::profilingSummary() const
-{
- if (!m_profileTimer.isNull()) {
- QMultiMap<int, const PluginSpec *> sorter;
- int total = 0;
-
- auto totalEnd = m_profileTotal.constEnd();
- for (auto it = m_profileTotal.constBegin(); it != totalEnd; ++it) {
- sorter.insert(it.value(), it.key());
- total += it.value();
- }
+QString PluginManagerPrivate::profilingSummary(qint64 *totalOut) const
+{
+ QString summary;
+ const QVector<PluginSpec *> specs = Utils::sorted(pluginSpecs,
+ [](PluginSpec *s1, PluginSpec *s2) {
+ return s1->performanceData().total()
+ < s2->performanceData().total();
+ });
+ const qint64 total
+ = std::accumulate(specs.constBegin(), specs.constEnd(), 0, [](qint64 t, PluginSpec *s) {
+ return t + s->performanceData().total();
+ });
+ for (PluginSpec *s : specs) {
+ if (!s->isEffectivelyEnabled())
+ continue;
+ const qint64 t = s->performanceData().total();
+ summary += QString("%1 %2ms ( %3% ) (%4)\n")
+ .arg(s->name(), -34)
+ .arg(t, 8)
+ .arg(100.0 * t / total, 5, 'f', 2)
+ .arg(s->performanceData().summary());
+ }
+ summary += QString("Total plugins: %1ms\n").arg(total, 8);
+ summary += QString("Total startup: %1ms\n").arg(m_totalStartupMS, 8);
+ if (totalOut)
+ *totalOut = total;
+ return summary;
+}
- auto sorterEnd = sorter.constEnd();
- for (auto it = sorter.constBegin(); it != sorterEnd; ++it)
- qDebug("%-22s %8dms ( %5.2f%% )", qPrintable(it.value()->name()),
- it.key(), 100.0 * it.key() / total);
- qDebug("Total: %8dms", total);
- Utils::Benchmarker::report("loadPlugins", "Total", total);
+void PluginManagerPrivate::printProfilingSummary() const
+{
+ if (m_profilingVerbosity > 0) {
+ qint64 total;
+ const QString summary = profilingSummary(&total);
+ qDebug() << qPrintable(summary);
+ Utils::Benchmarker::report("loadPlugins", "Total", total);
}
}
@@ -1857,4 +1898,11 @@ QObject *PluginManager::getObjectByName(const QString &name)
});
}
+void PluginManager::startProfiling()
+{
+ d->m_profileTimer.reset(new QElapsedTimer);
+ d->m_profileTimer->start();
+ d->m_profileElapsedMS = 0;
+}
+
} // ExtensionSystem
diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h
index ecd0ee70b73..e7c6a315259 100644
--- a/src/libs/extensionsystem/pluginmanager.h
+++ b/src/libs/extensionsystem/pluginmanager.h
@@ -64,6 +64,7 @@ public:
static QObject *getObjectByName(const QString &name);
+ static void startProfiling();
// Plugin operations
static QVector<PluginSpec *> loadQueue();
static void loadPlugins();
@@ -83,7 +84,7 @@ public:
// Settings
static void setSettings(Utils::QtcSettings *settings);
static Utils::QtcSettings *settings();
- static void setGlobalSettings(Utils::QtcSettings *settings);
+ static void setInstallSettings(Utils::QtcSettings *settings);
static Utils::QtcSettings *globalSettings();
static void writeSettings();
@@ -124,8 +125,6 @@ public:
static void setCreatorProcessData(const ProcessData &data);
static ProcessData creatorProcessData();
- static void profilingReport(const char *what, const PluginSpec *spec = nullptr);
-
static QString platformName();
static bool isInitializationDone();
diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h
index c7a4291a6b7..3de21388bbb 100644
--- a/src/libs/extensionsystem/pluginmanager_p.h
+++ b/src/libs/extensionsystem/pluginmanager_p.h
@@ -15,13 +15,13 @@
#include <QScopedPointer>
#include <QSet>
#include <QStringList>
+#include <QTimer>
#include <QWaitCondition>
#include <queue>
QT_BEGIN_NAMESPACE
class QTime;
-class QTimer;
class QEventLoop;
QT_END_NAMESPACE
@@ -38,9 +38,8 @@ namespace Internal {
class PluginSpecPrivate;
-class EXTENSIONSYSTEM_EXPORT PluginManagerPrivate : public QObject
+class EXTENSIONSYSTEM_TEST_EXPORT PluginManagerPrivate : public QObject
{
- Q_OBJECT
public:
PluginManagerPrivate(PluginManager *pluginManager);
~PluginManagerPrivate() override;
@@ -58,9 +57,11 @@ public:
void loadPlugin(PluginSpec *spec, PluginSpec::State destState);
void resolveDependencies();
void enableDependenciesIndirectly();
- void initProfiling();
- void profilingSummary() const;
- void profilingReport(const char *what, const PluginSpec *spec = nullptr);
+ void increaseProfilingVerbosity();
+ void enableTracing(const QString &filePath);
+ QString profilingSummary(qint64 *totalOut = nullptr) const;
+ void printProfilingSummary() const;
+ void profilingReport(const char *what, const PluginSpec *spec, qint64 *target = nullptr);
void setSettings(Utils::QtcSettings *settings);
void setGlobalSettings(Utils::QtcSettings *settings);
void readSettings();
@@ -97,7 +98,7 @@ public:
QStringList disabledPlugins;
QStringList forceEnabledPlugins;
// delayed initialization
- QTimer *delayedInitializeTimer = nullptr;
+ QTimer delayedInitializeTimer;
std::queue<PluginSpec *> delayedInitializeQueue;
// ansynchronous shutdown
QSet<PluginSpec *> asynchronousPlugins; // plugins that have requested async shutdown
@@ -106,8 +107,9 @@ public:
QStringList arguments;
QStringList argumentsForRestart;
QScopedPointer<QElapsedTimer> m_profileTimer;
- QHash<const PluginSpec *, int> m_profileTotal;
- int m_profileElapsedMS = 0;
+ qint64 m_profileElapsedMS = 0;
+ qint64 m_totalUntilDelayedInitialize = 0;
+ qint64 m_totalStartupMS = 0;
unsigned m_profilingVerbosity = 0;
Utils::QtcSettings *settings = nullptr;
Utils::QtcSettings *globalSettings = nullptr;
@@ -140,7 +142,7 @@ public:
private:
PluginManager *q;
- void nextDelayedInitialize();
+ void startDelayedInitialize();
void readPluginPaths();
bool loadQueue(PluginSpec *spec,
diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp
index 62b3c0096f6..bbc4e3541c0 100644
--- a/src/libs/extensionsystem/pluginspec.cpp
+++ b/src/libs/extensionsystem/pluginspec.cpp
@@ -402,6 +402,11 @@ QJsonObject PluginSpec::metaData() const
return d->metaData;
}
+const PerformanceData &PluginSpec::performanceData() const
+{
+ return d->performanceData;
+}
+
/*!
Returns a list of descriptions of command line arguments the plugin processes.
*/
@@ -1119,7 +1124,6 @@ bool PluginSpecPrivate::initializePlugin()
hasError = true;
return false;
}
- plugin->tryCreateObjects();
state = PluginSpec::Initialized;
return true;
}
@@ -1146,7 +1150,6 @@ bool PluginSpecPrivate::initializeExtensions()
return false;
}
plugin->extensionsInitialized();
- plugin->tryCreateObjects();
state = PluginSpec::Running;
return true;
}
@@ -1167,7 +1170,6 @@ bool PluginSpecPrivate::delayedInitialize()
return false;
}
const bool res = plugin->delayedInitialize();
- plugin->tryCreateObjects();
return res;
}
diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h
index 9abb4bf4475..6030bc568e4 100644
--- a/src/libs/extensionsystem/pluginspec.h
+++ b/src/libs/extensionsystem/pluginspec.h
@@ -53,6 +53,24 @@ struct EXTENSIONSYSTEM_EXPORT PluginArgumentDescription
QString description;
};
+struct EXTENSIONSYSTEM_EXPORT PerformanceData
+{
+ qint64 load = 0;
+ qint64 initialize = 0;
+ qint64 extensionsInitialized = 0;
+ qint64 delayedInitialize = 0;
+
+ qint64 total() const { return load + initialize + extensionsInitialized + delayedInitialize; }
+ QString summary() const
+ {
+ return QString("l: %1ms, i: %2ms, x: %3ms, d: %4ms")
+ .arg(load, 3)
+ .arg(initialize, 3)
+ .arg(extensionsInitialized, 3)
+ .arg(delayedInitialize, 3);
+ }
+};
+
class EXTENSIONSYSTEM_EXPORT PluginSpec
{
public:
@@ -84,6 +102,7 @@ public:
bool isForceDisabled() const;
QVector<PluginDependency> dependencies() const;
QJsonObject metaData() const;
+ const PerformanceData &performanceData() const;
using PluginArgumentDescriptions = QVector<PluginArgumentDescription>;
PluginArgumentDescriptions argumentDescriptions() const;
diff --git a/src/libs/extensionsystem/pluginspec_p.h b/src/libs/extensionsystem/pluginspec_p.h
index 568ab943a31..f802902e53c 100644
--- a/src/libs/extensionsystem/pluginspec_p.h
+++ b/src/libs/extensionsystem/pluginspec_p.h
@@ -22,7 +22,7 @@ class IPlugin;
namespace Internal {
-class EXTENSIONSYSTEM_EXPORT PluginSpecPrivate : public QObject
+class EXTENSIONSYSTEM_TEST_EXPORT PluginSpecPrivate : public QObject
{
Q_OBJECT
@@ -84,6 +84,8 @@ public:
bool hasError = false;
QString errorString;
+ PerformanceData performanceData;
+
static bool isValidVersion(const QString &version);
static int versionCompare(const QString &version1, const QString &version2);
diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp
index 693dd3c471e..f4afedc01ea 100644
--- a/src/libs/extensionsystem/pluginview.cpp
+++ b/src/libs/extensionsystem/pluginview.cpp
@@ -275,7 +275,6 @@ PluginView::PluginView(QWidget *parent)
m_categoryView = new TreeView(this);
m_categoryView->setAlternatingRowColors(true);
m_categoryView->setIndentation(20);
- m_categoryView->setUniformRowHeights(true);
m_categoryView->setSortingEnabled(true);
m_categoryView->setColumnWidth(LoadedColumn, 40);
m_categoryView->header()->setDefaultSectionSize(120);
diff --git a/src/libs/glsl/glslsymbol.cpp b/src/libs/glsl/glslsymbol.cpp
index 9b2630872c6..fb1324aacf9 100644
--- a/src/libs/glsl/glslsymbol.cpp
+++ b/src/libs/glsl/glslsymbol.cpp
@@ -52,5 +52,5 @@ Symbol *Scope::lookup(const QString &name) const
QList<Symbol *> Scope::members() const
{
- return QList<Symbol *>();
+ return {};
}
diff --git a/src/libs/languageserverprotocol/clientcapabilities.cpp b/src/libs/languageserverprotocol/clientcapabilities.cpp
index 321b46ecd2e..acae7ad554a 100644
--- a/src/libs/languageserverprotocol/clientcapabilities.cpp
+++ b/src/libs/languageserverprotocol/clientcapabilities.cpp
@@ -77,4 +77,46 @@ bool SemanticTokensClientCapabilities::isValid() const
&& contains(formatsKey);
}
+const char resourceOperationCreate[] = "create";
+const char resourceOperationRename[] = "rename";
+const char resourceOperationDelete[] = "delete";
+
+std::optional<QList<WorkspaceClientCapabilities::WorkspaceEditCapabilities::ResourceOperationKind>>
+WorkspaceClientCapabilities::WorkspaceEditCapabilities::resourceOperations() const
+{
+ if (!contains(resourceOperationsKey))
+ return std::nullopt;
+ QList<ResourceOperationKind> result;
+ for (const QJsonValue &value : this->value(resourceOperationsKey).toArray()) {
+ const QString str = value.toString();
+ if (str == resourceOperationCreate)
+ result << ResourceOperationKind::Create;
+ else if (str == resourceOperationRename)
+ result << ResourceOperationKind::Rename;
+ else if (str == resourceOperationDelete)
+ result << ResourceOperationKind::Delete;
+ }
+ return result;
+}
+
+void WorkspaceClientCapabilities::WorkspaceEditCapabilities::setResourceOperations(
+ const QList<ResourceOperationKind> &resourceOperations)
+{
+ QJsonArray array;
+ for (const auto &kind : resourceOperations) {
+ switch (kind) {
+ case ResourceOperationKind::Create:
+ array << resourceOperationCreate;
+ break;
+ case ResourceOperationKind::Rename:
+ array << resourceOperationRename;
+ break;
+ case ResourceOperationKind::Delete:
+ array << resourceOperationDelete;
+ break;
+ }
+ }
+ insert(resourceOperationsKey, array);
+}
+
} // namespace LanguageServerProtocol
diff --git a/src/libs/languageserverprotocol/clientcapabilities.h b/src/libs/languageserverprotocol/clientcapabilities.h
index 92f78ae0562..584c4b8d539 100644
--- a/src/libs/languageserverprotocol/clientcapabilities.h
+++ b/src/libs/languageserverprotocol/clientcapabilities.h
@@ -555,6 +555,14 @@ public:
void setDocumentChanges(bool documentChanges)
{ insert(documentChangesKey, documentChanges); }
void clearDocumentChanges() { remove(documentChangesKey); }
+
+ enum class ResourceOperationKind { Create, Rename, Delete };
+
+ // The resource operations the client supports. Clients should at least support 'create',
+ // 'rename' and 'delete' files and folders.
+ std::optional<QList<ResourceOperationKind>> resourceOperations() const;
+ void setResourceOperations(const QList<ResourceOperationKind> &resourceOperations);
+ void clearResourceOperations() { remove(resourceOperationsKey); }
};
// Capabilities specific to `WorkspaceEdit`s
@@ -628,7 +636,7 @@ public:
void clearWorkDoneProgress() { remove(workDoneProgressKey); }
private:
- constexpr static const char16_t workDoneProgressKey[] = u"workDoneProgress";
+ constexpr static const char workDoneProgressKey[] = "workDoneProgress";
};
class LANGUAGESERVERPROTOCOL_EXPORT ClientCapabilities : public JsonObject
diff --git a/src/libs/languageserverprotocol/jsonkeys.h b/src/libs/languageserverprotocol/jsonkeys.h
index 302c57bc209..250b5ca87c1 100644
--- a/src/libs/languageserverprotocol/jsonkeys.h
+++ b/src/libs/languageserverprotocol/jsonkeys.h
@@ -5,220 +5,227 @@
namespace LanguageServerProtocol {
-constexpr char16_t actionsKey[] = u"actions";
-constexpr char16_t activeParameterKey[] = u"activeParameter";
-constexpr char16_t activeParameterSupportKey[] = u"activeParameterSupport";
-constexpr char16_t activeSignatureKey[] = u"activeSignature";
-constexpr char16_t addedKey[] = u"added";
-constexpr char16_t additionalTextEditsKey[] = u"additionalTextEdits";
-constexpr char16_t alphaKey[] = u"alpha";
-constexpr char16_t appliedKey[] = u"applied";
-constexpr char16_t applyEditKey[] = u"applyEdit";
-constexpr char16_t argumentsKey[] = u"arguments";
-constexpr char16_t blueKey[] = u"blue";
-constexpr char16_t callHierarchyKey[] = u"callHierarchy";
-constexpr char16_t callHierarchyProviderKey[] = u"callHierarchyProvider";
-constexpr char16_t cancellableKey[] = u"cancellable";
-constexpr char16_t capabilitiesKey[] = u"capabilities";
-constexpr char16_t chKey[] = u"ch";
-constexpr char16_t changeKey[] = u"change";
-constexpr char16_t changeNotificationsKey[] = u"changeNotifications";
-constexpr char16_t changesKey[] = u"changes";
-constexpr char16_t characterKey[] = u"character";
-constexpr char16_t childrenKey[] = u"children";
-constexpr char16_t clientInfoKey[] = u"clientInfo";
-constexpr char16_t codeActionKey[] = u"codeAction";
-constexpr char16_t codeActionKindKey[] = u"codeActionKind";
-constexpr char16_t codeActionKindsKey[] = u"codeActionKinds";
-constexpr char16_t codeActionLiteralSupportKey[] = u"codeActionLiteralSupport";
-constexpr char16_t codeActionProviderKey[] = u"codeActionProvider";
-constexpr char16_t codeKey[] = u"code";
-constexpr char16_t codeLensKey[] = u"codeLens";
-constexpr char16_t codeLensProviderKey[] = u"codeLensProvider";
-constexpr char16_t colorInfoKey[] = u"colorInfo";
-constexpr char16_t colorKey[] = u"color";
-constexpr char16_t colorProviderKey[] = u"colorProvider";
-constexpr char16_t commandKey[] = u"command";
-constexpr char16_t commandsKey[] = u"commands";
-constexpr char16_t commitCharacterSupportKey[] = u"commitCharacterSupport";
-constexpr char16_t commitCharactersKey[] = u"commitCharacters";
-constexpr char16_t completionItemKey[] = u"completionItem";
-constexpr char16_t completionItemKindKey[] = u"completionItemKind";
-constexpr char16_t completionKey[] = u"completion";
-constexpr char16_t completionProviderKey[] = u"completionProvider";
-constexpr char16_t configurationKey[] = u"configuration";
-constexpr char16_t containerNameKey[] = u"containerName";
-constexpr char16_t contentChangesKey[] = u"contentChanges";
-constexpr char16_t contentFormatKey[] = u"contentFormat";
-constexpr char16_t contentKey[] = u"value";
-constexpr char16_t contentsKey[] = u"contents";
-constexpr char16_t contextKey[] = u"context";
-constexpr char16_t contextSupportKey[] = u"contextSupport";
-constexpr char16_t dataKey[] = u"data";
-constexpr char16_t definitionKey[] = u"definition";
-constexpr char16_t definitionProviderKey[] = u"definitionProvider";
-constexpr char16_t deleteCountKey[] = u"deleteCount";
-constexpr char16_t deltaKey[] = u"delta";
-constexpr char16_t deprecatedKey[] = u"deprecated";
-constexpr char16_t detailKey[] = u"detail";
-constexpr char16_t diagnosticsKey[] = u"diagnostics";
-constexpr char16_t didChangeConfigurationKey[] = u"didChangeConfiguration";
-constexpr char16_t didChangeWatchedFilesKey[] = u"didChangeWatchedFiles";
-constexpr char16_t didSaveKey[] = u"didSave";
-constexpr char16_t documentChangesKey[] = u"documentChanges";
-constexpr char16_t documentFormattingProviderKey[] = u"documentFormattingProvider";
-constexpr char16_t documentHighlightKey[] = u"documentHighlight";
-constexpr char16_t documentHighlightProviderKey[] = u"documentHighlightProvider";
-constexpr char16_t documentLinkKey[] = u"documentLink";
-constexpr char16_t documentLinkProviderKey[] = u"documentLinkProvider";
-constexpr char16_t documentRangeFormattingProviderKey[] = u"documentRangeFormattingProvider";
-constexpr char16_t documentSelectorKey[] = u"documentSelector";
-constexpr char16_t documentSymbolKey[] = u"documentSymbol";
-constexpr char16_t documentSymbolProviderKey[] = u"documentSymbolProvider";
-constexpr char16_t documentationFormatKey[] = u"documentationFormat";
-constexpr char16_t documentationKey[] = u"documentation";
-constexpr char16_t dynamicRegistrationKey[] = u"dynamicRegistration";
-constexpr char16_t editKey[] = u"edit";
-constexpr char16_t editsKey[] = u"edits";
-constexpr char16_t endKey[] = u"end";
-constexpr char16_t errorKey[] = u"error";
-constexpr char16_t eventKey[] = u"event";
-constexpr char16_t executeCommandKey[] = u"executeCommand";
-constexpr char16_t executeCommandProviderKey[] = u"executeCommandProvider";
-constexpr char16_t experimentalKey[] = u"experimental";
-constexpr char16_t filterTextKey[] = u"filterText";
-constexpr char16_t firstTriggerCharacterKey[] = u"firstTriggerCharacter";
-constexpr char16_t formatsKey[] = u"formats";
-constexpr char16_t formattingKey[] = u"formatting";
-constexpr char16_t fromKey[] = u"from";
-constexpr char16_t fromRangesKey[] = u"fromRanges";
-constexpr char16_t fullKey[] = u"full";
-constexpr char16_t greenKey[] = u"green";
-constexpr char16_t hierarchicalDocumentSymbolSupportKey[] = u"hierarchicalDocumentSymbolSupport";
-constexpr char16_t hoverKey[] = u"hover";
-constexpr char16_t hoverProviderKey[] = u"hoverProvider";
-constexpr char16_t idKey[] = u"id";
-constexpr char16_t implementationKey[] = u"implementation";
-constexpr char16_t implementationProviderKey[] = u"implementationProvider";
-constexpr char16_t includeDeclarationKey[] = u"includeDeclaration";
-constexpr char16_t includeTextKey[] = u"includeText";
-constexpr char16_t initializationOptionsKey[] = u"initializationOptions";
-constexpr char16_t insertFinalNewlineKey[] = u"insertFinalNewline";
-constexpr char16_t insertSpaceKey[] = u"insertSpace";
-constexpr char16_t insertTextFormatKey[] = u"insertTextFormat";
-constexpr char16_t insertTextKey[] = u"insertText";
-constexpr char16_t isIncompleteKey[] = u"isIncomplete";
-constexpr char16_t itemKey[] = u"item";
-constexpr char16_t itemsKey[] = u"items";
-constexpr char16_t jsonRpcVersionKey[] = u"jsonrpc";
-constexpr char16_t kindKey[] = u"kind";
-constexpr char16_t labelKey[] = u"label";
-constexpr char16_t languageIdKey[] = u"languageId";
-constexpr char16_t languageKey[] = u"language";
-constexpr char16_t legendKey[] = u"legend";
-constexpr char16_t limitKey[] = u"limit";
-constexpr char16_t lineKey[] = u"line";
-constexpr char16_t linesKey[] = u"lines";
-constexpr char16_t locationKey[] = u"location";
-constexpr char16_t messageKey[] = u"message";
-constexpr char16_t methodKey[] = u"method";
-constexpr char16_t moreTriggerCharacterKey[] = u"moreTriggerCharacter";
-constexpr char16_t multiLineTokenSupportKey[] = u"multiLineTokenSupport";
-constexpr char16_t nameKey[] = u"name";
-constexpr char16_t newNameKey[] = u"newName";
-constexpr char16_t newTextKey[] = u"newText";
-constexpr char16_t onTypeFormattingKey[] = u"onTypeFormatting";
-constexpr char16_t onlyKey[] = u"only";
-constexpr char16_t openCloseKey[] = u"openClose";
-constexpr char16_t optionsKey[] = u"options";
-constexpr char16_t overlappingTokenSupportKey[] = u"overlappingTokenSupport";
-constexpr char16_t parametersKey[] = u"parameters";
-constexpr char16_t paramsKey[] = u"params";
-constexpr char16_t patternKey[] = u"pattern";
-constexpr char16_t percentageKey[] = u"percentage";
-constexpr char16_t placeHolderKey[] = u"placeHolder";
-constexpr char16_t positionKey[] = u"position";
-constexpr char16_t prepareProviderKey[] = u"prepareProvider";
-constexpr char16_t prepareSupportKey[] = u"prepareSupport";
-constexpr char16_t previousResultIdKey[] = u"previousResultId";
-constexpr char16_t processIdKey[] = u"processId";
-constexpr char16_t queryKey[] = u"query";
-constexpr char16_t rangeFormattingKey[] = u"rangeFormatting";
-constexpr char16_t rangeKey[] = u"range";
-constexpr char16_t rangeLengthKey[] = u"rangeLength";
-constexpr char16_t reasonKey[] = u"reason";
-constexpr char16_t redKey[] = u"red";
-constexpr char16_t referencesKey[] = u"references";
-constexpr char16_t referencesProviderKey[] = u"referencesProvider";
-constexpr char16_t refreshSupportKey[] = u"refreshSupport";
-constexpr char16_t registerOptionsKey[] = u"registerOptions";
-constexpr char16_t registrationsKey[] = u"registrations";
-constexpr char16_t removedKey[] = u"removed";
-constexpr char16_t renameKey[] = u"rename";
-constexpr char16_t renameProviderKey[] = u"renameProvider";
-constexpr char16_t requestsKey[] = u"requests";
-constexpr char16_t resolveProviderKey[] = u"resolveProvider";
-constexpr char16_t resultIdKey[] = u"resultId";
-constexpr char16_t resultKey[] = u"result";
-constexpr char16_t retryKey[] = u"retry";
-constexpr char16_t rootPathKey[] = u"rootPath";
-constexpr char16_t rootUriKey[] = u"rootUri";
-constexpr char16_t saveKey[] = u"save";
-constexpr char16_t schemeKey[] = u"scheme";
-constexpr char16_t scopeUriKey[] = u"scopeUri";
-constexpr char16_t sectionKey[] = u"section";
-constexpr char16_t selectionRangeKey[] = u"selectionRange";
-constexpr char16_t semanticTokensKey[] = u"semanticTokens";
-constexpr char16_t semanticTokensProviderKey[] = u"semanticTokensProvider";
-constexpr char16_t serverInfoKey[] = u"serverInfo";
-constexpr char16_t settingsKey[] = u"settings";
-constexpr char16_t severityKey[] = u"severity";
-constexpr char16_t signatureHelpKey[] = u"signatureHelp";
-constexpr char16_t signatureHelpProviderKey[] = u"signatureHelpProvider";
-constexpr char16_t signatureInformationKey[] = u"signatureInformation";
-constexpr char16_t signaturesKey[] = u"signatures";
-constexpr char16_t snippetSupportKey[] = u"snippetSupport";
-constexpr char16_t sortTextKey[] = u"sortText";
-constexpr char16_t sourceKey[] = u"source";
-constexpr char16_t startKey[] = u"start";
-constexpr char16_t supportedKey[] = u"supported";
-constexpr char16_t symbolKey[] = u"symbol";
-constexpr char16_t symbolKindKey[] = u"symbolKind";
-constexpr char16_t syncKindKey[] = u"syncKind";
-constexpr char16_t synchronizationKey[] = u"synchronization";
-constexpr char16_t tabSizeKey[] = u"tabSize";
-constexpr char16_t tagsKey[] = u"tags";
-constexpr char16_t targetKey[] = u"target";
-constexpr char16_t textDocumentKey[] = u"textDocument";
-constexpr char16_t textDocumentSyncKey[] = u"textDocumentSync";
-constexpr char16_t textEditKey[] = u"textEdit";
-constexpr char16_t textKey[] = u"text";
-constexpr char16_t titleKey[] = u"title";
-constexpr char16_t tokenKey[] = u"token";
-constexpr char16_t toKey[] = u"to";
-constexpr char16_t tokenModifiersKey[] = u"tokenModifiers";
-constexpr char16_t tokenTypesKey[] = u"tokenTypes";
-constexpr char16_t traceKey[] = u"trace";
-constexpr char16_t triggerCharacterKey[] = u"triggerCharacter";
-constexpr char16_t triggerCharactersKey[] = u"triggerCharacters";
-constexpr char16_t triggerKindKey[] = u"triggerKind";
-constexpr char16_t trimFinalNewlinesKey[] = u"trimFinalNewlines";
-constexpr char16_t trimTrailingWhitespaceKey[] = u"trimTrailingWhitespace";
-constexpr char16_t typeDefinitionKey[] = u"typeDefinition";
-constexpr char16_t typeDefinitionProviderKey[] = u"typeDefinitionProvider";
-constexpr char16_t typeKey[] = u"type";
-constexpr char16_t unregistrationsKey[] = u"unregistrations";
-constexpr char16_t uriKey[] = u"uri";
-constexpr char16_t valueKey[] = u"value";
-constexpr char16_t valueSetKey[] = u"valueSet";
-constexpr char16_t versionKey[] = u"version";
-constexpr char16_t willSaveKey[] = u"willSave";
-constexpr char16_t willSaveWaitUntilKey[] = u"willSaveWaitUntil";
-constexpr char16_t windowKey[] = u"window";
-constexpr char16_t workDoneProgressKey[] = u"workDoneProgress";
-constexpr char16_t workspaceEditKey[] = u"workspaceEdit";
-constexpr char16_t workspaceFoldersKey[] = u"workspaceFolders";
-constexpr char16_t workspaceKey[] = u"workspace";
-constexpr char16_t workspaceSymbolProviderKey[] = u"workspaceSymbolProvider";
+constexpr char actionsKey[] = "actions";
+constexpr char activeParameterKey[] = "activeParameter";
+constexpr char activeParameterSupportKey[] = "activeParameterSupport";
+constexpr char activeSignatureKey[] = "activeSignature";
+constexpr char addedKey[] = "added";
+constexpr char additionalTextEditsKey[] = "additionalTextEdits";
+constexpr char alphaKey[] = "alpha";
+constexpr char appliedKey[] = "applied";
+constexpr char applyEditKey[] = "applyEdit";
+constexpr char argumentsKey[] = "arguments";
+constexpr char blueKey[] = "blue";
+constexpr char callHierarchyKey[] = "callHierarchy";
+constexpr char callHierarchyProviderKey[] = "callHierarchyProvider";
+constexpr char cancellableKey[] = "cancellable";
+constexpr char capabilitiesKey[] = "capabilities";
+constexpr char chKey[] = "ch";
+constexpr char changeKey[] = "change";
+constexpr char changeNotificationsKey[] = "changeNotifications";
+constexpr char changesKey[] = "changes";
+constexpr char characterKey[] = "character";
+constexpr char childrenKey[] = "children";
+constexpr char clientInfoKey[] = "clientInfo";
+constexpr char codeActionKey[] = "codeAction";
+constexpr char codeActionKindKey[] = "codeActionKind";
+constexpr char codeActionKindsKey[] = "codeActionKinds";
+constexpr char codeActionLiteralSupportKey[] = "codeActionLiteralSupport";
+constexpr char codeActionProviderKey[] = "codeActionProvider";
+constexpr char codeKey[] = "code";
+constexpr char codeLensKey[] = "codeLens";
+constexpr char codeLensProviderKey[] = "codeLensProvider";
+constexpr char colorInfoKey[] = "colorInfo";
+constexpr char colorKey[] = "color";
+constexpr char colorProviderKey[] = "colorProvider";
+constexpr char commandKey[] = "command";
+constexpr char commandsKey[] = "commands";
+constexpr char commitCharacterSupportKey[] = "commitCharacterSupport";
+constexpr char commitCharactersKey[] = "commitCharacters";
+constexpr char completionItemKey[] = "completionItem";
+constexpr char completionItemKindKey[] = "completionItemKind";
+constexpr char completionKey[] = "completion";
+constexpr char completionProviderKey[] = "completionProvider";
+constexpr char configurationKey[] = "configuration";
+constexpr char containerNameKey[] = "containerName";
+constexpr char contentChangesKey[] = "contentChanges";
+constexpr char contentFormatKey[] = "contentFormat";
+constexpr char contentKey[] = "value";
+constexpr char contentsKey[] = "contents";
+constexpr char contextKey[] = "context";
+constexpr char contextSupportKey[] = "contextSupport";
+constexpr char dataKey[] = "data";
+constexpr char definitionKey[] = "definition";
+constexpr char definitionProviderKey[] = "definitionProvider";
+constexpr char deleteCountKey[] = "deleteCount";
+constexpr char deltaKey[] = "delta";
+constexpr char deprecatedKey[] = "deprecated";
+constexpr char detailKey[] = "detail";
+constexpr char diagnosticsKey[] = "diagnostics";
+constexpr char didChangeConfigurationKey[] = "didChangeConfiguration";
+constexpr char didChangeWatchedFilesKey[] = "didChangeWatchedFiles";
+constexpr char didSaveKey[] = "didSave";
+constexpr char documentChangesKey[] = "documentChanges";
+constexpr char documentFormattingProviderKey[] = "documentFormattingProvider";
+constexpr char documentHighlightKey[] = "documentHighlight";
+constexpr char documentHighlightProviderKey[] = "documentHighlightProvider";
+constexpr char documentLinkKey[] = "documentLink";
+constexpr char documentLinkProviderKey[] = "documentLinkProvider";
+constexpr char documentRangeFormattingProviderKey[] = "documentRangeFormattingProvider";
+constexpr char documentSelectorKey[] = "documentSelector";
+constexpr char documentSymbolKey[] = "documentSymbol";
+constexpr char documentSymbolProviderKey[] = "documentSymbolProvider";
+constexpr char documentationFormatKey[] = "documentationFormat";
+constexpr char documentationKey[] = "documentation";
+constexpr char dynamicRegistrationKey[] = "dynamicRegistration";
+constexpr char editKey[] = "edit";
+constexpr char editsKey[] = "edits";
+constexpr char endKey[] = "end";
+constexpr char errorKey[] = "error";
+constexpr char eventKey[] = "event";
+constexpr char executeCommandKey[] = "executeCommand";
+constexpr char executeCommandProviderKey[] = "executeCommandProvider";
+constexpr char experimentalKey[] = "experimental";
+constexpr char filterTextKey[] = "filterText";
+constexpr char firstTriggerCharacterKey[] = "firstTriggerCharacter";
+constexpr char formatsKey[] = "formats";
+constexpr char formattingKey[] = "formatting";
+constexpr char fromKey[] = "from";
+constexpr char fromRangesKey[] = "fromRanges";
+constexpr char fullKey[] = "full";
+constexpr char greenKey[] = "green";
+constexpr char hierarchicalDocumentSymbolSupportKey[] = "hierarchicalDocumentSymbolSupport";
+constexpr char hoverKey[] = "hover";
+constexpr char hoverProviderKey[] = "hoverProvider";
+constexpr char idKey[] = "id";
+constexpr char ignoreIfExistsKey[] = "ignoreIfExists";
+constexpr char ignoreIfNotExistsKey[] = "ignoreIfNotExists";
+constexpr char implementationKey[] = "implementation";
+constexpr char implementationProviderKey[] = "implementationProvider";
+constexpr char includeDeclarationKey[] = "includeDeclaration";
+constexpr char includeTextKey[] = "includeText";
+constexpr char initializationOptionsKey[] = "initializationOptions";
+constexpr char insertFinalNewlineKey[] = "insertFinalNewline";
+constexpr char insertSpaceKey[] = "insertSpace";
+constexpr char insertTextFormatKey[] = "insertTextFormat";
+constexpr char insertTextKey[] = "insertText";
+constexpr char isIncompleteKey[] = "isIncomplete";
+constexpr char itemKey[] = "item";
+constexpr char itemsKey[] = "items";
+constexpr char jsonRpcVersionKey[] = "jsonrpc";
+constexpr char kindKey[] = "kind";
+constexpr char labelKey[] = "label";
+constexpr char languageIdKey[] = "languageId";
+constexpr char languageKey[] = "language";
+constexpr char legendKey[] = "legend";
+constexpr char limitKey[] = "limit";
+constexpr char lineKey[] = "line";
+constexpr char linesKey[] = "lines";
+constexpr char locationKey[] = "location";
+constexpr char messageKey[] = "message";
+constexpr char methodKey[] = "method";
+constexpr char moreTriggerCharacterKey[] = "moreTriggerCharacter";
+constexpr char multiLineTokenSupportKey[] = "multiLineTokenSupport";
+constexpr char nameKey[] = "name";
+constexpr char newNameKey[] = "newName";
+constexpr char newTextKey[] = "newText";
+constexpr char newUriKey[] = "newUri";
+constexpr char oldUriKey[] = "oldUri";
+constexpr char onTypeFormattingKey[] = "onTypeFormatting";
+constexpr char onlyKey[] = "only";
+constexpr char openCloseKey[] = "openClose";
+constexpr char optionsKey[] = "options";
+constexpr char overlappingTokenSupportKey[] = "overlappingTokenSupport";
+constexpr char overwriteKey[] = "overwrite";
+constexpr char parametersKey[] = "parameters";
+constexpr char paramsKey[] = "params";
+constexpr char patternKey[] = "pattern";
+constexpr char percentageKey[] = "percentage";
+constexpr char placeHolderKey[] = "placeHolder";
+constexpr char positionKey[] = "position";
+constexpr char prepareProviderKey[] = "prepareProvider";
+constexpr char prepareSupportKey[] = "prepareSupport";
+constexpr char previousResultIdKey[] = "previousResultId";
+constexpr char processIdKey[] = "processId";
+constexpr char queryKey[] = "query";
+constexpr char rangeFormattingKey[] = "rangeFormatting";
+constexpr char rangeKey[] = "range";
+constexpr char rangeLengthKey[] = "rangeLength";
+constexpr char reasonKey[] = "reason";
+constexpr char recursiveKey[] = "recursive";
+constexpr char redKey[] = "red";
+constexpr char referencesKey[] = "references";
+constexpr char referencesProviderKey[] = "referencesProvider";
+constexpr char refreshSupportKey[] = "refreshSupport";
+constexpr char registerOptionsKey[] = "registerOptions";
+constexpr char registrationsKey[] = "registrations";
+constexpr char removedKey[] = "removed";
+constexpr char renameKey[] = "rename";
+constexpr char renameProviderKey[] = "renameProvider";
+constexpr char requestsKey[] = "requests";
+constexpr char resolveProviderKey[] = "resolveProvider";
+constexpr char resourceOperationsKey[] = "resourceOperations";
+constexpr char resultIdKey[] = "resultId";
+constexpr char resultKey[] = "result";
+constexpr char retryKey[] = "retry";
+constexpr char rootPathKey[] = "rootPath";
+constexpr char rootUriKey[] = "rootUri";
+constexpr char saveKey[] = "save";
+constexpr char schemeKey[] = "scheme";
+constexpr char scopeUriKey[] = "scopeUri";
+constexpr char sectionKey[] = "section";
+constexpr char selectionRangeKey[] = "selectionRange";
+constexpr char semanticTokensKey[] = "semanticTokens";
+constexpr char semanticTokensProviderKey[] = "semanticTokensProvider";
+constexpr char serverInfoKey[] = "serverInfo";
+constexpr char settingsKey[] = "settings";
+constexpr char severityKey[] = "severity";
+constexpr char signatureHelpKey[] = "signatureHelp";
+constexpr char signatureHelpProviderKey[] = "signatureHelpProvider";
+constexpr char signatureInformationKey[] = "signatureInformation";
+constexpr char signaturesKey[] = "signatures";
+constexpr char snippetSupportKey[] = "snippetSupport";
+constexpr char sortTextKey[] = "sortText";
+constexpr char sourceKey[] = "source";
+constexpr char startKey[] = "start";
+constexpr char supportedKey[] = "supported";
+constexpr char symbolKey[] = "symbol";
+constexpr char symbolKindKey[] = "symbolKind";
+constexpr char syncKindKey[] = "syncKind";
+constexpr char synchronizationKey[] = "synchronization";
+constexpr char tabSizeKey[] = "tabSize";
+constexpr char tagsKey[] = "tags";
+constexpr char targetKey[] = "target";
+constexpr char textDocumentKey[] = "textDocument";
+constexpr char textDocumentSyncKey[] = "textDocumentSync";
+constexpr char textEditKey[] = "textEdit";
+constexpr char textKey[] = "text";
+constexpr char titleKey[] = "title";
+constexpr char toKey[] = "to";
+constexpr char tokenKey[] = "token";
+constexpr char tokenModifiersKey[] = "tokenModifiers";
+constexpr char tokenTypesKey[] = "tokenTypes";
+constexpr char traceKey[] = "trace";
+constexpr char triggerCharacterKey[] = "triggerCharacter";
+constexpr char triggerCharactersKey[] = "triggerCharacters";
+constexpr char triggerKindKey[] = "triggerKind";
+constexpr char trimFinalNewlinesKey[] = "trimFinalNewlines";
+constexpr char trimTrailingWhitespaceKey[] = "trimTrailingWhitespace";
+constexpr char typeDefinitionKey[] = "typeDefinition";
+constexpr char typeDefinitionProviderKey[] = "typeDefinitionProvider";
+constexpr char typeKey[] = "type";
+constexpr char unregistrationsKey[] = "unregistrations";
+constexpr char uriKey[] = "uri";
+constexpr char valueKey[] = "value";
+constexpr char valueSetKey[] = "valueSet";
+constexpr char versionKey[] = "version";
+constexpr char willSaveKey[] = "willSave";
+constexpr char willSaveWaitUntilKey[] = "willSaveWaitUntil";
+constexpr char windowKey[] = "window";
+constexpr char workDoneProgressKey[] = "workDoneProgress";
+constexpr char workspaceEditKey[] = "workspaceEdit";
+constexpr char workspaceFoldersKey[] = "workspaceFolders";
+constexpr char workspaceKey[] = "workspace";
+constexpr char workspaceSymbolProviderKey[] = "workspaceSymbolProvider";
} // namespace LanguageServerProtocol
diff --git a/src/libs/languageserverprotocol/jsonobject.cpp b/src/libs/languageserverprotocol/jsonobject.cpp
index 2a89f34a6ea..d591e06cb67 100644
--- a/src/libs/languageserverprotocol/jsonobject.cpp
+++ b/src/libs/languageserverprotocol/jsonobject.cpp
@@ -15,14 +15,14 @@ JsonObject &JsonObject::operator=(JsonObject &&other)
return *this;
}
-QJsonObject::iterator JsonObject::insert(const QStringView key, const JsonObject &object)
+QJsonObject::iterator JsonObject::insert(const std::string_view key, const JsonObject &object)
{
- return m_jsonObject.insert(key, object.m_jsonObject);
+ return m_jsonObject.insert(QLatin1String(key.data()), object.m_jsonObject);
}
-QJsonObject::iterator JsonObject::insert(const QStringView key, const QJsonValue &value)
+QJsonObject::iterator JsonObject::insert(const std::string_view key, const QJsonValue &value)
{
- return m_jsonObject.insert(key, value);
+ return m_jsonObject.insert(QLatin1String(key.data()), value);
}
} // namespace LanguageServerProtocol
diff --git a/src/libs/languageserverprotocol/jsonobject.h b/src/libs/languageserverprotocol/jsonobject.h
index 8f773d283ff..11c764c82c7 100644
--- a/src/libs/languageserverprotocol/jsonobject.h
+++ b/src/libs/languageserverprotocol/jsonobject.h
@@ -43,97 +43,98 @@ public:
const_iterator end() const { return m_jsonObject.end(); }
protected:
- iterator insert(const QStringView key, const JsonObject &value);
- iterator insert(const QStringView key, const QJsonValue &value);
+ iterator insert(const std::string_view key, const JsonObject &value);
+ iterator insert(const std::string_view key, const QJsonValue &value);
template <typename T, typename V>
- iterator insertVariant(const QStringView key, const V &variant);
+ iterator insertVariant(const std::string_view key, const V &variant);
template <typename T1, typename T2, typename... Args, typename V>
- iterator insertVariant(const QStringView key, const V &variant);
+ iterator insertVariant(const std::string_view key, const V &variant);
// QJSonObject redirections
- QJsonValue value(const QStringView key) const { return m_jsonObject.value(key); }
- bool contains(const QStringView key) const { return m_jsonObject.contains(key); }
- iterator find(const QStringView key) { return m_jsonObject.find(key); }
- const_iterator find(const QStringView key) const { return m_jsonObject.find(key); }
- void remove(const QStringView key) { m_jsonObject.remove(key); }
+ QJsonValue value(const std::string_view key) const { return m_jsonObject.value(QLatin1String(key.data())); }
+ bool contains(const std::string_view key) const { return m_jsonObject.contains(QLatin1String(key.data())); }
+ iterator find(const std::string_view key) { return m_jsonObject.find(QLatin1String(key.data())); }
+ const_iterator find(const std::string_view key) const { return m_jsonObject.find(QLatin1String(key.data())); }
+ void remove(const std::string_view key) { m_jsonObject.remove(QLatin1String(key.data())); }
QStringList keys() const { return m_jsonObject.keys(); }
// convenience value access
template<typename T>
- T typedValue(const QStringView key) const;
+ T typedValue(const std::string_view key) const;
template<typename T>
- std::optional<T> optionalValue(const QStringView key) const;
+ std::optional<T> optionalValue(const std::string_view key) const;
template<typename T>
- LanguageClientValue<T> clientValue(const QStringView key) const;
+ LanguageClientValue<T> clientValue(const std::string_view key) const;
template<typename T>
- std::optional<LanguageClientValue<T>> optionalClientValue(const QStringView key) const;
+ std::optional<LanguageClientValue<T>> optionalClientValue(const std::string_view key) const;
template<typename T>
- QList<T> array(const QStringView key) const;
+ QList<T> array(const std::string_view key) const;
template<typename T>
- std::optional<QList<T>> optionalArray(const QStringView key) const;
+ std::optional<QList<T>> optionalArray(const std::string_view key) const;
template<typename T>
- LanguageClientArray<T> clientArray(const QStringView key) const;
+ LanguageClientArray<T> clientArray(const std::string_view key) const;
template<typename T>
- std::optional<LanguageClientArray<T>> optionalClientArray(const QStringView key) const;
+ std::optional<LanguageClientArray<T>> optionalClientArray(const std::string_view key) const;
template<typename T>
- void insertArray(const QStringView key, const QList<T> &array);
+ void insertArray(const std::string_view key, const QList<T> &array);
template<typename>
- void insertArray(const QStringView key, const QList<JsonObject> &array);
+ void insertArray(const std::string_view key, const QList<JsonObject> &array);
private:
QJsonObject m_jsonObject;
};
template<typename T, typename V>
-JsonObject::iterator JsonObject::insertVariant(const QStringView key, const V &variant)
+JsonObject::iterator JsonObject::insertVariant(const std::string_view key, const V &variant)
{
return std::holds_alternative<T>(variant) ? insert(key, std::get<T>(variant)) : end();
}
template<typename T1, typename T2, typename... Args, typename V>
-JsonObject::iterator JsonObject::insertVariant(const QStringView key, const V &variant)
+JsonObject::iterator JsonObject::insertVariant(const std::string_view key, const V &variant)
{
auto result = insertVariant<T1>(key, variant);
return result != end() ? result : insertVariant<T2, Args...>(key, variant);
}
template<typename T>
-T JsonObject::typedValue(const QStringView key) const
+T JsonObject::typedValue(const std::string_view key) const
{
return fromJsonValue<T>(value(key));
}
template<typename T>
-std::optional<T> JsonObject::optionalValue(const QStringView key) const
+std::optional<T> JsonObject::optionalValue(const std::string_view key) const
{
const QJsonValue &val = value(key);
return val.isUndefined() ? std::nullopt : std::make_optional(fromJsonValue<T>(val));
}
template<typename T>
-LanguageClientValue<T> JsonObject::clientValue(const QStringView key) const
+LanguageClientValue<T> JsonObject::clientValue(const std::string_view key) const
{
return LanguageClientValue<T>(value(key));
}
template<typename T>
-std::optional<LanguageClientValue<T>> JsonObject::optionalClientValue(const QStringView key) const
+std::optional<LanguageClientValue<T>> JsonObject::optionalClientValue(const std::string_view key) const
{
return contains(key) ? std::make_optional(clientValue<T>(key)) : std::nullopt;
}
template<typename T>
-QList<T> JsonObject::array(const QStringView key) const
+QList<T> JsonObject::array(const std::string_view key) const
{
if (const std::optional<QList<T>> &array = optionalArray<T>(key))
return *array;
- qCDebug(conversionLog) << QString("Expected array under %1 in:").arg(key) << *this;
+ qCDebug(conversionLog) << QString("Expected array under %1 in:")
+ .arg(QLatin1String(key.data())) << *this;
return {};
}
template<typename T>
-std::optional<QList<T>> JsonObject::optionalArray(const QStringView key) const
+std::optional<QList<T>> JsonObject::optionalArray(const std::string_view key) const
{
const QJsonValue &jsonValue = value(key);
if (jsonValue.isUndefined())
@@ -142,13 +143,13 @@ std::optional<QList<T>> JsonObject::optionalArray(const QStringView key) const
}
template<typename T>
-LanguageClientArray<T> JsonObject::clientArray(const QStringView key) const
+LanguageClientArray<T> JsonObject::clientArray(const std::string_view key) const
{
return LanguageClientArray<T>(value(key));
}
template<typename T>
-std::optional<LanguageClientArray<T>> JsonObject::optionalClientArray(const QStringView key) const
+std::optional<LanguageClientArray<T>> JsonObject::optionalClientArray(const std::string_view key) const
{
const QJsonValue &val = value(key);
return !val.isUndefined() ? std::make_optional(LanguageClientArray<T>(value(key)))
@@ -156,7 +157,7 @@ std::optional<LanguageClientArray<T>> JsonObject::optionalClientArray(const QStr
}
template<typename T>
-void JsonObject::insertArray(const QStringView key, const QList<T> &array)
+void JsonObject::insertArray(const std::string_view key, const QList<T> &array)
{
QJsonArray jsonArray;
for (const T &item : array)
@@ -165,7 +166,7 @@ void JsonObject::insertArray(const QStringView key, const QList<T> &array)
}
template<typename >
-void JsonObject::insertArray(const QStringView key, const QList<JsonObject> &array)
+void JsonObject::insertArray(const std::string_view key, const QList<JsonObject> &array)
{
QJsonArray jsonArray;
for (const JsonObject &item : array)
diff --git a/src/libs/languageserverprotocol/languagefeatures.cpp b/src/libs/languageserverprotocol/languagefeatures.cpp
index 24a160f4b39..b4d124f96be 100644
--- a/src/libs/languageserverprotocol/languagefeatures.cpp
+++ b/src/libs/languageserverprotocol/languagefeatures.cpp
@@ -125,7 +125,7 @@ QHash<QString, DocumentFormattingProperty> FormattingOptions::properties() const
for (const QString &key : keys()) {
if (key == tabSizeKey || key == insertSpaceKey)
continue;
- QJsonValue property = value(key);
+ QJsonValue property = value(key.toStdString());
if (property.isBool())
ret[key] = property.toBool();
if (property.isDouble())
@@ -136,7 +136,7 @@ QHash<QString, DocumentFormattingProperty> FormattingOptions::properties() const
return ret;
}
-void FormattingOptions::setProperty(const QString &key, const DocumentFormattingProperty &property)
+void FormattingOptions::setProperty(const std::string_view key, const DocumentFormattingProperty &property)
{
using namespace std;
if (auto val = get_if<double>(&property))
diff --git a/src/libs/languageserverprotocol/languagefeatures.h b/src/libs/languageserverprotocol/languagefeatures.h
index 2fc3a991f96..b82b893f49d 100644
--- a/src/libs/languageserverprotocol/languagefeatures.h
+++ b/src/libs/languageserverprotocol/languagefeatures.h
@@ -678,8 +678,8 @@ public:
void clearTrimFinalNewlines() { remove(trimFinalNewlinesKey); }
QHash<QString, DocumentFormattingProperty> properties() const;
- void setProperty(const QString &key, const DocumentFormattingProperty &property);
- void removeProperty(const QString &key) { remove(key); }
+ void setProperty(const std::string_view key, const DocumentFormattingProperty &property);
+ void removeProperty(const std::string_view &key) { remove(key); }
bool isValid() const override { return contains(insertSpaceKey) && contains(tabSizeKey); }
};
diff --git a/src/libs/languageserverprotocol/languageserverprotocol.qbs b/src/libs/languageserverprotocol/languageserverprotocol.qbs
index 163b2d6d4ea..0368ceafee8 100644
--- a/src/libs/languageserverprotocol/languageserverprotocol.qbs
+++ b/src/libs/languageserverprotocol/languageserverprotocol.qbs
@@ -1,54 +1,50 @@
-import qbs 1.0
-
-Project {
+QtcLibrary {
name: "LanguageServerProtocol"
- QtcLibrary {
- Depends { name: "Utils" }
- cpp.defines: base.concat("LANGUAGESERVERPROTOCOL_LIBRARY")
+ Depends { name: "Utils" }
+ cpp.defines: base.concat("LANGUAGESERVERPROTOCOL_LIBRARY")
- files: [
- "basemessage.cpp",
- "basemessage.h",
- "callhierarchy.cpp",
- "callhierarchy.h",
- "client.cpp",
- "client.h",
- "clientcapabilities.cpp",
- "clientcapabilities.h",
- "completion.cpp",
- "completion.h",
- "diagnostics.cpp",
- "diagnostics.h",
- "initializemessages.cpp",
- "initializemessages.h",
- "jsonkeys.h",
- "jsonobject.cpp",
- "jsonobject.h",
- "jsonrpcmessages.cpp",
- "jsonrpcmessages.h",
- "languagefeatures.cpp",
- "languagefeatures.h",
- "languageserverprotocol_global.h",
- "languageserverprotocoltr.h",
- "lsptypes.cpp",
- "lsptypes.h",
- "lsputils.cpp",
- "lsputils.h",
- "messages.cpp",
- "messages.h",
- "progresssupport.cpp",
- "progresssupport.h",
- "semantictokens.cpp",
- "semantictokens.h",
- "servercapabilities.cpp",
- "servercapabilities.h",
- "shutdownmessages.cpp",
- "shutdownmessages.h",
- "textsynchronization.cpp",
- "textsynchronization.h",
- "workspace.cpp",
- "workspace.h",
- ]
- }
+ files: [
+ "basemessage.cpp",
+ "basemessage.h",
+ "callhierarchy.cpp",
+ "callhierarchy.h",
+ "client.cpp",
+ "client.h",
+ "clientcapabilities.cpp",
+ "clientcapabilities.h",
+ "completion.cpp",
+ "completion.h",
+ "diagnostics.cpp",
+ "diagnostics.h",
+ "initializemessages.cpp",
+ "initializemessages.h",
+ "jsonkeys.h",
+ "jsonobject.cpp",
+ "jsonobject.h",
+ "jsonrpcmessages.cpp",
+ "jsonrpcmessages.h",
+ "languagefeatures.cpp",
+ "languagefeatures.h",
+ "languageserverprotocol_global.h",
+ "languageserverprotocoltr.h",
+ "lsptypes.cpp",
+ "lsptypes.h",
+ "lsputils.cpp",
+ "lsputils.h",
+ "messages.cpp",
+ "messages.h",
+ "progresssupport.cpp",
+ "progresssupport.h",
+ "semantictokens.cpp",
+ "semantictokens.h",
+ "servercapabilities.cpp",
+ "servercapabilities.h",
+ "shutdownmessages.cpp",
+ "shutdownmessages.h",
+ "textsynchronization.cpp",
+ "textsynchronization.h",
+ "workspace.cpp",
+ "workspace.h",
+ ]
}
diff --git a/src/libs/languageserverprotocol/lsptypes.cpp b/src/libs/languageserverprotocol/lsptypes.cpp
index 6f0b57c1e35..ddd9b0e66c0 100644
--- a/src/libs/languageserverprotocol/lsptypes.cpp
+++ b/src/libs/languageserverprotocol/lsptypes.cpp
@@ -2,6 +2,8 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "lsptypes.h"
+
+#include "languageserverprotocoltr.h"
#include "lsputils.h"
#include <utils/textutils.h>
@@ -384,7 +386,7 @@ Utils::FilePath DocumentUri::toFilePath(const PathMapper &mapToHostPath) const
QTC_ASSERT(mapToHostPath, return serverPath);
return mapToHostPath(serverPath);
}
- return Utils::FilePath();
+ return {};
}
DocumentUri DocumentUri::fromProtocol(const QString &uri)
@@ -413,12 +415,76 @@ LanguageServerProtocol::MarkupKind::operator QJsonValue() const
return {};
}
-Utils::Text::Replacement TextEdit::toReplacement(QTextDocument *document) const
+DocumentChange::DocumentChange(const QJsonValue &value)
+{
+ const QString kind = value["kind"].toString();
+ if (kind == "create")
+ emplace<CreateFileOperation>(value);
+ else if (kind == "rename")
+ emplace<RenameFileOperation>(value);
+ else if (kind == "delete")
+ emplace<DeleteFileOperation>(value);
+ else
+ emplace<TextDocumentEdit>(value);
+}
+
+using DocumentChangeBase = std::variant<TextDocumentEdit, CreateFileOperation, RenameFileOperation, DeleteFileOperation>;
+
+bool DocumentChange::isValid() const
+{
+ return std::visit([](const auto &v) { return v.isValid(); }, DocumentChangeBase(*this));
+}
+
+DocumentChange::operator const QJsonValue () const
+{
+ return std::visit([](const auto &v) { return QJsonValue(v); }, DocumentChangeBase(*this));
+}
+
+CreateFileOperation::CreateFileOperation()
+{
+ insert(kindKey, "create");
+}
+
+QString CreateFileOperation::message(const DocumentUri::PathMapper &mapToHostPath) const
+{
+ return Tr::tr("Create %1").arg(uri().toFilePath(mapToHostPath).toUserOutput());
+}
+
+bool LanguageServerProtocol::CreateFileOperation::isValid() const
+{
+ return contains(uriKey) && value(kindKey) == "create";
+}
+
+RenameFileOperation::RenameFileOperation()
+{
+ insert(kindKey, "rename");
+}
+
+QString RenameFileOperation::message(const DocumentUri::PathMapper &mapToHostPath) const
+{
+ return Tr::tr("Rename %1 to %2")
+ .arg(oldUri().toFilePath(mapToHostPath).toUserOutput(),
+ newUri().toFilePath(mapToHostPath).toUserOutput());
+}
+
+bool RenameFileOperation::isValid() const
+{
+ return contains(oldUriKey) && contains(newUriKey) && value(kindKey) == "rename";
+}
+
+DeleteFileOperation::DeleteFileOperation()
+{
+ insert(kindKey, "delete");
+}
+
+QString DeleteFileOperation::message(const DocumentUri::PathMapper &mapToHostPath) const
+{
+ return Tr::tr("Delete %1").arg(uri().toFilePath(mapToHostPath).toUserOutput());
+}
+
+bool DeleteFileOperation::isValid() const
{
- const Range &range = this->range();
- const int start = range.start().toPositionInDocument(document);
- const int end = range.end().toPositionInDocument(document);
- return Utils::Text::Replacement(start, end - start, newText());
+ return contains(uriKey) && value(kindKey) == "delete";
}
} // namespace LanguageServerProtocol
diff --git a/src/libs/languageserverprotocol/lsptypes.h b/src/libs/languageserverprotocol/lsptypes.h
index 3a9adb1b0d8..ae19f36145b 100644
--- a/src/libs/languageserverprotocol/lsptypes.h
+++ b/src/libs/languageserverprotocol/lsptypes.h
@@ -228,8 +228,6 @@ public:
QString newText() const { return typedValue<QString>(newTextKey); }
void setNewText(const QString &text) { insert(newTextKey, text); }
- Utils::Text::Replacement toReplacement(QTextDocument *document) const;
-
bool isValid() const override
{ return contains(rangeKey) && contains(newTextKey); }
};
@@ -287,6 +285,106 @@ public:
bool isValid() const override { return contains(textDocumentKey) && contains(editsKey); }
};
+class CreateFileOptions : public JsonObject
+{
+public:
+ using JsonObject::JsonObject;
+
+ std::optional<bool> overwrite() const { return optionalValue<bool>(overwriteKey); }
+ void setOverwrite(bool overwrite) { insert(overwriteKey, overwrite); }
+ void clearOverwrite() { remove(overwriteKey); }
+
+ std::optional<bool> ignoreIfExists() const { return optionalValue<bool>(ignoreIfExistsKey); }
+ void setIgnoreIfExists(bool ignoreIfExists) { insert(ignoreIfExistsKey, ignoreIfExists); }
+ void clearIgnoreIfExists() { remove(ignoreIfExistsKey); }
+};
+
+class LANGUAGESERVERPROTOCOL_EXPORT CreateFileOperation : public JsonObject
+{
+public:
+ using JsonObject::JsonObject;
+ CreateFileOperation();
+
+ DocumentUri uri() const { return DocumentUri::fromProtocol(typedValue<QString>(uriKey)); }
+ void setUri(const DocumentUri &uri) { insert(uriKey, uri); }
+
+ std::optional<CreateFileOptions> options() const
+ { return optionalValue<CreateFileOptions>(optionsKey); }
+ void setOptions(const CreateFileOptions &options) { insert(optionsKey, options); }
+ void clearOptions() { remove(optionsKey); }
+
+ QString message(const DocumentUri::PathMapper &mapToHostPath) const;
+
+ bool isValid() const override;
+};
+
+class LANGUAGESERVERPROTOCOL_EXPORT RenameFileOperation : public JsonObject
+{
+public:
+ using JsonObject::JsonObject;
+ RenameFileOperation();
+
+ DocumentUri oldUri() const { return DocumentUri::fromProtocol(typedValue<QString>(oldUriKey)); }
+ void setOldUri(const DocumentUri &oldUri) { insert(oldUriKey, oldUri); }
+
+ DocumentUri newUri() const { return DocumentUri::fromProtocol(typedValue<QString>(newUriKey)); }
+ void setNewUri(const DocumentUri &newUri) { insert(newUriKey, newUri); }
+
+ std::optional<CreateFileOptions> options() const
+ { return optionalValue<CreateFileOptions>(optionsKey); }
+ void setOptions(const CreateFileOptions &options) { insert(optionsKey, options); }
+ void clearOptions() { remove(optionsKey); }
+
+ QString message(const DocumentUri::PathMapper &mapToHostPath) const;
+
+ bool isValid() const override;
+};
+
+class DeleteFileOptions : public JsonObject
+{
+public:
+ using JsonObject::JsonObject;
+
+ std::optional<bool> recursive() const { return optionalValue<bool>(recursiveKey); }
+ void setRecursive(bool recursive) { insert(recursiveKey, recursive); }
+ void clearRecursive() { remove(recursiveKey); }
+
+ std::optional<bool> ignoreIfNotExists() const { return optionalValue<bool>(ignoreIfNotExistsKey); }
+ void setIgnoreIfNotExists(bool ignoreIfNotExists) { insert(ignoreIfNotExistsKey, ignoreIfNotExists); }
+ void clearIgnoreIfNotExists() { remove(ignoreIfNotExistsKey); }
+};
+
+class LANGUAGESERVERPROTOCOL_EXPORT DeleteFileOperation : public JsonObject
+{
+public:
+ using JsonObject::JsonObject;
+ DeleteFileOperation();
+
+ DocumentUri uri() const { return DocumentUri::fromProtocol(typedValue<QString>(uriKey)); }
+ void setUri(const DocumentUri &uri) { insert(uriKey, uri); }
+
+ std::optional<DeleteFileOptions> options() const
+ { return optionalValue<DeleteFileOptions>(optionsKey); }
+ void setOptions(const DeleteFileOptions &options) { insert(optionsKey, options); }
+ void clearOptions() { remove(optionsKey); }
+
+ QString message(const DocumentUri::PathMapper &mapToHostPath) const;
+
+ bool isValid() const override;
+};
+
+class LANGUAGESERVERPROTOCOL_EXPORT DocumentChange
+ : public std::variant<TextDocumentEdit, CreateFileOperation, RenameFileOperation, DeleteFileOperation>
+{
+public:
+ using variant::variant;
+ DocumentChange(const QJsonValue &value);
+
+ bool isValid() const;
+
+ operator const QJsonValue() const;
+};
+
class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceEdit : public JsonObject
{
public:
@@ -298,17 +396,23 @@ public:
void setChanges(const Changes &changes);
/*
- * An array of `TextDocumentEdit`s to express changes to n different text documents
- * where each text document edit addresses a specific version of a text document.
+ * Depending on the client capability
+ * `workspace.workspaceEdit.resourceOperations` document changes are either
+ * an array of `TextDocumentEdit`s to express changes to n different text
+ * documents where each text document edit addresses a specific version of
+ * a text document. Or it can contain above `TextDocumentEdit`s mixed with
+ * create, rename and delete file / folder operations.
+ *
* Whether a client supports versioned document edits is expressed via
- * `WorkspaceClientCapabilities.workspaceEdit.documentChanges`.
+ * `workspace.workspaceEdit.documentChanges` client capability.
*
- * Note: If the client can handle versioned document edits and if documentChanges are present,
- * the latter are preferred over changes.
+ * If a client neither supports `documentChanges` nor
+ * `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s
+ * using the `changes` property are supported.
*/
- std::optional<QList<TextDocumentEdit>> documentChanges() const
- { return optionalArray<TextDocumentEdit>(documentChangesKey); }
- void setDocumentChanges(const QList<TextDocumentEdit> &changes)
+ std::optional<QList<DocumentChange>> documentChanges() const
+ { return optionalArray<DocumentChange>(documentChangesKey); }
+ void setDocumentChanges(const QList<DocumentChange> &changes)
{ insertArray(documentChangesKey, changes); }
};
diff --git a/src/libs/languageserverprotocol/servercapabilities.cpp b/src/libs/languageserverprotocol/servercapabilities.cpp
index 1c0d322e6e7..885198d12e8 100644
--- a/src/libs/languageserverprotocol/servercapabilities.cpp
+++ b/src/libs/languageserverprotocol/servercapabilities.cpp
@@ -52,6 +52,24 @@ void ServerCapabilities::setHoverProvider(
}
std::optional<std::variant<bool, ServerCapabilities::RegistrationOptions>>
+ServerCapabilities::definitionProvider() const
+{
+ using RetType = std::variant<bool, ServerCapabilities::RegistrationOptions>;
+ const QJsonValue &provider = value(definitionProviderKey);
+ if (provider.isUndefined() || !(provider.isBool() || provider.isObject()))
+ return std::nullopt;
+ return std::make_optional(provider.isBool()
+ ? RetType(provider.toBool())
+ : RetType(RegistrationOptions(provider.toObject())));
+}
+
+void ServerCapabilities::setDefinitionProvider(
+ const std::variant<bool, RegistrationOptions> &definitionProvider)
+{
+ insertVariant<bool, RegistrationOptions>(definitionProviderKey, definitionProvider);
+}
+
+std::optional<std::variant<bool, ServerCapabilities::RegistrationOptions>>
ServerCapabilities::typeDefinitionProvider() const
{
using RetType = std::variant<bool, ServerCapabilities::RegistrationOptions>;
diff --git a/src/libs/languageserverprotocol/servercapabilities.h b/src/libs/languageserverprotocol/servercapabilities.h
index bacddda19e6..c3b50dd5904 100644
--- a/src/libs/languageserverprotocol/servercapabilities.h
+++ b/src/libs/languageserverprotocol/servercapabilities.h
@@ -269,13 +269,6 @@ public:
{ insert(signatureHelpProviderKey, signatureHelpProvider); }
void clearSignatureHelpProvider() { remove(signatureHelpProviderKey); }
- // The server provides goto definition support.
- std::optional<bool> definitionProvider() const
- { return optionalValue<bool>(definitionProviderKey); }
- void setDefinitionProvider(bool definitionProvider)
- { insert(definitionProviderKey, definitionProvider); }
- void clearDefinitionProvider() { remove(definitionProviderKey); }
-
class LANGUAGESERVERPROTOCOL_EXPORT RegistrationOptions : public JsonObject
{
public:
@@ -298,6 +291,11 @@ public:
bool isValid() const override { return contains(documentSelectorKey); }
};
+ // The server provides goto definition support.
+ std::optional<std::variant<bool, RegistrationOptions>> definitionProvider() const;
+ void setDefinitionProvider(const std::variant<bool, RegistrationOptions> &typeDefinitionProvider);
+ void clearDefinitionProvider() { remove(typeDefinitionProviderKey); }
+
// The server provides Goto Type Definition support.
std::optional<std::variant<bool, RegistrationOptions>> typeDefinitionProvider() const;
void setTypeDefinitionProvider(const std::variant<bool, RegistrationOptions> &typeDefinitionProvider);
diff --git a/src/libs/languageserverprotocol/workspace.cpp b/src/libs/languageserverprotocol/workspace.cpp
index c9d2aeb4130..2d49be2d5ff 100644
--- a/src/libs/languageserverprotocol/workspace.cpp
+++ b/src/libs/languageserverprotocol/workspace.cpp
@@ -72,4 +72,11 @@ LanguageServerProtocol::WorkSpaceFolderResult::operator const QJsonValue() const
return array;
}
+std::optional<DocumentUri> ConfigurationParams::ConfigurationItem::scopeUri() const
+{
+ if (const std::optional<QString> optionalScope = optionalValue<QString>(scopeUriKey))
+ return std::make_optional(DocumentUri::fromProtocol(*optionalScope));
+ return std::nullopt;
+}
+
} // namespace LanguageServerProtocol
diff --git a/src/libs/languageserverprotocol/workspace.h b/src/libs/languageserverprotocol/workspace.h
index 42cfcf451d2..703310caaa3 100644
--- a/src/libs/languageserverprotocol/workspace.h
+++ b/src/libs/languageserverprotocol/workspace.h
@@ -92,8 +92,8 @@ public:
public:
using JsonObject::JsonObject;
- std::optional<QString> scopeUri() const { return optionalValue<QString>(scopeUriKey); }
- void setScopeUri(const QString &scopeUri) { insert(scopeUriKey, scopeUri); }
+ std::optional<DocumentUri> scopeUri() const;
+ void setScopeUri(const DocumentUri &scopeUri) { insert(scopeUriKey, scopeUri); }
void clearScopeUri() { remove(scopeUriKey); }
std::optional<QString> section() const { return optionalValue<QString>(sectionKey); }
@@ -109,8 +109,8 @@ public:
bool isValid() const override { return contains(itemsKey); }
};
-class LANGUAGESERVERPROTOCOL_EXPORT ConfigurationRequest : public Request<
- LanguageClientArray<QJsonValue>, std::nullptr_t, ConfigurationParams>
+class LANGUAGESERVERPROTOCOL_EXPORT ConfigurationRequest
+ : public Request<QJsonArray, std::nullptr_t, ConfigurationParams>
{
public:
explicit ConfigurationRequest(const ConfigurationParams &params);
@@ -166,7 +166,7 @@ public:
QString query() const { return typedValue<QString>(queryKey); }
void setQuery(const QString &query) { insert(queryKey, query); }
- void setLimit(int limit) { insert(u"limit", limit); } // clangd extension
+ void setLimit(int limit) { insert("limit", limit); } // clangd extension
bool isValid() const override { return contains(queryKey); }
};
diff --git a/src/libs/languageutils/languageutils.qbs b/src/libs/languageutils/languageutils.qbs
index 8b5d6a6e8ad..7a4cefd5ff3 100644
--- a/src/libs/languageutils/languageutils.qbs
+++ b/src/libs/languageutils/languageutils.qbs
@@ -1,20 +1,16 @@
-import qbs 1.0
-
-Project {
+QtcLibrary {
name: "LanguageUtils"
- QtcLibrary {
- cpp.defines: base.concat(["LANGUAGEUTILS_LIBRARY"])
- cpp.optimization: "fast"
+ cpp.defines: base.concat(["LANGUAGEUTILS_LIBRARY"])
+ cpp.optimization: "fast"
- Depends { name: "Qt.core" }
+ Depends { name: "Qt.core" }
- files: [
- "componentversion.cpp",
- "componentversion.h",
- "fakemetaobject.cpp",
- "fakemetaobject.h",
- "languageutils_global.h",
- ]
- }
+ files: [
+ "componentversion.cpp",
+ "componentversion.h",
+ "fakemetaobject.cpp",
+ "fakemetaobject.h",
+ "languageutils_global.h",
+ ]
}
diff --git a/src/libs/modelinglib/qmt/config/configcontroller.h b/src/libs/modelinglib/qmt/config/configcontroller.h
index 73efef16f4a..28e6d65afcd 100644
--- a/src/libs/modelinglib/qmt/config/configcontroller.h
+++ b/src/libs/modelinglib/qmt/config/configcontroller.h
@@ -3,9 +3,10 @@
#pragma once
-#include <QObject>
#include "qmt/infrastructure/qmt_global.h"
+#include <QObject>
+
namespace qmt {
class CustomRelation;
@@ -15,7 +16,6 @@ class Toolbar;
class QMT_EXPORT ConfigController : public QObject
{
- Q_OBJECT
class ConfigControllerPrivate;
public:
diff --git a/src/libs/modelinglib/qmt/config/textscanner.h b/src/libs/modelinglib/qmt/config/textscanner.h
index 341b2559039..d0bec89c93a 100644
--- a/src/libs/modelinglib/qmt/config/textscanner.h
+++ b/src/libs/modelinglib/qmt/config/textscanner.h
@@ -3,12 +3,12 @@
#pragma once
-#include <QObject>
-
#include "sourcepos.h"
#include "qmt/infrastructure/exceptions.h"
+#include <QObject>
+
namespace qmt {
class ITextSource;
@@ -29,7 +29,6 @@ private:
class QMT_EXPORT TextScanner : public QObject
{
- Q_OBJECT
class TextScannerPrivate;
public:
diff --git a/src/libs/modelinglib/qmt/controller/namecontroller.h b/src/libs/modelinglib/qmt/controller/namecontroller.h
index b9289fb9cd9..03e3be30bb8 100644
--- a/src/libs/modelinglib/qmt/controller/namecontroller.h
+++ b/src/libs/modelinglib/qmt/controller/namecontroller.h
@@ -13,8 +13,6 @@ namespace qmt {
class QMT_EXPORT NameController : public QObject
{
- Q_OBJECT
-
private:
explicit NameController(QObject *parent = nullptr);
~NameController() override;
diff --git a/src/libs/modelinglib/qmt/controller/undocontroller.h b/src/libs/modelinglib/qmt/controller/undocontroller.h
index aaf62c786bd..1bef6ed2081 100644
--- a/src/libs/modelinglib/qmt/controller/undocontroller.h
+++ b/src/libs/modelinglib/qmt/controller/undocontroller.h
@@ -3,9 +3,10 @@
#pragma once
-#include <QObject>
#include "qmt/infrastructure/qmt_global.h"
+#include <QObject>
+
QT_BEGIN_NAMESPACE
class QUndoStack;
QT_END_NAMESPACE
@@ -16,8 +17,6 @@ class UndoCommand;
class QMT_EXPORT UndoController : public QObject
{
- Q_OBJECT
-
public:
explicit UndoController(QObject *parent = nullptr);
~UndoController() override;
diff --git a/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.h b/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.h
index b56a303d881..bc726c50eab 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.h
@@ -3,11 +3,12 @@
#pragma once
-#include <QObject>
#include "qmt/infrastructure/qmt_global.h"
#include "capabilities/latchable.h"
+#include <QObject>
+
QT_BEGIN_NAMESPACE
class QGraphicsScene;
class QGraphicsSceneMouseEvent;
@@ -22,8 +23,6 @@ class AlignLineItem;
class QMT_EXPORT LatchController : public QObject
{
- Q_OBJECT
-
public:
explicit LatchController(QObject *parent = nullptr);
~LatchController() override;
@@ -44,7 +43,6 @@ private:
void hideLatches();
void applyLatches();
-private:
DiagramSceneModel *m_diagramSceneModel = nullptr;
AlignLineItem *m_horizontalAlignLine = nullptr;
AlignLineItem *m_verticalAlignLine = nullptr;
diff --git a/src/libs/modelinglib/qmt/model_controller/modelcontroller.cpp b/src/libs/modelinglib/qmt/model_controller/modelcontroller.cpp
index 3e38aabdf3f..b363decd683 100644
--- a/src/libs/modelinglib/qmt/model_controller/modelcontroller.cpp
+++ b/src/libs/modelinglib/qmt/model_controller/modelcontroller.cpp
@@ -878,7 +878,7 @@ void ModelController::moveRelation(MObject *newOwner, MRelation *relation)
QList<MRelation *> ModelController::findRelationsOfObject(const MObject *object) const
{
- QMT_ASSERT(object, return QList<MRelation *>());
+ QMT_ASSERT(object, return {});
return m_objectRelationsMap.values(object->uid());
}
diff --git a/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.h b/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.h
index 02f02779e5b..0c01cf7de79 100644
--- a/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.h
+++ b/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.h
@@ -3,9 +3,9 @@
#pragma once
-#include <QSortFilterProxyModel>
#include "qmt/infrastructure/qmt_global.h"
+#include <QSortFilterProxyModel>
#include <QTimer>
namespace qmt {
@@ -14,8 +14,6 @@ class TreeModel;
class QMT_EXPORT SortedTreeModel : public QSortFilterProxyModel
{
- Q_OBJECT
-
public:
explicit SortedTreeModel(QObject *parent = nullptr);
~SortedTreeModel() override;
diff --git a/src/libs/modelinglib/qmt/model_ui/treemodelmanager.h b/src/libs/modelinglib/qmt/model_ui/treemodelmanager.h
index 0dee6d31f9b..9e0793aba87 100644
--- a/src/libs/modelinglib/qmt/model_ui/treemodelmanager.h
+++ b/src/libs/modelinglib/qmt/model_ui/treemodelmanager.h
@@ -3,9 +3,10 @@
#pragma once
-#include <QObject>
#include "qmt/infrastructure/qmt_global.h"
+#include <QObject>
+
namespace qmt {
class TreeModel;
@@ -16,8 +17,6 @@ class MSelection;
class QMT_EXPORT TreeModelManager : public QObject
{
- Q_OBJECT
-
public:
explicit TreeModelManager(QObject *parent = nullptr);
~TreeModelManager() override;
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.cpp
index d9146c038fe..3f14eb93e5d 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.cpp
@@ -429,7 +429,7 @@ QString ClassMembersEdit::build(const QList<MClassMember> &members)
QList<MClassMember> ClassMembersEdit::parse(const QString &text, bool *ok)
{
- QMT_ASSERT(ok, return QList<MClassMember>());
+ QMT_ASSERT(ok, {});
*ok = true;
QList<MClassMember> members;
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.h b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.h
index ba115c03eda..b1255421d02 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.h
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.h
@@ -3,11 +3,11 @@
#pragma once
-#include <QObject>
-
#include "qmt/infrastructure/qmt_global.h"
+#include <QObject>
#include <QScopedPointer>
+
#include <functional>
QT_BEGIN_NAMESPACE
@@ -28,8 +28,6 @@ class StyleController;
class QMT_EXPORT PropertiesView : public QObject
{
- Q_OBJECT
-
public:
class MView;
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.h b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.h
index 7b94f445b7c..4762803a209 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.h
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.h
@@ -3,8 +3,6 @@
#pragma once
-#include <QObject>
-
#include "propertiesview.h"
#include "qmt/model/mconstvisitor.h"
@@ -14,6 +12,7 @@
#include "qmt/style/styleengine.h"
#include <QList>
+#include <QObject>
QT_BEGIN_NAMESPACE
class QWidget;
@@ -36,8 +35,6 @@ class PaletteBox;
class QMT_EXPORT PropertiesView::MView : public QObject, public MConstVisitor, public DConstVisitor
{
- Q_OBJECT
-
public:
explicit MView(PropertiesView *propertiesView);
~MView() override;
diff --git a/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.h b/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.h
index 949f1027a5c..676f9a275a5 100644
--- a/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.h
+++ b/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.h
@@ -3,11 +3,10 @@
#pragma once
-#include <QObject>
-
#include "stereotypeicon.h"
#include <QMarginsF>
+#include <QObject>
namespace qmt {
@@ -17,7 +16,6 @@ class Style;
class QMT_EXPORT StereotypeController : public QObject
{
- Q_OBJECT
class StereotypeControllerPrivate;
public:
diff --git a/src/libs/modelinglib/qmt/style/stylecontroller.h b/src/libs/modelinglib/qmt/style/stylecontroller.h
index 6eeeb61ac7f..2627bb2caa2 100644
--- a/src/libs/modelinglib/qmt/style/stylecontroller.h
+++ b/src/libs/modelinglib/qmt/style/stylecontroller.h
@@ -3,11 +3,10 @@
#pragma once
-#include <QObject>
-
#include "styleengine.h"
#include "qmt/diagram/dobject.h"
+#include <QObject>
#include <QScopedPointer>
namespace qmt {
@@ -21,7 +20,6 @@ class DBoundary;
class QMT_EXPORT StyleController : public QObject
{
- Q_OBJECT
class Parameters;
public:
diff --git a/src/libs/nanotrace/nanotrace.cpp b/src/libs/nanotrace/nanotrace.cpp
index 6af2db58bcf..c5adeb4d724 100644
--- a/src/libs/nanotrace/nanotrace.cpp
+++ b/src/libs/nanotrace/nanotrace.cpp
@@ -73,6 +73,7 @@ struct TraceEvent
int64_t oh;
int64_t ts;
+ int64_t dur = 0;
std::vector< Nanotrace::Arg > args;
@@ -100,7 +101,10 @@ std::ostream& operator<<(std::ostream &stream, const TraceEvent &event)
<< "{ \"cat\":\"" << event.cat
<< "\", \"pid\":" << event.pid
<< ", \"tid\":\"" << event.tid << "\""
- << ", \"ts\":" << event.ts
+ << ", \"ts\":" << event.ts;
+ if (event.dur > -1)
+ stream << ", \"dur\":" << event.dur;
+ stream
<< ", \"ph\":\"" << event.ph
<< "\", \"name\":\"" << event.name
<< "\", \"args\": { \"overhead\": " << event.oh;
@@ -112,7 +116,6 @@ std::ostream& operator<<(std::ostream &stream, const TraceEvent &event)
return stream;
}
-
void init(const std::string &process, const std::string &thread, const std::string &path)
{
auto now = Clock::now();
@@ -125,55 +128,56 @@ void init(const std::string &process, const std::string &thread, const std::stri
initEvent.ts = now;
events.reserve(eventCount);
- events.push_back(TraceEvent {
- getProcessId(),
- std::this_thread::get_id(),
- "process_name",
- "",
- 'M',
- 0,
- 0,
- {{"name", process}}
- } );
-
- events.push_back(TraceEvent {
- getProcessId(),
- std::this_thread::get_id(),
- "thread_name",
- "",
- 'M',
- 0,
- 0,
- {{"name", thread}}
- } );
+ events.push_back(TraceEvent{getProcessId(),
+ std::this_thread::get_id(),
+ "process_name",
+ "",
+ 'M',
+ 0,
+ 0,
+ -1,
+ {{"name", process}}});
+
+ events.push_back(TraceEvent{getProcessId(),
+ std::this_thread::get_id(),
+ "thread_name",
+ "",
+ 'M',
+ 0,
+ 0,
+ -1,
+ {{"name", thread}}});
if (std::ofstream stream(path, std::ios::trunc); stream.good())
stream << "{ \"traceEvents\": [\n";
else
std::cout << "Nanotrace::init: stream not good" << std::endl;
- events.push_back(TraceEvent {
- getProcessId(),
- std::this_thread::get_id(),
- "Initialize",
- "Initialize",
- 'I',
- 0,
- std::chrono::duration_cast< Units >(Clock::now() - now).count(),
- {}
- } );
+ events.push_back(TraceEvent{getProcessId(),
+ std::this_thread::get_id(),
+ "Initialize",
+ "Initialize",
+ 'I',
+ 0,
+ std::chrono::duration_cast<Units>(Clock::now() - now).count(),
+ -1,
+ {}});
initEvent.overhead = std::chrono::duration_cast< Units >(Clock::now() - now).count();
}
void shutdown()
{
+ if (!initEvent.initialized)
+ return;
+
flush();
if (std::ofstream stream(initEvent.filePath, std::ios::app); stream.good())
stream << "\n] }";
else
std::cout << "Nanotrace::shutdown: stream not good" << std::endl;
+ initEvent = {};
}
void addTracePoint(
@@ -188,16 +192,15 @@ void addTracePoint(
auto now = Clock::now();
auto beg = std::chrono::duration_cast< Units >(now - initEvent.ts);
- events.push_back( TraceEvent {
- getProcessId(),
- std::this_thread::get_id(),
- name,
- cat,
- phase,
- initEvent.overhead,
- beg.count(),
- {arguments}
- } );
+ events.push_back(TraceEvent{getProcessId(),
+ std::this_thread::get_id(),
+ name,
+ cat,
+ phase,
+ initEvent.overhead,
+ beg.count(),
+ -1,
+ {arguments}});
if (events.size() >= eventCount - 1)
flush();
@@ -238,20 +241,19 @@ ScopeTracer::~ScopeTracer()
return;
auto now = Clock::now();
- auto beg = std::chrono::duration_cast< Units >(m_start - initEvent.ts);
-
- m_args.push_back(Arg("dur", std::chrono::duration_cast< Units >(now - m_start).count()));
-
- events.push_back(TraceEvent {
- getProcessId(),
- std::this_thread::get_id(),
- m_name,
- m_cat,
- 'X',
- initEvent.overhead,
- beg.count(),
- { m_args }
- } );
+ auto beg = std::chrono::duration_cast<Units>(m_start - initEvent.ts);
+ const int64_t dur = std::chrono::duration_cast<Units>(now - m_start).count();
+
+ m_args.push_back(Arg("dur", dur));
+ events.push_back(TraceEvent{getProcessId(),
+ std::this_thread::get_id(),
+ m_name,
+ m_cat,
+ 'X',
+ initEvent.overhead,
+ beg.count(),
+ dur,
+ {m_args}});
if (events.size() >= eventCount - 1)
flush();
diff --git a/src/libs/nanotrace/nanotrace.h b/src/libs/nanotrace/nanotrace.h
index fae1892b80b..ed17797e344 100644
--- a/src/libs/nanotrace/nanotrace.h
+++ b/src/libs/nanotrace/nanotrace.h
@@ -45,7 +45,7 @@
namespace Nanotrace
{
-using Units = std::chrono::nanoseconds;
+using Units = std::chrono::microseconds;
using Clock = std::chrono::high_resolution_clock;
using TimePoint = std::chrono::time_point< Clock >;
diff --git a/src/libs/qlitehtml b/src/libs/qlitehtml
-Subproject 8e541a22b513432ed566fca824af207395ee0c9
+Subproject b8f6617f22a7bd0bf3da2e75d1613e1346b974f
diff --git a/src/libs/qmldebug/qmldebug.qbs b/src/libs/qmldebug/qmldebug.qbs
index bad5947682d..387f22b0aa0 100644
--- a/src/libs/qmldebug/qmldebug.qbs
+++ b/src/libs/qmldebug/qmldebug.qbs
@@ -1,40 +1,36 @@
-import qbs 1.0
-
-Project {
+QtcLibrary {
name: "QmlDebug"
- QtcLibrary {
- cpp.defines: base.concat("QMLDEBUG_LIBRARY")
+ cpp.defines: base.concat("QMLDEBUG_LIBRARY")
- Depends { name: "Qt"; submodules: ["gui", "network"] }
- Depends { name: "Utils" }
+ Depends { name: "Qt"; submodules: ["gui", "network"] }
+ Depends { name: "Utils" }
- files: [
- "baseenginedebugclient.cpp",
- "baseenginedebugclient.h",
- "basetoolsclient.cpp",
- "basetoolsclient.h",
- "qdebugmessageclient.cpp",
- "qdebugmessageclient.h",
- "qmldebug_global.h",
- "qmldebugtr.h",
- "qmldebugclient.cpp",
- "qmldebugclient.h",
- "qmldebugcommandlinearguments.h",
- "qmldebugconnection.cpp",
- "qmldebugconnection.h",
- "qmldebugconnectionmanager.cpp",
- "qmldebugconnectionmanager.h",
- "qmldebugconstants.h",
- "qmlenginecontrolclient.cpp",
- "qmlenginecontrolclient.h",
- "qmlenginedebugclient.h",
- "qmloutputparser.cpp",
- "qmloutputparser.h",
- "qmltoolsclient.cpp",
- "qmltoolsclient.h",
- "qpacketprotocol.cpp",
- "qpacketprotocol.h",
- ]
- }
+ files: [
+ "baseenginedebugclient.cpp",
+ "baseenginedebugclient.h",
+ "basetoolsclient.cpp",
+ "basetoolsclient.h",
+ "qdebugmessageclient.cpp",
+ "qdebugmessageclient.h",
+ "qmldebug_global.h",
+ "qmldebugtr.h",
+ "qmldebugclient.cpp",
+ "qmldebugclient.h",
+ "qmldebugcommandlinearguments.h",
+ "qmldebugconnection.cpp",
+ "qmldebugconnection.h",
+ "qmldebugconnectionmanager.cpp",
+ "qmldebugconnectionmanager.h",
+ "qmldebugconstants.h",
+ "qmlenginecontrolclient.cpp",
+ "qmlenginecontrolclient.h",
+ "qmlenginedebugclient.h",
+ "qmloutputparser.cpp",
+ "qmloutputparser.h",
+ "qmltoolsclient.cpp",
+ "qmltoolsclient.h",
+ "qpacketprotocol.cpp",
+ "qpacketprotocol.h",
+ ]
}
diff --git a/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp b/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp
index 12ec4da3d51..f188d6aa40a 100644
--- a/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp
+++ b/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp
@@ -10,7 +10,6 @@
#include <utils/layoutbuilder.h>
#include <QApplication>
-#include <QBoxLayout>
#include <QButtonGroup>
#include <QDebug>
#include <QDir>
@@ -260,7 +259,7 @@ void ContextPaneWidgetImage::setProperties(QmlJS::PropertyReader *propertyReader
if (propertyReader->hasProperty(QLatin1String("source"))) {
QString source = propertyReader->readProperty(QLatin1String("source")).toString();
m_fileWidget->setFileName(source);
- if (QFile::exists(m_path + QLatin1Char('/') + source))
+ if (QFileInfo::exists(m_path + QLatin1Char('/') + source))
setPixmap(m_path + QLatin1Char('/') + source);
else
setPixmap(source);
@@ -901,11 +900,6 @@ PreviewDialog::PreviewDialog(QWidget *parent) : DragWidget(parent)
setZoom(1);
- QVBoxLayout *layout = new QVBoxLayout(this);
- QHBoxLayout *horizontalLayout = new QHBoxLayout();
- QHBoxLayout *horizontalLayout2 = new QHBoxLayout();
- layout->setContentsMargins(2, 2, 2, 16);
- layout->setSpacing(4);
QToolButton *toolButton = new QToolButton(this);
QIcon icon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton));
toolButton->setIcon(icon);
@@ -922,17 +916,14 @@ PreviewDialog::PreviewDialog(QWidget *parent) : DragWidget(parent)
m_slider->setFixedWidth(80);
m_zoomLabel->setFixedWidth(50);
- horizontalLayout->addWidget(toolButton);
- horizontalLayout->addSpacing(6);
- horizontalLayout->addWidget(m_slider);
- horizontalLayout->addSpacing(6);
- horizontalLayout->addWidget(m_zoomLabel);
- horizontalLayout->addStretch(1);
-
- layout->addLayout(horizontalLayout);
- horizontalLayout2->addSpacing(24);
- horizontalLayout2->addWidget(scrollArea);
- layout->addLayout(horizontalLayout2);
+ using namespace Layouting;
+ Row {
+ Column { toolButton, st },
+ Column {
+ Row { m_slider, m_zoomLabel, st },
+ scrollArea,
+ }
+ }.attachTo(this);
wheelFilter->setTarget(this);
diff --git a/src/libs/qmljs/CMakeLists.txt b/src/libs/qmljs/CMakeLists.txt
index d166e666e74..4ca15cf7cc2 100644
--- a/src/libs/qmljs/CMakeLists.txt
+++ b/src/libs/qmljs/CMakeLists.txt
@@ -32,7 +32,6 @@ add_qtc_library(QmlJS
qmljsevaluate.cpp qmljsevaluate.h
qmljsfindexportedcpptypes.cpp qmljsfindexportedcpptypes.h
qmljsicons.cpp qmljsicons.h
- qmljsicontextpane.h
qmljsimportdependencies.cpp qmljsimportdependencies.h
qmljsindenter.cpp qmljsindenter.h
qmljsinterpreter.cpp qmljsinterpreter.h
diff --git a/src/libs/qmljs/jsoncheck.cpp b/src/libs/qmljs/jsoncheck.cpp
index b7ce1443fb9..1d7c04e50cf 100644
--- a/src/libs/qmljs/jsoncheck.cpp
+++ b/src/libs/qmljs/jsoncheck.cpp
@@ -4,19 +4,24 @@
#include "jsoncheck.h"
#include <qmljs/parser/qmljsast_p.h>
+
+#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <QDebug>
+#include <QDir>
+#include <QJsonDocument>
#include <QLatin1String>
#include <QRegularExpression>
#include <cmath>
-using namespace QmlJS;
using namespace QmlJS::AST;
using namespace QmlJS::StaticAnalysis;
using namespace Utils;
+namespace QmlJS {
+
JsonCheck::JsonCheck(Document::Ptr doc)
: m_doc(doc)
, m_schema(nullptr)
@@ -29,7 +34,7 @@ JsonCheck::~JsonCheck()
QList<Message> JsonCheck::operator ()(JsonSchema *schema)
{
- QTC_ASSERT(schema, return QList<Message>());
+ QTC_ASSERT(schema, return {});
m_schema = schema;
@@ -384,3 +389,716 @@ JsonCheck::AnalysisData *JsonCheck::analysis()
{
return &m_analysis.top();
}
+
+
+JsonMemoryPool::~JsonMemoryPool()
+{
+ for (char *obj : std::as_const(_objs)) {
+ reinterpret_cast<JsonValue *>(obj)->~JsonValue();
+ delete[] obj;
+ }
+}
+
+JsonValue::JsonValue(Kind kind)
+ : m_kind(kind)
+{}
+
+JsonValue::~JsonValue() = default;
+
+JsonValue *JsonValue::create(const QString &s, JsonMemoryPool *pool)
+{
+ const QJsonDocument document = QJsonDocument::fromJson(s.toUtf8());
+ if (document.isNull())
+ return nullptr;
+
+ return build(document.toVariant(), pool);
+}
+
+void *JsonValue::operator new(size_t size, JsonMemoryPool *pool)
+{ return pool->allocate(size); }
+
+void JsonValue::operator delete(void *)
+{ }
+
+void JsonValue::operator delete(void *, JsonMemoryPool *)
+{ }
+
+QString JsonValue::kindToString(JsonValue::Kind kind)
+{
+ if (kind == String)
+ return QLatin1String("string");
+ if (kind == Double)
+ return QLatin1String("number");
+ if (kind == Int)
+ return QLatin1String("integer");
+ if (kind == Object)
+ return QLatin1String("object");
+ if (kind == Array)
+ return QLatin1String("array");
+ if (kind == Boolean)
+ return QLatin1String("boolean");
+ if (kind == Null)
+ return QLatin1String("null");
+
+ return QLatin1String("unknown");
+}
+
+JsonValue *JsonValue::build(const QVariant &variant, JsonMemoryPool *pool)
+{
+ switch (variant.typeId()) {
+
+ case QVariant::List: {
+ auto newValue = new (pool) JsonArrayValue;
+ const QList<QVariant> list = variant.toList();
+ for (const QVariant &element : list)
+ newValue->addElement(build(element, pool));
+ return newValue;
+ }
+
+ case QVariant::Map: {
+ auto newValue = new (pool) JsonObjectValue;
+ const QVariantMap variantMap = variant.toMap();
+ for (QVariantMap::const_iterator it = variantMap.begin(); it != variantMap.end(); ++it)
+ newValue->addMember(it.key(), build(it.value(), pool));
+ return newValue;
+ }
+
+ case QVariant::String:
+ return new (pool) JsonStringValue(variant.toString());
+
+ case QVariant::Int:
+ return new (pool) JsonIntValue(variant.toInt());
+
+ case QVariant::Double:
+ return new (pool) JsonDoubleValue(variant.toDouble());
+
+ case QVariant::Bool:
+ return new (pool) JsonBooleanValue(variant.toBool());
+
+ case QVariant::Invalid:
+ return new (pool) JsonNullValue;
+
+ default:
+ break;
+ }
+
+ return nullptr;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString JsonSchema::kType() { return QStringLiteral("type"); }
+QString JsonSchema::kProperties() { return QStringLiteral("properties"); }
+QString JsonSchema::kPatternProperties() { return QStringLiteral("patternProperties"); }
+QString JsonSchema::kAdditionalProperties() { return QStringLiteral("additionalProperties"); }
+QString JsonSchema::kItems() { return QStringLiteral("items"); }
+QString JsonSchema::kAdditionalItems() { return QStringLiteral("additionalItems"); }
+QString JsonSchema::kRequired() { return QStringLiteral("required"); }
+QString JsonSchema::kDependencies() { return QStringLiteral("dependencies"); }
+QString JsonSchema::kMinimum() { return QStringLiteral("minimum"); }
+QString JsonSchema::kMaximum() { return QStringLiteral("maximum"); }
+QString JsonSchema::kExclusiveMinimum() { return QStringLiteral("exclusiveMinimum"); }
+QString JsonSchema::kExclusiveMaximum() { return QStringLiteral("exclusiveMaximum"); }
+QString JsonSchema::kMinItems() { return QStringLiteral("minItems"); }
+QString JsonSchema::kMaxItems() { return QStringLiteral("maxItems"); }
+QString JsonSchema::kUniqueItems() { return QStringLiteral("uniqueItems"); }
+QString JsonSchema::kPattern() { return QStringLiteral("pattern"); }
+QString JsonSchema::kMinLength() { return QStringLiteral("minLength"); }
+QString JsonSchema::kMaxLength() { return QStringLiteral("maxLength"); }
+QString JsonSchema::kTitle() { return QStringLiteral("title"); }
+QString JsonSchema::kDescription() { return QStringLiteral("description"); }
+QString JsonSchema::kExtends() { return QStringLiteral("extends"); }
+QString JsonSchema::kRef() { return QStringLiteral("$ref"); }
+
+JsonSchema::JsonSchema(JsonObjectValue *rootObject, const JsonSchemaManager *manager)
+ : m_manager(manager)
+{
+ enter(rootObject);
+}
+
+bool JsonSchema::isTypeConstrained() const
+{
+ // Simple types
+ if (JsonStringValue *sv = getStringValue(kType(), currentValue()))
+ return isCheckableType(sv->value());
+
+ // Union types
+ if (JsonArrayValue *av = getArrayValue(kType(), currentValue())) {
+ QTC_ASSERT(currentIndex() != -1, return false);
+ QTC_ASSERT(av->elements().at(currentIndex())->kind() == JsonValue::String, return false);
+ JsonStringValue *sv = av->elements().at(currentIndex())->toString();
+ return isCheckableType(sv->value());
+ }
+
+ return false;
+}
+
+bool JsonSchema::acceptsType(const QString &type) const
+{
+ // Simple types
+ if (JsonStringValue *sv = getStringValue(kType(), currentValue()))
+ return typeMatches(sv->value(), type);
+
+ // Union types
+ if (JsonArrayValue *av = getArrayValue(kType(), currentValue())) {
+ QTC_ASSERT(currentIndex() != -1, return false);
+ QTC_ASSERT(av->elements().at(currentIndex())->kind() == JsonValue::String, return false);
+ JsonStringValue *sv = av->elements().at(currentIndex())->toString();
+ return typeMatches(sv->value(), type);
+ }
+
+ return false;
+}
+
+QStringList JsonSchema::validTypes(JsonObjectValue *v)
+{
+ QStringList all;
+
+ if (JsonStringValue *sv = getStringValue(kType(), v))
+ all.append(sv->value());
+
+ if (JsonObjectValue *ov = getObjectValue(kType(), v))
+ return validTypes(ov);
+
+ if (JsonArrayValue *av = getArrayValue(kType(), v)) {
+ const QList<JsonValue *> elements = av->elements();
+ for (JsonValue *v : elements) {
+ if (JsonStringValue *sv = v->toString())
+ all.append(sv->value());
+ else if (JsonObjectValue *ov = v->toObject())
+ all.append(validTypes(ov));
+ }
+ }
+
+ return all;
+}
+
+bool JsonSchema::typeMatches(const QString &expected, const QString &actual)
+{
+ if (expected == QLatin1String("number") && actual == QLatin1String("integer"))
+ return true;
+
+ return expected == actual;
+}
+
+bool JsonSchema::isCheckableType(const QString &s)
+{
+ return s == QLatin1String("string")
+ || s == QLatin1String("number")
+ || s == QLatin1String("integer")
+ || s == QLatin1String("boolean")
+ || s == QLatin1String("object")
+ || s == QLatin1String("array")
+ || s == QLatin1String("null");
+}
+
+QStringList JsonSchema::validTypes() const
+{
+ return validTypes(currentValue());
+}
+
+bool JsonSchema::hasTypeSchema() const
+{
+ return getObjectValue(kType(), currentValue());
+}
+
+void JsonSchema::enterNestedTypeSchema()
+{
+ QTC_ASSERT(hasTypeSchema(), return);
+
+ enter(getObjectValue(kType(), currentValue()));
+}
+
+QStringList JsonSchema::properties(JsonObjectValue *v) const
+{
+ using Members = QHash<QString, JsonValue *>;
+
+ QStringList all;
+
+ if (JsonObjectValue *ov = getObjectValue(kProperties(), v)) {
+ const Members members = ov->members();
+ const Members::ConstIterator cend = members.constEnd();
+ for (Members::ConstIterator it = members.constBegin(); it != cend; ++it)
+ if (hasPropertySchema(it.key()))
+ all.append(it.key());
+ }
+
+ if (JsonObjectValue *base = resolveBase(v))
+ all.append(properties(base));
+
+ return all;
+}
+
+QStringList JsonSchema::properties() const
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Object)), return {});
+
+ return properties(currentValue());
+}
+
+JsonObjectValue *JsonSchema::propertySchema(const QString &property,
+ JsonObjectValue *v) const
+{
+ if (JsonObjectValue *ov = getObjectValue(kProperties(), v)) {
+ JsonValue *member = ov->member(property);
+ if (member && member->kind() == JsonValue::Object)
+ return member->toObject();
+ }
+
+ if (JsonObjectValue *base = resolveBase(v))
+ return propertySchema(property, base);
+
+ return nullptr;
+}
+
+bool JsonSchema::hasPropertySchema(const QString &property) const
+{
+ return propertySchema(property, currentValue());
+}
+
+void JsonSchema::enterNestedPropertySchema(const QString &property)
+{
+ QTC_ASSERT(hasPropertySchema(property), return);
+
+ JsonObjectValue *schema = propertySchema(property, currentValue());
+
+ enter(schema);
+}
+
+/*!
+ * An array schema is allowed to have its \e items specification in the form of
+ * another schema
+ * or in the form of an array of schemas [Sec. 5.5]. This functions checks whether this is case
+ * in which the items are a schema.
+ *
+ * Returns whether or not the items from the array are a schema.
+ */
+bool JsonSchema::hasItemSchema() const
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Array)), return false);
+
+ return getObjectValue(kItems(), currentValue());
+}
+
+void JsonSchema::enterNestedItemSchema()
+{
+ QTC_ASSERT(hasItemSchema(), return);
+
+ enter(getObjectValue(kItems(), currentValue()));
+}
+
+/*!
+ * An array schema is allowed to have its \e items specification in the form of another schema
+ * or in the form of an array of schemas [Sec. 5.5]. This functions checks whether this is case
+ * in which the items are an array of schemas.
+ *
+ * Returns whether or not the items from the array are a an array of schemas.
+ */
+bool JsonSchema::hasItemArraySchema() const
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Array)), return false);
+
+ return getArrayValue(kItems(), currentValue());
+}
+
+int JsonSchema::itemArraySchemaSize() const
+{
+ QTC_ASSERT(hasItemArraySchema(), return false);
+
+ return getArrayValue(kItems(), currentValue())->size();
+}
+
+/*!
+ * When evaluating the items of an array it might be necessary to \e enter a
+ * particular schema,
+ * since this API assumes that there's always a valid schema in context (the one the user is
+ * interested on). This shall only happen if the item at the supplied array index is of type
+ * object, which is then assumed to be a schema.
+ *
+ * The function also marks the context as being inside an array evaluation.
+ *
+ * Returns whether it was necessary to enter a schema for the supplied
+ * array \a index, false if index is out of bounds.
+ */
+bool JsonSchema::maybeEnterNestedArraySchema(int index)
+{
+ QTC_ASSERT(itemArraySchemaSize(), return false);
+ QTC_ASSERT(index >= 0 && index < itemArraySchemaSize(), return false);
+
+ JsonValue *v = getArrayValue(kItems(), currentValue())->elements().at(index);
+
+ return maybeEnter(v, Array, index);
+}
+
+/*!
+ * The type of a schema can be specified in the form of a union type, which is basically an
+ * array of allowed types for the particular instance [Sec. 5.1]. This function checks whether
+ * the current schema is one of such.
+ *
+ * Returns whether or not the current schema specifies a union type.
+ */
+bool JsonSchema::hasUnionSchema() const
+{
+ return getArrayValue(kType(), currentValue());
+}
+
+int JsonSchema::unionSchemaSize() const
+{
+ return getArrayValue(kType(), currentValue())->size();
+}
+
+/*!
+ * When evaluating union types it might be necessary to enter a particular
+ * schema, since this
+ * API assumes that there's always a valid schema in context (the one the user is interested on).
+ * This shall only happen if the item at the supplied union \a index, which is then assumed to be
+ * a schema.
+ *
+ * The function also marks the context as being inside an union evaluation.
+ *
+ * Returns whether or not it was necessary to enter a schema for the
+ * supplied union index.
+ */
+bool JsonSchema::maybeEnterNestedUnionSchema(int index)
+{
+ QTC_ASSERT(unionSchemaSize(), return false);
+ QTC_ASSERT(index >= 0 && index < unionSchemaSize(), return false);
+
+ JsonValue *v = getArrayValue(kType(), currentValue())->elements().at(index);
+
+ return maybeEnter(v, Union, index);
+}
+
+void JsonSchema::leaveNestedSchema()
+{
+ QTC_ASSERT(!m_schemas.isEmpty(), return);
+
+ leave();
+}
+
+bool JsonSchema::required() const
+{
+ if (JsonBooleanValue *bv = getBooleanValue(kRequired(), currentValue()))
+ return bv->value();
+
+ return false;
+}
+
+bool JsonSchema::hasMinimum() const
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
+
+ return getDoubleValue(kMinimum(), currentValue());
+}
+
+double JsonSchema::minimum() const
+{
+ QTC_ASSERT(hasMinimum(), return 0);
+
+ return getDoubleValue(kMinimum(), currentValue())->value();
+}
+
+bool JsonSchema::hasExclusiveMinimum()
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
+
+ if (JsonBooleanValue *bv = getBooleanValue(kExclusiveMinimum(), currentValue()))
+ return bv->value();
+
+ return false;
+}
+
+bool JsonSchema::hasMaximum() const
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
+
+ return getDoubleValue(kMaximum(), currentValue());
+}
+
+double JsonSchema::maximum() const
+{
+ QTC_ASSERT(hasMaximum(), return 0);
+
+ return getDoubleValue(kMaximum(), currentValue())->value();
+}
+
+bool JsonSchema::hasExclusiveMaximum()
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
+
+ if (JsonBooleanValue *bv = getBooleanValue(kExclusiveMaximum(), currentValue()))
+ return bv->value();
+
+ return false;
+}
+
+QString JsonSchema::pattern() const
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::String)), return QString());
+
+ if (JsonStringValue *sv = getStringValue(kPattern(), currentValue()))
+ return sv->value();
+
+ return QString();
+}
+
+int JsonSchema::minimumLength() const
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::String)), return -1);
+
+ if (JsonDoubleValue *dv = getDoubleValue(kMinLength(), currentValue()))
+ return dv->value();
+
+ return -1;
+}
+
+int JsonSchema::maximumLength() const
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::String)), return -1);
+
+ if (JsonDoubleValue *dv = getDoubleValue(kMaxLength(), currentValue()))
+ return dv->value();
+
+ return -1;
+}
+
+bool JsonSchema::hasAdditionalItems() const
+{
+ QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Array)), return false);
+
+ return currentValue()->member(kAdditionalItems());
+}
+
+bool JsonSchema::maybeSchemaName(const QString &s)
+{
+ if (s.isEmpty() || s == QLatin1String("any"))
+ return false;
+
+ return !isCheckableType(s);
+}
+
+JsonObjectValue *JsonSchema::rootValue() const
+{
+ QTC_ASSERT(!m_schemas.isEmpty(), return nullptr);
+
+ return m_schemas.first().m_value;
+}
+
+JsonObjectValue *JsonSchema::currentValue() const
+{
+ QTC_ASSERT(!m_schemas.isEmpty(), return nullptr);
+
+ return m_schemas.last().m_value;
+}
+
+int JsonSchema::currentIndex() const
+{
+ QTC_ASSERT(!m_schemas.isEmpty(), return 0);
+
+ return m_schemas.last().m_index;
+}
+
+void JsonSchema::evaluate(EvaluationMode eval, int index)
+{
+ QTC_ASSERT(!m_schemas.isEmpty(), return);
+
+ m_schemas.last().m_eval = eval;
+ m_schemas.last().m_index = index;
+}
+
+void JsonSchema::enter(JsonObjectValue *ov, EvaluationMode eval, int index)
+{
+ Context context;
+ context.m_eval = eval;
+ context.m_index = index;
+ context.m_value = resolveReference(ov);
+
+ m_schemas.push_back(context);
+}
+
+bool JsonSchema::maybeEnter(JsonValue *v, EvaluationMode eval, int index)
+{
+ evaluate(eval, index);
+
+ if (v->kind() == JsonValue::Object) {
+ enter(v->toObject());
+ return true;
+ }
+
+ if (v->kind() == JsonValue::String) {
+ const QString &s = v->toString()->value();
+ if (maybeSchemaName(s)) {
+ JsonSchema *schema = m_manager->schemaByName(s);
+ if (schema) {
+ enter(schema->rootValue());
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void JsonSchema::leave()
+{
+ QTC_ASSERT(!m_schemas.isEmpty(), return);
+
+ m_schemas.pop_back();
+}
+
+JsonObjectValue *JsonSchema::resolveReference(JsonObjectValue *ov) const
+{
+ if (JsonStringValue *sv = getStringValue(kRef(), ov)) {
+ JsonSchema *referenced = m_manager->schemaByName(sv->value());
+ if (referenced)
+ return referenced->rootValue();
+ }
+
+ return ov;
+}
+
+JsonObjectValue *JsonSchema::resolveBase(JsonObjectValue *ov) const
+{
+ if (JsonValue *v = ov->member(kExtends())) {
+ if (v->kind() == JsonValue::String) {
+ JsonSchema *schema = m_manager->schemaByName(v->toString()->value());
+ if (schema)
+ return schema->rootValue();
+ } else if (v->kind() == JsonValue::Object) {
+ return resolveReference(v->toObject());
+ }
+ }
+
+ return nullptr;
+}
+
+JsonStringValue *JsonSchema::getStringValue(const QString &name, JsonObjectValue *value)
+{
+ JsonValue *v = value->member(name);
+ if (!v)
+ return nullptr;
+
+ return v->toString();
+}
+
+JsonObjectValue *JsonSchema::getObjectValue(const QString &name, JsonObjectValue *value)
+{
+ JsonValue *v = value->member(name);
+ if (!v)
+ return nullptr;
+
+ return v->toObject();
+}
+
+JsonBooleanValue *JsonSchema::getBooleanValue(const QString &name, JsonObjectValue *value)
+{
+ JsonValue *v = value->member(name);
+ if (!v)
+ return nullptr;
+
+ return v->toBoolean();
+}
+
+JsonArrayValue *JsonSchema::getArrayValue(const QString &name, JsonObjectValue *value)
+{
+ JsonValue *v = value->member(name);
+ if (!v)
+ return nullptr;
+
+ return v->toArray();
+}
+
+JsonDoubleValue *JsonSchema::getDoubleValue(const QString &name, JsonObjectValue *value)
+{
+ JsonValue *v = value->member(name);
+ if (!v)
+ return nullptr;
+
+ return v->toDouble();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+JsonSchemaManager::JsonSchemaManager(const QStringList &searchPaths)
+ : m_searchPaths(searchPaths)
+{
+ for (const QString &path : searchPaths) {
+ QDir dir(path);
+ if (!dir.exists())
+ continue;
+ dir.setNameFilters(QStringList(QLatin1String("*.json")));
+ const QList<QFileInfo> entries = dir.entryInfoList();
+ for (const QFileInfo &fi : entries)
+ m_schemas.insert(fi.baseName(), JsonSchemaData(fi.absoluteFilePath()));
+ }
+}
+
+JsonSchemaManager::~JsonSchemaManager()
+{
+ for (const JsonSchemaData &schemaData : std::as_const(m_schemas))
+ delete schemaData.m_schema;
+}
+
+/*!
+ * Tries to find a JSON schema to validate \a fileName against. According
+ * to the specification, how the schema/instance association is done is implementation defined.
+ * Currently we use a quite naive approach which is simply based on file names. Specifically,
+ * if one opens a foo.json file we'll look for a schema named foo.json. We should probably
+ * investigate alternative settings later.
+ *
+ * Returns a valid schema or 0.
+ */
+JsonSchema *JsonSchemaManager::schemaForFile(const QString &fileName) const
+{
+ QString baseName(QFileInfo(fileName).baseName());
+
+ return schemaByName(baseName);
+}
+
+JsonSchema *JsonSchemaManager::schemaByName(const QString &baseName) const
+{
+ QHash<QString, JsonSchemaData>::iterator it = m_schemas.find(baseName);
+ if (it == m_schemas.end()) {
+ for (const QString &path : m_searchPaths) {
+ QFileInfo candidate(path + baseName + ".json");
+ if (candidate.exists()) {
+ m_schemas.insert(baseName, candidate.absoluteFilePath());
+ break;
+ }
+ }
+ }
+
+ it = m_schemas.find(baseName);
+ if (it == m_schemas.end())
+ return nullptr;
+
+ JsonSchemaData *schemaData = &it.value();
+ if (!schemaData->m_schema) {
+ // Schemas are built on-demand.
+ QFileInfo currentSchema(schemaData->m_absoluteFileName);
+ Q_ASSERT(currentSchema.exists());
+ if (schemaData->m_lastParseAttempt.isNull()
+ || schemaData->m_lastParseAttempt < currentSchema.lastModified()) {
+ schemaData->m_schema = parseSchema(currentSchema.absoluteFilePath());
+ }
+ }
+
+ return schemaData->m_schema;
+}
+
+JsonSchema *JsonSchemaManager::parseSchema(const QString &schemaFileName) const
+{
+ FileReader reader;
+ if (reader.fetch(FilePath::fromString(schemaFileName), QIODevice::Text)) {
+ const QString &contents = QString::fromUtf8(reader.data());
+ JsonValue *json = JsonValue::create(contents, &m_pool);
+ if (json && json->kind() == JsonValue::Object)
+ return new JsonSchema(json->toObject(), this);
+ }
+
+ return nullptr;
+}
+
+} // QmlJs
diff --git a/src/libs/qmljs/jsoncheck.h b/src/libs/qmljs/jsoncheck.h
index 6050ff72897..261c349cc30 100644
--- a/src/libs/qmljs/jsoncheck.h
+++ b/src/libs/qmljs/jsoncheck.h
@@ -9,21 +9,397 @@
#include <qmljs/parser/qmljsastvisitor_p.h>
#include <qmljs/qmljsstaticanalysismessage.h>
-#include <utils/json.h>
-
#include <QStack>
#include <QList>
-
namespace QmlJS {
+class JsonStringValue;
+class JsonDoubleValue;
+class JsonIntValue;
+class JsonObjectValue;
+class JsonArrayValue;
+class JsonBooleanValue;
+class JsonNullValue;
+
+class QMLJS_EXPORT JsonMemoryPool
+{
+public:
+ ~JsonMemoryPool();
+
+ inline void *allocate(size_t size)
+ {
+ auto obj = new char[size];
+ _objs.append(obj);
+ return obj;
+ }
+
+private:
+ QList<char *> _objs;
+};
+
+/*!
+ * \brief The JsonValue class
+ */
+class QMLJS_EXPORT JsonValue
+{
+public:
+ enum Kind {
+ String,
+ Double,
+ Int,
+ Object,
+ Array,
+ Boolean,
+ Null,
+ Unknown
+ };
+
+ virtual ~JsonValue();
+
+ Kind kind() const { return m_kind; }
+ static QString kindToString(Kind kind);
+
+ virtual JsonStringValue *toString() { return nullptr; }
+ virtual JsonDoubleValue *toDouble() { return nullptr; }
+ virtual JsonIntValue *toInt() { return nullptr; }
+ virtual JsonObjectValue *toObject() { return nullptr; }
+ virtual JsonArrayValue *toArray() { return nullptr; }
+ virtual JsonBooleanValue *toBoolean() { return nullptr; }
+ virtual JsonNullValue *toNull() { return nullptr; }
+
+ static JsonValue *create(const QString &s, JsonMemoryPool *pool);
+ void *operator new(size_t size, JsonMemoryPool *pool);
+ void operator delete(void *);
+ void operator delete(void *, JsonMemoryPool *);
+
+protected:
+ JsonValue(Kind kind);
+
+private:
+ static JsonValue *build(const QVariant &varixant, JsonMemoryPool *pool);
+
+ Kind m_kind;
+};
+
+
+/*!
+ * \brief The JsonStringValue class
+ */
+class QMLJS_EXPORT JsonStringValue : public JsonValue
+{
+public:
+ JsonStringValue(const QString &value)
+ : JsonValue(String)
+ , m_value(value)
+ {}
+
+ JsonStringValue *toString() override { return this; }
+
+ const QString &value() const { return m_value; }
+
+private:
+ QString m_value;
+};
+
+
+/*!
+ * \brief The JsonDoubleValue class
+ */
+class QMLJS_EXPORT JsonDoubleValue : public JsonValue
+{
+public:
+ JsonDoubleValue(double value)
+ : JsonValue(Double)
+ , m_value(value)
+ {}
+
+ JsonDoubleValue *toDouble() override { return this; }
+
+ double value() const { return m_value; }
+
+private:
+ double m_value;
+};
+
+/*!
+ * \brief The JsonIntValue class
+ */
+class QMLJS_EXPORT JsonIntValue : public JsonValue
+{
+public:
+ JsonIntValue(int value)
+ : JsonValue(Int)
+ , m_value(value)
+ {}
+
+ JsonIntValue *toInt() override { return this; }
+
+ int value() const { return m_value; }
+
+private:
+ int m_value;
+};
+
+
+/*!
+ * \brief The JsonObjectValue class
+ */
+class QMLJS_EXPORT JsonObjectValue : public JsonValue
+{
+public:
+ JsonObjectValue()
+ : JsonValue(Object)
+ {}
+
+ JsonObjectValue *toObject() override { return this; }
+
+ void addMember(const QString &name, JsonValue *value) { m_members.insert(name, value); }
+ bool hasMember(const QString &name) const { return m_members.contains(name); }
+ JsonValue *member(const QString &name) const { return m_members.value(name); }
+ QHash<QString, JsonValue *> members() const { return m_members; }
+ bool isEmpty() const { return m_members.isEmpty(); }
+
+protected:
+ JsonObjectValue(Kind kind)
+ : JsonValue(kind)
+ {}
+
+private:
+ QHash<QString, JsonValue *> m_members;
+};
+
+
+/*!
+ * \brief The JsonArrayValue class
+ */
+class QMLJS_EXPORT JsonArrayValue : public JsonValue
+{
+public:
+ JsonArrayValue()
+ : JsonValue(Array)
+ {}
+
+ JsonArrayValue *toArray() override { return this; }
+
+ void addElement(JsonValue *value) { m_elements.append(value); }
+ QList<JsonValue *> elements() const { return m_elements; }
+ int size() const { return m_elements.size(); }
+
+private:
+ QList<JsonValue *> m_elements;
+};
+
+
+/*!
+ * \brief The JsonBooleanValue class
+ */
+class QMLJS_EXPORT JsonBooleanValue : public JsonValue
+{
+public:
+ JsonBooleanValue(bool value)
+ : JsonValue(Boolean)
+ , m_value(value)
+ {}
+
+ JsonBooleanValue *toBoolean() override { return this; }
+
+ bool value() const { return m_value; }
+
+private:
+ bool m_value;
+};
+
+class QMLJS_EXPORT JsonNullValue : public JsonValue
+{
+public:
+ JsonNullValue()
+ : JsonValue(Null)
+ {}
+
+ JsonNullValue *toNull() override { return this; }
+};
+
+class JsonSchemaManager;
+
+/*!
+ * \brief The JsonSchema class
+ *
+ * [NOTE: This is an incomplete implementation and a work in progress.]
+ *
+ * This class provides an interface for traversing and evaluating a JSON schema, as described
+ * in the draft http://tools.ietf.org/html/draft-zyp-json-schema-03.
+ *
+ * JSON schemas are recursive in concept. This means that a particular attribute from a schema
+ * might be also another schema. Therefore, the basic working principle of this API is that
+ * from within some schema, one can investigate its attributes and if necessary "enter" a
+ * corresponding nested schema. Afterwards, it's expected that one would "leave" such nested
+ * schema.
+ *
+ * All functions assume that the current "context" is a valid schema. Once an instance of this
+ * class is created the root schema is put on top of the stack.
+ *
+ */
+class QMLJS_EXPORT JsonSchema
+{
+public:
+ bool isTypeConstrained() const;
+ bool acceptsType(const QString &type) const;
+ QStringList validTypes() const;
+
+ // Applicable on schemas of any type.
+ bool required() const;
+
+ bool hasTypeSchema() const;
+ void enterNestedTypeSchema();
+
+ bool hasUnionSchema() const;
+ int unionSchemaSize() const;
+ bool maybeEnterNestedUnionSchema(int index);
+
+ void leaveNestedSchema();
+
+ // Applicable on schemas of type number/integer.
+ bool hasMinimum() const;
+ bool hasMaximum() const;
+ bool hasExclusiveMinimum();
+ bool hasExclusiveMaximum();
+ double minimum() const;
+ double maximum() const;
+
+ // Applicable on schemas of type string.
+ QString pattern() const;
+ int minimumLength() const;
+ int maximumLength() const;
+
+ // Applicable on schemas of type object.
+ QStringList properties() const;
+ bool hasPropertySchema(const QString &property) const;
+ void enterNestedPropertySchema(const QString &property);
+
+ // Applicable on schemas of type array.
+ bool hasAdditionalItems() const;
+
+ bool hasItemSchema() const;
+ void enterNestedItemSchema();
+
+ bool hasItemArraySchema() const;
+ int itemArraySchemaSize() const;
+ bool maybeEnterNestedArraySchema(int index);
+
+private:
+ friend class JsonSchemaManager;
+ JsonSchema(JsonObjectValue *rootObject, const JsonSchemaManager *manager);
+ Q_DISABLE_COPY(JsonSchema)
+
+ enum EvaluationMode {
+ Normal,
+ Array,
+ Union
+ };
+
+ void enter(JsonObjectValue *ov, EvaluationMode eval = Normal, int index = -1);
+ bool maybeEnter(JsonValue *v, EvaluationMode eval, int index);
+ void evaluate(EvaluationMode eval, int index);
+ void leave();
+
+ JsonObjectValue *resolveReference(JsonObjectValue *ov) const;
+ JsonObjectValue *resolveBase(JsonObjectValue *ov) const;
+
+ JsonObjectValue *currentValue() const;
+ int currentIndex() const;
+
+ JsonObjectValue *rootValue() const;
+
+ static JsonStringValue *getStringValue(const QString &name, JsonObjectValue *value);
+ static JsonObjectValue *getObjectValue(const QString &name, JsonObjectValue *value);
+ static JsonBooleanValue *getBooleanValue(const QString &name, JsonObjectValue *value);
+ static JsonArrayValue *getArrayValue(const QString &name, JsonObjectValue *value);
+ static JsonDoubleValue *getDoubleValue(const QString &name, JsonObjectValue *value);
+
+ static QStringList validTypes(JsonObjectValue *v);
+ static bool typeMatches(const QString &expected, const QString &actual);
+ static bool isCheckableType(const QString &s);
+
+ QStringList properties(JsonObjectValue *v) const;
+ JsonObjectValue *propertySchema(const QString &property, JsonObjectValue *v) const;
+ // TODO: Similar functions for other attributes which require looking into base schemas.
+
+ static bool maybeSchemaName(const QString &s);
+
+ static QString kType();
+ static QString kProperties();
+ static QString kPatternProperties();
+ static QString kAdditionalProperties();
+ static QString kItems();
+ static QString kAdditionalItems();
+ static QString kRequired();
+ static QString kDependencies();
+ static QString kMinimum();
+ static QString kMaximum();
+ static QString kExclusiveMinimum();
+ static QString kExclusiveMaximum();
+ static QString kMinItems();
+ static QString kMaxItems();
+ static QString kUniqueItems();
+ static QString kPattern();
+ static QString kMinLength();
+ static QString kMaxLength();
+ static QString kTitle();
+ static QString kDescription();
+ static QString kExtends();
+ static QString kRef();
+
+ struct Context
+ {
+ JsonObjectValue *m_value;
+ EvaluationMode m_eval;
+ int m_index;
+ };
+
+ QList<Context> m_schemas;
+ const JsonSchemaManager *m_manager;
+};
+
+
+/*!
+ * \brief The JsonSchemaManager class
+ */
+class QMLJS_EXPORT JsonSchemaManager
+{
+public:
+ JsonSchemaManager(const QStringList &searchPaths);
+ ~JsonSchemaManager();
+
+ JsonSchema *schemaForFile(const QString &fileName) const;
+ JsonSchema *schemaByName(const QString &baseName) const;
+
+private:
+ struct JsonSchemaData
+ {
+ JsonSchemaData(const QString &absoluteFileName, JsonSchema *schema = nullptr)
+ : m_absoluteFileName(absoluteFileName)
+ , m_schema(schema)
+ {}
+ QString m_absoluteFileName;
+ JsonSchema *m_schema;
+ QDateTime m_lastParseAttempt;
+ };
+
+ JsonSchema *parseSchema(const QString &schemaFileName) const;
+
+ QStringList m_searchPaths;
+ mutable QHash<QString, JsonSchemaData> m_schemas;
+ mutable JsonMemoryPool m_pool;
+};
+
class QMLJS_EXPORT JsonCheck : public AST::Visitor
{
public:
JsonCheck(Document::Ptr doc);
~JsonCheck();
- QList<StaticAnalysis::Message> operator()(Utils::JsonSchema *schema);
+ QList<StaticAnalysis::Message> operator()(JsonSchema *schema);
private:
bool preVisit(AST::Node *) override;
@@ -52,14 +428,14 @@ private:
};
void processSchema(AST::Node *ast);
- bool proceedCheck(Utils::JsonValue::Kind kind, const SourceLocation &location);
+ bool proceedCheck(JsonValue::Kind kind, const SourceLocation &location);
AnalysisData *analysis();
Document::Ptr m_doc;
SourceLocation m_firstLoc;
- Utils::JsonSchema *m_schema;
+ JsonSchema *m_schema;
QStack<AnalysisData> m_analysis;
};
-} // QmlJs
+} // QmlJS
diff --git a/src/libs/qmljs/qmljs.qbs b/src/libs/qmljs/qmljs.qbs
index 59eecc55f4c..18434c83bad 100644
--- a/src/libs/qmljs/qmljs.qbs
+++ b/src/libs/qmljs/qmljs.qbs
@@ -1,84 +1,79 @@
-import qbs 1.0
-
-Project {
+QtcLibrary {
name: "QmlJS"
- QtcLibrary {
- cpp.defines: base.concat(["QMLJS_LIBRARY"])
- cpp.optimization: "fast"
+ cpp.defines: base.concat(["QMLJS_LIBRARY"])
+ cpp.optimization: "fast"
- Depends { name: "ExtensionSystem" }
- Depends { name: "Utils" }
- Depends { name: "LanguageUtils" }
- Depends { name: "CPlusPlus" }
- Depends { name: "Qt"; submodules: ["widgets", "xml"] }
+ Depends { name: "ExtensionSystem" }
+ Depends { name: "Utils" }
+ Depends { name: "LanguageUtils" }
+ Depends { name: "CPlusPlus" }
+ Depends { name: "Qt"; submodules: ["widgets", "xml"] }
- Group {
- name: "General"
- files: [
- "jsoncheck.cpp", "jsoncheck.h",
- "persistenttrie.cpp", "persistenttrie.h",
- "qmljs_global.h",
- "qmljsbind.cpp", "qmljsbind.h",
- "qmljsbundle.cpp", "qmljsbundle.h",
- "qmljscheck.cpp", "qmljscheck.h",
- "qmljscodeformatter.cpp", "qmljscodeformatter.h",
- "qmljscompletioncontextfinder.cpp", "qmljscompletioncontextfinder.h",
- "qmljsconstants.h",
- "qmljscontext.cpp", "qmljscontext.h",
- "qmljsdocument.cpp", "qmljsdocument.h",
- "qmljsevaluate.cpp", "qmljsevaluate.h",
- "qmljsfindexportedcpptypes.cpp", "qmljsfindexportedcpptypes.h",
- "qmljsicons.cpp", "qmljsicons.h",
- "qmljsicontextpane.h",
- "qmljsimportdependencies.cpp", "qmljsimportdependencies.h",
- "qmljsindenter.cpp", "qmljsindenter.h",
- "qmljsinterpreter.cpp", "qmljsinterpreter.h",
- "qmljsdialect.cpp", "qmljsdialect.h",
- "qmljslineinfo.cpp", "qmljslineinfo.h",
- "qmljslink.cpp", "qmljslink.h",
- "qmljsmodelmanagerinterface.cpp", "qmljsmodelmanagerinterface.h",
- "qmljsplugindumper.cpp", "qmljsplugindumper.h",
- "qmljspropertyreader.cpp", "qmljspropertyreader.h",
- "qmljsreformatter.cpp", "qmljsreformatter.h",
- "qmljsrewriter.cpp", "qmljsrewriter.h",
- "qmljsscanner.cpp", "qmljsscanner.h",
- "qmljsscopeastpath.cpp", "qmljsscopeastpath.h",
- "qmljsscopebuilder.cpp", "qmljsscopebuilder.h",
- "qmljsscopechain.cpp", "qmljsscopechain.h",
- "qmljssimplereader.cpp", "qmljssimplereader.h",
- "qmljsstaticanalysismessage.cpp", "qmljsstaticanalysismessage.h",
- "qmljstr.h",
- "qmljstypedescriptionreader.cpp", "qmljstypedescriptionreader.h",
- "qmljsutils.cpp", "qmljsutils.h",
- "qmljsvalueowner.cpp", "qmljsvalueowner.h",
- "qmljsviewercontext.h"
- ]
- }
+ Group {
+ name: "General"
+ files: [
+ "jsoncheck.cpp", "jsoncheck.h",
+ "persistenttrie.cpp", "persistenttrie.h",
+ "qmljs_global.h",
+ "qmljsbind.cpp", "qmljsbind.h",
+ "qmljsbundle.cpp", "qmljsbundle.h",
+ "qmljscheck.cpp", "qmljscheck.h",
+ "qmljscodeformatter.cpp", "qmljscodeformatter.h",
+ "qmljscompletioncontextfinder.cpp", "qmljscompletioncontextfinder.h",
+ "qmljsconstants.h",
+ "qmljscontext.cpp", "qmljscontext.h",
+ "qmljsdocument.cpp", "qmljsdocument.h",
+ "qmljsevaluate.cpp", "qmljsevaluate.h",
+ "qmljsfindexportedcpptypes.cpp", "qmljsfindexportedcpptypes.h",
+ "qmljsicons.cpp", "qmljsicons.h",
+ "qmljsimportdependencies.cpp", "qmljsimportdependencies.h",
+ "qmljsindenter.cpp", "qmljsindenter.h",
+ "qmljsinterpreter.cpp", "qmljsinterpreter.h",
+ "qmljsdialect.cpp", "qmljsdialect.h",
+ "qmljslineinfo.cpp", "qmljslineinfo.h",
+ "qmljslink.cpp", "qmljslink.h",
+ "qmljsmodelmanagerinterface.cpp", "qmljsmodelmanagerinterface.h",
+ "qmljsplugindumper.cpp", "qmljsplugindumper.h",
+ "qmljspropertyreader.cpp", "qmljspropertyreader.h",
+ "qmljsreformatter.cpp", "qmljsreformatter.h",
+ "qmljsrewriter.cpp", "qmljsrewriter.h",
+ "qmljsscanner.cpp", "qmljsscanner.h",
+ "qmljsscopeastpath.cpp", "qmljsscopeastpath.h",
+ "qmljsscopebuilder.cpp", "qmljsscopebuilder.h",
+ "qmljsscopechain.cpp", "qmljsscopechain.h",
+ "qmljssimplereader.cpp", "qmljssimplereader.h",
+ "qmljsstaticanalysismessage.cpp", "qmljsstaticanalysismessage.h",
+ "qmljstr.h",
+ "qmljstypedescriptionreader.cpp", "qmljstypedescriptionreader.h",
+ "qmljsutils.cpp", "qmljsutils.h",
+ "qmljsvalueowner.cpp", "qmljsvalueowner.h",
+ "qmljsviewercontext.h"
+ ]
+ }
- Group {
- name: "Parser"
- prefix: "parser/"
- files: [
- "qmldirparser.cpp", "qmldirparser_p.h",
- "qmlimportresolver.cpp", "qmlimportresolver_p.h",
- "qmljsast.cpp", "qmljsast_p.h",
- "qmljsastfwd_p.h",
- "qmljsastvisitor.cpp", "qmljsastvisitor_p.h",
- "qmljsengine_p.h",
- "qmljsglobal_p.h",
- "qmljsgrammar.cpp", "qmljsgrammar_p.h",
- "qmljskeywords_p.h",
- "qmljslexer.cpp", "qmljslexer_p.h",
- "qmljsmemorypool_p.h",
- "qmljsparser.cpp", "qmljsparser_p.h",
- "qmljssourcelocation_p.h",
- ]
- }
+ Group {
+ name: "Parser"
+ prefix: "parser/"
+ files: [
+ "qmldirparser.cpp", "qmldirparser_p.h",
+ "qmlimportresolver.cpp", "qmlimportresolver_p.h",
+ "qmljsast.cpp", "qmljsast_p.h",
+ "qmljsastfwd_p.h",
+ "qmljsastvisitor.cpp", "qmljsastvisitor_p.h",
+ "qmljsengine_p.h",
+ "qmljsglobal_p.h",
+ "qmljsgrammar.cpp", "qmljsgrammar_p.h",
+ "qmljskeywords_p.h",
+ "qmljslexer.cpp", "qmljslexer_p.h",
+ "qmljsmemorypool_p.h",
+ "qmljsparser.cpp", "qmljsparser_p.h",
+ "qmljssourcelocation_p.h",
+ ]
+ }
- Export {
- Depends { name: "CPlusPlus" }
- Depends { name: "LanguageUtils" }
- }
+ Export {
+ Depends { name: "CPlusPlus" }
+ Depends { name: "LanguageUtils" }
}
}
diff --git a/src/libs/qmljs/qmljsbundle.cpp b/src/libs/qmljs/qmljsbundle.cpp
index e4d536a3da2..28f88fca452 100644
--- a/src/libs/qmljs/qmljsbundle.cpp
+++ b/src/libs/qmljs/qmljsbundle.cpp
@@ -3,7 +3,7 @@
#include "qmljsbundle.h"
-#include <utils/json.h>
+#include "jsoncheck.h"
#include <QString>
#include <QFile>
@@ -11,6 +11,7 @@
#include <QTextStream>
#include <QHash>
+
namespace QmlJS {
typedef PersistentTrie::Trie Trie;
@@ -45,19 +46,16 @@ Trie QmlBundle::implicitImports() const
return m_implicitImports;
}
-
Trie QmlBundle::supportedImports() const
{
return m_supportedImports;
}
-
void QmlBundle::merge(const QmlBundle &o)
{
*this = mergeF(o);
}
-
void QmlBundle::intersect(const QmlBundle &o)
{
*this = intersectF(o);
@@ -186,7 +184,7 @@ QString QmlBundle::toString(const QString &indent)
return res;
}
-QStringList QmlBundle::maybeReadTrie(Trie &trie, Utils::JsonObjectValue *config,
+QStringList QmlBundle::maybeReadTrie(Trie &trie, JsonObjectValue *config,
const QString &path, const QString &propertyName,
bool required, bool stripVersions)
{
@@ -198,12 +196,13 @@ QStringList QmlBundle::maybeReadTrie(Trie &trie, Utils::JsonObjectValue *config,
path);
return res;
}
- Utils::JsonValue *imp0 = config->member(propertyName);
- Utils::JsonArrayValue *imp = ((imp0 != nullptr) ? imp0->toArray() : nullptr);
+
+ JsonValue *imp0 = config->member(propertyName);
+ JsonArrayValue *imp = ((imp0 != nullptr) ? imp0->toArray() : nullptr);
if (imp != nullptr) {
- const QList<Utils::JsonValue *> elements = imp->elements();
- for (Utils::JsonValue *v : elements) {
- Utils::JsonStringValue *impStr = ((v != nullptr) ? v->toString() : nullptr);
+ const QList<JsonValue *> elements = imp->elements();
+ for (JsonValue *v : elements) {
+ JsonStringValue *impStr = ((v != nullptr) ? v->toString() : nullptr);
if (impStr != nullptr) {
QString value = impStr->value();
if (stripVersions) {
@@ -228,9 +227,8 @@ QStringList QmlBundle::maybeReadTrie(Trie &trie, Utils::JsonObjectValue *config,
bool QmlBundle::readFrom(QString path, bool stripVersions, QStringList *errors)
{
- Utils::JsonMemoryPool pool;
+ JsonMemoryPool pool;
- using namespace Utils;
QFile f(path);
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (errors)
diff --git a/src/libs/qmljs/qmljsbundle.h b/src/libs/qmljs/qmljsbundle.h
index 5d2058eef48..ebc0d49e251 100644
--- a/src/libs/qmljs/qmljsbundle.h
+++ b/src/libs/qmljs/qmljsbundle.h
@@ -12,10 +12,10 @@
QT_FORWARD_DECLARE_CLASS(QTextStream)
-namespace Utils { class JsonObjectValue; }
-
namespace QmlJS {
+class JsonObjectValue;
+
/* !
\class QmlJS::QmlBundle
@@ -59,7 +59,7 @@ public:
private:
static void printEscaped(QTextStream &s, const QString &str);
static void writeTrie(QTextStream &stream, const Trie &t, const QString &indent);
- QStringList maybeReadTrie(Trie &trie, Utils::JsonObjectValue *config, const QString &path,
+ QStringList maybeReadTrie(Trie &trie, JsonObjectValue *config, const QString &path,
const QString &propertyName, bool required = false,
bool stripVersions = false);
@@ -80,4 +80,5 @@ public:
private:
QHash<Dialect,QmlBundle> m_bundles;
};
+
} // namespace QmlJS
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index feab41f24bf..7ceff0e78de 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -1364,71 +1364,6 @@ static bool shouldAvoidNonStrictEqualityCheck(const Value *lhs, const Value *rhs
return false;
}
-static bool equalIsAlwaysFalse(const Value *lhs, const Value *rhs)
-{
- if ((lhs->asNullValue() || lhs->asUndefinedValue())
- && (rhs->asNumberValue() || rhs->asBooleanValue() || rhs->asStringValue()))
- return true;
- return false;
-}
-
-static bool isIntegerValue(const Value *value)
-{
- if (value->asNumberValue() || value->asIntValue())
- return true;
- if (auto obj = value->asObjectValue())
- return obj->className() == "Number" || obj->className() == "int";
-
- return false;
-}
-
-static bool isStringValue(const Value *value)
-{
- if (value->asStringValue())
- return true;
- if (auto obj = value->asObjectValue())
- return obj->className() == "QString" || obj->className() == "string" || obj->className() == "String";
-
- return false;
-}
-
-static bool isBooleanValue(const Value *value)
-{
- if (value->asBooleanValue())
- return true;
- if (auto obj = value->asObjectValue())
- return obj->className() == "boolean" || obj->className() == "Boolean";
-
- return false;
-}
-
-static bool strictCompareConstant(const Value *lhs, const Value *rhs)
-{
- // attached properties and working at runtime cases may be undefined at evaluation time
- if (lhs->asUndefinedValue() || rhs->asUndefinedValue())
- return false;
- if (lhs->asUnknownValue() || rhs->asUnknownValue())
- return false;
- if (lhs->asFunctionValue() || rhs->asFunctionValue()) // function evaluation not implemented
- return false;
- if (isIntegerValue(lhs) && isIntegerValue(rhs))
- return false;
- if (isStringValue(lhs) && isStringValue(rhs))
- return false;
- if (isBooleanValue(lhs) && isBooleanValue(rhs))
- return false;
- if (lhs->asBooleanValue() && !rhs->asBooleanValue())
- return true;
- if (lhs->asNumberValue() && !rhs->asNumberValue())
- return true;
- if (lhs->asStringValue() && !rhs->asStringValue())
- return true;
- if (lhs->asObjectValue() && (!rhs->asObjectValue() || !rhs->asNullValue()))
- return true;
- return false;
-}
-
-
bool Check::visit(BinaryExpression *ast)
{
const QString source = _doc->source();
@@ -1458,18 +1393,6 @@ bool Check::visit(BinaryExpression *ast)
|| shouldAvoidNonStrictEqualityCheck(rhsValue, lhsValue)) {
addMessage(MaybeWarnEqualityTypeCoercion, ast->operatorToken);
}
- if (equalIsAlwaysFalse(lhsValue, rhsValue)
- || equalIsAlwaysFalse(rhsValue, lhsValue))
- addMessage(WarnLogicalValueDoesNotDependOnValues, ast->operatorToken);
- }
- if (ast->op == QSOperator::StrictEqual || ast->op == QSOperator::StrictNotEqual) {
- Evaluate eval(&_scopeChain);
- const Value *lhsValue = eval(ast->left);
- const Value *rhsValue = eval(ast->right);
- if (strictCompareConstant(lhsValue, rhsValue)
- || strictCompareConstant(rhsValue, lhsValue)) {
- addMessage(WarnLogicalValueDoesNotDependOnValues, ast->operatorToken);
- }
}
// check odd + ++ combinations
diff --git a/src/libs/qmljs/qmljsdialect.cpp b/src/libs/qmljs/qmljsdialect.cpp
index 58b9771bcd1..387c06a3ab9 100644
--- a/src/libs/qmljs/qmljsdialect.cpp
+++ b/src/libs/qmljs/qmljsdialect.cpp
@@ -192,7 +192,7 @@ QList<Dialect> Dialect::companionLanguages() const
<< Dialect::QmlQtQuick2Ui << Dialect::Qml;
break;
case Dialect::NoLanguage:
- return QList<Dialect>(); // return at least itself?
+ return {}; // return at least itself?
}
if (*this != Dialect::AnyLanguage)
langs << Dialect::AnyLanguage;
diff --git a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp
index 7716e77ed5a..36125539776 100644
--- a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp
+++ b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp
@@ -247,7 +247,7 @@ protected:
nameLit = translationUnit()->stringLiteral(nameAst->literal_token);
if (!nameLit) {
int line, column;
- translationUnit()->getTokenStartPosition(nameExp->firstToken(), &line, &column);
+ translationUnit()->getTokenPosition(nameExp->firstToken(), &line, &column);
_messages += Document::DiagnosticMessage(
Document::DiagnosticMessage::Warning,
_doc->filePath(),
@@ -308,7 +308,7 @@ protected:
if (packageName.isEmpty()) {
packageName = QmlJS::CppQmlTypes::defaultPackage;
int line, column;
- translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column);
+ translationUnit()->getTokenPosition(ast->firstToken(), &line, &column);
_messages += Document::DiagnosticMessage(
Document::DiagnosticMessage::Warning,
_doc->filePath(),
@@ -346,7 +346,7 @@ protected:
// we want to do lookup later, so also store the surrounding scope
int line, column;
- translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column);
+ translationUnit()->getTokenPosition(ast->firstToken(), &line, &column);
exportedType.scope = _doc->scopeAt(line, column);
if (typeId){
@@ -490,7 +490,7 @@ protected:
nameLit = translationUnit()->stringLiteral(nameAst->literal_token);
if (!nameLit) {
int line, column;
- translationUnit()->getTokenStartPosition(ast->expression_list->value->firstToken(), &line, &column);
+ translationUnit()->getTokenPosition(ast->expression_list->value->firstToken(), &line, &column);
_messages += Document::DiagnosticMessage(
Document::DiagnosticMessage::Warning,
_doc->filePath(),
@@ -504,9 +504,9 @@ protected:
contextProperty.name = QString::fromUtf8(nameLit->chars(), nameLit->size());
contextProperty.expression = stringOf(skipQVariant(ast->expression_list->next->value, translationUnit()));
// we want to do lookup later, so also store the line and column of the target scope
- translationUnit()->getTokenStartPosition(ast->firstToken(),
- &contextProperty.line,
- &contextProperty.column);
+ translationUnit()->getTokenPosition(ast->firstToken(),
+ &contextProperty.line,
+ &contextProperty.column);
_contextProperties += contextProperty;
@@ -827,7 +827,7 @@ FindExportedCppTypes::FindExportedCppTypes(const CPlusPlus::Snapshot &snapshot)
QStringList FindExportedCppTypes::operator()(const CPlusPlus::Document::Ptr &document)
{
- QTC_ASSERT(!document.isNull(), return QStringList());
+ QTC_ASSERT(!document.isNull(), return {});
m_contextProperties.clear();
m_exportedTypes.clear();
@@ -842,8 +842,7 @@ QStringList FindExportedCppTypes::operator()(const CPlusPlus::Document::Ptr &doc
FindExportsVisitor finder(document);
finder();
static const QString kindKey = QLatin1String("QmlJSTools.ExportedQmlTypesDiagnostic");
- CppModelManagerBase::trySetExtraDiagnostics(document->filePath().toString(), kindKey,
- finder.messages());
+ CppModelManagerBase::trySetExtraDiagnostics(document->filePath(), kindKey, finder.messages());
// if nothing was found, done
const QList<ContextProperty> contextPropertyDescriptions = finder.contextProperties();
diff --git a/src/libs/qmljs/qmljsicontextpane.h b/src/libs/qmljs/qmljsicontextpane.h
deleted file mode 100644
index 4bbc33a7d73..00000000000
--- a/src/libs/qmljs/qmljsicontextpane.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include <QObject>
-
-#include "qmljs_global.h"
-
-#include <qmljs/qmljsdocument.h>
-#include <qmljs/parser/qmljsastfwd_p.h>
-
-namespace TextEditor { class TextEditorWidget; }
-
-namespace QmlJS {
-
-class ScopeChain;
-
-class QMLJS_EXPORT IContextPane : public QObject
-{
- Q_OBJECT
-
-public:
- IContextPane(QObject *parent = nullptr) : QObject(parent) {}
- virtual ~IContextPane() {}
- virtual void apply(TextEditor::TextEditorWidget *editorWidget, Document::Ptr document, const ScopeChain *scopeChain, AST::Node *node, bool update, bool force = false) = 0;
- virtual void setEnabled(bool) = 0;
- virtual bool isAvailable(TextEditor::TextEditorWidget *editorWidget, Document::Ptr document, AST::Node *node) = 0;
- virtual QWidget* widget() = 0;
-signals:
- void closed();
-};
-
-} // namespace QmlJS
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 7a2cd6fa717..63e009607b9 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -1321,10 +1321,32 @@ const Function *Function::asFunction() const
// typing environment
////////////////////////////////////////////////////////////////////////////////
-CppQmlTypesLoader::BuiltinObjects CppQmlTypesLoader::defaultLibraryObjects;
-CppQmlTypesLoader::BuiltinObjects CppQmlTypesLoader::defaultQtObjects;
+CppQmlTypesLoader::BuiltinObjects sDefaultLibraryObjects;
+CppQmlTypesLoader::BuiltinObjects sDefaultQtObjects;
+std::function<void()> CppQmlTypesLoader::defaultObjectsInitializer;
-CppQmlTypesLoader::BuiltinObjects CppQmlTypesLoader::loadQmlTypes(const QFileInfoList &qmlTypeFiles, QStringList *errors, QStringList *warnings)
+CppQmlTypesLoader::BuiltinObjects &CppQmlTypesLoader::defaultQtObjects()
+{
+ if (defaultObjectsInitializer) {
+ const std::function<void()> init = defaultObjectsInitializer;
+ defaultObjectsInitializer = {};
+ init();
+ }
+ return sDefaultLibraryObjects;
+}
+CppQmlTypesLoader::BuiltinObjects &CppQmlTypesLoader::defaultLibraryObjects()
+{
+ if (defaultObjectsInitializer) {
+ const std::function<void()> init = defaultObjectsInitializer;
+ defaultObjectsInitializer = {};
+ init();
+ }
+ return sDefaultQtObjects;
+}
+
+CppQmlTypesLoader::BuiltinObjects CppQmlTypesLoader::loadQmlTypes(const QFileInfoList &qmlTypeFiles,
+ QStringList *errors,
+ QStringList *warnings)
{
QHash<QString, FakeMetaObject::ConstPtr> newObjects;
QStringList newDependencies;
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index c0a953d7bd8..8ca9f4ec26c 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -3,10 +3,11 @@
#pragma once
+#include "qmljsdocument.h"
+#include <qmljs/parser/qmljsastfwd_p.h>
#include <qmljs/qmljs_global.h>
#include <qmljs/qmljsconstants.h>
#include <qmljs/qmljsimportdependencies.h>
-#include <qmljs/parser/qmljsastfwd_p.h>
#include <languageutils/fakemetaobject.h>
@@ -689,8 +690,8 @@ public:
static BuiltinObjects loadQmlTypes(const QFileInfoList &qmltypesFiles,
QStringList *errors, QStringList *warnings);
- static BuiltinObjects defaultQtObjects;
- static BuiltinObjects defaultLibraryObjects;
+ static BuiltinObjects &defaultQtObjects();
+ static BuiltinObjects &defaultLibraryObjects();
// parses the contents of a qmltypes file and fills the newObjects map
static void parseQmlTypeDescriptions(const QByteArray &contents,
@@ -700,6 +701,8 @@ public:
QString *errorMessage,
QString *warningMessage,
const QString &fileName);
+
+ static std::function<void()> defaultObjectsInitializer;
};
class QMLJS_EXPORT FakeMetaObjectWithOrigin
@@ -1108,12 +1111,20 @@ class QMLJS_EXPORT CustomImportsProvider : public QObject
{
Q_OBJECT
public:
+ typedef QHash<const Document *, QSharedPointer<const Imports>> ImportsPerDocument;
explicit CustomImportsProvider(QObject *parent = nullptr);
virtual ~CustomImportsProvider();
static const QList<CustomImportsProvider *> allProviders();
- virtual QList<Import> imports(ValueOwner *valueOwner, const Document *context) const = 0;
+ virtual QList<Import> imports(ValueOwner *valueOwner,
+ const Document *context,
+ Snapshot *snapshot = nullptr) const = 0;
+ virtual void loadBuiltins([[maybe_unused]] ImportsPerDocument *importsPerDocument,
+ [[maybe_unused]] Imports *imports,
+ [[maybe_unused]] const Document *context,
+ [[maybe_unused]] ValueOwner *valueOwner,
+ [[maybe_unused]] Snapshot *snapshot) {}
};
} // namespace QmlJS
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index ed1c506df73..b837037b7c8 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -196,12 +196,12 @@ Context::ImportsPerDocument LinkPrivate::linkImports()
m_valueOwner->cppQmlTypes().load(QLatin1String("<builtins>"), m_builtins.metaObjects());
} else {
m_valueOwner->cppQmlTypes().load(QLatin1String("<defaults>"),
- CppQmlTypesLoader::defaultQtObjects);
+ CppQmlTypesLoader::defaultQtObjects());
}
// load library objects shipped with Creator
m_valueOwner->cppQmlTypes().load(QLatin1String("<defaultQt4>"),
- CppQmlTypesLoader::defaultLibraryObjects);
+ CppQmlTypesLoader::defaultLibraryObjects());
if (document) {
// do it on document first, to make sure import errors are shown
@@ -209,9 +209,16 @@ Context::ImportsPerDocument LinkPrivate::linkImports()
// Add custom imports for the opened document
for (const auto &provider : CustomImportsProvider::allProviders()) {
- const auto providerImports = provider->imports(m_valueOwner, document.data());
+ const auto providerImports = provider->imports(m_valueOwner,
+ document.data(),
+ &m_snapshot);
for (const auto &import : providerImports)
importCache.insert(ImportCacheKey(import.info), import);
+ provider->loadBuiltins(&importsPerDocument,
+ imports,
+ document.data(),
+ m_valueOwner,
+ &m_snapshot);
}
populateImportedTypes(imports, document);
@@ -656,14 +663,12 @@ void LinkPrivate::loadQmldirComponents(ObjectValue *import,
QSet<QString> importedTypes;
const auto components = libraryInfo.components();
for (const QmlDirParser::Component &component : components) {
- if (importedTypes.contains(component.typeName))
- continue;
-
ComponentVersion componentVersion(component.majorVersion, component.minorVersion);
if (version < componentVersion)
continue;
- importedTypes.insert(component.typeName);
+ if (!Utils::insert(importedTypes, component.typeName))
+ continue;
if (Document::Ptr importedDoc = m_snapshot.document(
libraryPath.pathAppended(component.fileName))) {
if (ObjectValue *v = importedDoc->bind()->rootObjectValue())
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
index 66a670d1b8a..fb0c806fe60 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
@@ -279,8 +279,9 @@ void ModelManagerInterface::loadQmlTypeDescriptionsInternal(const QString &resou
if (qmlTypesFiles.at(i).baseName() == QLatin1String("builtins")) {
QFileInfoList list;
list.append(qmlTypesFiles.at(i));
- CppQmlTypesLoader::defaultQtObjects =
- CppQmlTypesLoader::loadQmlTypes(list, &errors, &warnings);
+ CppQmlTypesLoader::defaultQtObjects() = CppQmlTypesLoader::loadQmlTypes(list,
+ &errors,
+ &warnings);
qmlTypesFiles.removeAt(i);
break;
}
@@ -290,7 +291,7 @@ void ModelManagerInterface::loadQmlTypeDescriptionsInternal(const QString &resou
const CppQmlTypesLoader::BuiltinObjects objs =
CppQmlTypesLoader::loadQmlTypes(qmlTypesFiles, &errors, &warnings);
for (auto it = objs.cbegin(); it != objs.cend(); ++it)
- CppQmlTypesLoader::defaultLibraryObjects.insert(it.key(), it.value());
+ CppQmlTypesLoader::defaultLibraryObjects().insert(it.key(), it.value());
for (const QString &error : std::as_const(errors))
writeMessageInternal(error);
@@ -734,10 +735,9 @@ static void findNewImplicitImports(const Document::Ptr &doc,
// scan files that could be implicitly imported
// it's important we also do this for JS files, otherwise the isEmpty check will fail
if (snapshot.documentsInDirectory(doc->path()).isEmpty()) {
- if (!scannedPaths->contains(doc->path())) {
+ if (Utils::insert(*scannedPaths, doc->path())) {
*importedFiles += filesInDirectoryForLanguages(doc->path(),
doc->language().companionLanguages());
- scannedPaths->insert(doc->path());
}
}
}
@@ -757,11 +757,10 @@ static void findNewFileImports(const Document::Ptr &doc,
*importedFiles += importPath;
} else if (import.type() == ImportType::Directory) {
if (snapshot.documentsInDirectory(importPath).isEmpty()) {
- if (!scannedPaths->contains(importPath)) {
+ if (Utils::insert(*scannedPaths, importPath)) {
*importedFiles
+= filesInDirectoryForLanguages(importPath,
doc->language().companionLanguages());
- scannedPaths->insert(importPath);
}
}
} else if (import.type() == ImportType::QrcFile) {
@@ -890,10 +889,9 @@ static bool findNewQmlLibraryInPath(const Utils::FilePath &path,
if (!component.fileName.isEmpty()) {
const FilePath componentFile = path.pathAppended(component.fileName);
const FilePath path = componentFile.absolutePath().cleanPath();
- if (!scannedPaths->contains(path)) {
+ if (Utils::insert(*scannedPaths, path)) {
*importedFiles += filesInDirectoryForLanguages(path, Dialect(Dialect::AnyLanguage)
.companionLanguages());
- scannedPaths->insert(path);
}
}
}
@@ -904,7 +902,7 @@ static bool findNewQmlLibraryInPath(const Utils::FilePath &path,
static FilePath modulePath(const ImportInfo &import, const FilePaths &paths)
{
if (!import.version().isValid())
- return FilePath();
+ return {};
const FilePaths modPaths = modulePaths(import.name(), import.version().toString(), paths);
return modPaths.value(0); // first is best match
@@ -1110,10 +1108,9 @@ void ModelManagerInterface::importScanAsync(QPromise<void> &promise, const Worki
QMutexLocker l(&modelManager->m_mutex);
for (const auto &path : paths) {
Utils::FilePath cPath = path.path().cleanPath();
- if (!forceRescan && modelManager->m_scannedPaths.contains(cPath))
+ if (!forceRescan && !Utils::insert(modelManager->m_scannedPaths, cPath))
continue;
pathsToScan.append({cPath, 0, path.language()});
- modelManager->m_scannedPaths.insert(cPath);
}
}
const int maxScanDepth = 5;
@@ -1370,13 +1367,12 @@ void ModelManagerInterface::startCppQmlTypeUpdate()
return;
}
- CPlusPlus::CppModelManagerBase *cppModelManager =
- CPlusPlus::CppModelManagerBase::instance();
- if (!cppModelManager)
+ if (!CPlusPlus::CppModelManagerBase::hasSnapshots())
return;
m_cppQmlTypesUpdater = Utils::asyncRun(&ModelManagerInterface::updateCppQmlTypes, this,
- cppModelManager->snapshot(), m_queuedCppDocuments);
+ CPlusPlus::CppModelManagerBase::snapshot(),
+ m_queuedCppDocuments);
m_queuedCppDocuments.clear();
}
diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp
index 761df90ddcd..04913de3ddc 100644
--- a/src/libs/qmljs/qmljsplugindumper.cpp
+++ b/src/libs/qmljs/qmljsplugindumper.cpp
@@ -387,14 +387,14 @@ Utils::FilePath PluginDumper::buildQmltypesPath(const QString &name) const
m_modelManager->importPathsNames());
if (paths.isEmpty())
- return Utils::FilePath();
+ return {};
for (const Utils::FilePath &path : paths) {
auto qmltypes = path.dirEntries(FileFilter(QStringList{"*.qmltypes"}, QDir::Files));
if (!qmltypes.isEmpty())
return qmltypes.first();
}
- return Utils::FilePath();
+ return {};
}
/*!
diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.cpp b/src/libs/qmljs/qmljsstaticanalysismessage.cpp
index 98bff3a4b69..5b15e694281 100644
--- a/src/libs/qmljs/qmljsstaticanalysismessage.cpp
+++ b/src/libs/qmljs/qmljsstaticanalysismessage.cpp
@@ -229,8 +229,6 @@ StaticAnalysisMessages::StaticAnalysisMessages()
Tr::tr("Hit maximum recursion limit when visiting AST."));
newMsg(ErrTypeIsInstantiatedRecursively, Error,
Tr::tr("Type cannot be instantiated recursively (%1)."), 1);
- newMsg(WarnLogicalValueDoesNotDependOnValues, Warning,
- Tr::tr("Logical value does not depend on actual values."));
newMsg(ErrToManyComponentChildren, Error,
Tr::tr("Components are only allowed to have a single child element."));
newMsg(WarnComponentRequiresChildren, Warning,
diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.h b/src/libs/qmljs/qmljsstaticanalysismessage.h
index 01b3b52d698..97dd95c5eb9 100644
--- a/src/libs/qmljs/qmljsstaticanalysismessage.h
+++ b/src/libs/qmljs/qmljsstaticanalysismessage.h
@@ -109,7 +109,6 @@ enum Type {
ErrShorterStringValueExpected = 322,
ErrInvalidArrayValueLength = 323,
ErrHitMaximumRecursion = 324,
- WarnLogicalValueDoesNotDependOnValues = 325,
ErrToManyComponentChildren = 326,
WarnComponentRequiresChildren = 327,
WarnDuplicateImport = 400,
diff --git a/src/libs/qmlpuppetcommunication/container/sharedmemory_unix.cpp b/src/libs/qmlpuppetcommunication/container/sharedmemory_unix.cpp
index fce49841803..76b93a3c4f9 100644
--- a/src/libs/qmlpuppetcommunication/container/sharedmemory_unix.cpp
+++ b/src/libs/qmlpuppetcommunication/container/sharedmemory_unix.cpp
@@ -15,7 +15,7 @@
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MACOS
#include <sys/posix_shm.h>
#endif
#include <fcntl.h>
@@ -326,7 +326,7 @@ bool SharedMemory::createInternal(QSharedMemory::AccessMode mode, size_t size)
{
detachInternal();
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MACOS
if (m_fileHandle > -1 && m_createdByMe) {
close(m_fileHandle);
shm_unlink(m_nativeKey.constData());
diff --git a/src/libs/qt-breakpad/qtcrashhandler/mainwidget.cpp b/src/libs/qt-breakpad/qtcrashhandler/mainwidget.cpp
index cdf921e8f16..e70e316a9d5 100644
--- a/src/libs/qt-breakpad/qtcrashhandler/mainwidget.cpp
+++ b/src/libs/qt-breakpad/qtcrashhandler/mainwidget.cpp
@@ -4,7 +4,6 @@
#include "mainwidget.h"
#include "ui_mainwidget.h"
-#include <app/app_version.h>
#include <QApplication>
#include <QDateTime>
@@ -23,7 +22,8 @@ MainWidget::MainWidget(QWidget *parent) :
{
ui->setupUi(this);
- ui->mainWidgetTopLabel.setText(tr("%1 has crashed").arg(Core::Constants::IDE_DISPLAY_NAME));
+ const QString applicationName = QApplication::arguments().at(3);
+ ui->mainWidgetTopLabel.setText(tr("%1 has crashed").arg(applicationName));
connect(ui->restartButton, &QAbstractButton::clicked, this, &MainWidget::restartApplication);
connect(ui->quitButton, &QAbstractButton::clicked, this, &MainWidget::quitApplication);
diff --git a/src/libs/qtcreatorcdbext/CMakeLists.txt b/src/libs/qtcreatorcdbext/CMakeLists.txt
index 8c95cb400b8..07a5493de34 100644
--- a/src/libs/qtcreatorcdbext/CMakeLists.txt
+++ b/src/libs/qtcreatorcdbext/CMakeLists.txt
@@ -12,6 +12,7 @@ if (NOT QT_CREATOR_API_DEFINED)
# standalone build
include(QtCreatorIDEBranding)
include(QtCreatorAPI)
+ qtc_handle_compiler_cache_support()
endif()
if (NOT WIN32 OR NOT MSVC)
diff --git a/src/libs/solutions/CMakeLists.txt b/src/libs/solutions/CMakeLists.txt
index 2a47fbee5fb..67630f067c7 100644
--- a/src/libs/solutions/CMakeLists.txt
+++ b/src/libs/solutions/CMakeLists.txt
@@ -1,2 +1,3 @@
add_subdirectory(spinner)
add_subdirectory(tasking)
+add_subdirectory(terminal)
diff --git a/src/libs/solutions/solutions.qbs b/src/libs/solutions/solutions.qbs
index 3978235666e..d166c43f439 100644
--- a/src/libs/solutions/solutions.qbs
+++ b/src/libs/solutions/solutions.qbs
@@ -4,5 +4,6 @@ Project {
references: [
"spinner/spinner.qbs",
"tasking/tasking.qbs",
+ "terminal/terminal.qbs",
].concat(project.additionalLibs)
}
diff --git a/src/libs/solutions/spinner/icons/spinner_large.png b/src/libs/solutions/spinner/icons/spinner_large.png
index c24ff1b77cf..0a3f894397b 100644
--- a/src/libs/solutions/spinner/icons/spinner_large.png
+++ b/src/libs/solutions/spinner/icons/spinner_large.png
Binary files differ
diff --git a/src/libs/solutions/spinner/icons/spinner_large@2x.png b/src/libs/solutions/spinner/icons/spinner_large@2x.png
new file mode 100644
index 00000000000..910a11bc756
--- /dev/null
+++ b/src/libs/solutions/spinner/icons/spinner_large@2x.png
Binary files differ
diff --git a/src/libs/solutions/spinner/icons/spinner_medium.png b/src/libs/solutions/spinner/icons/spinner_medium.png
index d64cc514e1b..6cb735f18ac 100644
--- a/src/libs/solutions/spinner/icons/spinner_medium.png
+++ b/src/libs/solutions/spinner/icons/spinner_medium.png
Binary files differ
diff --git a/src/libs/solutions/spinner/icons/spinner_medium@2x.png b/src/libs/solutions/spinner/icons/spinner_medium@2x.png
new file mode 100644
index 00000000000..3cd93d63e24
--- /dev/null
+++ b/src/libs/solutions/spinner/icons/spinner_medium@2x.png
Binary files differ
diff --git a/src/libs/solutions/spinner/icons/spinner_small.png b/src/libs/solutions/spinner/icons/spinner_small.png
index 254e9c82fc0..cd6e92a7370 100644
--- a/src/libs/solutions/spinner/icons/spinner_small.png
+++ b/src/libs/solutions/spinner/icons/spinner_small.png
Binary files differ
diff --git a/src/libs/solutions/spinner/icons/spinner_small@2x.png b/src/libs/solutions/spinner/icons/spinner_small@2x.png
new file mode 100644
index 00000000000..36821a92e19
--- /dev/null
+++ b/src/libs/solutions/spinner/icons/spinner_small@2x.png
Binary files differ
diff --git a/src/libs/solutions/spinner/spinner.cpp b/src/libs/solutions/spinner/spinner.cpp
index 2dc241db7e1..114fea537da 100644
--- a/src/libs/solutions/spinner/spinner.cpp
+++ b/src/libs/solutions/spinner/spinner.cpp
@@ -3,7 +3,9 @@
#include "spinner.h"
+#include <QApplication>
#include <QEvent>
+#include <QIcon>
#include <QPainter>
#include <QTimer>
#include <QWidget>
@@ -81,7 +83,7 @@ private:
int m_rotationStep = 45;
int m_rotation = 0;
QTimer m_timer;
- QPixmap m_pixmap;
+ mutable QPixmap m_pixmap;
UpdateCallback m_callback;
};
@@ -98,6 +100,18 @@ static QString imageFileNameForSpinnerSize(SpinnerSize size)
return {};
}
+static QPixmap themedPixmapForSpinnerSize(SpinnerSize size, qreal dpr)
+{
+ QImage mask(qt_findAtNxFile(imageFileNameForSpinnerSize(size), dpr));
+ mask.invertPixels();
+ QImage themedImage(mask.size(), QImage::Format_ARGB32);
+ themedImage.fill(qApp->palette().text().color());
+ themedImage.setAlphaChannel(mask);
+ QPixmap themedPixmap = QPixmap::fromImage(themedImage);
+ themedPixmap.setDevicePixelRatio(mask.devicePixelRatio());
+ return themedPixmap;
+}
+
SpinnerPainter::SpinnerPainter(SpinnerSize size)
{
m_timer.setSingleShot(false);
@@ -114,11 +128,14 @@ void SpinnerPainter::setSize(SpinnerSize size)
m_size = size;
m_rotationStep = size == SpinnerSize::Small ? 45 : 30;
m_timer.setInterval(size == SpinnerSize::Small ? 100 : 80);
- m_pixmap = QPixmap(imageFileNameForSpinnerSize(size));
+ m_pixmap = themedPixmapForSpinnerSize(size, qApp->devicePixelRatio());
}
void SpinnerPainter::paint(QPainter &painter, const QRect &rect) const
{
+ const qreal dpr = painter.device()->devicePixelRatioF();
+ if (!qFuzzyCompare(m_pixmap.devicePixelRatio(), dpr))
+ m_pixmap = themedPixmapForSpinnerSize(m_size, dpr);
painter.save();
painter.setRenderHint(QPainter::SmoothPixmapTransform);
QPoint translate(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2);
diff --git a/src/libs/solutions/spinner/spinner.h b/src/libs/solutions/spinner/spinner.h
index 86dfbee6ebd..16ec6bb71db 100644
--- a/src/libs/solutions/spinner/spinner.h
+++ b/src/libs/solutions/spinner/spinner.h
@@ -13,7 +13,7 @@ namespace SpinnerSolution {
Q_NAMESPACE_EXPORT(SPINNER_EXPORT)
enum class SpinnerSize { Small, Medium, Large };
-Q_ENUM_NS(SpinnerSize);
+Q_ENUM_NS(SpinnerSize)
// TODO: SpinnerOverlay and SpinnerWidget?
diff --git a/src/libs/solutions/spinner/spinner.qbs b/src/libs/solutions/spinner/spinner.qbs
index cd830d107ec..d02858d0484 100644
--- a/src/libs/solutions/spinner/spinner.qbs
+++ b/src/libs/solutions/spinner/spinner.qbs
@@ -1,6 +1,8 @@
QtcLibrary {
name: "Spinner"
- Depends { name: "Qt"; submodules: ["core", "widgets"] }
+
+ Depends { name: "Qt.widgets" }
+
cpp.defines: base.concat("SPINNER_LIBRARY")
files: [
@@ -9,5 +11,10 @@ QtcLibrary {
"spinner.qrc",
"spinner_global.h",
]
+
+ Export {
+ Depends { name: "cpp" }
+ cpp.includePaths: ".."
+ }
}
diff --git a/src/libs/solutions/spinner/spinner.qrc b/src/libs/solutions/spinner/spinner.qrc
index 5ad85953e8d..0b8a980272e 100644
--- a/src/libs/solutions/spinner/spinner.qrc
+++ b/src/libs/solutions/spinner/spinner.qrc
@@ -1,7 +1,10 @@
<RCC>
<qresource prefix="/" >
<file>icons/spinner_large.png</file>
+ <file>icons/spinner_large@2x.png</file>
<file>icons/spinner_medium.png</file>
+ <file>icons/spinner_medium@2x.png</file>
<file>icons/spinner_small.png</file>
+ <file>icons/spinner_small@2x.png</file>
</qresource>
</RCC>
diff --git a/src/libs/solutions/tasking/barrier.h b/src/libs/solutions/tasking/barrier.h
index 64a59ec8733..71081209f4d 100644
--- a/src/libs/solutions/tasking/barrier.h
+++ b/src/libs/solutions/tasking/barrier.h
@@ -41,11 +41,7 @@ public:
void start() final { task()->start(); }
};
-} // namespace Tasking
-
-TASKING_DECLARE_TASK(BarrierTask, Tasking::BarrierTaskAdapter);
-
-namespace Tasking {
+using BarrierTask = CustomTask<BarrierTaskAdapter>;
template <int Limit = 1>
class SharedBarrier
@@ -70,28 +66,26 @@ using MultiBarrier = TreeStorage<SharedBarrier<Limit>>;
// alias template deduction only available with C++20.
using SingleBarrier = MultiBarrier<1>;
-class TASKING_EXPORT WaitForBarrierTask : public BarrierTask
+template <int Limit>
+GroupItem waitForBarrierTask(const MultiBarrier<Limit> &sharedBarrier)
{
-public:
- template <int Limit>
- WaitForBarrierTask(const MultiBarrier<Limit> &sharedBarrier)
- : BarrierTask([sharedBarrier](Barrier &barrier) {
- SharedBarrier<Limit> *activeBarrier = sharedBarrier.activeStorage();
- if (!activeBarrier) {
- qWarning("The barrier referenced from WaitForBarrier element "
- "is not reachable in the running tree. "
- "It is possible that no barrier was added to the tree, "
- "or the storage is not reachable from where it is referenced. "
- "The WaitForBarrier task finishes with an error. ");
- return SetupResult::StopWithError;
- }
- Barrier *activeSharedBarrier = activeBarrier->barrier();
- const std::optional<bool> result = activeSharedBarrier->result();
- if (result.has_value())
- return result.value() ? SetupResult::StopWithDone : SetupResult::StopWithError;
- QObject::connect(activeSharedBarrier, &Barrier::done, &barrier, &Barrier::stopWithResult);
- return SetupResult::Continue;
- }) {}
-};
+ return BarrierTask([sharedBarrier](Barrier &barrier) {
+ SharedBarrier<Limit> *activeBarrier = sharedBarrier.activeStorage();
+ if (!activeBarrier) {
+ qWarning("The barrier referenced from WaitForBarrier element "
+ "is not reachable in the running tree. "
+ "It is possible that no barrier was added to the tree, "
+ "or the storage is not reachable from where it is referenced. "
+ "The WaitForBarrier task finishes with an error. ");
+ return SetupResult::StopWithError;
+ }
+ Barrier *activeSharedBarrier = activeBarrier->barrier();
+ const std::optional<bool> result = activeSharedBarrier->result();
+ if (result.has_value())
+ return result.value() ? SetupResult::StopWithDone : SetupResult::StopWithError;
+ QObject::connect(activeSharedBarrier, &Barrier::done, &barrier, &Barrier::stopWithResult);
+ return SetupResult::Continue;
+ });
+}
} // namespace Tasking
diff --git a/src/libs/solutions/tasking/concurrentcall.h b/src/libs/solutions/tasking/concurrentcall.h
index d7799159447..7c0d1cf47ef 100644
--- a/src/libs/solutions/tasking/concurrentcall.h
+++ b/src/libs/solutions/tasking/concurrentcall.h
@@ -95,6 +95,7 @@ private:
std::unique_ptr<QFutureWatcher<ResultType>> m_watcher;
};
-} // namespace Tasking
+template <typename T>
+using ConcurrentCallTask = CustomTask<ConcurrentCallTaskAdapter<T>>;
-TASKING_DECLARE_TEMPLATE_TASK(ConcurrentCallTask, Tasking::ConcurrentCallTaskAdapter);
+} // namespace Tasking
diff --git a/src/libs/solutions/tasking/networkquery.h b/src/libs/solutions/tasking/networkquery.h
index faf482df90d..0cac720584a 100644
--- a/src/libs/solutions/tasking/networkquery.h
+++ b/src/libs/solutions/tasking/networkquery.h
@@ -50,6 +50,6 @@ public:
void start() final { task()->start(); }
};
-} // namespace Tasking
+using NetworkQueryTask = CustomTask<NetworkQueryTaskAdapter>;
-TASKING_DECLARE_TASK(NetworkQueryTask, Tasking::NetworkQueryTaskAdapter);
+} // namespace Tasking
diff --git a/src/libs/solutions/tasking/tasking.qbs b/src/libs/solutions/tasking/tasking.qbs
index fa0a5ebacc9..fba42b10b1d 100644
--- a/src/libs/solutions/tasking/tasking.qbs
+++ b/src/libs/solutions/tasking/tasking.qbs
@@ -1,6 +1,8 @@
QtcLibrary {
name: "Tasking"
- Depends { name: "Qt"; submodules: ["concurrent", "core", "network"] }
+
+ Depends { name: "Qt"; submodules: ["concurrent", "network"] }
+
cpp.defines: base.concat("TASKING_LIBRARY")
files: [
@@ -13,5 +15,10 @@ QtcLibrary {
"tasktree.cpp",
"tasktree.h",
]
+
+ Export {
+ Depends { name: "cpp" }
+ cpp.includePaths: ["..", "../.."]
+ }
}
diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp
index 4e6b40ccc1e..5dc743f1324 100644
--- a/src/libs/solutions/tasking/tasktree.cpp
+++ b/src/libs/solutions/tasking/tasktree.cpp
@@ -6,6 +6,7 @@
#include <QEventLoop>
#include <QFutureWatcher>
#include <QPromise>
+#include <QPointer>
#include <QSet>
#include <QTimer>
@@ -105,6 +106,19 @@ private:
implement the start() method, and emit the done() signal when the task is finished.
Use task() to access the associated \c Task instance.
+ To use your task adapter inside the task tree, create an alias to the
+ Tasking::CustomTask template passing your task adapter as a template parameter:
+ \code
+ // Defines actual worker
+ class Worker {...};
+
+ // Adapts Worker's interface to work with task tree
+ class WorkerTaskAdapter : public TaskAdapter<Worker> {...};
+
+ // Defines WorkerTask as a new task tree element
+ using WorkerTask = CustomTask<WorkerTaskAdapter>;
+ \endcode
+
For more information on implementing the custom task adapters, refer to \l {Task Adapters}.
\sa start(), done(), task()
@@ -333,8 +347,8 @@ private:
The CustomTask class template is used inside TaskTree for describing custom task items.
- Custom task names are aliased with unique names inside the \l Tasking namespace
- via the TASKING_DECLARE_TASK or TASKING_DECLARE_TEMPLATE_TASK macros.
+ Custom task names are aliased with unique names using the CustomTask template
+ with a given TaskAdapter subclass as a template parameter.
For example, \c ConcurrentCallTask<T> is an alias to the CustomTask that is defined
to work with \c ConcurrentCall<T> as an associated task class.
The following table contains all the built-in tasks and their associated task classes:
@@ -502,26 +516,6 @@ private:
*/
/*!
- \macro TASKING_DECLARE_TASK(CustomTaskName, TaskAdapterClass)
- \relates Tasking
-
- Registers the new custom task type under a \a CustomTaskName name inside the
- Tasking namespace for the passed \a TaskAdapterClass adapter class.
-
- For more information on implementing the custom task adapters, refer to \l {Task Adapters}.
-*/
-
-/*!
- \macro TASKING_DECLARE_TEMPLATE_TASK(CustomTaskName, TaskAdapterClass)
- \relates Tasking
-
- Registers the new custom task template type under a \a CustomTaskName name inside the
- Tasking namespace for the passed \a TaskAdapterClass adapter class template.
-
- For more information on implementing the custom task adapters, refer to \l {Task Adapters}.
-*/
-
-/*!
\enum Tasking::WorkflowPolicy
This enum describes the possible behavior of the Group element when any group's child task
@@ -2117,8 +2111,8 @@ void TaskNode::invokeEndHandler(bool success)
TreeStorage<CopyStorage> storage;
const Group root = ...; // storage placed inside root's group and inside handlers
TaskTree taskTree(root);
- auto initStorage = [](CopyStorage *storage){
- storage->content = "initial content";
+ auto initStorage = [](CopyStorage &storage){
+ storage.content = "initial content";
};
taskTree.onStorageSetup(storage, initStorage);
taskTree.start();
@@ -2137,8 +2131,8 @@ void TaskNode::invokeEndHandler(bool success)
TreeStorage<CopyStorage> storage;
const Group root = ...; // storage placed inside root's group and inside handlers
TaskTree taskTree(root);
- auto collectStorage = [](CopyStorage *storage){
- qDebug() << "final content" << storage->content;
+ auto collectStorage = [](const CopyStorage &storage){
+ qDebug() << "final content" << storage.content;
};
taskTree.onStorageDone(storage, collectStorage);
taskTree.start();
@@ -2156,10 +2150,10 @@ void TaskNode::invokeEndHandler(bool success)
asynchronous task:
\code
- class TimeoutTaskAdapter : public Tasking::TaskAdapter<QTimer>
+ class TimerTaskAdapter : public TaskAdapter<QTimer>
{
public:
- TimeoutTaskAdapter() {
+ TimerTaskAdapter() {
task()->setSingleShot(true);
task()->setInterval(1000);
connect(task(), &QTimer::timeout, this, [this] { emit done(true); });
@@ -2168,7 +2162,7 @@ void TaskNode::invokeEndHandler(bool success)
void start() final { task()->start(); }
};
- TASKING_DECLARE_TASK(TimeoutTask, TimeoutTaskAdapter);
+ using TimerTask = CustomTask<TimerTaskAdapter>;
\endcode
You must derive the custom adapter from the TaskAdapter class template
@@ -2177,28 +2171,27 @@ void TaskNode::invokeEndHandler(bool success)
later as an argument to the task's handlers. The instance of this class
parameter automatically becomes a member of the TaskAdapter template, and is
accessible through the TaskAdapter::task() method. The constructor
- of TimeoutTaskAdapter initially configures the QTimer object and connects
- to the QTimer::timeout signal. When the signal is triggered, TimeoutTaskAdapter
+ of TimerTaskAdapter initially configures the QTimer object and connects
+ to the QTimer::timeout signal. When the signal is triggered, TimerTaskAdapter
emits the \c done(true) signal to inform the task tree that the task finished
successfully. If it emits \c done(false), the task finished with an error.
The TaskAdapter::start() method starts the timer.
- To make QTimer accessible inside TaskTree under the \e TimeoutTask name,
- register it with TASKING_DECLARE_TASK(TimeoutTask, TimeoutTaskAdapter).
- TimeoutTask becomes a new task type inside Tasking namespace, using TimeoutTaskAdapter.
+ To make QTimer accessible inside TaskTree under the \e TimerTask name,
+ define TimerTask to be an alias to the Tasking::CustomTask<TimerTaskAdapter>.
+ TimerTask becomes a new task type, using TimerTaskAdapter.
The new task type is now registered, and you can use it in TaskTree:
\code
- const auto onTimeoutSetup = [](QTimer &task) {
+ const auto onTimerSetup = [](QTimer &task) {
task.setInterval(2000);
};
- const auto onTimeoutDone = [](const QTimer &task) {
- qDebug() << "timeout triggered";
+ const auto onTimerDone = [](const QTimer &task) {
+ qDebug() << "timer triggered";
};
-
const Group root {
- TimeoutTask(onTimeoutSetup, onTimeoutDone)
+ TimerTask(onTimerSetup, onTimerDone)
};
\endcode
@@ -2537,7 +2530,7 @@ int TaskTree::progressValue() const
Installs a storage setup \a handler for the \a storage to pass the initial data
dynamically to the running task tree.
- The \c StorageHandler takes the pointer to the \c StorageStruct instance:
+ The \c StorageHandler takes a reference to the \c StorageStruct instance:
\code
static void save(const QString &fileName, const QByteArray &array) { ... }
@@ -2554,8 +2547,8 @@ int TaskTree::progressValue() const
};
TaskTree taskTree(root);
- auto initStorage = [](QByteArray *storage){
- *storage = "initial content";
+ auto initStorage = [](QByteArray &storage){
+ storage = "initial content";
};
taskTree.onStorageSetup(storage, initStorage);
taskTree.start();
@@ -2575,10 +2568,10 @@ int TaskTree::progressValue() const
/*!
\fn template <typename StorageStruct, typename StorageHandler> void TaskTree::onStorageDone(const TreeStorage<StorageStruct> &storage, StorageHandler &&handler)
- Installs a storage done \a handler for the \a storage to retrie the final data
+ Installs a storage done \a handler for the \a storage to retrieve the final data
dynamically from the running task tree.
- The \c StorageHandler takes the pointer to the \c StorageStruct instance:
+ The \c StorageHandler takes a const reference to the \c StorageStruct instance:
\code
static QByteArray load(const QString &fileName) { ... }
@@ -2598,8 +2591,8 @@ int TaskTree::progressValue() const
};
TaskTree taskTree(root);
- auto collectStorage = [](QByteArray *storage){
- qDebug() << "final content" << *storage;
+ auto collectStorage = [](const QByteArray &storage){
+ qDebug() << "final content" << storage;
};
taskTree.onStorageDone(storage, collectStorage);
taskTree.start();
diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h
index 88f89ef0c51..5e1226eb2c4 100644
--- a/src/libs/solutions/tasking/tasktree.h
+++ b/src/libs/solutions/tasking/tasktree.h
@@ -33,6 +33,9 @@ private:
template <typename Task> friend class TaskAdapter;
friend class TaskNode;
TaskInterface() = default;
+#ifdef Q_QDOC
+protected:
+#endif
virtual void start() = 0;
};
@@ -41,14 +44,13 @@ class TASKING_EXPORT TreeStorageBase
public:
bool isValid() const;
-protected:
+private:
using StorageConstructor = std::function<void *(void)>;
using StorageDestructor = std::function<void(void *)>;
TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor);
void *activeStorageVoid() const;
-private:
int createStorage() const;
void deleteStorage(int id) const;
void activateStorage(int id) const;
@@ -71,13 +73,15 @@ private:
int m_storageCounter = 0;
};
QSharedPointer<StorageData> m_storageData;
+
+ template <typename StorageStruct> friend class TreeStorage;
friend ExecutionContextActivator;
friend TaskContainer;
friend TaskTreePrivate;
};
template <typename StorageStruct>
-class TreeStorage : public TreeStorageBase
+class TreeStorage final : public TreeStorageBase
{
public:
TreeStorage() : TreeStorageBase(TreeStorage::ctor(), TreeStorage::dtor()) {}
@@ -190,7 +194,7 @@ protected:
static GroupItem parallelLimit(int limit) { return GroupItem({{}, limit}); }
static GroupItem workflowPolicy(WorkflowPolicy policy) { return GroupItem({{}, {}, policy}); }
static GroupItem withTimeout(const GroupItem &item, std::chrono::milliseconds timeout,
- const GroupEndHandler &handler = {});
+ const GroupEndHandler &handler = {});
private:
Type m_type = Type::Group;
@@ -200,7 +204,7 @@ private:
TaskHandler m_taskHandler;
};
-class TASKING_EXPORT Group : public GroupItem
+class TASKING_EXPORT Group final : public GroupItem
{
public:
Group(const QList<GroupItem> &children) { addChildren(children); }
@@ -267,23 +271,22 @@ TASKING_EXPORT extern const GroupItem stopOnFinished;
TASKING_EXPORT extern const GroupItem finishAllAndDone;
TASKING_EXPORT extern const GroupItem finishAllAndError;
-class TASKING_EXPORT Storage : public GroupItem
+class TASKING_EXPORT Storage final : public GroupItem
{
public:
Storage(const TreeStorageBase &storage) : GroupItem(storage) { }
};
// Synchronous invocation. Similarly to Group - isn't counted as a task inside taskCount()
-class TASKING_EXPORT Sync : public Group
+class TASKING_EXPORT Sync final : public GroupItem
{
-
public:
template<typename Function>
- Sync(Function &&function) : Group(init(std::forward<Function>(function))) {}
+ Sync(Function &&function) { addChildren({init(std::forward<Function>(function))}); }
private:
template<typename Function>
- static QList<GroupItem> init(Function &&function) {
+ static GroupItem init(Function &&function) {
constexpr bool isInvocable = std::is_invocable_v<std::decay_t<Function>>;
static_assert(isInvocable,
"Sync element: The synchronous function can't take any arguments.");
@@ -292,10 +295,10 @@ private:
static_assert(isBool || isVoid,
"Sync element: The synchronous function has to return void or bool.");
if constexpr (isBool) {
- return {onGroupSetup([function] { return function() ? SetupResult::StopWithDone
- : SetupResult::StopWithError; })};
+ return onGroupSetup([function] { return function() ? SetupResult::StopWithDone
+ : SetupResult::StopWithError; });
}
- return {onGroupSetup([function] { function(); return SetupResult::StopWithDone; })};
+ return onGroupSetup([function] { function(); return SetupResult::StopWithDone; });
};
};
@@ -314,10 +317,13 @@ private:
};
template <typename Adapter>
-class CustomTask : public GroupItem
+class CustomTask final : public GroupItem
{
public:
using Task = typename Adapter::Type;
+ static_assert(std::is_base_of_v<TaskAdapter<Task>, Adapter>,
+ "The Adapter type for the CustomTask<Adapter> needs to be derived from "
+ "TaskAdapter<Task>.");
using EndHandler = std::function<void(const Task &)>;
static Adapter *createAdapter() { return new Adapter; }
CustomTask() : GroupItem({&createAdapter}) {}
@@ -407,11 +413,21 @@ public:
template <typename StorageStruct, typename StorageHandler>
void onStorageSetup(const TreeStorage<StorageStruct> &storage, StorageHandler &&handler) {
+ constexpr bool isInvokable = std::is_invocable_v<std::decay_t<StorageHandler>,
+ StorageStruct &>;
+ static_assert(isInvokable,
+ "Storage setup handler needs to take (Storage &) as an argument. "
+ "The passed handler doesn't fulfill these requirements.");
setupStorageHandler(storage,
wrapHandler<StorageStruct>(std::forward<StorageHandler>(handler)), {});
}
template <typename StorageStruct, typename StorageHandler>
void onStorageDone(const TreeStorage<StorageStruct> &storage, StorageHandler &&handler) {
+ constexpr bool isInvokable = std::is_invocable_v<std::decay_t<StorageHandler>,
+ const StorageStruct &>;
+ static_assert(isInvokable,
+ "Storage done handler needs to take (const Storage &) as an argument. "
+ "The passed handler doesn't fulfill these requirements.");
setupStorageHandler(storage,
{}, wrapHandler<StorageStruct>(std::forward<StorageHandler>(handler)));
}
@@ -431,7 +447,7 @@ private:
StorageVoidHandler wrapHandler(StorageHandler &&handler) {
return [=](void *voidStruct) {
StorageStruct *storageStruct = static_cast<StorageStruct *>(voidStruct);
- std::invoke(handler, storageStruct);
+ std::invoke(handler, *storageStruct);
};
}
@@ -457,16 +473,7 @@ private:
std::optional<int> m_timerId;
};
-} // namespace Tasking
-
-#define TASKING_DECLARE_TASK(CustomTaskName, TaskAdapterClass)\
-namespace Tasking { using CustomTaskName = CustomTask<TaskAdapterClass>; }
+using TaskTreeTask = CustomTask<TaskTreeTaskAdapter>;
+using TimeoutTask = CustomTask<TimeoutTaskAdapter>;
-#define TASKING_DECLARE_TEMPLATE_TASK(CustomTaskName, TaskAdapterClass)\
-namespace Tasking {\
-template <typename ...Args>\
-using CustomTaskName = CustomTask<TaskAdapterClass<Args...>>;\
} // namespace Tasking
-
-TASKING_DECLARE_TASK(TaskTreeTask, TaskTreeTaskAdapter);
-TASKING_DECLARE_TASK(TimeoutTask, TimeoutTaskAdapter);
diff --git a/src/libs/solutions/terminal/CMakeLists.txt b/src/libs/solutions/terminal/CMakeLists.txt
new file mode 100644
index 00000000000..0cf48fefbc7
--- /dev/null
+++ b/src/libs/solutions/terminal/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_qtc_library(TerminalLib
+ DEPENDS Qt::Core Qt::Widgets libvterm
+ SOURCES
+ celliterator.cpp celliterator.h
+ glyphcache.cpp glyphcache.h
+ keys.cpp keys.h
+ scrollback.cpp scrollback.h
+ surfaceintegration.h
+ terminal_global.h
+ terminal.qrc
+ terminalsurface.cpp terminalsurface.h
+ terminalview.cpp terminalview.h
+)
diff --git a/src/libs/solutions/terminal/celliterator.cpp b/src/libs/solutions/terminal/celliterator.cpp
new file mode 100644
index 00000000000..b7053438e08
--- /dev/null
+++ b/src/libs/solutions/terminal/celliterator.cpp
@@ -0,0 +1,94 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "celliterator.h"
+
+#include "terminalsurface.h"
+
+#include <stdexcept>
+
+namespace TerminalSolution {
+
+CellIterator::CellIterator(const TerminalSurface *surface, QPoint pos)
+ : CellIterator(surface, pos.x() + (pos.y() * surface->liveSize().width()))
+{}
+
+CellIterator::CellIterator(const TerminalSurface *surface, int pos)
+ : m_state(State::INSIDE)
+ , m_surface(surface)
+{
+ m_maxpos = surface->fullSize().width() * (surface->fullSize().height()) - 1;
+ m_pos = qMax(0, qMin(m_maxpos + 1, pos));
+
+ if (m_pos == 0) {
+ m_state = State::BEGIN;
+ } else if (m_pos == m_maxpos + 1) {
+ m_state = State::END;
+ }
+
+ if (m_state != State::END)
+ updateChar();
+}
+
+CellIterator::CellIterator(const TerminalSurface *surface)
+ : m_state(State::END)
+ , m_surface(surface)
+{
+ m_maxpos = surface->fullSize().width() * (surface->fullSize().height()) - 1;
+ m_pos = m_maxpos + 1;
+}
+
+QPoint CellIterator::gridPos() const
+{
+ return m_surface->posToGrid(m_pos);
+}
+
+bool CellIterator::updateChar()
+{
+ QPoint cell = m_surface->posToGrid(m_pos);
+ m_char = m_surface->fetchCharAt(cell.x(), cell.y());
+ return m_char != 0;
+}
+
+CellIterator &CellIterator::operator-=(int n)
+{
+ if (n == 0)
+ return *this;
+
+ if (m_pos - n < 0)
+ throw new std::runtime_error("-= n too big!");
+
+ m_pos -= n;
+
+ while (!updateChar() && m_pos > 0 && m_skipZeros)
+ m_pos--;
+
+ m_state = State::INSIDE;
+
+ if (m_pos == 0) {
+ m_state = State::BEGIN;
+ }
+
+ return *this;
+}
+
+CellIterator &CellIterator::operator+=(int n)
+{
+ if (n == 0)
+ return *this;
+
+ if (m_pos + n < m_maxpos + 1) {
+ m_state = State::INSIDE;
+ m_pos += n;
+ while (!updateChar() && m_pos < (m_maxpos + 1) && m_skipZeros)
+ m_pos++;
+
+ if (m_pos == m_maxpos + 1)
+ m_state = State::END;
+ } else {
+ *this = m_surface->end();
+ }
+ return *this;
+}
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/celliterator.h b/src/libs/solutions/terminal/celliterator.h
new file mode 100644
index 00000000000..e1fc6efce74
--- /dev/null
+++ b/src/libs/solutions/terminal/celliterator.h
@@ -0,0 +1,99 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "terminal_global.h"
+
+#include <string>
+
+#include <QPoint>
+
+namespace TerminalSolution {
+
+class TerminalSurface;
+
+class TERMINAL_EXPORT CellIterator
+{
+public:
+ using iterator_category = std::bidirectional_iterator_tag;
+ using difference_type = std::ptrdiff_t;
+ using value_type = std::u32string::value_type;
+ using pointer = std::u32string::value_type *;
+ // We need to return copies for std::reverse_iterator to work
+ using reference = std::u32string::value_type;
+
+ enum class State { BEGIN, INSIDE, END } m_state{};
+
+public:
+ CellIterator(const TerminalSurface *surface, QPoint pos);
+ CellIterator(const TerminalSurface *surface, int pos);
+ CellIterator(const TerminalSurface *surface);
+
+public:
+ QPoint gridPos() const;
+
+public:
+ CellIterator &operator-=(int n);
+ CellIterator &operator+=(int n);
+
+ reference operator*() const { return m_char; }
+ pointer operator->() { return &m_char; }
+
+ CellIterator &operator++() { return *this += 1; }
+ CellIterator operator++(int)
+ {
+ CellIterator tmp = *this;
+ ++(*this);
+ return tmp;
+ }
+
+ CellIterator &operator--() { return *this -= 1; }
+ CellIterator operator--(int)
+ {
+ CellIterator tmp = *this;
+ --(*this);
+ return tmp;
+ }
+
+ bool operator!=(const CellIterator &other) const
+ {
+ if (other.m_state != m_state)
+ return true;
+
+ if (other.m_pos != m_pos)
+ return true;
+
+ return false;
+ }
+
+ bool operator==(const CellIterator &other) const { return !operator!=(other); }
+
+ CellIterator operator-(int n) const
+ {
+ CellIterator result = *this;
+ result -= n;
+ return result;
+ }
+
+ CellIterator operator+(int n) const
+ {
+ CellIterator result = *this;
+ result += n;
+ return result;
+ }
+
+ int position() const { return m_pos; }
+ void setSkipZeros(bool skipZeros) { m_skipZeros = skipZeros; }
+
+private:
+ bool updateChar();
+
+ const TerminalSurface *m_surface{nullptr};
+ int m_pos{-1};
+ int m_maxpos{-1};
+ bool m_skipZeros{false};
+ mutable std::u32string::value_type m_char;
+};
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/glyphcache.cpp b/src/libs/solutions/terminal/glyphcache.cpp
new file mode 100644
index 00000000000..1941f1c0366
--- /dev/null
+++ b/src/libs/solutions/terminal/glyphcache.cpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "glyphcache.h"
+
+#include <QTextLayout>
+
+namespace TerminalSolution {
+
+size_t qHash(const GlyphCacheKey &key, size_t seed = 0)
+{
+ return qHash(key.font, seed) ^ qHash(key.text, seed);
+}
+
+GlyphCache &GlyphCache::instance()
+{
+ static GlyphCache cache(5000);
+ return cache;
+}
+
+const QGlyphRun *GlyphCache::get(const QFont &font, const QString &text)
+{
+ GlyphCacheKey key{font, text};
+ if (auto *run = object(key))
+ return run;
+
+ QTextLayout layout;
+
+ layout.setText(text);
+ layout.setFont(font);
+
+ layout.beginLayout();
+ layout.createLine().setNumColumns(std::numeric_limits<int>::max());
+ layout.endLayout();
+
+ if (layout.lineCount() > 0) {
+ const auto &line = layout.lineAt(0);
+ const auto runs = line.glyphRuns();
+ if (!runs.isEmpty()) {
+ QGlyphRun *run = new QGlyphRun(layout.lineAt(0).glyphRuns().first());
+ if (insert(key, run))
+ return run;
+ }
+ }
+ return nullptr;
+}
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/glyphcache.h b/src/libs/solutions/terminal/glyphcache.h
new file mode 100644
index 00000000000..a5ebfc21453
--- /dev/null
+++ b/src/libs/solutions/terminal/glyphcache.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include <QCache>
+#include <QFont>
+#include <QGlyphRun>
+#include <QString>
+
+namespace TerminalSolution {
+
+struct GlyphCacheKey
+{
+ QFont font;
+ QString text;
+
+ bool operator==(const GlyphCacheKey &other) const
+ {
+ return font == other.font && text == other.text;
+ }
+};
+
+class GlyphCache : public QCache<GlyphCacheKey, QGlyphRun>
+{
+public:
+ using QCache::QCache;
+
+ static GlyphCache &instance();
+
+ const QGlyphRun *get(const QFont &font, const QString &text);
+};
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/images/passwordlock.png b/src/libs/solutions/terminal/images/passwordlock.png
new file mode 100644
index 00000000000..c548e28cab2
--- /dev/null
+++ b/src/libs/solutions/terminal/images/passwordlock.png
Binary files differ
diff --git a/src/libs/solutions/terminal/keys.cpp b/src/libs/solutions/terminal/keys.cpp
new file mode 100644
index 00000000000..adbcda10ea7
--- /dev/null
+++ b/src/libs/solutions/terminal/keys.cpp
@@ -0,0 +1,90 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "keys.h"
+
+namespace TerminalSolution {
+
+VTermModifier qtModifierToVTerm(Qt::KeyboardModifiers mod)
+{
+ int ret = VTERM_MOD_NONE;
+
+ if (mod & Qt::ShiftModifier)
+ ret |= VTERM_MOD_SHIFT;
+
+ if (mod & Qt::AltModifier)
+ ret |= VTERM_MOD_ALT;
+
+#ifdef Q_OS_DARWIN
+ if (mod & Qt::MetaModifier)
+ ret |= VTERM_MOD_CTRL;
+#else
+ if (mod & Qt::ControlModifier)
+ ret |= VTERM_MOD_CTRL;
+#endif
+
+ return static_cast<VTermModifier>(ret);
+}
+
+VTermKey qtKeyToVTerm(Qt::Key key, bool keypad)
+{
+ if (key >= Qt::Key_F1 && key <= Qt::Key_F35)
+ return static_cast<VTermKey>(VTERM_KEY_FUNCTION_0 + key - Qt::Key_F1 + 1);
+
+ switch (key) {
+ case Qt::Key_Return:
+ return VTERM_KEY_ENTER;
+ case Qt::Key_Tab:
+ return VTERM_KEY_TAB;
+ case Qt::Key_Backspace:
+ return VTERM_KEY_BACKSPACE;
+ case Qt::Key_Escape:
+ return VTERM_KEY_ESCAPE;
+ case Qt::Key_Up:
+ return VTERM_KEY_UP;
+ case Qt::Key_Down:
+ return VTERM_KEY_DOWN;
+ case Qt::Key_Left:
+ return VTERM_KEY_LEFT;
+ case Qt::Key_Right:
+ return VTERM_KEY_RIGHT;
+ case Qt::Key_Insert:
+ return VTERM_KEY_INS;
+ case Qt::Key_Delete:
+ return VTERM_KEY_DEL;
+ case Qt::Key_Home:
+ return VTERM_KEY_HOME;
+ case Qt::Key_End:
+ return VTERM_KEY_END;
+ case Qt::Key_PageUp:
+ return VTERM_KEY_PAGEUP;
+ case Qt::Key_PageDown:
+ return VTERM_KEY_PAGEDOWN;
+ case Qt::Key_multiply:
+ return keypad ? VTERM_KEY_KP_MULT : VTERM_KEY_NONE;
+ case Qt::Key_Plus:
+ return keypad ? VTERM_KEY_KP_PLUS : VTERM_KEY_NONE;
+ case Qt::Key_Comma:
+ return keypad ? VTERM_KEY_KP_COMMA : VTERM_KEY_NONE;
+ case Qt::Key_Minus:
+ return keypad ? VTERM_KEY_KP_MINUS : VTERM_KEY_NONE;
+ case Qt::Key_Period:
+ return keypad ? VTERM_KEY_KP_PERIOD : VTERM_KEY_NONE;
+ case Qt::Key_Slash:
+ return keypad ? VTERM_KEY_KP_DIVIDE : VTERM_KEY_NONE;
+ case Qt::Key_Enter: {
+ VTermKey enterKey = VTERM_KEY_KP_ENTER;
+
+#ifdef Q_OS_WIN
+ enterKey = VTERM_KEY_ENTER;
+#endif
+
+ return keypad ? enterKey : VTERM_KEY_NONE;
+ }
+ case Qt::Key_Equal:
+ return keypad ? VTERM_KEY_KP_EQUAL : VTERM_KEY_NONE;
+ default:
+ return VTERM_KEY_NONE;
+ }
+}
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/keys.h b/src/libs/solutions/terminal/keys.h
new file mode 100644
index 00000000000..2f967010db9
--- /dev/null
+++ b/src/libs/solutions/terminal/keys.h
@@ -0,0 +1,15 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include <vterm_keycodes.h>
+
+#include <QKeyEvent>
+
+namespace TerminalSolution {
+
+VTermKey qtKeyToVTerm(Qt::Key key, bool keypad);
+VTermModifier qtModifierToVTerm(Qt::KeyboardModifiers mod);
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/scrollback.cpp b/src/libs/solutions/terminal/scrollback.cpp
new file mode 100644
index 00000000000..b3fa9af8433
--- /dev/null
+++ b/src/libs/solutions/terminal/scrollback.cpp
@@ -0,0 +1,61 @@
+// Copyright (c) 2020, Justin Bronder
+// Copied and modified from: https://github.com/jsbronder/sff
+// SPDX-License-Identifier: BSD-3-Clause
+
+#include "scrollback.h"
+
+#include <cassert>
+#include <cstring>
+#include <future>
+
+namespace TerminalSolution {
+
+Scrollback::Line::Line(int cols, const VTermScreenCell *cells)
+ : m_cols(cols)
+ , m_cells(std::make_unique<VTermScreenCell[]>(cols))
+{
+ memcpy(m_cells.get(), cells, cols * sizeof(cells[0]));
+}
+
+const VTermScreenCell *Scrollback::Line::cell(int i) const
+{
+ assert(i >= 0 && i < m_cols);
+ return &m_cells[i];
+}
+
+Scrollback::Scrollback(size_t capacity)
+ : m_capacity(capacity)
+{}
+
+void Scrollback::emplace(int cols, const VTermScreenCell *cells)
+{
+ m_deque.emplace_front(cols, cells);
+ while (m_deque.size() > m_capacity) {
+ m_deque.pop_back();
+ }
+}
+
+void Scrollback::popto(int cols, VTermScreenCell *cells)
+{
+ const Line &sbl = m_deque.front();
+
+ int ncells = cols;
+ if (ncells > sbl.cols())
+ ncells = sbl.cols();
+
+ memcpy(cells, sbl.cells(), sizeof(cells[0]) * ncells);
+ for (size_t i = ncells; i < static_cast<size_t>(cols); ++i) {
+ cells[i].chars[0] = '\0';
+ cells[i].width = 1;
+ cells[i].bg = cells[ncells - 1].bg;
+ }
+
+ m_deque.pop_front();
+}
+
+void Scrollback::clear()
+{
+ m_deque.clear();
+}
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/scrollback.h b/src/libs/solutions/terminal/scrollback.h
new file mode 100644
index 00000000000..a03f9891e64
--- /dev/null
+++ b/src/libs/solutions/terminal/scrollback.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2020, Justin Bronder
+// Copied and modified from: https://github.com/jsbronder/sff
+// SPDX-License-Identifier: BSD-3-Clause
+
+#pragma once
+
+#include <vterm.h>
+
+#include <deque>
+#include <future>
+#include <memory>
+
+#include <QFont>
+#include <QTextLayout>
+
+namespace TerminalSolution {
+
+class Scrollback
+{
+public:
+ class Line
+ {
+ public:
+ Line(int cols, const VTermScreenCell *cells);
+ Line(Line &&other) = default;
+ Line() = delete;
+
+ int cols() const { return m_cols; };
+ const VTermScreenCell *cell(int i) const;
+ const VTermScreenCell *cells() const { return &m_cells[0]; };
+
+ private:
+ int m_cols;
+ std::unique_ptr<VTermScreenCell[]> m_cells;
+ };
+
+public:
+ Scrollback(size_t capacity);
+ Scrollback() = delete;
+
+ int capacity() const { return static_cast<int>(m_capacity); };
+ int size() const { return static_cast<int>(m_deque.size()); };
+
+ const Line &line(size_t index) const { return m_deque.at(index); };
+ const std::deque<Line> &lines() const { return m_deque; };
+
+ void emplace(int cols, const VTermScreenCell *cells);
+ void popto(int cols, VTermScreenCell *cells);
+
+ void clear();
+
+private:
+ size_t m_capacity;
+ std::deque<Line> m_deque;
+};
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/surfaceintegration.h b/src/libs/solutions/terminal/surfaceintegration.h
new file mode 100644
index 00000000000..99b9538de15
--- /dev/null
+++ b/src/libs/solutions/terminal/surfaceintegration.h
@@ -0,0 +1,22 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include <QString>
+
+namespace TerminalSolution {
+
+class SurfaceIntegration
+{
+public:
+ virtual void onOsc(int cmd, std::string_view str, bool initial, bool final) = 0;
+
+ virtual void onBell() {}
+ virtual void onTitle(const QString &title) { Q_UNUSED(title); }
+
+ virtual void onSetClipboard(const QByteArray &text) { Q_UNUSED(text); }
+ virtual void onGetClipboard() {}
+};
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/terminal.qbs b/src/libs/solutions/terminal/terminal.qbs
new file mode 100644
index 00000000000..aa1293e3994
--- /dev/null
+++ b/src/libs/solutions/terminal/terminal.qbs
@@ -0,0 +1,26 @@
+QtcLibrary {
+ name: "TerminalLib"
+
+ Depends { name: "vterm" }
+ Depends { name: "Qt.widgets" }
+
+ cpp.defines: base.concat("TERMINALLIB_LIBRARY")
+
+ files: [
+ "celliterator.cpp",
+ "celliterator.h",
+ "glyphcache.cpp",
+ "glyphcache.h",
+ "keys.cpp",
+ "keys.h",
+ "scrollback.cpp",
+ "scrollback.h",
+ "surfaceintegration.h",
+ "terminal.qrc",
+ "terminal_global.h",
+ "terminalsurface.cpp",
+ "terminalsurface.h",
+ "terminalview.cpp",
+ "terminalview.h",
+ ]
+}
diff --git a/src/libs/solutions/terminal/terminal.qrc b/src/libs/solutions/terminal/terminal.qrc
new file mode 100644
index 00000000000..0877ca08b9d
--- /dev/null
+++ b/src/libs/solutions/terminal/terminal.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/terminal">
+ <file>images/passwordlock.png</file>
+ </qresource>
+</RCC>
diff --git a/src/libs/solutions/terminal/terminal_global.h b/src/libs/solutions/terminal/terminal_global.h
new file mode 100644
index 00000000000..b7fec1c77c5
--- /dev/null
+++ b/src/libs/solutions/terminal/terminal_global.h
@@ -0,0 +1,14 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include <qglobal.h>
+
+#if defined(TERMINALLIB_LIBRARY)
+#define TERMINAL_EXPORT Q_DECL_EXPORT
+#elif defined(TERMINALLIB_STATIC_LIBRARY)
+#define TERMINAL_EXPORT
+#else
+#define TERMINAL_EXPORT Q_DECL_IMPORT
+#endif
diff --git a/src/libs/solutions/terminal/terminalsurface.cpp b/src/libs/solutions/terminal/terminalsurface.cpp
new file mode 100644
index 00000000000..e51c09d8944
--- /dev/null
+++ b/src/libs/solutions/terminal/terminalsurface.cpp
@@ -0,0 +1,689 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "terminalsurface.h"
+#include "surfaceintegration.h"
+
+#include "keys.h"
+#include "scrollback.h"
+
+#include <vterm.h>
+
+#include <QLoggingCategory>
+#include <QTimer>
+
+namespace TerminalSolution {
+
+Q_LOGGING_CATEGORY(log, "qtc.terminal.surface", QtWarningMsg);
+
+QColor toQColor(const VTermColor &c)
+{
+ return QColor(qRgb(c.rgb.red, c.rgb.green, c.rgb.blue));
+};
+
+constexpr int batchFlushSize = 256;
+
+struct TerminalSurfacePrivate
+{
+ TerminalSurfacePrivate(TerminalSurface *surface, const QSize &initialGridSize)
+ : m_vterm(vterm_new(initialGridSize.height(), initialGridSize.width()), vterm_free)
+ , m_vtermScreen(vterm_obtain_screen(m_vterm.get()))
+ , m_scrollback(std::make_unique<Scrollback>(5000))
+ , q(surface)
+ {}
+
+ void flush()
+ {
+ if (m_writeBuffer.isEmpty())
+ return;
+
+ QByteArray data = m_writeBuffer.left(batchFlushSize);
+ qint64 result = m_writeToPty(data);
+
+ if (result != data.size()) {
+ // Not all data was written, remove the unwritten data from the array
+ data.resize(qMax(0, result));
+ }
+
+ // Remove the written data from the buffer
+ if (data.size() > 0)
+ m_writeBuffer = m_writeBuffer.mid(data.size());
+
+ if (!m_writeBuffer.isEmpty())
+ m_delayWriteTimer.start();
+ }
+
+ void init()
+ {
+ m_delayWriteTimer.setInterval(1);
+ m_delayWriteTimer.setSingleShot(true);
+
+ QObject::connect(&m_delayWriteTimer, &QTimer::timeout, &m_delayWriteTimer, [this] {
+ flush();
+ });
+
+ vterm_set_utf8(m_vterm.get(), true);
+
+ static auto writeToPty = [](const char *s, size_t len, void *user) {
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ QByteArray d(s, len);
+
+ // If its just a couple of chars, or we already have data in the writeBuffer,
+ // add the new data to the write buffer and start the delay timer
+ if (d.size() < batchFlushSize || !p->m_writeBuffer.isEmpty()) {
+ p->m_writeBuffer.append(d);
+ p->m_delayWriteTimer.start();
+ return;
+ }
+
+ // Try to write the data ...
+ qint64 result = p->m_writeToPty(d);
+
+ if (result != d.size()) {
+ // if writing failed, append the data to the writeBuffer and start the delay timer
+
+ // Check if partial data may have already been written ...
+ if (result <= 0)
+ p->m_writeBuffer.append(d);
+ else
+ p->m_writeBuffer.append(d.mid(result));
+
+ p->m_delayWriteTimer.start();
+ }
+ };
+
+ vterm_output_set_callback(m_vterm.get(), writeToPty, this);
+
+ memset(&m_vtermScreenCallbacks, 0, sizeof(m_vtermScreenCallbacks));
+
+ m_vtermScreenCallbacks.damage = [](VTermRect rect, void *user) {
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ p->invalidate(rect);
+ return 1;
+ };
+ m_vtermScreenCallbacks.sb_pushline = [](int cols, const VTermScreenCell *cells, void *user) {
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ return p->sb_pushline(cols, cells);
+ };
+ m_vtermScreenCallbacks.sb_popline = [](int cols, VTermScreenCell *cells, void *user) {
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ return p->sb_popline(cols, cells);
+ };
+ m_vtermScreenCallbacks.settermprop = [](VTermProp prop, VTermValue *val, void *user) {
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ return p->setTerminalProperties(prop, val);
+ };
+ m_vtermScreenCallbacks.movecursor =
+ [](VTermPos pos, VTermPos oldpos, int visible, void *user) {
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ return p->movecursor(pos, oldpos, visible);
+ };
+ m_vtermScreenCallbacks.sb_clear = [](void *user) {
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ return p->sb_clear();
+ };
+ m_vtermScreenCallbacks.bell = [](void *user) {
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ if (p->m_surfaceIntegration)
+ p->m_surfaceIntegration->onBell();
+ return 1;
+ };
+
+ vterm_screen_set_callbacks(m_vtermScreen, &m_vtermScreenCallbacks, this);
+ vterm_screen_set_damage_merge(m_vtermScreen, VTERM_DAMAGE_SCROLL);
+ vterm_screen_enable_altscreen(m_vtermScreen, true);
+
+ memset(&m_vtermStateFallbacks, 0, sizeof(m_vtermStateFallbacks));
+
+ m_vtermStateFallbacks.osc = [](int cmd, VTermStringFragment fragment, void *user) {
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ return p->osc(cmd, fragment);
+ };
+
+ VTermState *vts = vterm_obtain_state(m_vterm.get());
+ vterm_state_set_unrecognised_fallbacks(vts, &m_vtermStateFallbacks, this);
+
+ memset(&m_vtermSelectionCallbacks, 0, sizeof(m_vtermSelectionCallbacks));
+
+ m_vtermSelectionCallbacks.query = [](VTermSelectionMask mask, void *user) {
+ if (!(mask & 0xF))
+ return 0;
+
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ if (p->m_surfaceIntegration)
+ p->m_surfaceIntegration->onGetClipboard();
+
+ return 0;
+ };
+
+ m_vtermSelectionCallbacks.set =
+ [](VTermSelectionMask mask, VTermStringFragment frag, void *user) {
+ if (!(mask & 0xF))
+ return 0;
+
+ auto p = static_cast<TerminalSurfacePrivate *>(user);
+ if (frag.initial)
+ p->m_selectionBuffer.clear();
+
+ p->m_selectionBuffer.append(frag.str, frag.len);
+ if (!frag.final)
+ return 1;
+
+ if (p->m_surfaceIntegration)
+ p->m_surfaceIntegration->onSetClipboard(p->m_selectionBuffer);
+
+ return 1;
+ };
+
+ vterm_state_set_selection_callbacks(vts, &m_vtermSelectionCallbacks, this, nullptr, 256);
+
+ vterm_state_set_bold_highbright(vts, true);
+
+ VTermColor fg;
+ VTermColor bg;
+ vterm_color_indexed(&fg, ColorIndex::Foreground);
+ vterm_color_indexed(&bg, ColorIndex::Background);
+ vterm_state_set_default_colors(vts, &fg, &bg);
+
+ for (int i = 0; i < 16; ++i) {
+ VTermColor col;
+ vterm_color_indexed(&col, i);
+ vterm_state_set_palette_color(vts, i, &col);
+ }
+
+ vterm_screen_reset(m_vtermScreen, 1);
+ }
+
+ QSize liveSize() const
+ {
+ int rows;
+ int cols;
+ vterm_get_size(m_vterm.get(), &rows, &cols);
+
+ return QSize(cols, rows);
+ }
+
+ std::variant<int, QColor> toVariantColor(const VTermColor &color)
+ {
+ if (color.type & VTERM_COLOR_DEFAULT_BG)
+ return ColorIndex::Background;
+ else if (color.type & VTERM_COLOR_DEFAULT_FG)
+ return ColorIndex::Foreground;
+ else if (color.type & VTERM_COLOR_INDEXED) {
+ if (color.indexed.idx >= 16) {
+ VTermColor c = color;
+ vterm_state_convert_color_to_rgb(vterm_obtain_state(m_vterm.get()), &c);
+ return toQColor(c);
+ }
+ return color.indexed.idx;
+ } else if (color.type == VTERM_COLOR_RGB)
+ return toQColor(color);
+ else
+ return -1;
+ }
+
+ TerminalCell toCell(const VTermScreenCell &cell)
+ {
+ TerminalCell result;
+ result.width = cell.width;
+ result.text = QString::fromUcs4(cell.chars);
+
+ const VTermColor *bg = &cell.bg;
+ const VTermColor *fg = &cell.fg;
+
+ if (static_cast<bool>(cell.attrs.reverse))
+ std::swap(fg, bg);
+
+ result.backgroundColor = toVariantColor(*bg);
+ result.foregroundColor = toVariantColor(*fg);
+
+ result.bold = cell.attrs.bold;
+ result.strikeOut = cell.attrs.strike;
+
+ if (cell.attrs.underline > 0) {
+ result.underlineStyle = QTextCharFormat::NoUnderline;
+ switch (cell.attrs.underline) {
+ case VTERM_UNDERLINE_SINGLE:
+ result.underlineStyle = QTextCharFormat::SingleUnderline;
+ break;
+ case VTERM_UNDERLINE_DOUBLE:
+ // TODO: Double underline
+ result.underlineStyle = QTextCharFormat::SingleUnderline;
+ break;
+ case VTERM_UNDERLINE_CURLY:
+ result.underlineStyle = QTextCharFormat::WaveUnderline;
+ break;
+ case VTERM_UNDERLINE_DASHED:
+ result.underlineStyle = QTextCharFormat::DashUnderline;
+ break;
+ case VTERM_UNDERLINE_DOTTED:
+ result.underlineStyle = QTextCharFormat::DotLine;
+ break;
+ }
+ }
+
+ result.strikeOut = cell.attrs.strike;
+
+ return result;
+ }
+
+ // Callbacks from vterm
+ void invalidate(VTermRect rect)
+ {
+ if (!m_altscreen) {
+ rect.start_row += m_scrollback->size();
+ rect.end_row += m_scrollback->size();
+ }
+
+ emit q->invalidated(
+ QRect{QPoint{rect.start_col, rect.start_row}, QPoint{rect.end_col, rect.end_row - 1}});
+ }
+
+ int sb_pushline(int cols, const VTermScreenCell *cells)
+ {
+ m_scrollback->emplace(cols, cells);
+ emit q->fullSizeChanged(q->fullSize());
+ return 1;
+ }
+
+ int sb_popline(int cols, VTermScreenCell *cells)
+ {
+ if (m_scrollback->size() == 0)
+ return 0;
+
+ m_scrollback->popto(cols, cells);
+ emit q->fullSizeChanged(q->fullSize());
+ return 1;
+ }
+
+ int sb_clear()
+ {
+ m_scrollback->clear();
+ emit q->fullSizeChanged(q->fullSize());
+ return 1;
+ }
+
+ int osc(int cmd, const VTermStringFragment &fragment)
+ {
+ if (m_surfaceIntegration) {
+ m_surfaceIntegration->onOsc(cmd,
+ {fragment.str, fragment.len},
+ fragment.initial,
+ fragment.final);
+ }
+
+ return 1;
+ }
+
+ int setTerminalProperties(VTermProp prop, VTermValue *val)
+ {
+ switch (prop) {
+ case VTERM_PROP_CURSORVISIBLE: {
+ Cursor old = q->cursor();
+ m_cursor.visible = val->boolean;
+ q->cursorChanged(old, q->cursor());
+ break;
+ }
+ case VTERM_PROP_CURSORBLINK: {
+ Cursor old = q->cursor();
+ m_cursor.blink = val->boolean;
+ emit q->cursorChanged(old, q->cursor());
+ break;
+ }
+ case VTERM_PROP_CURSORSHAPE: {
+ Cursor old = q->cursor();
+ m_cursor.shape = (Cursor::Shape) val->number;
+ emit q->cursorChanged(old, q->cursor());
+ break;
+ }
+ case VTERM_PROP_ICONNAME:
+ break;
+ case VTERM_PROP_TITLE:
+ if (m_surfaceIntegration)
+ m_surfaceIntegration->onTitle(QString::fromUtf8(val->string.str, val->string.len));
+ break;
+ case VTERM_PROP_ALTSCREEN:
+ m_altscreen = val->boolean;
+ emit q->altscreenChanged(m_altscreen);
+ break;
+ case VTERM_PROP_MOUSE:
+ qCDebug(log) << "Ignoring VTERM_PROP_MOUSE" << val->number;
+ break;
+ case VTERM_PROP_REVERSE:
+ qCDebug(log) << "Ignoring VTERM_PROP_REVERSE" << val->boolean;
+ break;
+ case VTERM_N_PROPS:
+ break;
+ case VTERM_PROP_FOCUSREPORT:
+ break;
+ }
+ return 1;
+ }
+ int movecursor(VTermPos pos, VTermPos oldpos, int visible)
+ {
+ Q_UNUSED(oldpos);
+ Cursor oldCursor = q->cursor();
+ m_cursor.position = {pos.col, pos.row};
+ m_cursor.visible = visible > 0;
+ q->cursorChanged(oldCursor, q->cursor());
+ return 1;
+ }
+
+ const VTermScreenCell *cellAt(int x, int y)
+ {
+ if (y < 0 || x < 0 || y >= q->fullSize().height() || x >= liveSize().width()) {
+ qCWarning(log) << "Invalid Parameter for cellAt:" << x << y << "liveSize:" << liveSize()
+ << "fullSize:" << q->fullSize();
+ return nullptr;
+ }
+
+ if (!m_altscreen && y < m_scrollback->size()) {
+ const auto &sbl = m_scrollback->line((m_scrollback->size() - 1) - y);
+ if (x < sbl.cols()) {
+ return sbl.cell(x);
+ }
+ return nullptr;
+ }
+
+ if (!m_altscreen)
+ y -= m_scrollback->size();
+
+ static VTermScreenCell refCell{};
+ VTermPos vtp{y, x};
+ vterm_screen_get_cell(m_vtermScreen, vtp, &refCell);
+
+ return &refCell;
+ }
+
+ std::unique_ptr<VTerm, void (*)(VTerm *)> m_vterm;
+ VTermScreen *m_vtermScreen;
+ VTermScreenCallbacks m_vtermScreenCallbacks;
+ VTermStateFallbacks m_vtermStateFallbacks;
+
+ VTermSelectionCallbacks m_vtermSelectionCallbacks;
+
+ Cursor m_cursor;
+ QString m_currentCommand;
+
+ bool m_altscreen{false};
+
+ std::unique_ptr<Scrollback> m_scrollback;
+
+ SurfaceIntegration *m_surfaceIntegration{nullptr};
+
+ TerminalSurface *q;
+ QTimer m_delayWriteTimer;
+ QByteArray m_writeBuffer;
+ QByteArray m_selectionBuffer;
+
+ TerminalSurface::WriteToPty m_writeToPty;
+};
+
+TerminalSurface::TerminalSurface(QSize initialGridSize)
+ : d(std::make_unique<TerminalSurfacePrivate>(this, initialGridSize))
+{
+ d->init();
+}
+
+TerminalSurface::~TerminalSurface() = default;
+
+int TerminalSurface::cellWidthAt(int x, int y) const
+{
+ const VTermScreenCell *cell = d->cellAt(x, y);
+ if (!cell)
+ return 0;
+ return cell->width;
+}
+
+QSize TerminalSurface::liveSize() const
+{
+ return d->liveSize();
+}
+
+QSize TerminalSurface::fullSize() const
+{
+ if (d->m_altscreen)
+ return liveSize();
+ return QSize{d->liveSize().width(), d->liveSize().height() + d->m_scrollback->size()};
+}
+
+std::u32string::value_type TerminalSurface::fetchCharAt(int x, int y) const
+{
+ const VTermScreenCell *cell = d->cellAt(x, y);
+ if (!cell)
+ return 0;
+
+ if (cell->width == 0)
+ return 0;
+
+ QString s = QString::fromUcs4(cell->chars, 6).normalized(QString::NormalizationForm_C);
+ const QList<uint> ucs4 = s.toUcs4();
+ return std::u32string(ucs4.begin(), ucs4.end()).front();
+}
+
+TerminalCell TerminalSurface::fetchCell(int x, int y) const
+{
+ static TerminalCell emptyCell{1,
+ {},
+ {},
+ false,
+ ColorIndex::Foreground,
+ ColorIndex::Background,
+ QTextCharFormat::NoUnderline,
+ false};
+
+ if (y < 0 || y >= fullSize().height() || x >= fullSize().width()) {
+ qCWarning(log) << "Invalid Parameter for fetchCell:" << x << y << "fullSize:" << fullSize();
+ return emptyCell;
+ }
+
+ const VTermScreenCell *refCell = d->cellAt(x, y);
+ if (!refCell)
+ return emptyCell;
+
+ return d->toCell(*refCell);
+}
+
+void TerminalSurface::clearAll()
+{
+ // Fake a scrollback clearing
+ QByteArray data{"\x1b[3J"};
+ vterm_input_write(d->m_vterm.get(), data.constData(), data.size());
+
+ // Send Ctrl+L which will clear the screen
+ d->m_writeToPty(QByteArray("\f"));
+}
+
+void TerminalSurface::resize(QSize newSize)
+{
+ vterm_set_size(d->m_vterm.get(), newSize.height(), newSize.width());
+}
+
+QPoint TerminalSurface::posToGrid(int pos) const
+{
+ return {pos % d->liveSize().width(), pos / d->liveSize().width()};
+}
+int TerminalSurface::gridToPos(QPoint gridPos) const
+{
+ return gridPos.y() * d->liveSize().width() + gridPos.x();
+}
+
+void TerminalSurface::dataFromPty(const QByteArray &data)
+{
+ vterm_input_write(d->m_vterm.get(), data.constData(), data.size());
+ vterm_screen_flush_damage(d->m_vtermScreen);
+}
+
+void TerminalSurface::flush()
+{
+ vterm_screen_flush_damage(d->m_vtermScreen);
+}
+
+void TerminalSurface::pasteFromClipboard(const QString &clipboardText)
+{
+ if (clipboardText.isEmpty())
+ return;
+
+ vterm_keyboard_start_paste(d->m_vterm.get());
+ for (unsigned int ch : clipboardText.toUcs4()) {
+ // Workaround for weird nano behavior to correctly paste newlines
+ // see: http://savannah.gnu.org/bugs/?49176
+ // and: https://github.com/kovidgoyal/kitty/issues/994
+ if (ch == '\n')
+ ch = '\r';
+ vterm_keyboard_unichar(d->m_vterm.get(), ch, VTERM_MOD_NONE);
+ }
+ vterm_keyboard_end_paste(d->m_vterm.get());
+
+ if (!d->m_altscreen) {
+ emit unscroll();
+ }
+}
+
+void TerminalSurface::sendKey(Qt::Key key)
+{
+ if (key == Qt::Key_Escape)
+ vterm_keyboard_key(d->m_vterm.get(), VTERM_KEY_ESCAPE, VTERM_MOD_NONE);
+}
+
+void TerminalSurface::sendKey(const QString &text)
+{
+ for (const unsigned int ch : text.toUcs4())
+ vterm_keyboard_unichar(d->m_vterm.get(), ch, VTERM_MOD_NONE);
+}
+
+void TerminalSurface::sendKey(QKeyEvent *event)
+{
+ bool keypad = event->modifiers() & Qt::KeypadModifier;
+ VTermModifier mod = qtModifierToVTerm(event->modifiers());
+ VTermKey key = qtKeyToVTerm(Qt::Key(event->key()), keypad);
+
+ if (key != VTERM_KEY_NONE) {
+ if (mod == VTERM_MOD_SHIFT && (key == VTERM_KEY_ESCAPE || key == VTERM_KEY_BACKSPACE))
+ mod = VTERM_MOD_NONE;
+
+ vterm_keyboard_key(d->m_vterm.get(), key, mod);
+ } else if (event->text().length() == 1) {
+ // event->text() already contains the correct unicode character based on the modifiers
+ // used, so we can simply convert it to Ucs4 and send it to the terminal.
+ vterm_keyboard_unichar(d->m_vterm.get(), event->text().toUcs4()[0], VTERM_MOD_NONE);
+ } else if (mod == VTERM_MOD_CTRL && event->key() >= Qt::Key_A && event->key() < Qt::Key_Z) {
+ vterm_keyboard_unichar(d->m_vterm.get(), 'a' + (event->key() - Qt::Key_A), mod);
+ }
+}
+
+Cursor TerminalSurface::cursor() const
+{
+ Cursor cursor = d->m_cursor;
+ if (!d->m_altscreen)
+ cursor.position.setY(cursor.position.y() + d->m_scrollback->size());
+
+ return cursor;
+}
+
+SurfaceIntegration *TerminalSurface::surfaceIntegration() const
+{
+ return d->m_surfaceIntegration;
+}
+
+void TerminalSurface::setSurfaceIntegration(SurfaceIntegration *surfaceIntegration)
+{
+ d->m_surfaceIntegration = surfaceIntegration;
+}
+
+void TerminalSurface::mouseMove(QPoint pos, Qt::KeyboardModifiers modifiers)
+{
+ vterm_mouse_move(d->m_vterm.get(), pos.y(), pos.x(), qtModifierToVTerm(modifiers));
+}
+
+void TerminalSurface::mouseButton(Qt::MouseButton button,
+ bool pressed,
+ Qt::KeyboardModifiers modifiers)
+{
+ int btnIdx = 0;
+ switch (button) {
+ case Qt::LeftButton:
+ btnIdx = 1;
+ break;
+ case Qt::RightButton:
+ btnIdx = 3;
+ break;
+ case Qt::MiddleButton:
+ btnIdx = 2;
+ break;
+ case Qt::ExtraButton1:
+ btnIdx = 4;
+ break;
+ case Qt::ExtraButton2:
+ btnIdx = 5;
+ break;
+ case Qt::ExtraButton3:
+ btnIdx = 6;
+ break;
+ case Qt::ExtraButton4:
+ btnIdx = 7;
+ break;
+ default:
+ return;
+ }
+
+ vterm_mouse_button(d->m_vterm.get(), btnIdx, pressed, qtModifierToVTerm(modifiers));
+}
+
+void TerminalSurface::sendFocus(bool hasFocus)
+{
+ VTermState *vts = vterm_obtain_state(d->m_vterm.get());
+
+ if (hasFocus)
+ vterm_state_focus_in(vts);
+ else
+ vterm_state_focus_out(vts);
+}
+
+void TerminalSurface::setWriteToPty(WriteToPty writeToPty)
+{
+ d->m_writeToPty = writeToPty;
+}
+
+CellIterator TerminalSurface::begin() const
+{
+ auto res = CellIterator(this, {0, 0});
+ res.m_state = CellIterator::State::BEGIN;
+ return res;
+}
+
+CellIterator TerminalSurface::end() const
+{
+ return CellIterator(this);
+}
+
+std::reverse_iterator<CellIterator> TerminalSurface::rbegin() const
+{
+ return std::make_reverse_iterator(end());
+}
+
+std::reverse_iterator<CellIterator> TerminalSurface::rend() const
+{
+ return std::make_reverse_iterator(begin());
+}
+
+CellIterator TerminalSurface::iteratorAt(QPoint pos) const
+{
+ return CellIterator(this, pos);
+}
+CellIterator TerminalSurface::iteratorAt(int pos) const
+{
+ return CellIterator(this, pos);
+}
+
+std::reverse_iterator<CellIterator> TerminalSurface::rIteratorAt(QPoint pos) const
+{
+ return std::make_reverse_iterator(iteratorAt(pos));
+}
+
+std::reverse_iterator<CellIterator> TerminalSurface::rIteratorAt(int pos) const
+{
+ return std::make_reverse_iterator(iteratorAt(pos));
+}
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/terminalsurface.h b/src/libs/solutions/terminal/terminalsurface.h
new file mode 100644
index 00000000000..a8cc12fa4b0
--- /dev/null
+++ b/src/libs/solutions/terminal/terminalsurface.h
@@ -0,0 +1,119 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "terminal_global.h"
+
+#include "celliterator.h"
+
+#include <QKeyEvent>
+#include <QSize>
+#include <QTextCharFormat>
+
+#include <memory>
+
+namespace TerminalSolution {
+
+class Scrollback;
+class SurfaceIntegration;
+
+struct TerminalSurfacePrivate;
+
+enum ColorIndex { Foreground = 16, Background = 17 };
+
+struct TerminalCell
+{
+ int width;
+ QString text;
+ bool bold{false};
+ bool italic{false};
+ std::variant<int, QColor> foregroundColor;
+ std::variant<int, QColor> backgroundColor;
+ QTextCharFormat::UnderlineStyle underlineStyle{QTextCharFormat::NoUnderline};
+ bool strikeOut{false};
+};
+
+struct Cursor
+{
+ enum class Shape {
+ Block = 1,
+ Underline,
+ LeftBar,
+ };
+ QPoint position;
+ bool visible;
+ Shape shape;
+ bool blink{false};
+};
+
+class TERMINAL_EXPORT TerminalSurface : public QObject
+{
+ Q_OBJECT;
+
+public:
+ TerminalSurface(QSize initialGridSize);
+ ~TerminalSurface();
+
+public:
+ CellIterator begin() const;
+ CellIterator end() const;
+ std::reverse_iterator<CellIterator> rbegin() const;
+ std::reverse_iterator<CellIterator> rend() const;
+
+ CellIterator iteratorAt(QPoint pos) const;
+ CellIterator iteratorAt(int pos) const;
+
+ std::reverse_iterator<CellIterator> rIteratorAt(QPoint pos) const;
+ std::reverse_iterator<CellIterator> rIteratorAt(int pos) const;
+
+public:
+ void clearAll();
+
+ void resize(QSize newSize);
+
+ TerminalCell fetchCell(int x, int y) const;
+ std::u32string::value_type fetchCharAt(int x, int y) const;
+ int cellWidthAt(int x, int y) const;
+
+ QSize liveSize() const;
+ QSize fullSize() const;
+
+ QPoint posToGrid(int pos) const;
+ int gridToPos(QPoint gridPos) const;
+
+ void dataFromPty(const QByteArray &data);
+ void flush();
+
+ void pasteFromClipboard(const QString &text);
+
+ void sendKey(Qt::Key key);
+ void sendKey(QKeyEvent *event);
+ void sendKey(const QString &text);
+
+ int invertedScrollOffset() const;
+
+ Cursor cursor() const;
+
+ SurfaceIntegration *surfaceIntegration() const;
+ void setSurfaceIntegration(SurfaceIntegration *surfaceIntegration);
+
+ using WriteToPty = std::function<qint64(const QByteArray &)>;
+ void setWriteToPty(WriteToPty writeToPty);
+
+ void mouseMove(QPoint pos, Qt::KeyboardModifiers modifiers);
+ void mouseButton(Qt::MouseButton button, bool pressed, Qt::KeyboardModifiers modifiers);
+
+ void sendFocus(bool hasFocus);
+signals:
+ void invalidated(QRect grid);
+ void fullSizeChanged(QSize newSize);
+ void cursorChanged(Cursor oldCursor, Cursor newCursor);
+ void altscreenChanged(bool altScreen);
+ void unscroll();
+
+private:
+ std::unique_ptr<TerminalSurfacePrivate> d;
+};
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/terminalview.cpp b/src/libs/solutions/terminal/terminalview.cpp
new file mode 100644
index 00000000000..2244ea62d73
--- /dev/null
+++ b/src/libs/solutions/terminal/terminalview.cpp
@@ -0,0 +1,1300 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "terminalview.h"
+#include "glyphcache.h"
+#include "terminalsurface.h"
+
+#include <vterm.h>
+
+#include <QApplication>
+#include <QCache>
+#include <QClipboard>
+#include <QDesktopServices>
+#include <QElapsedTimer>
+#include <QGlyphRun>
+#include <QLoggingCategory>
+#include <QMenu>
+#include <QMimeData>
+#include <QPaintEvent>
+#include <QPainter>
+#include <QPainterPath>
+#include <QPixmapCache>
+#include <QRawFont>
+#include <QRegularExpression>
+#include <QScrollBar>
+#include <QTextItem>
+#include <QTextLayout>
+#include <QToolTip>
+
+Q_LOGGING_CATEGORY(terminalLog, "qtc.terminal", QtWarningMsg)
+Q_LOGGING_CATEGORY(selectionLog, "qtc.terminal.selection", QtWarningMsg)
+Q_LOGGING_CATEGORY(paintLog, "qtc.terminal.paint", QtWarningMsg)
+
+namespace TerminalSolution {
+
+using namespace std::chrono_literals;
+
+// Minimum time between two refreshes. (30fps)
+static constexpr std::chrono::milliseconds minRefreshInterval = 33ms;
+
+class TerminalViewPrivate
+{
+public:
+ TerminalViewPrivate()
+ {
+ m_cursorBlinkTimer.setInterval(750ms);
+ m_cursorBlinkTimer.setSingleShot(false);
+
+ m_flushDelayTimer.setSingleShot(true);
+ m_flushDelayTimer.setInterval(minRefreshInterval);
+
+ m_scrollTimer.setSingleShot(false);
+ m_scrollTimer.setInterval(500ms);
+ }
+
+ std::optional<TerminalView::Selection> m_selection;
+ std::unique_ptr<TerminalSurface> m_surface;
+
+ QSizeF m_cellSize;
+
+ bool m_ignoreScroll{false};
+
+ QString m_preEditString;
+
+ std::optional<TerminalView::LinkSelection> m_linkSelection;
+
+ struct
+ {
+ QPoint start;
+ QPoint end;
+ } m_activeMouseSelect;
+
+ QTimer m_flushDelayTimer;
+
+ QTimer m_scrollTimer;
+ int m_scrollDirection{0};
+
+ std::array<QColor, 20> m_currentColors;
+
+ std::chrono::system_clock::time_point m_lastFlush{std::chrono::system_clock::now()};
+ std::chrono::system_clock::time_point m_lastDoubleClick{std::chrono::system_clock::now()};
+ bool m_selectLineMode{false};
+ Cursor m_cursor;
+ QTimer m_cursorBlinkTimer;
+ bool m_cursorBlinkState{true};
+ bool m_allowBlinkingCursor{true};
+ bool m_allowMouseTracking{true};
+ bool m_passwordModeActive{false};
+
+ SurfaceIntegration *m_surfaceIntegration{nullptr};
+};
+
+QString defaultFontFamily()
+{
+#ifdef Q_OS_DARWIN
+ return QLatin1String("Menlo");
+#elif defined(Q_OS_WIN)
+ return QLatin1String("Consolas");
+#else
+ return QLatin1String("Monospace");
+#endif
+}
+
+int defaultFontSize()
+{
+#ifdef Q_OS_DARWIN
+ return 12;
+#elif defined(Q_OS_WIN)
+ return 10;
+#else
+ return 9;
+#endif
+}
+
+TerminalView::TerminalView(QWidget *parent)
+ : QAbstractScrollArea(parent)
+ , d(std::make_unique<TerminalViewPrivate>())
+{
+ setupSurface();
+ setFont(QFont(defaultFontFamily(), defaultFontSize()));
+
+ connect(&d->m_cursorBlinkTimer, &QTimer::timeout, this, [this]() {
+ if (hasFocus())
+ d->m_cursorBlinkState = !d->m_cursorBlinkState;
+ else
+ d->m_cursorBlinkState = true;
+ updateViewportRect(gridToViewport(QRect{d->m_cursor.position, d->m_cursor.position}));
+ });
+
+ setAttribute(Qt::WA_InputMethodEnabled);
+ setAttribute(Qt::WA_MouseTracking);
+ setAcceptDrops(true);
+
+ setCursor(Qt::IBeamCursor);
+
+ setViewportMargins(1, 1, 1, 1);
+
+ setFocus();
+ setFocusPolicy(Qt::StrongFocus);
+
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+
+ connect(&d->m_flushDelayTimer, &QTimer::timeout, this, [this]() { flushVTerm(true); });
+
+ connect(&d->m_scrollTimer, &QTimer::timeout, this, [this] {
+ if (d->m_scrollDirection < 0)
+ verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepSub);
+ else if (d->m_scrollDirection > 0)
+ verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepAdd);
+ });
+}
+
+TerminalView::~TerminalView() = default;
+
+void TerminalView::setSurfaceIntegration(SurfaceIntegration *surfaceIntegration)
+{
+ d->m_surfaceIntegration = surfaceIntegration;
+ if (d->m_surface)
+ d->m_surface->setSurfaceIntegration(d->m_surfaceIntegration);
+}
+
+TerminalSurface *TerminalView::surface() const
+{
+ return d->m_surface.get();
+}
+
+void TerminalView::setupSurface()
+{
+ d->m_surface = std::make_unique<TerminalSurface>(QSize{80, 60});
+
+ if (d->m_surfaceIntegration)
+ d->m_surface->setSurfaceIntegration(d->m_surfaceIntegration);
+
+ d->m_surface->setWriteToPty([this](const QByteArray &data) { return writeToPty(data); });
+
+ connect(d->m_surface.get(), &TerminalSurface::fullSizeChanged, this, [this] {
+ updateScrollBars();
+ });
+ connect(d->m_surface.get(), &TerminalSurface::invalidated, this, [this](const QRect &rect) {
+ setSelection(std::nullopt);
+ updateViewportRect(gridToViewport(rect));
+ verticalScrollBar()->setValue(d->m_surface->fullSize().height());
+ });
+ connect(
+ d->m_surface.get(),
+ &TerminalSurface::cursorChanged,
+ this,
+ [this](const Cursor &oldCursor, const Cursor &newCursor) {
+ int startX = oldCursor.position.x();
+ int endX = newCursor.position.x();
+
+ if (startX > endX)
+ std::swap(startX, endX);
+
+ int startY = oldCursor.position.y();
+ int endY = newCursor.position.y();
+ if (startY > endY)
+ std::swap(startY, endY);
+
+ d->m_cursor = newCursor;
+
+ updateViewportRect(gridToViewport(QRect{QPoint{startX, startY}, QPoint{endX, endY}}));
+ configBlinkTimer();
+ });
+ connect(d->m_surface.get(), &TerminalSurface::altscreenChanged, this, [this] {
+ updateScrollBars();
+ if (!setSelection(std::nullopt))
+ updateViewport();
+ });
+ connect(d->m_surface.get(), &TerminalSurface::unscroll, this, [this] {
+ verticalScrollBar()->setValue(verticalScrollBar()->maximum());
+ });
+
+ surfaceChanged();
+ updateScrollBars();
+}
+
+void TerminalView::setAllowBlinkingCursor(bool allow)
+{
+ d->m_allowBlinkingCursor = allow;
+}
+bool TerminalView::allowBlinkingCursor() const
+{
+ return d->m_allowBlinkingCursor;
+}
+
+void TerminalView::configBlinkTimer()
+{
+ bool shouldRun = d->m_cursor.visible && d->m_cursor.blink && hasFocus()
+ && d->m_allowBlinkingCursor;
+ if (shouldRun != d->m_cursorBlinkTimer.isActive()) {
+ if (shouldRun)
+ d->m_cursorBlinkTimer.start();
+ else
+ d->m_cursorBlinkTimer.stop();
+ }
+}
+
+QColor TerminalView::toQColor(std::variant<int, QColor> color) const
+{
+ if (std::holds_alternative<int>(color)) {
+ int idx = std::get<int>(color);
+ if (idx >= 0 && idx < 18)
+ return d->m_currentColors[idx];
+
+ return d->m_currentColors[(int) WidgetColorIdx::Background];
+ }
+ return std::get<QColor>(color);
+}
+
+void TerminalView::setColors(const std::array<QColor, 20> &newColors)
+{
+ if (d->m_currentColors == newColors)
+ return;
+
+ d->m_currentColors = newColors;
+
+ updateViewport();
+ update();
+}
+
+void TerminalView::setPasswordMode(bool passwordMode)
+{
+ if (passwordMode != d->m_passwordModeActive) {
+ d->m_passwordModeActive = passwordMode;
+ updateViewport();
+ }
+}
+
+void TerminalView::setFont(const QFont &font)
+{
+ QAbstractScrollArea::setFont(font);
+
+ QFontMetricsF qfm{font};
+ qCInfo(terminalLog) << font.family() << font.pointSize() << qfm.averageCharWidth()
+ << qfm.maxWidth() << viewport()->size();
+
+ d->m_cellSize = {qfm.averageCharWidth(), (double) qCeil(qfm.height())};
+
+ QAbstractScrollArea::setFont(font);
+
+ applySizeChange();
+}
+
+void TerminalView::copyToClipboard()
+{
+ if (!d->m_selection.has_value())
+ return;
+
+ QString text = textFromSelection();
+
+ qCDebug(selectionLog) << "Copied to clipboard: " << text;
+
+ setClipboard(text);
+
+ clearSelection();
+}
+
+void TerminalView::pasteFromClipboard()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ const QString clipboardText = clipboard->text(QClipboard::Clipboard);
+
+ if (clipboardText.isEmpty())
+ return;
+
+ d->m_surface->pasteFromClipboard(clipboardText);
+}
+
+void TerminalView::copyLinkToClipboard()
+{
+ if (d->m_linkSelection)
+ setClipboard(d->m_linkSelection->link.text);
+}
+
+std::optional<TerminalView::Selection> TerminalView::selection() const
+{
+ return d->m_selection;
+}
+
+void TerminalView::clearSelection()
+{
+ setSelection(std::nullopt);
+ //d->m_surface->sendKey(Qt::Key_Escape);
+}
+
+void TerminalView::zoomIn()
+{
+ QFont f = font();
+ f.setPointSize(f.pointSize() + 1);
+ setFont(f);
+}
+
+void TerminalView::zoomOut()
+{
+ QFont f = font();
+ f.setPointSize(qMax(f.pointSize() - 1, 1));
+ setFont(f);
+}
+
+void TerminalView::moveCursorWordLeft()
+{
+ writeToPty("\x1b\x62");
+}
+
+void TerminalView::moveCursorWordRight()
+{
+ writeToPty("\x1b\x66");
+}
+
+void TerminalView::clearContents()
+{
+ d->m_surface->clearAll();
+}
+
+void TerminalView::writeToTerminal(const QByteArray &data, bool forceFlush)
+{
+ d->m_surface->dataFromPty(data);
+ flushVTerm(forceFlush);
+}
+
+void TerminalView::flushVTerm(bool force)
+{
+ const std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
+ const std::chrono::milliseconds timeSinceLastFlush
+ = std::chrono::duration_cast<std::chrono::milliseconds>(now - d->m_lastFlush);
+
+ const bool shouldFlushImmediately = timeSinceLastFlush > minRefreshInterval;
+ if (force || shouldFlushImmediately) {
+ if (d->m_flushDelayTimer.isActive())
+ d->m_flushDelayTimer.stop();
+
+ d->m_lastFlush = now;
+ d->m_surface->flush();
+ return;
+ }
+
+ if (!d->m_flushDelayTimer.isActive()) {
+ const std::chrono::milliseconds timeToNextFlush = (minRefreshInterval - timeSinceLastFlush);
+ d->m_flushDelayTimer.start(timeToNextFlush.count());
+ }
+}
+
+QString TerminalView::textFromSelection() const
+{
+ if (!d->m_selection)
+ return {};
+
+ CellIterator it = d->m_surface->iteratorAt(d->m_selection->start);
+ CellIterator end = d->m_surface->iteratorAt(d->m_selection->end);
+
+ if (it.position() >= end.position()) {
+ qCWarning(selectionLog) << "Invalid selection: start >= end";
+ return {};
+ }
+
+ std::u32string s;
+ bool previousWasZero = false;
+ for (; it != end; ++it) {
+ if (it.gridPos().x() == 0 && !s.empty() && previousWasZero)
+ s += U'\n';
+
+ if (*it != 0) {
+ previousWasZero = false;
+ s += *it;
+ } else {
+ previousWasZero = true;
+ }
+ }
+
+ return QString::fromUcs4(s.data(), static_cast<int>(s.size()));
+}
+
+bool TerminalView::setSelection(const std::optional<Selection> &selection, bool scroll)
+{
+ qCDebug(selectionLog) << "setSelection" << selection.has_value();
+ if (selection.has_value())
+ qCDebug(selectionLog) << "start:" << selection->start << "end:" << selection->end
+ << "final:" << selection->final;
+
+ if (selectionLog().isDebugEnabled())
+ updateViewport();
+
+ if (selection == d->m_selection)
+ return false;
+
+ d->m_selection = selection;
+ selectionChanged(d->m_selection);
+
+ if (d->m_selection && d->m_selection->final && scroll) {
+ QPoint start = d->m_surface->posToGrid(d->m_selection->start);
+ QPoint end = d->m_surface->posToGrid(d->m_selection->end);
+ QRect viewRect = gridToViewport(QRect{start, end});
+ if (viewRect.y() >= viewport()->height() || viewRect.y() < 0) {
+ // Selection is outside of the viewport, scroll to it.
+ verticalScrollBar()->setValue(start.y());
+ }
+ }
+
+ if (!selectionLog().isDebugEnabled())
+ updateViewport();
+
+ return true;
+}
+
+void TerminalView::restart()
+{
+ setupSurface();
+ applySizeChange();
+}
+
+QPoint TerminalView::viewportToGlobal(QPoint p) const
+{
+ int y = p.y() - topMargin();
+ const double offset = verticalScrollBar()->value() * d->m_cellSize.height();
+ y += offset;
+
+ return {p.x(), y};
+}
+
+QPoint TerminalView::globalToViewport(QPoint p) const
+{
+ int y = p.y() + topMargin();
+ const double offset = verticalScrollBar()->value() * d->m_cellSize.height();
+ y -= offset;
+
+ return {p.x(), y};
+}
+
+QPoint TerminalView::globalToGrid(QPointF p) const
+{
+ return QPoint(p.x() / d->m_cellSize.width(), p.y() / d->m_cellSize.height());
+}
+
+QPointF TerminalView::gridToGlobal(QPoint p, bool bottom, bool right) const
+{
+ QPointF result = QPointF(p.x() * d->m_cellSize.width(), p.y() * d->m_cellSize.height());
+ if (bottom || right)
+ result += {right ? d->m_cellSize.width() : 0, bottom ? d->m_cellSize.height() : 0};
+ return result;
+}
+
+qreal TerminalView::topMargin() const
+{
+ return viewport()->size().height()
+ - (d->m_surface->liveSize().height() * d->m_cellSize.height());
+}
+
+static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
+{
+ const qreal radiusBase = qMax(qreal(1), maxRadius);
+ const qreal pWidth = pen.widthF();
+
+ const QString key = QLatin1String("WaveUnderline-") % pen.color().name()
+ % QString::number(int(radiusBase), 16) % QString::number(int(pWidth), 16);
+
+ QPixmap pixmap;
+ if (QPixmapCache::find(key, &pixmap))
+ return pixmap;
+
+ const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
+ const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod);
+ const qreal radius = qFloor(radiusBase * 2) / 2.;
+
+ QPainterPath path;
+
+ qreal xs = 0;
+ qreal ys = radius;
+
+ while (xs < width) {
+ xs += halfPeriod;
+ ys = -ys;
+ path.quadTo(xs - halfPeriod / 2, ys, xs, 0);
+ }
+
+ pixmap = QPixmap(width, radius * 2);
+ pixmap.fill(Qt::transparent);
+ {
+ QPen wavePen = pen;
+ wavePen.setCapStyle(Qt::SquareCap);
+
+ // This is to protect against making the line too fat, as happens on macOS
+ // due to it having a rather thick width for the regular underline.
+ const qreal maxPenWidth = .8 * radius;
+ if (wavePen.widthF() > maxPenWidth)
+ wavePen.setWidthF(maxPenWidth);
+
+ QPainter imgPainter(&pixmap);
+ imgPainter.setPen(wavePen);
+ imgPainter.setRenderHint(QPainter::Antialiasing);
+ imgPainter.translate(0, radius);
+ imgPainter.drawPath(path);
+ }
+
+ QPixmapCache::insert(key, pixmap);
+
+ return pixmap;
+}
+
+// Copied from qpainter.cpp
+static void drawTextItemDecoration(QPainter &painter,
+ const QPointF &pos,
+ QTextCharFormat::UnderlineStyle underlineStyle,
+ QTextItem::RenderFlags flags,
+ qreal width,
+ const QColor &underlineColor,
+ const QRawFont &font)
+{
+ if (underlineStyle == QTextCharFormat::NoUnderline
+ && !(flags & (QTextItem::StrikeOut | QTextItem::Overline)))
+ return;
+
+ const QPen oldPen = painter.pen();
+ const QBrush oldBrush = painter.brush();
+ painter.setBrush(Qt::NoBrush);
+ QPen pen = oldPen;
+ pen.setStyle(Qt::SolidLine);
+ pen.setWidthF(font.lineThickness());
+ pen.setCapStyle(Qt::FlatCap);
+
+ QLineF line(qFloor(pos.x()), pos.y(), qFloor(pos.x() + width), pos.y());
+
+ const qreal underlineOffset = font.underlinePosition();
+
+ /*if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
+ QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
+ if (theme)
+ underlineStyle = QTextCharFormat::UnderlineStyle(
+ theme->themeHint(QPlatformTheme::SpellCheckUnderlineStyle).toInt());
+ if (underlineStyle == QTextCharFormat::SpellCheckUnderline) // still not resolved
+ underlineStyle = QTextCharFormat::WaveUnderline;
+ }*/
+
+ if (underlineStyle == QTextCharFormat::WaveUnderline) {
+ painter.save();
+ painter.translate(0, pos.y() + 1);
+ qreal maxHeight = font.descent() - qreal(1);
+
+ QColor uc = underlineColor;
+ if (uc.isValid())
+ pen.setColor(uc);
+
+ // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms
+ const QPixmap wave = generateWavyPixmap(qMin(qMax(underlineOffset, pen.widthF()),
+ maxHeight / qreal(2.)),
+ pen);
+ const int descent = qFloor(maxHeight);
+
+ painter.setBrushOrigin(painter.brushOrigin().x(), 0);
+ painter.fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
+ painter.restore();
+ } else if (underlineStyle != QTextCharFormat::NoUnderline) {
+ // Deliberately ceil the offset to avoid the underline coming too close to
+ // the text above it, but limit it to stay within descent.
+ qreal adjustedUnderlineOffset = std::ceil(underlineOffset) + 0.5;
+ if (underlineOffset <= font.descent())
+ adjustedUnderlineOffset = qMin(adjustedUnderlineOffset, font.descent() - qreal(0.5));
+ const qreal underlinePos = pos.y() + adjustedUnderlineOffset;
+ QColor uc = underlineColor;
+ if (uc.isValid())
+ pen.setColor(uc);
+
+ pen.setStyle((Qt::PenStyle)(underlineStyle));
+ painter.setPen(pen);
+ QLineF underline(line.x1(), underlinePos, line.x2(), underlinePos);
+ painter.drawLine(underline);
+ }
+
+ pen.setStyle(Qt::SolidLine);
+ pen.setColor(oldPen.color());
+
+ if (flags & QTextItem::StrikeOut) {
+ QLineF strikeOutLine = line;
+ strikeOutLine.translate(0., -font.ascent() / 3.);
+ QColor uc = underlineColor;
+ if (uc.isValid())
+ pen.setColor(uc);
+ painter.setPen(pen);
+ painter.drawLine(strikeOutLine);
+ }
+
+ if (flags & QTextItem::Overline) {
+ QLineF overline = line;
+ overline.translate(0., -font.ascent());
+ QColor uc = underlineColor;
+ if (uc.isValid())
+ pen.setColor(uc);
+ painter.setPen(pen);
+ painter.drawLine(overline);
+ }
+
+ painter.setPen(oldPen);
+ painter.setBrush(oldBrush);
+}
+
+bool TerminalView::paintFindMatches(QPainter &p,
+ QList<SearchHit>::const_iterator &it,
+ const QRectF &cellRect,
+ const QPoint gridPos) const
+{
+ if (it == searchHits().constEnd())
+ return false;
+
+ const int pos = d->m_surface->gridToPos(gridPos);
+ while (it != searchHits().constEnd()) {
+ if (pos < it->start)
+ return false;
+
+ if (pos >= it->end) {
+ ++it;
+ continue;
+ }
+ break;
+ }
+
+ if (it == searchHits().constEnd())
+ return false;
+
+ p.fillRect(cellRect, d->m_currentColors[(size_t) WidgetColorIdx::FindMatch]);
+
+ return true;
+}
+
+bool TerminalView::paintSelection(QPainter &p, const QRectF &cellRect, const QPoint gridPos) const
+{
+ bool isInSelection = false;
+ const int pos = d->m_surface->gridToPos(gridPos);
+
+ if (d->m_selection)
+ isInSelection = pos >= d->m_selection->start && pos < d->m_selection->end;
+
+ if (isInSelection)
+ p.fillRect(cellRect, d->m_currentColors[(size_t) WidgetColorIdx::Selection]);
+
+ return isInSelection;
+}
+
+int TerminalView::paintCell(QPainter &p,
+ const QRectF &cellRect,
+ QPoint gridPos,
+ const TerminalCell &cell,
+ QFont &f,
+ QList<SearchHit>::const_iterator &searchIt) const
+{
+ bool paintBackground = !paintSelection(p, cellRect, gridPos)
+ && !paintFindMatches(p, searchIt, cellRect, gridPos);
+
+ bool isDefaultBg = std::holds_alternative<int>(cell.backgroundColor)
+ && std::get<int>(cell.backgroundColor) == 17;
+
+ if (paintBackground && !isDefaultBg)
+ p.fillRect(cellRect, toQColor(cell.backgroundColor));
+
+ p.setPen(toQColor(cell.foregroundColor));
+
+ f.setBold(cell.bold);
+ f.setItalic(cell.italic);
+
+ if (!cell.text.isEmpty()) {
+ const auto r = GlyphCache::instance().get(f, cell.text);
+
+ if (r) {
+ const auto brSize = r->boundingRect().size();
+ QPointF brOffset;
+ if (brSize.width() > cellRect.size().width())
+ brOffset.setX(-(brSize.width() - cellRect.size().width()) / 2.0);
+ if (brSize.height() > cellRect.size().height())
+ brOffset.setY(-(brSize.height() - cellRect.size().height()) / 2.0);
+
+ QPointF finalPos = cellRect.topLeft() + brOffset;
+
+ p.drawGlyphRun(finalPos, *r);
+
+ bool tempLink = false;
+ if (d->m_linkSelection) {
+ int chPos = d->m_surface->gridToPos(gridPos);
+ tempLink = chPos >= d->m_linkSelection->start && chPos < d->m_linkSelection->end;
+ }
+ if (cell.underlineStyle != QTextCharFormat::NoUnderline || cell.strikeOut || tempLink) {
+ QTextItem::RenderFlags flags;
+ //flags.setFlag(QTextItem::RenderFlag::Underline, cell.format.fontUnderline());
+ flags.setFlag(QTextItem::StrikeOut, cell.strikeOut);
+ finalPos.setY(finalPos.y() + r->rawFont().ascent());
+ drawTextItemDecoration(p,
+ finalPos,
+ tempLink ? QTextCharFormat::DashUnderline
+ : cell.underlineStyle,
+ flags,
+ cellRect.size().width(),
+ {},
+ r->rawFont());
+ }
+ }
+ }
+
+ return cell.width;
+}
+
+void TerminalView::paintCursor(QPainter &p) const
+{
+ auto cursor = d->m_surface->cursor();
+
+ const int cursorCellWidth = d->m_surface->cellWidthAt(cursor.position.x(), cursor.position.y());
+
+ if (!d->m_preEditString.isEmpty()) {
+ cursor.shape = Cursor::Shape::Underline;
+ } else if (d->m_passwordModeActive) {
+ QRectF cursorRect = QRectF(gridToGlobal(cursor.position),
+ gridToGlobal({cursor.position.x() + cursorCellWidth,
+ cursor.position.y()},
+ true))
+ .toAlignedRect();
+
+ const qreal dpr = p.device()->devicePixelRatioF();
+ const QString key = QString("terminalpasswordlock-")
+ % QString::number(cursorRect.size().height())
+ % "@" % QString::number(dpr);
+ QPixmap px;
+ if (!QPixmapCache::find(key, &px)) {
+ const QPixmap lock(":/terminal/images/passwordlock.png");
+ px = lock.scaledToHeight(cursorRect.size().height() * dpr, Qt::SmoothTransformation);
+ px.setDevicePixelRatio(dpr);
+ QPixmapCache::insert(key, px);
+ }
+
+ p.drawPixmap(cursorRect.topLeft(), px);
+
+ return;
+ }
+ const bool blinkState = !cursor.blink || d->m_cursorBlinkState || !d->m_allowBlinkingCursor
+ || !d->m_cursorBlinkTimer.isActive();
+
+ if (cursor.visible && blinkState) {
+ QRectF cursorRect = QRectF(gridToGlobal(cursor.position),
+ gridToGlobal({cursor.position.x() + cursorCellWidth,
+ cursor.position.y()},
+ true))
+ .toAlignedRect();
+
+ cursorRect.adjust(1, 1, -1, -1);
+
+ QPen pen(Qt::white, 0, Qt::SolidLine);
+ p.setPen(pen);
+
+ if (hasFocus()) {
+ QPainter::CompositionMode oldMode = p.compositionMode();
+ p.setCompositionMode(QPainter::RasterOp_NotDestination);
+ switch (cursor.shape) {
+ case Cursor::Shape::Block:
+ p.fillRect(cursorRect, p.pen().brush());
+ break;
+ case Cursor::Shape::Underline:
+ p.drawLine(cursorRect.bottomLeft(), cursorRect.bottomRight());
+ break;
+ case Cursor::Shape::LeftBar:
+ p.drawLine(cursorRect.topLeft(), cursorRect.bottomLeft());
+ break;
+ }
+ p.setCompositionMode(oldMode);
+ } else {
+ p.drawRect(cursorRect);
+ }
+ }
+}
+
+void TerminalView::paintPreedit(QPainter &p) const
+{
+ auto cursor = d->m_surface->cursor();
+ if (!d->m_preEditString.isEmpty()) {
+ QRectF rect = QRectF(gridToGlobal(cursor.position),
+ gridToGlobal({cursor.position.x(), cursor.position.y()}, true, true));
+
+ rect.setWidth(viewport()->width() - rect.x());
+
+ p.setPen(toQColor((int) WidgetColorIdx::Foreground));
+ QFont f = font();
+ f.setUnderline(true);
+ p.setFont(f);
+ p.drawText(rect, Qt::TextDontClip | Qt::TextWrapAnywhere, d->m_preEditString);
+ }
+}
+
+void TerminalView::paintCells(QPainter &p, QPaintEvent *event) const
+{
+ QFont f = font();
+
+ const int scrollOffset = verticalScrollBar()->value();
+
+ const int maxRow = d->m_surface->fullSize().height();
+ const int startRow = qFloor((qreal) event->rect().y() / d->m_cellSize.height()) + scrollOffset;
+ const int endRow = qMin(maxRow,
+ qCeil((event->rect().y() + event->rect().height())
+ / d->m_cellSize.height())
+ + scrollOffset);
+
+ QList<SearchHit>::const_iterator searchIt
+ = std::lower_bound(searchHits().constBegin(),
+ searchHits().constEnd(),
+ startRow,
+ [this](const SearchHit &hit, int value) {
+ return d->m_surface->posToGrid(hit.start).y() < value;
+ });
+
+ for (int cellY = startRow; cellY < endRow; ++cellY) {
+ for (int cellX = 0; cellX < d->m_surface->liveSize().width();) {
+ const auto cell = d->m_surface->fetchCell(cellX, cellY);
+
+ QRectF cellRect(gridToGlobal({cellX, cellY}),
+ QSizeF{d->m_cellSize.width() * cell.width, d->m_cellSize.height()});
+
+ int numCells = paintCell(p, cellRect, {cellX, cellY}, cell, f, searchIt);
+
+ cellX += numCells;
+ }
+ }
+}
+
+void TerminalView::paintDebugSelection(QPainter &p, const Selection &selection) const
+{
+ auto s = globalToViewport(gridToGlobal(d->m_surface->posToGrid(selection.start)).toPoint());
+ const auto e = globalToViewport(
+ gridToGlobal(d->m_surface->posToGrid(selection.end), true).toPoint());
+
+ p.setPen(QPen(Qt::green, 1, Qt::DashLine));
+ p.drawLine(s.x(), 0, s.x(), height());
+ p.drawLine(0, s.y(), width(), s.y());
+
+ p.setPen(QPen(Qt::red, 1, Qt::DashLine));
+
+ p.drawLine(e.x(), 0, e.x(), height());
+ p.drawLine(0, e.y(), width(), e.y());
+}
+
+void TerminalView::paintEvent(QPaintEvent *event)
+{
+ QElapsedTimer t;
+ t.start();
+ event->accept();
+ QPainter p(viewport());
+
+ p.save();
+
+ if (paintLog().isDebugEnabled())
+ p.fillRect(event->rect(), QColor::fromRgb(rand() % 60, rand() % 60, rand() % 60));
+ else
+ p.fillRect(event->rect(), d->m_currentColors[(size_t) WidgetColorIdx::Background]);
+
+ int scrollOffset = verticalScrollBar()->value();
+ int offset = -(scrollOffset * d->m_cellSize.height());
+
+ qreal margin = topMargin();
+
+ p.translate(QPointF{0.0, offset + margin});
+
+ paintCells(p, event);
+ paintCursor(p);
+ paintPreedit(p);
+
+ p.restore();
+
+ p.fillRect(QRectF{{0, 0}, QSizeF{(qreal) width(), topMargin()}},
+ d->m_currentColors[(size_t) WidgetColorIdx::Background]);
+
+ if (selectionLog().isDebugEnabled()) {
+ if (d->m_selection)
+ paintDebugSelection(p, *d->m_selection);
+ if (d->m_linkSelection)
+ paintDebugSelection(p, *d->m_linkSelection);
+ }
+
+ if (paintLog().isDebugEnabled()) {
+ QToolTip::showText(this->mapToGlobal(QPoint(width() - 200, 0)),
+ QString("Paint: %1ms").arg(t.elapsed()));
+ }
+}
+
+void TerminalView::keyPressEvent(QKeyEvent *event)
+{
+ // Don't blink during typing
+ if (d->m_cursorBlinkTimer.isActive()) {
+ d->m_cursorBlinkTimer.start();
+ d->m_cursorBlinkState = true;
+ }
+
+ if (event->key() == Qt::Key_Control) {
+ if (!d->m_linkSelection.has_value() && checkLinkAt(mapFromGlobal(QCursor::pos()))) {
+ setCursor(Qt::PointingHandCursor);
+ }
+ }
+
+ event->accept();
+
+ d->m_surface->sendKey(event);
+}
+
+void TerminalView::keyReleaseEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Control && d->m_linkSelection.has_value()) {
+ d->m_linkSelection.reset();
+ setCursor(Qt::IBeamCursor);
+ updateViewport();
+ }
+}
+
+void TerminalView::applySizeChange()
+{
+ QSize newLiveSize = {
+ qFloor((qreal) (viewport()->size().width()) / (qreal) d->m_cellSize.width()),
+ qFloor((qreal) (viewport()->size().height()) / d->m_cellSize.height()),
+ };
+
+ if (newLiveSize.height() <= 0)
+ newLiveSize.setHeight(1);
+
+ if (newLiveSize.width() <= 0)
+ newLiveSize.setWidth(1);
+
+ resizePty(newLiveSize);
+ d->m_surface->resize(newLiveSize);
+ flushVTerm(true);
+}
+
+void TerminalView::updateScrollBars()
+{
+ int scrollSize = d->m_surface->fullSize().height() - d->m_surface->liveSize().height();
+ verticalScrollBar()->setRange(0, scrollSize);
+ verticalScrollBar()->setValue(verticalScrollBar()->maximum());
+ updateViewport();
+}
+
+void TerminalView::resizeEvent(QResizeEvent *event)
+{
+ event->accept();
+
+ // If increasing in size, we'll trigger libvterm to call sb_popline in
+ // order to pull lines out of the history. This will cause the scrollback
+ // to decrease in size which reduces the size of the verticalScrollBar.
+ // That will trigger a scroll offset increase which we want to ignore.
+ d->m_ignoreScroll = true;
+
+ applySizeChange();
+
+ setSelection(std::nullopt);
+ d->m_ignoreScroll = false;
+}
+
+QRect TerminalView::gridToViewport(QRect rect) const
+{
+ int offset = verticalScrollBar()->value();
+
+ int startRow = rect.y() - offset;
+ int numRows = rect.height();
+ int numCols = rect.width();
+
+ QRectF r{rect.x() * d->m_cellSize.width(),
+ startRow * d->m_cellSize.height(),
+ numCols * d->m_cellSize.width(),
+ numRows * d->m_cellSize.height()};
+
+ r.translate(0, topMargin());
+
+ return r.toAlignedRect();
+}
+
+QPoint TerminalView::toGridPos(QMouseEvent *event) const
+{
+ return globalToGrid(QPointF(event->pos()) + QPointF(0, -topMargin() + 0.5));
+}
+
+void TerminalView::updateViewport()
+{
+ viewport()->update();
+}
+
+void TerminalView::updateViewportRect(const QRect &rect)
+{
+ if (d->m_passwordModeActive)
+ viewport()->update();
+ else
+ viewport()->update(rect);
+}
+
+void TerminalView::focusInEvent(QFocusEvent *)
+{
+ updateViewport();
+ configBlinkTimer();
+ selectionChanged(d->m_selection);
+ d->m_surface->sendFocus(true);
+}
+void TerminalView::focusOutEvent(QFocusEvent *)
+{
+ updateViewport();
+ configBlinkTimer();
+ d->m_surface->sendFocus(false);
+}
+
+void TerminalView::inputMethodEvent(QInputMethodEvent *event)
+{
+ d->m_preEditString = event->preeditString();
+
+ if (event->commitString().isEmpty()) {
+ updateViewport();
+ return;
+ }
+
+ d->m_surface->sendKey(event->commitString());
+}
+
+void TerminalView::mousePressEvent(QMouseEvent *event)
+{
+ if (d->m_allowMouseTracking) {
+ d->m_surface->mouseMove(toGridPos(event), event->modifiers());
+ d->m_surface->mouseButton(event->button(), true, event->modifiers());
+ }
+
+ d->m_scrollDirection = 0;
+
+ d->m_activeMouseSelect.start = viewportToGlobal(event->pos());
+
+ if (event->button() == Qt::LeftButton && event->modifiers() & Qt::ControlModifier) {
+ if (d->m_linkSelection) {
+ if (event->modifiers() & Qt::ShiftModifier) {
+ copyLinkToClipboard();
+ return;
+ }
+
+ linkActivated(d->m_linkSelection->link);
+ }
+ return;
+ }
+
+ if (event->button() == Qt::LeftButton) {
+ if (std::chrono::system_clock::now() - d->m_lastDoubleClick < 500ms) {
+ d->m_selectLineMode = true;
+ const Selection newSelection{d->m_surface->gridToPos(
+ {0,
+ d->m_surface->posToGrid(d->m_selection->start).y()}),
+ d->m_surface->gridToPos(
+ {d->m_surface->liveSize().width(),
+ d->m_surface->posToGrid(d->m_selection->end).y()}),
+ false};
+ setSelection(newSelection);
+ } else {
+ d->m_selectLineMode = false;
+ int pos = d->m_surface->gridToPos(globalToGrid(viewportToGlobal(event->pos())));
+ setSelection(Selection{pos, pos, false});
+ }
+ event->accept();
+ updateViewport();
+ } else if (event->button() == Qt::RightButton) {
+ if (event->modifiers() & Qt::ShiftModifier) {
+ contextMenuRequested(event->pos());
+ } else if (d->m_selection) {
+ copyToClipboard();
+ setSelection(std::nullopt);
+ } else {
+ pasteFromClipboard();
+ }
+ } else if (event->button() == Qt::MiddleButton) {
+ QClipboard *clipboard = QApplication::clipboard();
+ if (clipboard->supportsSelection()) {
+ const QString selectionText = clipboard->text(QClipboard::Selection);
+ if (!selectionText.isEmpty())
+ d->m_surface->pasteFromClipboard(selectionText);
+ } else {
+ d->m_surface->pasteFromClipboard(textFromSelection());
+ }
+ }
+}
+void TerminalView::mouseMoveEvent(QMouseEvent *event)
+{
+ if (d->m_allowMouseTracking)
+ d->m_surface->mouseMove(toGridPos(event), event->modifiers());
+
+ if (d->m_selection && event->buttons() & Qt::LeftButton) {
+ Selection newSelection = *d->m_selection;
+ int scrollVelocity = 0;
+ if (event->pos().y() < 0) {
+ scrollVelocity = (event->pos().y());
+ } else if (event->pos().y() > viewport()->height()) {
+ scrollVelocity = (event->pos().y() - viewport()->height());
+ }
+
+ if ((scrollVelocity != 0) != d->m_scrollTimer.isActive()) {
+ if (scrollVelocity != 0)
+ d->m_scrollTimer.start();
+ else
+ d->m_scrollTimer.stop();
+ }
+
+ d->m_scrollDirection = scrollVelocity;
+
+ if (d->m_scrollTimer.isActive() && scrollVelocity != 0) {
+ const std::chrono::milliseconds scrollInterval = 1000ms / qAbs(scrollVelocity);
+ if (d->m_scrollTimer.intervalAsDuration() != scrollInterval)
+ d->m_scrollTimer.setInterval(scrollInterval);
+ }
+
+ QPoint posBoundedToViewport = event->pos();
+ posBoundedToViewport.setX(qBound(0, posBoundedToViewport.x(), viewport()->width()));
+
+ int start = d->m_surface->gridToPos(globalToGrid(d->m_activeMouseSelect.start));
+ int newEnd = d->m_surface->gridToPos(globalToGrid(viewportToGlobal(posBoundedToViewport)));
+
+ if (start > newEnd) {
+ std::swap(start, newEnd);
+ }
+ if (start < 0)
+ start = 0;
+
+ if (d->m_selectLineMode) {
+ newSelection.start = d->m_surface->gridToPos({0, d->m_surface->posToGrid(start).y()});
+ newSelection.end = d->m_surface->gridToPos(
+ {d->m_surface->liveSize().width(), d->m_surface->posToGrid(newEnd).y()});
+ } else {
+ newSelection.start = start;
+ newSelection.end = newEnd;
+ }
+
+ setSelection(newSelection);
+ } else if (event->modifiers() & Qt::ControlModifier) {
+ checkLinkAt(event->pos());
+ } else if (d->m_linkSelection) {
+ d->m_linkSelection.reset();
+ updateViewport();
+ }
+
+ if (d->m_linkSelection) {
+ setCursor(Qt::PointingHandCursor);
+ } else {
+ setCursor(Qt::IBeamCursor);
+ }
+}
+
+void TerminalView::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (d->m_allowMouseTracking) {
+ d->m_surface->mouseMove(toGridPos(event), event->modifiers());
+ d->m_surface->mouseButton(event->button(), false, event->modifiers());
+ }
+
+ d->m_scrollTimer.stop();
+
+ if (d->m_selection && event->button() == Qt::LeftButton) {
+ if (d->m_selection->end - d->m_selection->start == 0)
+ setSelection(std::nullopt);
+ else
+ setSelection(Selection{d->m_selection->start, d->m_selection->end, true});
+ }
+}
+
+void TerminalView::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (d->m_allowMouseTracking) {
+ d->m_surface->mouseMove(toGridPos(event), event->modifiers());
+ d->m_surface->mouseButton(event->button(), true, event->modifiers());
+ d->m_surface->mouseButton(event->button(), false, event->modifiers());
+ }
+
+ const auto hit = textAt(event->pos());
+
+ setSelection(Selection{hit.start, hit.end, true});
+
+ d->m_lastDoubleClick = std::chrono::system_clock::now();
+
+ event->accept();
+}
+
+void TerminalView::wheelEvent(QWheelEvent *event)
+{
+ verticalScrollBar()->event(event);
+
+ if (!d->m_allowMouseTracking)
+ return;
+
+ if (event->angleDelta().ry() > 0)
+ d->m_surface->mouseButton(Qt::ExtraButton1, true, event->modifiers());
+ else if (event->angleDelta().ry() < 0)
+ d->m_surface->mouseButton(Qt::ExtraButton2, true, event->modifiers());
+}
+
+bool TerminalView::checkLinkAt(const QPoint &pos)
+{
+ const TextAndOffsets hit = textAt(pos);
+
+ if (hit.text.size() > 0) {
+ QString t = QString::fromUcs4(hit.text.c_str(), hit.text.size()).trimmed();
+ auto newLink = toLink(t);
+ if (newLink) {
+ const LinkSelection newSelection = LinkSelection{{hit.start, hit.end}, newLink.value()};
+ if (!d->m_linkSelection || *d->m_linkSelection != newSelection) {
+ d->m_linkSelection = newSelection;
+ updateViewport();
+ }
+
+ return true;
+ }
+ }
+
+ if (d->m_linkSelection) {
+ d->m_linkSelection.reset();
+ updateViewport();
+ }
+ return false;
+}
+
+TerminalView::TextAndOffsets TerminalView::textAt(const QPoint &pos) const
+{
+ auto it = d->m_surface->iteratorAt(globalToGrid(viewportToGlobal(pos)));
+ auto itRev = d->m_surface->rIteratorAt(globalToGrid(viewportToGlobal(pos)));
+
+ std::u32string whiteSpaces = U" \t\x00a0";
+
+ const bool inverted = whiteSpaces.find(*it) != std::u32string::npos || *it == 0;
+
+ auto predicate = [inverted, whiteSpaces](const std::u32string::value_type &ch) {
+ if (inverted)
+ return ch != 0 && whiteSpaces.find(ch) == std::u32string::npos;
+ else
+ return ch == 0 || whiteSpaces.find(ch) != std::u32string::npos;
+ };
+
+ auto itRight = std::find_if(it, d->m_surface->end(), predicate);
+ auto itLeft = std::find_if(itRev, d->m_surface->rend(), predicate);
+
+ std::u32string text;
+ std::copy(itLeft.base(), it, std::back_inserter(text));
+ std::copy(it, itRight, std::back_inserter(text));
+ std::transform(text.begin(), text.end(), text.begin(), [](const char32_t &ch) {
+ return ch == 0 ? U' ' : ch;
+ });
+
+ return {(itLeft.base()).position(), itRight.position(), text};
+}
+
+bool TerminalView::event(QEvent *event)
+{
+ if (event->type() == QEvent::Paint) {
+ QPainter p(this);
+ p.fillRect(QRect(QPoint(0, 0), size()),
+ d->m_currentColors[(size_t) WidgetColorIdx::Background]);
+ return true;
+ }
+
+ // TODO: Is this necessary?
+ if (event->type() == QEvent::KeyPress) {
+ auto k = static_cast<QKeyEvent *>(event);
+ keyPressEvent(k);
+ return true;
+ }
+ if (event->type() == QEvent::KeyRelease) {
+ auto k = static_cast<QKeyEvent *>(event);
+ keyReleaseEvent(k);
+ return true;
+ }
+
+ return QAbstractScrollArea::event(event);
+}
+
+} // namespace TerminalSolution
diff --git a/src/libs/solutions/terminal/terminalview.h b/src/libs/solutions/terminal/terminalview.h
new file mode 100644
index 00000000000..4745c63ee15
--- /dev/null
+++ b/src/libs/solutions/terminal/terminalview.h
@@ -0,0 +1,227 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "terminal_global.h"
+#include "terminalsurface.h"
+
+#include <QAbstractScrollArea>
+#include <QAction>
+#include <QTextLayout>
+#include <QTimer>
+
+#include <chrono>
+#include <memory>
+#include <optional>
+
+namespace TerminalSolution {
+
+class SurfaceIntegration;
+class TerminalViewPrivate;
+
+struct SearchHit
+{
+ int start{-1};
+ int end{-1};
+
+ bool operator!=(const SearchHit &other) const
+ {
+ return start != other.start || end != other.end;
+ }
+ bool operator==(const SearchHit &other) const { return !operator!=(other); }
+};
+
+QString defaultFontFamily();
+int defaultFontSize();
+
+class TERMINAL_EXPORT TerminalView : public QAbstractScrollArea
+{
+ friend class CellIterator;
+ Q_OBJECT
+public:
+ enum class WidgetColorIdx {
+ Foreground = ColorIndex::Foreground,
+ Background = ColorIndex::Background,
+ Selection,
+ FindMatch,
+ };
+
+ TerminalView(QWidget *parent = nullptr);
+ ~TerminalView() override;
+
+ void setAllowBlinkingCursor(bool allow);
+ bool allowBlinkingCursor() const;
+
+ void setFont(const QFont &font);
+
+ void copyToClipboard();
+ void pasteFromClipboard();
+ void copyLinkToClipboard();
+
+ struct Selection
+ {
+ int start;
+ int end;
+ bool final{false};
+
+ bool operator!=(const Selection &other) const
+ {
+ return start != other.start || end != other.end || final != other.final;
+ }
+
+ bool operator==(const Selection &other) const { return !operator!=(other); }
+ };
+
+ std::optional<Selection> selection() const;
+ void clearSelection();
+
+ void zoomIn();
+ void zoomOut();
+
+ void moveCursorWordLeft();
+ void moveCursorWordRight();
+
+ void clearContents();
+
+ void setSurfaceIntegration(SurfaceIntegration *surfaceIntegration);
+ void setColors(const std::array<QColor, 20> &colors);
+
+ void setPasswordMode(bool passwordMode);
+
+ struct Link
+ {
+ QString text;
+ int targetLine = 0;
+ int targetColumn = 0;
+ };
+
+ struct LinkSelection : public Selection
+ {
+ Link link;
+
+ bool operator!=(const LinkSelection &other) const
+ {
+ return link.text != other.link.text || link.targetLine != other.link.targetLine
+ || link.targetColumn != other.link.targetColumn || Selection::operator!=(other);
+ }
+ };
+
+ virtual qint64 writeToPty(const QByteArray &data)
+ {
+ Q_UNUSED(data);
+ return 0;
+ }
+ void writeToTerminal(const QByteArray &data, bool forceFlush);
+
+ void restart();
+
+ virtual const QList<SearchHit> &searchHits() const
+ {
+ static QList<SearchHit> noHits;
+ return noHits;
+ }
+
+ virtual void resizePty(QSize newSize) { Q_UNUSED(newSize); }
+ virtual void setClipboard(const QString &text) { Q_UNUSED(text); }
+ virtual std::optional<Link> toLink(const QString &text)
+ {
+ Q_UNUSED(text);
+ return std::nullopt;
+ }
+
+ virtual void selectionChanged(const std::optional<Selection> &newSelection)
+ {
+ Q_UNUSED(newSelection);
+ }
+ virtual void linkActivated(const Link &link) { Q_UNUSED(link); }
+ virtual void contextMenuRequested(const QPoint &pos) { Q_UNUSED(pos); }
+
+ virtual void surfaceChanged(){};
+
+ TerminalSurface *surface() const;
+
+protected:
+ void paintEvent(QPaintEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+ void keyReleaseEvent(QKeyEvent *event) override;
+ void resizeEvent(QResizeEvent *event) override;
+ void wheelEvent(QWheelEvent *event) override;
+ void focusInEvent(QFocusEvent *event) override;
+ void focusOutEvent(QFocusEvent *event) override;
+ void inputMethodEvent(QInputMethodEvent *event) override;
+
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseDoubleClickEvent(QMouseEvent *event) override;
+
+ bool event(QEvent *event) override;
+
+protected:
+ void setupSurface();
+
+ int paintCell(QPainter &p,
+ const QRectF &cellRect,
+ QPoint gridPos,
+ const TerminalCell &cell,
+ QFont &f,
+ QList<SearchHit>::const_iterator &searchIt) const;
+ void paintCells(QPainter &painter, QPaintEvent *event) const;
+ void paintCursor(QPainter &painter) const;
+ void paintPreedit(QPainter &painter) const;
+ bool paintFindMatches(QPainter &painter,
+ QList<SearchHit>::const_iterator &searchIt,
+ const QRectF &cellRect,
+ const QPoint gridPos) const;
+
+ bool paintSelection(QPainter &painter, const QRectF &cellRect, const QPoint gridPos) const;
+ void paintDebugSelection(QPainter &painter, const Selection &selection) const;
+
+ qreal topMargin() const;
+
+ QPoint viewportToGlobal(QPoint p) const;
+ QPoint globalToViewport(QPoint p) const;
+ QPoint globalToGrid(QPointF p) const;
+ QPointF gridToGlobal(QPoint p, bool bottom = false, bool right = false) const;
+ QRect gridToViewport(QRect rect) const;
+ QPoint toGridPos(QMouseEvent *event) const;
+
+ void updateViewport();
+ void updateViewportRect(const QRect &rect);
+
+ int textLineFromPixel(int y) const;
+ std::optional<int> textPosFromPoint(const QTextLayout &textLayout, QPoint p) const;
+
+ std::optional<QTextLayout::FormatRange> selectionToFormatRange(Selection selection,
+ const QTextLayout &layout,
+ int rowOffset) const;
+
+ bool checkLinkAt(const QPoint &pos);
+
+ struct TextAndOffsets
+ {
+ int start;
+ int end;
+ std::u32string text;
+ };
+
+ TextAndOffsets textAt(const QPoint &pos) const;
+
+ void applySizeChange();
+ void updateScrollBars();
+
+ void flushVTerm(bool force);
+
+ bool setSelection(const std::optional<Selection> &selection, bool scroll = true);
+ QString textFromSelection() const;
+
+ void configBlinkTimer();
+
+ QColor toQColor(std::variant<int, QColor> color) const;
+
+private:
+ std::unique_ptr<TerminalViewPrivate> d;
+};
+
+} // namespace TerminalSolution
diff --git a/src/libs/sqlite/sqlite.qbs b/src/libs/sqlite/sqlite.qbs
index f0c58790006..c25bd5f3fc0 100644
--- a/src/libs/sqlite/sqlite.qbs
+++ b/src/libs/sqlite/sqlite.qbs
@@ -1,9 +1,13 @@
-import qbs 1.0
+import qbs.Utilities
QtcLibrary {
name: "Sqlite"
+ Depends { name: "Utils" }
Depends { name: "sqlite_sources" }
+ Depends { name: "Qt.core"; required:false }
+ condition: Qt.core.present && Utilities.versionCompare(Qt.core.version, "6.4.3") >= 0
+
property string exportedIncludeDir: sqlite_sources.includeDir
Export {
diff --git a/src/libs/tracing/CMakeLists.txt b/src/libs/tracing/CMakeLists.txt
index 3e0a7237f6c..e89f31f9cc8 100644
--- a/src/libs/tracing/CMakeLists.txt
+++ b/src/libs/tracing/CMakeLists.txt
@@ -1,11 +1,3 @@
-if (WITH_TESTS)
- set(TEST_SOURCES
- runscenegraphtest.cpp runscenegraphtest.h
- )
-else()
- set(TEST_SOURCES "")
-endif()
-
set(TRACING_CPP_SOURCES
flamegraph.cpp flamegraph.h
flamegraphattached.h
@@ -40,8 +32,6 @@ add_qtc_library(Tracing
FEATURE_INFO
DEPENDS Utils Qt::Quick
PUBLIC_DEPENDS Qt::Widgets Qt::Qml
- SOURCES
- ${TEST_SOURCES}
)
if (NOT TARGET Tracing)
diff --git a/src/libs/tracing/qml/CategoryLabel.qml b/src/libs/tracing/qml/CategoryLabel.qml
index 58704aa175a..db58b13c0ff 100644
--- a/src/libs/tracing/qml/CategoryLabel.qml
+++ b/src/libs/tracing/qml/CategoryLabel.qml
@@ -15,7 +15,7 @@ Item {
property bool expanded: model && model.expanded
property var labels: (expanded && model) ? model.labels : []
- property bool dragging
+ property bool isDragging
property int visualIndex
property int dragOffset
property Item draggerParent
@@ -38,10 +38,10 @@ Item {
id: dragArea
anchors.fill: txt
drag.target: dragger
- cursorShape: labelContainer.dragging ? Qt.ClosedHandCursor : Qt.OpenHandCursor
+ cursorShape: labelContainer.isDragging ? Qt.ClosedHandCursor : Qt.OpenHandCursor
// Account for parent change below
- drag.minimumY: labelContainer.dragging ? 0 : -labelContainer.dragOffset
- drag.maximumY: labelContainer.visibleHeight - (labelContainer.dragging ? 0 : labelContainer.dragOffset)
+ drag.minimumY: labelContainer.isDragging ? 0 : -labelContainer.dragOffset
+ drag.maximumY: labelContainer.visibleHeight - (labelContainer.isDragging ? 0 : labelContainer.dragOffset)
drag.axis: Drag.YAxis
hoverEnabled: true
ToolTip {
@@ -221,7 +221,7 @@ Item {
MouseArea {
anchors.top: dragArea.bottom
- anchors.bottom: labelContainer.dragging ? labelContainer.bottom : dragArea.bottom
+ anchors.bottom: labelContainer.isDragging ? labelContainer.bottom : dragArea.bottom
anchors.left: labelContainer.left
anchors.right: labelContainer.right
cursorShape: dragArea.cursorShape
diff --git a/src/libs/tracing/qml/TimelineLabels.qml b/src/libs/tracing/qml/TimelineLabels.qml
index 754f36e1902..99f36467875 100644
--- a/src/libs/tracing/qml/TimelineLabels.qml
+++ b/src/libs/tracing/qml/TimelineLabels.qml
@@ -26,7 +26,7 @@ Flickable {
// Dispatch the cursor shape to all labels. When dragging the DropArea receiving
// the drag events is not necessarily related to the MouseArea receiving the mouse
// events, so we can't use the drag events to determine the cursor shape.
- property bool dragging: false
+ property bool isDragging: false
Column {
id: categoryContent
@@ -75,10 +75,10 @@ Flickable {
model: modelData
notesModel: categories.modelProxy.notes
visualIndex: loader.visualIndex
- dragging: categories.dragging
+ isDragging: categories.isDragging
reverseSelect: categories.reverseSelect
- onDragStarted: categories.dragging = true
- onDragStopped: categories.dragging = false
+ onDragStarted: categories.isDragging = true
+ onDragStopped: categories.isDragging = false
draggerParent: categories
contentY: categories.contentY
contentHeight: categories.contentHeight
diff --git a/src/libs/tracing/runscenegraphtest.cpp b/src/libs/tracing/runscenegraphtest.cpp
deleted file mode 100644
index d88dd03271f..00000000000
--- a/src/libs/tracing/runscenegraphtest.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "runscenegraphtest.h"
-
-#include <QTest>
-#include <QString>
-#include <QOpenGLContext>
-#include <QOffscreenSurface>
-
-namespace Timeline {
-
-void runSceneGraphTest(QSGNode *node)
-{
- Q_UNUSED(node)
-
- QSurfaceFormat format;
- format.setStencilBufferSize(8);
- format.setDepthBufferSize(24);
-
- QOpenGLContext context;
- context.setFormat(format);
- QVERIFY(context.create());
-
- QOffscreenSurface surface;
- surface.setFormat(format);
- surface.create();
-
- QVERIFY(context.makeCurrent(&surface));
-
- context.doneCurrent();
-}
-
-} // namespace Timeline
diff --git a/src/libs/tracing/runscenegraphtest.h b/src/libs/tracing/runscenegraphtest.h
deleted file mode 100644
index e76702d6818..00000000000
--- a/src/libs/tracing/runscenegraphtest.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include "tracing_global.h"
-#include <QSGNode>
-
-namespace Timeline {
-
-void TRACING_EXPORT runSceneGraphTest(QSGNode *node);
-
-} // namespace Timeline
diff --git a/src/libs/tracing/timelinemodel.cpp b/src/libs/tracing/timelinemodel.cpp
index d0c88f55280..46ab37f3f5a 100644
--- a/src/libs/tracing/timelinemodel.cpp
+++ b/src/libs/tracing/timelinemodel.cpp
@@ -83,6 +83,54 @@ void TimelineModel::computeNesting()
}
}
+/*!
+ Compute all ranges' nesting level. Sort them into rows by finding the
+ first row that has "an open spot".
+*/
+QList<int> TimelineModel::computeRows(int *maxlevel) const
+{
+ *maxlevel = 0;
+ std::list<int> rows;
+ QList<int> levels;
+ levels.reserve(d->ranges.count());
+ for (int range = 0; range != count(); ++range) {
+ TimelineModelPrivate::Range &current = d->ranges[range];
+ // find first row for inserting
+ int level = 0;
+ auto rowIt = rows.begin();
+ forever {
+ if (rowIt == rows.end()) {
+ // didn't find a row, insert new one
+ rows.push_back(range);
+ break;
+ }
+ TimelineModelPrivate::Range &rowItem = d->ranges[*rowIt];
+ if (rowItem.start + rowItem.duration < current.start) {
+ // We've completely passed the item
+ // Use this row for the range
+ *rowIt = range;
+ break;
+ }
+ ++rowIt;
+ ++level;
+ }
+ levels.append(level);
+ if (level > *maxlevel)
+ *maxlevel = level;
+ // remove other rows that we passed
+ while (rowIt != rows.end()) {
+ TimelineModelPrivate::Range &rowItem = d->ranges[*rowIt];
+ if (rowItem.start + rowItem.duration < current.start) {
+ // We've completely passed the item, remove
+ rowIt = rows.erase(rowIt);
+ } else {
+ ++rowIt;
+ }
+ }
+ }
+ return levels;
+}
+
int TimelineModel::collapsedRowCount() const
{
return d->collapsedRowCount;
diff --git a/src/libs/tracing/timelinemodel.h b/src/libs/tracing/timelinemodel.h
index dd89fb0c5f4..5720909d563 100644
--- a/src/libs/tracing/timelinemodel.h
+++ b/src/libs/tracing/timelinemodel.h
@@ -133,6 +133,7 @@ protected:
int insertStart(qint64 startTime, int selectionId);
void insertEnd(int index, qint64 duration);
void computeNesting();
+ QList<int> computeRows(int *maxlevel) const;
void setCollapsedRowCount(int rows);
void setExpandedRowCount(int rows);
diff --git a/src/libs/tracing/timelinerenderer.cpp b/src/libs/tracing/timelinerenderer.cpp
index 07abb071445..ace3efe3ffe 100644
--- a/src/libs/tracing/timelinerenderer.cpp
+++ b/src/libs/tracing/timelinerenderer.cpp
@@ -183,23 +183,28 @@ void TimelineRenderer::wheelEvent(QWheelEvent *event)
// ctrl-wheel means zoom
if (event->modifiers() & Qt::ControlModifier) {
event->setAccepted(true);
+ if (event->angleDelta().y() == 0)
+ return;
TimelineZoomControl *zoom = zoomer();
- int degrees = (event->angleDelta().x() + event->angleDelta().y()) / 8;
- const qint64 circle = 360;
- qint64 mouseTime = event->position().toPoint().x() * zoom->windowDuration() / width() +
- zoom->windowStart();
- qint64 beforeMouse = (mouseTime - zoom->rangeStart()) * (circle - degrees) / circle;
- qint64 afterMouse = (zoom->rangeEnd() - mouseTime) * (circle - degrees) / circle;
-
- qint64 newStart = qBound(zoom->traceStart(), zoom->traceEnd(), mouseTime - beforeMouse);
- if (newStart + zoom->minimumRangeLength() > zoom->traceEnd())
- return; // too close to trace end
-
- qint64 newEnd = qBound(newStart + zoom->minimumRangeLength(), zoom->traceEnd(),
- mouseTime + afterMouse);
-
- zoom->setRange(newStart, newEnd);
+ // Handle similar to text editor, but avoid floats.
+ // angleDelta of 120 is considered a 10% change in zoom.
+ const qint64 delta = event->angleDelta().y();
+ const qint64 newDuration = qBound(zoom->minimumRangeLength(),
+ zoom->rangeDuration() * 1200 / (1200 + delta),
+ std::max(zoom->minimumRangeLength(),
+ zoom->traceDuration()));
+ const qint64 mouseTime = event->position().toPoint().x() * zoom->windowDuration() / width()
+ + zoom->windowStart();
+ // Try to keep mouseTime where it was in relation to the shown range,
+ // but keep within traceStart/End
+ const qint64 newStart
+ = qBound(zoom->traceStart(),
+ mouseTime
+ - newDuration * /*rest is mouse time position [0,1] in range:*/
+ (mouseTime - zoom->rangeStart()) / zoom->rangeDuration(),
+ std::max(zoom->traceStart(), zoom->traceEnd() - newDuration));
+ zoom->setRange(newStart, newStart + newDuration);
} else {
TimelineAbstractRenderer::wheelEvent(event);
}
diff --git a/src/libs/tracing/timelinezoomcontrol.cpp b/src/libs/tracing/timelinezoomcontrol.cpp
index f5783d09797..7d9ee28c7e8 100644
--- a/src/libs/tracing/timelinezoomcontrol.cpp
+++ b/src/libs/tracing/timelinezoomcontrol.cpp
@@ -44,7 +44,7 @@ void TimelineZoomControl::clear()
void TimelineZoomControl::setTrace(qint64 start, qint64 end)
{
- Q_ASSERT(start <= end);
+ QTC_ASSERT(start <= end, { std::swap(start, end); });
if (start != m_traceStart || end != m_traceEnd) {
m_traceStart = start;
m_traceEnd = end;
@@ -55,7 +55,7 @@ void TimelineZoomControl::setTrace(qint64 start, qint64 end)
void TimelineZoomControl::setRange(qint64 start, qint64 end)
{
- Q_ASSERT(start <= end);
+ QTC_ASSERT(start <= end, { std::swap(start, end); });
if (m_rangeStart != start || m_rangeEnd != end) {
if (m_timer.isActive()) {
m_timer.stop();
diff --git a/src/libs/tracing/tracing.qbs b/src/libs/tracing/tracing.qbs
index 465a92c8ffe..6876dccd256 100644
--- a/src/libs/tracing/tracing.qbs
+++ b/src/libs/tracing/tracing.qbs
@@ -1,60 +1,46 @@
-import qbs 1.0
-
-import QtcLibrary
-
-Project {
+QtcLibrary {
name: "Tracing"
- QtcLibrary {
- Depends { name: "Qt"; submodules: ["qml", "quick", "gui"] }
- Depends { name: "Qt.testlib"; condition: project.withAutotests }
- Depends { name: "Utils" }
-
- Group {
- name: "General"
- files: [
- "README",
- "flamegraph.cpp", "flamegraph.h",
- "flamegraphattached.h",
- "safecastable.h",
- "timelineabstractrenderer.cpp", "timelineabstractrenderer.h",
- "timelineabstractrenderer_p.h",
- "timelineformattime.cpp", "timelineformattime.h",
- "timelineitemsrenderpass.cpp", "timelineitemsrenderpass.h",
- "timelinemodel.cpp", "timelinemodel.h", "timelinemodel_p.h",
- "timelinemodelaggregator.cpp", "timelinemodelaggregator.h",
- "timelinenotesmodel.cpp", "timelinenotesmodel.h", "timelinenotesmodel_p.h",
- "timelinenotesrenderpass.cpp", "timelinenotesrenderpass.h",
- "timelineoverviewrenderer.cpp", "timelineoverviewrenderer.h",
- "timelineoverviewrenderer_p.h",
- "timelinerenderer.cpp", "timelinerenderer.h", "timelinerenderer_p.h",
- "timelinerenderpass.cpp", "timelinerenderpass.h",
- "timelinerenderstate.cpp", "timelinerenderstate.h", "timelinerenderstate_p.h",
- "timelineselectionrenderpass.cpp", "timelineselectionrenderpass.h",
- "timelinetheme.cpp", "timelinetheme.h",
- "timelinetracefile.cpp", "timelinetracefile.h",
- "timelinetracemanager.cpp", "timelinetracemanager.h",
- "timelinezoomcontrol.cpp", "timelinezoomcontrol.h",
- "traceevent.h", "traceeventtype.h", "tracestashfile.h",
- "tracingtr.h",
- ]
- }
+ Depends { name: "Qt"; submodules: ["qml", "quick", "gui"] }
+ Depends { name: "Qt.testlib"; condition: qtc.withAutotests }
+ Depends { name: "Utils" }
- Group {
- name: "Qml Files"
- Qt.core.resourcePrefix: "qt/qml/QtCreator/Tracing/"
- fileTags: "qt.core.resource_data"
- files: "qml/**"
- }
-
- Group {
- name: "Unit test utilities"
- condition: project.withAutotests
- files: [
- "runscenegraphtest.cpp", "runscenegraphtest.h"
- ]
- }
+ Group {
+ name: "General"
+ files: [
+ "README",
+ "flamegraph.cpp", "flamegraph.h",
+ "flamegraphattached.h",
+ "safecastable.h",
+ "timelineabstractrenderer.cpp", "timelineabstractrenderer.h",
+ "timelineabstractrenderer_p.h",
+ "timelineformattime.cpp", "timelineformattime.h",
+ "timelineitemsrenderpass.cpp", "timelineitemsrenderpass.h",
+ "timelinemodel.cpp", "timelinemodel.h", "timelinemodel_p.h",
+ "timelinemodelaggregator.cpp", "timelinemodelaggregator.h",
+ "timelinenotesmodel.cpp", "timelinenotesmodel.h", "timelinenotesmodel_p.h",
+ "timelinenotesrenderpass.cpp", "timelinenotesrenderpass.h",
+ "timelineoverviewrenderer.cpp", "timelineoverviewrenderer.h",
+ "timelineoverviewrenderer_p.h",
+ "timelinerenderer.cpp", "timelinerenderer.h", "timelinerenderer_p.h",
+ "timelinerenderpass.cpp", "timelinerenderpass.h",
+ "timelinerenderstate.cpp", "timelinerenderstate.h", "timelinerenderstate_p.h",
+ "timelineselectionrenderpass.cpp", "timelineselectionrenderpass.h",
+ "timelinetheme.cpp", "timelinetheme.h",
+ "timelinetracefile.cpp", "timelinetracefile.h",
+ "timelinetracemanager.cpp", "timelinetracemanager.h",
+ "timelinezoomcontrol.cpp", "timelinezoomcontrol.h",
+ "traceevent.h", "traceeventtype.h", "tracestashfile.h",
+ "tracingtr.h",
+ ]
+ }
- cpp.defines: base.concat("TRACING_LIBRARY")
+ Group {
+ name: "Qml Files"
+ Qt.core.resourcePrefix: "qt/qml/QtCreator/Tracing/"
+ fileTags: "qt.core.resource_data"
+ files: "qml/**"
}
+
+ cpp.defines: base.concat("TRACING_LIBRARY")
}
diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt
index 146aeafbe5f..6a890815d07 100644
--- a/src/libs/utils/CMakeLists.txt
+++ b/src/libs/utils/CMakeLists.txt
@@ -1,16 +1,15 @@
add_qtc_library(Utils
- DEPENDS Tasking Qt::Qml Qt::Xml
+ DEPENDS Tasking Qt::Qml Qt::Xml Spinner
PUBLIC_DEPENDS
Qt::Concurrent Qt::Core Qt::Network Qt::Gui Qt::Widgets
Qt::Core5Compat
SOURCES
../3rdparty/span/span.hpp
../3rdparty/tl_expected/include/tl/expected.hpp
- QtConcurrentTools
algorithm.h
ansiescapecodehandler.cpp ansiescapecodehandler.h
+ appinfo.cpp appinfo.h
appmainwindow.cpp appmainwindow.h
- archive.cpp archive.h
array.h
aspects.cpp aspects.h
async.cpp async.h
@@ -62,11 +61,9 @@ add_qtc_library(Utils
filesystemwatcher.cpp filesystemwatcher.h
fileutils.cpp fileutils.h
filewizardpage.cpp filewizardpage.h
- fixedsizeclicklabel.cpp fixedsizeclicklabel.h
flowlayout.cpp flowlayout.h
fsengine/fsengine.cpp fsengine/fsengine.h
fsengine/fileiconprovider.cpp fsengine/fileiconprovider.h
- functiontraits.h
futuresynchronizer.cpp futuresynchronizer.h
fuzzymatcher.cpp fuzzymatcher.h
genericconstants.h
@@ -78,12 +75,12 @@ add_qtc_library(Utils
hostosinfo.cpp hostosinfo.h
htmldocextractor.cpp htmldocextractor.h
icon.cpp icon.h
+ iconbutton.cpp iconbutton.h
id.cpp id.h
indexedcontainerproxyconstiterator.h
infobar.cpp infobar.h
infolabel.cpp infolabel.h
itemviews.cpp itemviews.h
- json.cpp json.h
jsontreeitem.cpp jsontreeitem.h
launcherinterface.cpp launcherinterface.h
launcherpackets.cpp launcherpackets.h
@@ -93,7 +90,6 @@ add_qtc_library(Utils
listmodel.h
listutils.h
macroexpander.cpp macroexpander.h
- mapreduce.h
mathutils.cpp mathutils.h
mimeutils.h
minimizableinfobars.cpp
@@ -119,8 +115,10 @@ add_qtc_library(Utils
overlaywidget.cpp overlaywidget.h
overridecursor.cpp overridecursor.h
parameteraction.cpp parameteraction.h
+ passworddialog.cpp passworddialog.h
pathchooser.cpp pathchooser.h
pathlisteditor.cpp pathlisteditor.h
+ persistentcachestore.cpp persistentcachestore.h
persistentsettings.cpp persistentsettings.h
pointeralgorithm.h
port.cpp port.h
@@ -143,7 +141,6 @@ add_qtc_library(Utils
ranges.h
reloadpromptutils.cpp reloadpromptutils.h
removefiledialog.cpp removefiledialog.h
- runextensions.cpp runextensions.h
savefile.cpp savefile.h
scopedswap.h
scopedtimer.cpp scopedtimer.h
@@ -151,7 +148,6 @@ add_qtc_library(Utils
set_algorithm.h
settingsaccessor.cpp settingsaccessor.h
settingsselector.cpp settingsselector.h
- settingsutils.h
singleton.cpp singleton.h
sizedarray.h
smallstring.h
@@ -166,6 +162,8 @@ add_qtc_library(Utils
sortfiltermodel.h
span.h
statuslabel.cpp statuslabel.h
+ store.cpp store.h
+ storekey.h
stringtable.cpp stringtable.h
stringutils.cpp stringutils.h
styleanimator.cpp styleanimator.h
@@ -190,6 +188,7 @@ add_qtc_library(Utils
transientscroll.cpp transientscroll.h
treemodel.cpp treemodel.h
treeviewcombobox.cpp treeviewcombobox.h
+ unarchiver.cpp unarchiver.h
uncommentselection.cpp uncommentselection.h
uniqueobjectptr.h
unixutils.cpp unixutils.h
@@ -278,6 +277,11 @@ extend_qtc_library(Utils
fsengine/filepathinfocache.h
)
+extend_qtc_library(Utils
+ CONDITION TARGET Nanotrace
+ DEPENDS Nanotrace
+)
+
if (WIN32)
add_qtc_executable(qtcreator_ctrlc_stub
DEPENDS user32 shell32
diff --git a/src/libs/utils/QtConcurrentTools b/src/libs/utils/QtConcurrentTools
deleted file mode 100644
index bbec0a89f09..00000000000
--- a/src/libs/utils/QtConcurrentTools
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "runextensions.h"
diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h
index 3c0a4b45c1f..dd201b647c7 100644
--- a/src/libs/utils/algorithm.h
+++ b/src/libs/utils/algorithm.h
@@ -1507,4 +1507,13 @@ void addToHash(QHash<Key, T> *result, const QHash<Key, T> &additionalContents)
result->insert(additionalContents);
}
+// Workaround for missing information from QSet::insert()
+// Return type could be a pair like for std::set, but we never use the iterator anyway.
+template<typename T, typename U> [[nodiscard]] bool insert(QSet<T> &s, const U &v)
+{
+ const int oldSize = s.size();
+ s.insert(v);
+ return s.size() > oldSize;
+}
+
} // namespace Utils
diff --git a/src/libs/utils/appinfo.cpp b/src/libs/utils/appinfo.cpp
new file mode 100644
index 00000000000..465b3a46e46
--- /dev/null
+++ b/src/libs/utils/appinfo.cpp
@@ -0,0 +1,20 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "appinfo.h"
+
+Q_GLOBAL_STATIC(Utils::AppInfo, sAppInfo)
+
+namespace Utils {
+
+Utils::AppInfo appInfo()
+{
+ return *sAppInfo;
+}
+
+void Internal::setAppInfo(const AppInfo &info)
+{
+ *sAppInfo = info;
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/appinfo.h b/src/libs/utils/appinfo.h
new file mode 100644
index 00000000000..9fd5a3f35e8
--- /dev/null
+++ b/src/libs/utils/appinfo.h
@@ -0,0 +1,30 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "utils_global.h"
+
+#include <QString>
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT AppInfo
+{
+public:
+ QString author;
+ QString year;
+ QString displayVersion;
+ QString id;
+ QString revision;
+ QString revisionUrl;
+ QString userFileExtension;
+};
+
+QTCREATOR_UTILS_EXPORT AppInfo appInfo();
+
+namespace Internal {
+QTCREATOR_UTILS_EXPORT void setAppInfo(const AppInfo &info);
+} // namespace Internal
+
+} // namespace Utils
diff --git a/src/libs/utils/archive.h b/src/libs/utils/archive.h
deleted file mode 100644
index ccf62d3885c..00000000000
--- a/src/libs/utils/archive.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include "utils_global.h"
-
-#include "commandline.h"
-
-#include <QObject>
-
-namespace Utils {
-
-class FilePath;
-class Process;
-
-class QTCREATOR_UTILS_EXPORT Archive : public QObject
-{
- Q_OBJECT
-public:
- Archive(const FilePath &src, const FilePath &dest);
- ~Archive();
-
- bool isValid() const;
- void unarchive();
-
- static bool supportsFile(const FilePath &filePath, QString *reason = nullptr);
-
-signals:
- void outputReceived(const QString &output);
- void finished(bool success);
-
-private:
- CommandLine m_commandLine;
- FilePath m_workingDirectory;
- std::unique_ptr<Process> m_process;
-};
-
-} // namespace Utils
diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp
index b11e149c0d5..b14a429ed92 100644
--- a/src/libs/utils/aspects.cpp
+++ b/src/libs/utils/aspects.cpp
@@ -7,11 +7,15 @@
#include "checkablemessagebox.h"
#include "environment.h"
#include "fancylineedit.h"
+#include "iconbutton.h"
#include "layoutbuilder.h"
+#include "passworddialog.h"
#include "pathchooser.h"
+#include "pathlisteditor.h"
#include "qtcassert.h"
#include "qtcolorbutton.h"
#include "qtcsettings.h"
+#include "utilsicons.h"
#include "utilstr.h"
#include "variablechooser.h"
@@ -19,40 +23,61 @@
#include <QButtonGroup>
#include <QCheckBox>
#include <QComboBox>
+#include <QCompleter>
#include <QDebug>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
+#include <QPaintEvent>
+#include <QPainter>
#include <QPointer>
#include <QPushButton>
#include <QRadioButton>
-#include <QSettings>
+#include <QScrollArea>
#include <QSpinBox>
+#include <QStandardItemModel>
#include <QTextEdit>
+#include <QUndoStack>
using namespace Layouting;
namespace Utils {
-namespace Internal {
-class BaseAspectPrivate
+static QtcSettings *theSettings = nullptr;
+
+void BaseAspect::setQtcSettings(QtcSettings *settings)
+{
+ theSettings = settings;
+}
+
+QtcSettings *BaseAspect::qtcSettings()
+{
+ return theSettings;
+}
+
+BaseAspect::Changes::Changes()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+class Internal::BaseAspectPrivate
{
public:
+ explicit BaseAspectPrivate(AspectContainer *container) : m_container(container) {}
+
Id m_id;
- QVariant m_value;
- QVariant m_defaultValue;
std::function<QVariant(const QVariant &)> m_toSettings;
std::function<QVariant(const QVariant &)> m_fromSettings;
QString m_displayName;
- QString m_settingsKey; // Name of data in settings.
+ Key m_settingsKey; // Name of data in settings.
QString m_tooltip;
QString m_labelText;
QPixmap m_labelPixmap;
QIcon m_icon;
- QPointer<QLabel> m_label; // Owned by configuration widget
QPointer<QAction> m_action; // Owned by us.
+ AspectContainer *m_container = nullptr; // Not owned by us.
bool m_visible = true;
bool m_enabled = true;
@@ -66,9 +91,9 @@ public:
BaseAspect::DataCreator m_dataCreator;
BaseAspect::DataCloner m_dataCloner;
QList<BaseAspect::DataExtractor> m_dataExtractors;
-};
-} // Internal
+ QUndoStack *m_undoStack = nullptr;
+};
/*!
\class Utils::BaseAspect
@@ -95,11 +120,11 @@ public:
If \a container is non-null, the aspect is made known to the container.
*/
BaseAspect::BaseAspect(AspectContainer *container)
- : d(new Internal::BaseAspectPrivate)
+ : d(new Internal::BaseAspectPrivate(container))
{
if (container)
container->registerAspect(this);
- addDataExtractor(this, &BaseAspect::value, &Data::value);
+ addDataExtractor(this, &BaseAspect::variantValue, &Data::value);
}
/*!
@@ -120,43 +145,47 @@ void BaseAspect::setId(Id id)
d->m_id = id;
}
-QVariant BaseAspect::value() const
+QVariant BaseAspect::volatileVariantValue() const
{
- return d->m_value;
+ return {};
+}
+
+QVariant BaseAspect::variantValue() const
+{
+ return {};
}
/*!
Sets \a value.
- Emits \c changed() if the value changed.
+ Prefer the typed setValue() of derived classes.
*/
-void BaseAspect::setValue(const QVariant &value)
+void BaseAspect::setVariantValue(const QVariant &value, Announcement howToAnnounce)
{
- if (setValueQuietly(value)) {
- emit changed();
- emitChangedValue();
- }
+ Q_UNUSED(value)
+ Q_UNUSED(howToAnnounce)
+ QTC_CHECK(false);
}
-/*!
- Sets \a value without emitting \c changed().
+void BaseAspect::setDefaultVariantValue(const QVariant &value)
+{
+ Q_UNUSED(value)
+ QTC_CHECK(false);
+}
- Returns whether the value changed.
-*/
-bool BaseAspect::setValueQuietly(const QVariant &value)
+bool BaseAspect::isDefaultValue() const
{
- if (d->m_value == value)
- return false;
- d->m_value = value;
- return true;
+ return defaultVariantValue() == variantValue();
}
-QVariant BaseAspect::defaultValue() const
+QVariant BaseAspect::defaultVariantValue() const
{
- return d->m_defaultValue;
+ return {};
}
/*!
+ \fn TypedAspect::setDefaultValue(const ValueType &value)
+
Sets a default \a value and the current value for this aspect.
\note The current value will be set silently to the same value.
@@ -165,11 +194,6 @@ QVariant BaseAspect::defaultValue() const
Default values will not be stored in settings.
*/
-void BaseAspect::setDefaultValue(const QVariant &value)
-{
- d->m_defaultValue = value;
- d->m_value = value;
-}
void BaseAspect::setDisplayName(const QString &displayName)
{
@@ -194,31 +218,38 @@ void BaseAspect::setVisible(bool visible)
// This may happen during layout building. Explicit setting visibility here
// may create a show a toplevel widget for a moment until it is parented
// to some non-shown widget.
- if (w->parentWidget())
+ if (!visible || w->parentWidget())
w->setVisible(visible);
}
}
-void BaseAspect::setupLabel()
+QLabel *BaseAspect::createLabel()
{
- QTC_ASSERT(!d->m_label, delete d->m_label);
if (d->m_labelText.isEmpty() && d->m_labelPixmap.isNull())
- return;
- d->m_label = new QLabel(d->m_labelText);
- d->m_label->setTextInteractionFlags(d->m_label->textInteractionFlags()
- | Qt::TextSelectableByMouse);
- connect(d->m_label, &QLabel::linkActivated, this, [this](const QString &link) {
+ return nullptr;
+
+ auto label = new QLabel(d->m_labelText);
+ label->setTextInteractionFlags(label->textInteractionFlags() | Qt::TextSelectableByMouse);
+ connect(label, &QLabel::linkActivated, this, [this](const QString &link) {
emit labelLinkActivated(link);
});
if (!d->m_labelPixmap.isNull())
- d->m_label->setPixmap(d->m_labelPixmap);
- registerSubWidget(d->m_label);
+ label->setPixmap(d->m_labelPixmap);
+ registerSubWidget(label);
+
+ connect(this, &BaseAspect::labelTextChanged, label, [label, this] {
+ label->setText(d->m_labelText);
+ });
+ connect(this, &BaseAspect::labelPixmapChanged, label, [label, this] {
+ label->setPixmap(d->m_labelPixmap);
+ });
+
+ return label;
}
void BaseAspect::addLabeledItem(LayoutItem &parent, QWidget *widget)
{
- setupLabel();
- if (QLabel *l = label()) {
+ if (QLabel *l = createLabel()) {
l->setBuddy(widget);
parent.addItem(l);
parent.addItem(Span(std::max(d->m_spanX - 1, 1), LayoutItem(widget)));
@@ -234,8 +265,7 @@ void BaseAspect::addLabeledItem(LayoutItem &parent, QWidget *widget)
void BaseAspect::setLabelText(const QString &labelText)
{
d->m_labelText = labelText;
- if (d->m_label)
- d->m_label->setText(labelText);
+ emit labelTextChanged();
}
/*!
@@ -245,8 +275,7 @@ void BaseAspect::setLabelText(const QString &labelText)
void BaseAspect::setLabelPixmap(const QPixmap &labelPixmap)
{
d->m_labelPixmap = labelPixmap;
- if (d->m_label)
- d->m_label->setPixmap(labelPixmap);
+ emit labelPixmapChanged();
}
void BaseAspect::setIcon(const QIcon &icon)
@@ -265,11 +294,6 @@ QString BaseAspect::labelText() const
return d->m_labelText;
}
-QLabel *BaseAspect::label() const
-{
- return d->m_label.data();
-}
-
QString BaseAspect::toolTip() const
{
return d->m_tooltip;
@@ -287,6 +311,16 @@ void BaseAspect::setToolTip(const QString &tooltip)
}
}
+void BaseAspect::setUndoStack(QUndoStack *undoStack)
+{
+ d->m_undoStack = undoStack;
+}
+
+QUndoStack *BaseAspect::undoStack() const
+{
+ return d->m_undoStack;
+}
+
bool BaseAspect::isEnabled() const
{
return d->m_enabled;
@@ -294,11 +328,16 @@ bool BaseAspect::isEnabled() const
void BaseAspect::setEnabled(bool enabled)
{
- d->m_enabled = enabled;
for (QWidget *w : std::as_const(d->m_subWidgets)) {
QTC_ASSERT(w, continue);
w->setEnabled(enabled);
}
+
+ if (enabled == d->m_enabled)
+ return;
+
+ d->m_enabled = enabled;
+ emit enabledChanged();
}
/*!
@@ -307,9 +346,16 @@ void BaseAspect::setEnabled(bool enabled)
void BaseAspect::setEnabler(BoolAspect *checker)
{
QTC_ASSERT(checker, return);
- setEnabled(checker->value());
- connect(checker, &BoolAspect::volatileValueChanged, this, &BaseAspect::setEnabled);
- connect(checker, &BoolAspect::valueChanged, this, &BaseAspect::setEnabled);
+
+ auto update = [this, checker] {
+ BaseAspect::setEnabled(checker->isEnabled() && checker->volatileValue());
+ };
+
+ connect(checker, &BoolAspect::volatileValueChanged, this, update);
+ connect(checker, &BoolAspect::changed, this, update);
+ connect(checker, &BaseAspect::enabledChanged, this, update);
+
+ update();
}
bool BaseAspect::isReadOnly() const
@@ -326,6 +372,8 @@ void BaseAspect::setReadOnly(bool readOnly)
lineEdit->setReadOnly(readOnly);
else if (auto textEdit = qobject_cast<QTextEdit *>(w))
textEdit->setReadOnly(readOnly);
+ else if (auto pathChooser = qobject_cast<PathChooser *>(w))
+ pathChooser->setReadOnly(readOnly);
}
}
@@ -366,7 +414,7 @@ void BaseAspect::setConfigWidgetCreator(const ConfigWidgetCreator &configWidgetC
\sa setSettingsKey()
*/
-QString BaseAspect::settingsKey() const
+Key BaseAspect::settingsKey() const
{
return d->m_settingsKey;
}
@@ -376,7 +424,7 @@ QString BaseAspect::settingsKey() const
\sa settingsKey()
*/
-void BaseAspect::setSettingsKey(const QString &key)
+void BaseAspect::setSettingsKey(const Key &key)
{
d->m_settingsKey = key;
}
@@ -386,12 +434,28 @@ void BaseAspect::setSettingsKey(const QString &key)
\sa settingsKey()
*/
-void BaseAspect::setSettingsKey(const QString &group, const QString &key)
+void BaseAspect::setSettingsKey(const Key &group, const Key &key)
{
d->m_settingsKey = group + "/" + key;
}
/*!
+ Immediately writes the value of this aspect into its specified
+ settings, taking a potential container's settings group specification
+ into account.
+
+ \note This is expensive, so it should only be used with good reason.
+*/
+void BaseAspect::writeToSettingsImmediatly() const
+{
+ QStringList groups;
+ if (d->m_container)
+ groups = d->m_container->settingsGroups();
+ const SettingsGroupNester nester(groups);
+ writeSettings();
+}
+
+/*!
Returns the string that should be used when this action appears in menus
or other places that are typically used with Book style capitalization.
@@ -420,6 +484,11 @@ QAction *BaseAspect::action()
return d->m_action;
}
+AspectContainer *BaseAspect::container() const
+{
+ return d->m_container;
+}
+
/*!
Adds the visual representation of this aspect to the layout with the
specified \a parent using a layout builder.
@@ -442,13 +511,20 @@ void createItem(Layouting::LayoutItem *item, const BaseAspect *aspect)
/*!
Updates this aspect's value from user-initiated changes in the widget.
- This has only an effect if \c isAutoApply is false.
+ Emits changed() if the value changed.
*/
void BaseAspect::apply()
{
- QTC_CHECK(!d->m_autoApply);
- if (isDirty())
- setValue(volatileValue());
+ // We assume m_buffer to reflect current gui state as invariant after signalling settled down.
+ // It's an aspect (-subclass) implementation problem if this doesn't hold. Fix it up and bark.
+ QTC_CHECK(!guiToBuffer());
+
+ if (!bufferToInternal()) // Nothing to do.
+ return;
+
+ Changes changes;
+ changes.internalFromBuffer = true;
+ announceChanges(changes);
}
/*!
@@ -459,9 +535,8 @@ void BaseAspect::apply()
*/
void BaseAspect::cancel()
{
- QTC_CHECK(!d->m_autoApply);
- if (!d->m_subWidgets.isEmpty())
- setVolatileValue(d->m_value);
+ internalToBuffer();
+ bufferToGui();
}
void BaseAspect::finish()
@@ -476,24 +551,24 @@ bool BaseAspect::hasAction() const
return d->m_action != nullptr;
}
-bool BaseAspect::isDirty() const
+void BaseAspect::announceChanges(Changes changes, Announcement howToAnnounce)
{
- QTC_CHECK(!isAutoApply());
- // Aspects that were never shown cannot contain unsaved user changes.
- if (d->m_subWidgets.isEmpty())
- return false;
- return volatileValue() != d->m_value;
-}
+ if (howToAnnounce == BeQuiet)
+ return;
-QVariant BaseAspect::volatileValue() const
-{
- QTC_CHECK(!isAutoApply());
- return {};
+ if (changes.bufferFromInternal || changes.bufferFromOutside || changes.bufferFromGui)
+ emit volatileValueChanged();
+
+ if (changes.internalFromOutside || changes.internalFromBuffer) {
+ emit changed();
+ if (hasAction())
+ emit action()->triggered(variantValue().toBool());
+ }
}
-void BaseAspect::setVolatileValue(const QVariant &val)
+bool BaseAspect::isDirty()
{
- Q_UNUSED(val);
+ return false;
}
void BaseAspect::registerSubWidget(QWidget *widget)
@@ -518,8 +593,14 @@ void BaseAspect::registerSubWidget(QWidget *widget)
widget->setVisible(d->m_visible);
}
-void BaseAspect::saveToMap(QVariantMap &data, const QVariant &value,
- const QVariant &defaultValue, const QString &key)
+void BaseAspect::forEachSubWidget(const std::function<void(QWidget *)> &func)
+{
+ for (const QPointer<QWidget> &w : d->m_subWidgets)
+ func(w);
+}
+
+void BaseAspect::saveToMap(Store &data, const QVariant &value,
+ const QVariant &defaultValue, const Key &key)
{
if (key.isEmpty())
return;
@@ -530,38 +611,53 @@ void BaseAspect::saveToMap(QVariantMap &data, const QVariant &value,
}
/*!
- Retrieves the internal value of this BaseAspect from the QVariantMap \a map.
+ Retrieves the internal value of this BaseAspect from the Store \a map.
*/
-void BaseAspect::fromMap(const QVariantMap &map)
+void BaseAspect::fromMap(const Store &map)
{
- const QVariant val = map.value(settingsKey(), toSettingsValue(defaultValue()));
- setValue(fromSettingsValue(val));
+ if (settingsKey().isEmpty())
+ return;
+ const QVariant val = map.value(settingsKey(), toSettingsValue(defaultVariantValue()));
+ setVariantValue(fromSettingsValue(val), BeQuiet);
}
/*!
- Stores the internal value of this BaseAspect into the QVariantMap \a map.
+ Stores the internal value of this BaseAspect into the Store \a map.
*/
-void BaseAspect::toMap(QVariantMap &map) const
+void BaseAspect::toMap(Store &map) const
+{
+ if (settingsKey().isEmpty())
+ return;
+ saveToMap(map, toSettingsValue(variantValue()), toSettingsValue(defaultVariantValue()), settingsKey());
+}
+
+void BaseAspect::volatileToMap(Store &map) const
{
- saveToMap(map, toSettingsValue(d->m_value), toSettingsValue(d->m_defaultValue), settingsKey());
+ if (settingsKey().isEmpty())
+ return;
+ saveToMap(map,
+ toSettingsValue(volatileVariantValue()),
+ toSettingsValue(defaultVariantValue()),
+ settingsKey());
}
-void BaseAspect::readSettings(const QSettings *settings)
+void BaseAspect::readSettings()
{
if (settingsKey().isEmpty())
return;
- const QVariant &val = settings->value(settingsKey());
- setValue(val.isValid() ? fromSettingsValue(val) : defaultValue());
+ QTC_ASSERT(theSettings, return);
+ const QVariant val = theSettings->value(settingsKey());
+ setVariantValue(val.isValid() ? fromSettingsValue(val) : defaultVariantValue(), BeQuiet);
}
-void BaseAspect::writeSettings(QSettings *settings) const
+void BaseAspect::writeSettings() const
{
if (settingsKey().isEmpty())
return;
- QtcSettings::setValueWithDefault(settings,
- settingsKey(),
- toSettingsValue(value()),
- toSettingsValue(defaultValue()));
+ QTC_ASSERT(theSettings, return);
+ theSettings->setValueWithDefault(settingsKey(),
+ toSettingsValue(variantValue()),
+ toSettingsValue(defaultVariantValue()));
}
void BaseAspect::setFromSettingsTransformation(const SavedValueTransformation &transform)
@@ -590,9 +686,7 @@ class BoolAspectPrivate
{
public:
BoolAspect::LabelPlacement m_labelPlacement = BoolAspect::LabelPlacement::AtCheckBox;
- QPointer<QAbstractButton> m_button; // Owned by configuration widget
- QPointer<QGroupBox> m_groupBox; // For BoolAspects handling GroupBox check boxes
- bool m_buttonIsAdopted = false;
+ UndoableValue<bool> m_undoable;
};
class ColorAspectPrivate
@@ -608,7 +702,7 @@ public:
SelectionAspect::DisplayStyle m_displayStyle
= SelectionAspect::DisplayStyle::RadioButtons;
- QVector<SelectionAspect::Option> m_options;
+ QList<SelectionAspect::Option> m_options;
// These are all owned by the configuration widget.
QList<QPointer<QRadioButton>> m_buttons;
@@ -632,55 +726,126 @@ public:
QPointer<QListWidget> m_listView;
};
+class CheckableAspectImplementation
+{
+public:
+ void fromMap(const Store &map)
+ {
+ if (m_checked)
+ m_checked->fromMap(map);
+ }
+
+ void toMap(Store &map)
+ {
+ if (m_checked)
+ m_checked->toMap(map);
+ }
+
+ void volatileToMap(Store &map)
+ {
+ if (m_checked)
+ m_checked->volatileToMap(map);
+ }
+
+ template<class Widget>
+ void updateWidgetFromCheckStatus(BaseAspect *aspect, Widget *w)
+ {
+ const bool enabled = !m_checked || m_checked->value();
+ if (m_uncheckedSemantics == UncheckedSemantics::Disabled)
+ w->setEnabled(enabled && aspect->isEnabled());
+ else
+ w->setReadOnly(!enabled || aspect->isReadOnly());
+ }
+
+ void setUncheckedSemantics(UncheckedSemantics semantics)
+ {
+ m_uncheckedSemantics = semantics;
+ }
+
+ bool isChecked() const
+ {
+ QTC_ASSERT(m_checked, return false);
+ return m_checked->value();
+ }
+
+ void setChecked(bool checked)
+ {
+ QTC_ASSERT(m_checked, return);
+ m_checked->setValue(checked);
+ }
+
+ void makeCheckable(CheckBoxPlacement checkBoxPlacement, const QString &checkerLabel,
+ const Key &checkerKey, BaseAspect *aspect)
+ {
+ QTC_ASSERT(!m_checked, return);
+ m_checkBoxPlacement = checkBoxPlacement;
+ m_checked.reset(new BoolAspect);
+ m_checked->setLabel(checkerLabel, checkBoxPlacement == CheckBoxPlacement::Top
+ ? BoolAspect::LabelPlacement::InExtraLabel
+ : BoolAspect::LabelPlacement::AtCheckBox);
+ m_checked->setSettingsKey(checkerKey);
+
+ QObject::connect(m_checked.get(), &BoolAspect::changed, aspect, [aspect] {
+ // FIXME: Check.
+ aspect->internalToBuffer();
+ aspect->bufferToGui();
+ emit aspect->changed();
+ aspect->checkedChanged();
+ });
+
+ QObject::connect(m_checked.get(), &BoolAspect::volatileValueChanged, aspect, [aspect] {
+ // FIXME: Check.
+ aspect->internalToBuffer();
+ aspect->bufferToGui();
+ aspect->checkedChanged();
+ });
+
+ aspect->internalToBuffer();
+ aspect->bufferToGui();
+ }
+
+ void addToLayoutFirst(LayoutItem &parent)
+ {
+ if (m_checked && m_checkBoxPlacement == CheckBoxPlacement::Top) {
+ m_checked->addToLayout(parent);
+ parent.addItem(br);
+ }
+ }
+
+ void addToLayoutLast(LayoutItem &parent)
+ {
+ if (m_checked && m_checkBoxPlacement == CheckBoxPlacement::Right)
+ m_checked->addToLayout(parent);
+ }
+
+ CheckBoxPlacement m_checkBoxPlacement = CheckBoxPlacement::Right;
+ UncheckedSemantics m_uncheckedSemantics = UncheckedSemantics::Disabled;
+ std::unique_ptr<BoolAspect> m_checked;
+};
+
class StringAspectPrivate
{
public:
StringAspect::DisplayStyle m_displayStyle = StringAspect::LabelDisplay;
- StringAspect::CheckBoxPlacement m_checkBoxPlacement
- = StringAspect::CheckBoxPlacement::Right;
- StringAspect::UncheckedSemantics m_uncheckedSemantics
- = StringAspect::UncheckedSemantics::Disabled;
std::function<QString(const QString &)> m_displayFilter;
- std::unique_ptr<BoolAspect> m_checker;
Qt::TextElideMode m_elideMode = Qt::ElideNone;
QString m_placeHolderText;
- QString m_prompDialogFilter;
- QString m_prompDialogTitle;
- QStringList m_commandVersionArguments;
- QString m_historyCompleterKey;
- PathChooser::Kind m_expectedKind = PathChooser::File;
- Environment m_environment;
- QPointer<ElidingLabel> m_labelDisplay;
- QPointer<FancyLineEdit> m_lineEditDisplay;
- QPointer<PathChooser> m_pathChooserDisplay;
- QPointer<QTextEdit> m_textEditDisplay;
+ Key m_historyCompleterKey;
MacroExpanderProvider m_expanderProvider;
- FilePath m_baseFileName;
StringAspect::ValueAcceptor m_valueAcceptor;
- FancyLineEdit::ValidationFunction m_validator;
- std::function<void()> m_openTerminal;
+ std::optional<FancyLineEdit::ValidationFunction> m_validator;
+
+ CheckableAspectImplementation m_checkerImpl;
bool m_undoRedoEnabled = true;
bool m_acceptRichText = false;
bool m_showToolTipOnLabel = false;
- bool m_fileDialogOnly = false;
bool m_useResetButton = false;
bool m_autoApplyOnEditingFinished = false;
- // Used to block recursive editingFinished signals for example when return is pressed, and
- // the validation changes focus by opening a dialog
- bool m_blockAutoApply = false;
- bool m_allowPathFromDevice = true;
bool m_validatePlaceHolder = false;
- template<class Widget> void updateWidgetFromCheckStatus(StringAspect *aspect, Widget *w)
- {
- const bool enabled = !m_checker || m_checker->value();
- if (m_uncheckedSemantics == StringAspect::UncheckedSemantics::Disabled)
- w->setEnabled(enabled && aspect->isEnabled());
- else
- w->setReadOnly(!enabled || aspect->isReadOnly());
- }
+ UndoableValue<QString> undoable;
};
class IntegerAspectPrivate
@@ -714,6 +879,13 @@ class StringListAspectPrivate
public:
};
+class FilePathListAspectPrivate
+{
+public:
+ UndoableValue<QStringList> undoable;
+ QString placeHolderText;
+};
+
class TextDisplayPrivate
{
public:
@@ -747,6 +919,9 @@ public:
\value PathChooserDisplay
Based on Utils::PathChooser.
+ \value PasswordLineEditDisplay
+ Based on QLineEdit, used for password strings
+
\sa Utils::PathChooser
*/
@@ -773,13 +948,9 @@ public:
*/
StringAspect::StringAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::StringAspectPrivate)
+ : TypedAspect(container), d(new Internal::StringAspectPrivate)
{
- setDefaultValue(QString());
setSpan(2, 1); // Default: Label + something
-
- addDataExtractor(this, &StringAspect::value, &Data::value);
- addDataExtractor(this, &StringAspect::filePath, &Data::filePath);
}
/*!
@@ -796,102 +967,28 @@ void StringAspect::setValueAcceptor(StringAspect::ValueAcceptor &&acceptor)
}
/*!
- Returns the value of this StringAspect as an ordinary \c QString.
-*/
-QString StringAspect::value() const
-{
- return BaseAspect::value().toString();
-}
-
-/*!
- Sets the value, \a val, of this StringAspect from an ordinary \c QString.
-*/
-void StringAspect::setValue(const QString &val)
-{
- const bool isSame = val == value();
- if (isSame)
- return;
-
- QString processedValue = val;
- if (d->m_valueAcceptor) {
- const std::optional<QString> tmp = d->m_valueAcceptor(value(), val);
- if (!tmp) {
- update(); // Make sure the original value is retained in the UI
- return;
- }
- processedValue = tmp.value();
- }
-
- if (BaseAspect::setValueQuietly(QVariant(processedValue))) {
- update();
- emit changed();
- emit valueChanged(processedValue);
- }
-}
-
-QString StringAspect::defaultValue() const
-{
- return BaseAspect::defaultValue().toString();
-}
-
-void StringAspect::setDefaultValue(const QString &val)
-{
- BaseAspect::setDefaultValue(val);
-}
-
-/*!
\reimp
*/
-void StringAspect::fromMap(const QVariantMap &map)
+void StringAspect::fromMap(const Store &map)
{
if (!settingsKey().isEmpty())
- BaseAspect::setValueQuietly(map.value(settingsKey(), defaultValue()));
- if (d->m_checker)
- d->m_checker->fromMap(map);
+ setValue(map.value(settingsKey(), defaultValue()).toString(), BeQuiet);
+ d->m_checkerImpl.fromMap(map);
}
/*!
\reimp
*/
-void StringAspect::toMap(QVariantMap &map) const
+void StringAspect::toMap(Store &map) const
{
saveToMap(map, value(), defaultValue(), settingsKey());
- if (d->m_checker)
- d->m_checker->toMap(map);
+ d->m_checkerImpl.toMap(map);
}
-/*!
- Returns the value of this string aspect as \c Utils::FilePath.
-
- \note This simply uses \c FilePath::fromUserInput() for the
- conversion. It does not use any check that the value is actually
- a valid file path.
-*/
-FilePath StringAspect::filePath() const
+void StringAspect::volatileToMap(Store &map) const
{
- return FilePath::fromUserInput(value());
-}
-
-/*!
- Sets the value of this string aspect to \a value.
-
- \note This simply uses \c FilePath::toUserOutput() for the
- conversion. It does not use any check that the value is actually
- a file path.
-*/
-void StringAspect::setFilePath(const FilePath &value)
-{
- setValue(value.toUserOutput());
-}
-
-void StringAspect::setDefaultFilePath(const FilePath &value)
-{
- setDefaultValue(value.toUserOutput());
-}
-
-PathChooser *StringAspect::pathChooser() const
-{
- return d->m_pathChooserDisplay.data();
+ saveToMap(map, volatileValue(), defaultValue(), settingsKey());
+ d->m_checkerImpl.volatileToMap(map);
}
/*!
@@ -900,7 +997,7 @@ PathChooser *StringAspect::pathChooser() const
void StringAspect::setShowToolTipOnLabel(bool show)
{
d->m_showToolTipOnLabel = show;
- update();
+ bufferToGui();
}
/*!
@@ -913,27 +1010,6 @@ void StringAspect::setDisplayFilter(const std::function<QString(const QString &)
}
/*!
- Returns the check box value.
-
- \sa makeCheckable(), setChecked()
-*/
-bool StringAspect::isChecked() const
-{
- return !d->m_checker || d->m_checker->value();
-}
-
-/*!
- Sets the check box of this aspect to \a checked.
-
- \sa makeCheckable(), isChecked()
-*/
-void StringAspect::setChecked(bool checked)
-{
- QTC_ASSERT(d->m_checker, return);
- d->m_checker->setValue(checked);
-}
-
-/*!
Selects the main display characteristics of the aspect according to
\a displayStyle.
@@ -951,46 +1027,11 @@ void StringAspect::setDisplayStyle(DisplayStyle displayStyle)
*/
void StringAspect::setPlaceHolderText(const QString &placeHolderText)
{
- d->m_placeHolderText = placeHolderText;
- if (d->m_lineEditDisplay)
- d->m_lineEditDisplay->setPlaceholderText(placeHolderText);
- if (d->m_textEditDisplay)
- d->m_textEditDisplay->setPlaceholderText(placeHolderText);
-}
-
-void StringAspect::setPromptDialogFilter(const QString &filter)
-{
- d->m_prompDialogFilter = filter;
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setPromptDialogFilter(filter);
-}
-
-void StringAspect::setPromptDialogTitle(const QString &title)
-{
- d->m_prompDialogTitle = title;
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setPromptDialogTitle(title);
-}
-
-void StringAspect::setCommandVersionArguments(const QStringList &arguments)
-{
- d->m_commandVersionArguments = arguments;
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setCommandVersionArguments(arguments);
-}
-
-void StringAspect::setAllowPathFromDevice(bool allowPathFromDevice)
-{
- d->m_allowPathFromDevice = allowPathFromDevice;
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setAllowPathFromDevice(allowPathFromDevice);
-}
+ if (d->m_placeHolderText == placeHolderText)
+ return;
-void StringAspect::setValidatePlaceHolder(bool validatePlaceHolder)
-{
- d->m_validatePlaceHolder = validatePlaceHolder;
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->lineEdit()->setValidatePlaceHolder(validatePlaceHolder);
+ d->m_placeHolderText = placeHolderText;
+ emit placeholderTextChanged(placeHolderText);
}
/*!
@@ -998,9 +1039,10 @@ void StringAspect::setValidatePlaceHolder(bool validatePlaceHolder)
*/
void StringAspect::setElideMode(Qt::TextElideMode elideMode)
{
+ if (d->m_elideMode == elideMode)
+ return;
d->m_elideMode = elideMode;
- if (d->m_labelDisplay)
- d->m_labelDisplay->setElideMode(elideMode);
+ emit elideModeChanged(elideMode);
}
/*!
@@ -1009,53 +1051,16 @@ void StringAspect::setElideMode(Qt::TextElideMode elideMode)
\sa Utils::PathChooser::setExpectedKind()
*/
-void StringAspect::setHistoryCompleter(const QString &historyCompleterKey)
+void StringAspect::setHistoryCompleter(const Key &historyCompleterKey)
{
d->m_historyCompleterKey = historyCompleterKey;
- if (d->m_lineEditDisplay)
- d->m_lineEditDisplay->setHistoryCompleter(historyCompleterKey);
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setHistoryCompleter(historyCompleterKey);
-}
-
-/*!
- Sets \a expectedKind as expected kind for path chooser displays.
-
- \sa Utils::PathChooser::setExpectedKind()
-*/
-void StringAspect::setExpectedKind(const PathChooser::Kind expectedKind)
-{
- d->m_expectedKind = expectedKind;
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setExpectedKind(expectedKind);
-}
-
-void StringAspect::setEnvironment(const Environment &env)
-{
- d->m_environment = env;
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setEnvironment(env);
-}
-
-void StringAspect::setBaseFileName(const FilePath &baseFileName)
-{
- d->m_baseFileName = baseFileName;
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setBaseDirectory(baseFileName);
-}
-
-void StringAspect::setUndoRedoEnabled(bool undoRedoEnabled)
-{
- d->m_undoRedoEnabled = undoRedoEnabled;
- if (d->m_textEditDisplay)
- d->m_textEditDisplay->setUndoRedoEnabled(undoRedoEnabled);
+ emit historyCompleterKeyChanged(historyCompleterKey);
}
void StringAspect::setAcceptRichText(bool acceptRichText)
{
d->m_acceptRichText = acceptRichText;
- if (d->m_textEditDisplay)
- d->m_textEditDisplay->setAcceptRichText(acceptRichText);
+ emit acceptRichTextChanged(acceptRichText);
}
void StringAspect::setMacroExpanderProvider(const MacroExpanderProvider &expanderProvider)
@@ -1076,17 +1081,7 @@ void StringAspect::setUseResetButton()
void StringAspect::setValidationFunction(const FancyLineEdit::ValidationFunction &validator)
{
d->m_validator = validator;
- if (d->m_lineEditDisplay)
- d->m_lineEditDisplay->setValidationFunction(d->m_validator);
- else if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setValidationFunction(d->m_validator);
-}
-
-void StringAspect::setOpenTerminalHandler(const std::function<void ()> &openTerminal)
-{
- d->m_openTerminal = openTerminal;
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setOpenTerminalHandler(openTerminal);
+ emit validationFunctionChanged(validator);
}
void StringAspect::setAutoApplyOnEditingFinished(bool applyOnEditingFinished)
@@ -1094,25 +1089,9 @@ void StringAspect::setAutoApplyOnEditingFinished(bool applyOnEditingFinished)
d->m_autoApplyOnEditingFinished = applyOnEditingFinished;
}
-void StringAspect::validateInput()
-{
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->triggerChanged();
- if (d->m_lineEditDisplay)
- d->m_lineEditDisplay->validate();
-}
-
-void StringAspect::setUncheckedSemantics(StringAspect::UncheckedSemantics semantics)
-{
- d->m_uncheckedSemantics = semantics;
-}
-
void StringAspect::addToLayout(LayoutItem &parent)
{
- if (d->m_checker && d->m_checkBoxPlacement == CheckBoxPlacement::Top) {
- d->m_checker->addToLayout(parent);
- parent.addItem(br);
- }
+ d->m_checkerImpl.addToLayoutFirst(parent);
const auto useMacroExpander = [this](QWidget *w) {
if (!d->m_expanderProvider)
@@ -1125,203 +1104,196 @@ void StringAspect::addToLayout(LayoutItem &parent)
const QString displayedString = d->m_displayFilter ? d->m_displayFilter(value()) : value();
switch (d->m_displayStyle) {
- case PathChooserDisplay:
- d->m_pathChooserDisplay = createSubWidget<PathChooser>();
- d->m_pathChooserDisplay->setExpectedKind(d->m_expectedKind);
+ case PasswordLineEditDisplay:
+ case LineEditDisplay: {
+ auto lineEditDisplay = createSubWidget<FancyLineEdit>();
+ lineEditDisplay->setPlaceholderText(d->m_placeHolderText);
if (!d->m_historyCompleterKey.isEmpty())
- d->m_pathChooserDisplay->setHistoryCompleter(d->m_historyCompleterKey);
- if (d->m_validator)
- d->m_pathChooserDisplay->setValidationFunction(d->m_validator);
- d->m_pathChooserDisplay->setEnvironment(d->m_environment);
- d->m_pathChooserDisplay->setBaseDirectory(d->m_baseFileName);
- d->m_pathChooserDisplay->setOpenTerminalHandler(d->m_openTerminal);
- d->m_pathChooserDisplay->setPromptDialogFilter(d->m_prompDialogFilter);
- d->m_pathChooserDisplay->setPromptDialogTitle(d->m_prompDialogTitle);
- d->m_pathChooserDisplay->setCommandVersionArguments(d->m_commandVersionArguments);
- d->m_pathChooserDisplay->setAllowPathFromDevice(d->m_allowPathFromDevice);
- d->m_pathChooserDisplay->lineEdit()->setValidatePlaceHolder(d->m_validatePlaceHolder);
- if (defaultValue() == value())
- d->m_pathChooserDisplay->setDefaultValue(defaultValue());
- else
- d->m_pathChooserDisplay->setFilePath(FilePath::fromUserInput(displayedString));
- // do not override default value with placeholder, but use placeholder if default is empty
- if (d->m_pathChooserDisplay->lineEdit()->placeholderText().isEmpty())
- d->m_pathChooserDisplay->lineEdit()->setPlaceholderText(d->m_placeHolderText);
- d->updateWidgetFromCheckStatus(this, d->m_pathChooserDisplay.data());
- addLabeledItem(parent, d->m_pathChooserDisplay);
- useMacroExpander(d->m_pathChooserDisplay->lineEdit());
- if (isAutoApply()) {
- if (d->m_autoApplyOnEditingFinished) {
- const auto setPathChooserValue = [this] {
- if (d->m_blockAutoApply)
- return;
- d->m_blockAutoApply = true;
- setValueQuietly(d->m_pathChooserDisplay->filePath().toString());
- d->m_blockAutoApply = false;
- };
- connect(d->m_pathChooserDisplay, &PathChooser::editingFinished, this, setPathChooserValue);
- connect(d->m_pathChooserDisplay, &PathChooser::browsingFinished, this, setPathChooserValue);
- } else {
- connect(d->m_pathChooserDisplay, &PathChooser::textChanged,
- this, [this](const QString &path) {
- setValueQuietly(path);
+ lineEditDisplay->setHistoryCompleter(d->m_historyCompleterKey);
+
+ connect(this,
+ &StringAspect::historyCompleterKeyChanged,
+ lineEditDisplay,
+ [lineEditDisplay](const Key &historyCompleterKey) {
+ lineEditDisplay->setHistoryCompleter(historyCompleterKey);
});
- }
- }
- break;
- case LineEditDisplay:
- d->m_lineEditDisplay = createSubWidget<FancyLineEdit>();
- d->m_lineEditDisplay->setPlaceholderText(d->m_placeHolderText);
- if (!d->m_historyCompleterKey.isEmpty())
- d->m_lineEditDisplay->setHistoryCompleter(d->m_historyCompleterKey);
+ connect(this,
+ &StringAspect::placeholderTextChanged,
+ lineEditDisplay,
+ &FancyLineEdit::setPlaceholderText);
+
if (d->m_validator)
- d->m_lineEditDisplay->setValidationFunction(d->m_validator);
- d->m_lineEditDisplay->setTextKeepingActiveCursor(displayedString);
- d->m_lineEditDisplay->setReadOnly(isReadOnly());
- d->m_lineEditDisplay->setValidatePlaceHolder(d->m_validatePlaceHolder);
- d->updateWidgetFromCheckStatus(this, d->m_lineEditDisplay.data());
- addLabeledItem(parent, d->m_lineEditDisplay);
- useMacroExpander(d->m_lineEditDisplay);
- if (isAutoApply()) {
- if (d->m_autoApplyOnEditingFinished) {
- connect(d->m_lineEditDisplay, &FancyLineEdit::editingFinished, this, [this] {
- if (d->m_blockAutoApply)
- return;
- d->m_blockAutoApply = true;
- setValue(d->m_lineEditDisplay->text());
- d->m_blockAutoApply = false;
- });
- } else {
- connect(d->m_lineEditDisplay,
- &FancyLineEdit::textEdited,
- this,
- &StringAspect::setValue);
- connect(d->m_lineEditDisplay, &FancyLineEdit::editingFinished, this, [this] {
- setValue(d->m_lineEditDisplay->text());
- });
- }
+ lineEditDisplay->setValidationFunction(*d->m_validator);
+ lineEditDisplay->setTextKeepingActiveCursor(displayedString);
+ lineEditDisplay->setReadOnly(isReadOnly());
+ lineEditDisplay->setValidatePlaceHolder(d->m_validatePlaceHolder);
+
+ d->m_checkerImpl.updateWidgetFromCheckStatus(this, lineEditDisplay);
+
+ if (d->m_checkerImpl.m_checked.get()) {
+ connect(d->m_checkerImpl.m_checked.get(),
+ &BoolAspect::volatileValueChanged,
+ lineEditDisplay,
+ [this, lineEditDisplay]() {
+ d->m_checkerImpl.updateWidgetFromCheckStatus(this, lineEditDisplay);
+ });
}
+
+ addLabeledItem(parent, lineEditDisplay);
+ useMacroExpander(lineEditDisplay);
if (d->m_useResetButton) {
auto resetButton = createSubWidget<QPushButton>(Tr::tr("Reset"));
- resetButton->setEnabled(d->m_lineEditDisplay->text() != defaultValue());
- connect(resetButton, &QPushButton::clicked, this, [this] {
- d->m_lineEditDisplay->setText(defaultValue());
- });
- connect(d->m_lineEditDisplay, &QLineEdit::textChanged, this, [this, resetButton] {
- resetButton->setEnabled(d->m_lineEditDisplay->text() != defaultValue());
+ resetButton->setEnabled(lineEditDisplay->text() != defaultValue());
+ connect(resetButton, &QPushButton::clicked, lineEditDisplay, [this, lineEditDisplay] {
+ lineEditDisplay->setText(defaultValue());
});
+ connect(lineEditDisplay,
+ &QLineEdit::textChanged,
+ resetButton,
+ [this, lineEditDisplay, resetButton] {
+ resetButton->setEnabled(lineEditDisplay->text() != defaultValue());
+ });
parent.addItem(resetButton);
}
- break;
- case TextEditDisplay:
- d->m_textEditDisplay = createSubWidget<QTextEdit>();
- d->m_textEditDisplay->setPlaceholderText(d->m_placeHolderText);
- d->m_textEditDisplay->setUndoRedoEnabled(d->m_undoRedoEnabled);
- d->m_textEditDisplay->setAcceptRichText(d->m_acceptRichText);
- d->m_textEditDisplay->setTextInteractionFlags(Qt::TextEditorInteraction);
- d->m_textEditDisplay->setText(displayedString);
- d->m_textEditDisplay->setReadOnly(isReadOnly());
- d->updateWidgetFromCheckStatus(this, d->m_textEditDisplay.data());
- addLabeledItem(parent, d->m_textEditDisplay);
- useMacroExpander(d->m_textEditDisplay);
- if (isAutoApply()) {
- connect(d->m_textEditDisplay, &QTextEdit::textChanged, this, [this] {
- setValue(d->m_textEditDisplay->document()->toPlainText());
+ connect(lineEditDisplay, &FancyLineEdit::validChanged, this, &StringAspect::validChanged);
+ bufferToGui();
+ if (isAutoApply() && d->m_autoApplyOnEditingFinished) {
+ connect(lineEditDisplay,
+ &FancyLineEdit::editingFinished,
+ this,
+ [this, lineEditDisplay]() {
+ d->undoable.set(undoStack(), lineEditDisplay->text());
+ handleGuiChanged();
+ });
+ } else {
+ connect(lineEditDisplay, &QLineEdit::textChanged, this, [this, lineEditDisplay]() {
+ d->undoable.set(undoStack(), lineEditDisplay->text());
+ handleGuiChanged();
});
}
- break;
- case LabelDisplay:
- d->m_labelDisplay = createSubWidget<ElidingLabel>();
- d->m_labelDisplay->setElideMode(d->m_elideMode);
- d->m_labelDisplay->setTextInteractionFlags(Qt::TextSelectableByMouse);
- d->m_labelDisplay->setText(displayedString);
- d->m_labelDisplay->setToolTip(d->m_showToolTipOnLabel ? displayedString : toolTip());
- addLabeledItem(parent, d->m_labelDisplay);
- break;
- }
+ if (d->m_displayStyle == PasswordLineEditDisplay) {
+ auto showPasswordButton = createSubWidget<ShowPasswordButton>();
+ lineEditDisplay->setEchoMode(QLineEdit::PasswordEchoOnEdit);
+ parent.addItem(showPasswordButton);
+ connect(showPasswordButton,
+ &ShowPasswordButton::toggled,
+ lineEditDisplay,
+ [showPasswordButton, lineEditDisplay] {
+ lineEditDisplay->setEchoMode(showPasswordButton->isChecked()
+ ? QLineEdit::Normal
+ : QLineEdit::PasswordEchoOnEdit);
+ });
+ }
- validateInput();
+ connect(&d->undoable.m_signal,
+ &UndoSignaller::changed,
+ lineEditDisplay,
+ [this, lineEditDisplay] {
+ if (lineEditDisplay->text() != d->undoable.get())
+ lineEditDisplay->setTextKeepingActiveCursor(d->undoable.get());
- if (d->m_checker && d->m_checkBoxPlacement == CheckBoxPlacement::Right)
- d->m_checker->addToLayout(parent);
-}
+ lineEditDisplay->validate();
+ });
-QVariant StringAspect::volatileValue() const
-{
- switch (d->m_displayStyle) {
- case PathChooserDisplay:
- QTC_ASSERT(d->m_pathChooserDisplay, return {});
- if (d->m_pathChooserDisplay->filePath().isEmpty())
- return defaultValue();
- return d->m_pathChooserDisplay->filePath().toString();
- case LineEditDisplay:
- QTC_ASSERT(d->m_lineEditDisplay, return {});
- if (d->m_lineEditDisplay->text().isEmpty())
- return defaultValue();
- return d->m_lineEditDisplay->text();
- case TextEditDisplay:
- QTC_ASSERT(d->m_textEditDisplay, return {});
- if (d->m_textEditDisplay->document()->isEmpty())
- return defaultValue();
- return d->m_textEditDisplay->document()->toPlainText();
- case LabelDisplay:
break;
}
- return {};
-}
+ case TextEditDisplay: {
+ auto textEditDisplay = createSubWidget<QTextEdit>();
+ textEditDisplay->setPlaceholderText(d->m_placeHolderText);
+ textEditDisplay->setUndoRedoEnabled(false);
+ textEditDisplay->setAcceptRichText(d->m_acceptRichText);
+ textEditDisplay->setTextInteractionFlags(Qt::TextEditorInteraction);
+ textEditDisplay->setText(displayedString);
+ textEditDisplay->setReadOnly(isReadOnly());
+ d->m_checkerImpl.updateWidgetFromCheckStatus(this, textEditDisplay);
+
+ if (d->m_checkerImpl.m_checked) {
+ connect(d->m_checkerImpl.m_checked.get(),
+ &BoolAspect::volatileValueChanged,
+ textEditDisplay,
+ [this, textEditDisplay]() {
+ d->m_checkerImpl.updateWidgetFromCheckStatus(this, textEditDisplay);
+ });
+ }
-void StringAspect::setVolatileValue(const QVariant &val)
-{
- switch (d->m_displayStyle) {
- case PathChooserDisplay:
- if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setFilePath(FilePath::fromVariant(val));
- break;
- case LineEditDisplay:
- if (d->m_lineEditDisplay)
- d->m_lineEditDisplay->setText(val.toString());
- break;
- case TextEditDisplay:
- if (d->m_textEditDisplay)
- d->m_textEditDisplay->document()->setPlainText(val.toString());
+ addLabeledItem(parent, textEditDisplay);
+ useMacroExpander(textEditDisplay);
+ bufferToGui();
+ connect(this,
+ &StringAspect::acceptRichTextChanged,
+ textEditDisplay,
+ &QTextEdit::setAcceptRichText);
+ connect(this,
+ &StringAspect::placeholderTextChanged,
+ textEditDisplay,
+ &QTextEdit::setPlaceholderText);
+
+ connect(textEditDisplay, &QTextEdit::textChanged, this, [this, textEditDisplay]() {
+ if (textEditDisplay->toPlainText() != d->undoable.get()) {
+ d->undoable.set(undoStack(), textEditDisplay->toPlainText());
+ handleGuiChanged();
+ }
+ });
+
+ connect(&d->undoable.m_signal,
+ &UndoSignaller::changed,
+ textEditDisplay,
+ [this, textEditDisplay] {
+ if (textEditDisplay->toPlainText() != d->undoable.get())
+ textEditDisplay->setText(d->undoable.get());
+ });
break;
- case LabelDisplay:
+ }
+ case LabelDisplay: {
+ auto labelDisplay = createSubWidget<ElidingLabel>();
+ labelDisplay->setElideMode(d->m_elideMode);
+ labelDisplay->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ labelDisplay->setText(displayedString);
+ labelDisplay->setToolTip(d->m_showToolTipOnLabel ? displayedString : toolTip());
+ connect(this, &StringAspect::elideModeChanged, labelDisplay, &ElidingLabel::setElideMode);
+ addLabeledItem(parent, labelDisplay);
+
+ connect(&d->undoable.m_signal, &UndoSignaller::changed, labelDisplay, [this, labelDisplay] {
+ labelDisplay->setText(d->undoable.get());
+ labelDisplay->setToolTip(d->m_showToolTipOnLabel ? d->undoable.get() : toolTip());
+ });
+
break;
}
+ }
+
+ d->m_checkerImpl.addToLayoutLast(parent);
}
-void StringAspect::emitChangedValue()
+QString StringAspect::expandedValue() const
{
- emit valueChanged(value());
+ // FIXME: Use macroexpander here later.
+ return m_internal;
}
-void StringAspect::update()
+bool StringAspect::guiToBuffer()
{
- const QString displayedString = d->m_displayFilter ? d->m_displayFilter(value()) : value();
-
- if (d->m_pathChooserDisplay) {
- d->m_pathChooserDisplay->setFilePath(FilePath::fromUserInput(displayedString));
- d->updateWidgetFromCheckStatus(this, d->m_pathChooserDisplay.data());
- }
-
- if (d->m_lineEditDisplay) {
- d->m_lineEditDisplay->setTextKeepingActiveCursor(displayedString);
- d->updateWidgetFromCheckStatus(this, d->m_lineEditDisplay.data());
- }
+ return updateStorage(m_buffer, d->undoable.get());
+}
- if (d->m_textEditDisplay) {
- const QString old = d->m_textEditDisplay->document()->toPlainText();
- if (displayedString != old)
- d->m_textEditDisplay->setText(displayedString);
- d->updateWidgetFromCheckStatus(this, d->m_textEditDisplay.data());
+bool StringAspect::bufferToInternal()
+{
+ if (d->m_valueAcceptor) {
+ if (const std::optional<QString> tmp = d->m_valueAcceptor(m_internal, m_buffer))
+ return updateStorage(m_internal, *tmp);
}
+ return updateStorage(m_internal, m_buffer);
+}
- if (d->m_labelDisplay) {
- d->m_labelDisplay->setText(displayedString);
- d->m_labelDisplay->setToolTip(d->m_showToolTipOnLabel ? displayedString : toolTip());
- }
+bool StringAspect::internalToBuffer()
+{
+ const QString val = d->m_displayFilter ? d->m_displayFilter(m_internal) : m_internal;
+ return updateStorage(m_buffer, val);
+}
- validateInput();
+void StringAspect::bufferToGui()
+{
+ d->undoable.setWithoutUndo(m_buffer);
}
/*!
@@ -1332,21 +1304,19 @@ void StringAspect::update()
\a checkerKey.
*/
void StringAspect::makeCheckable(CheckBoxPlacement checkBoxPlacement,
- const QString &checkerLabel, const QString &checkerKey)
+ const QString &checkerLabel, const Key &checkerKey)
{
- QTC_ASSERT(!d->m_checker, return);
- d->m_checkBoxPlacement = checkBoxPlacement;
- d->m_checker.reset(new BoolAspect);
- d->m_checker->setLabel(checkerLabel, checkBoxPlacement == CheckBoxPlacement::Top
- ? BoolAspect::LabelPlacement::InExtraLabel
- : BoolAspect::LabelPlacement::AtCheckBox);
- d->m_checker->setSettingsKey(checkerKey);
+ d->m_checkerImpl.makeCheckable(checkBoxPlacement, checkerLabel, checkerKey, this);
+}
- connect(d->m_checker.get(), &BoolAspect::changed, this, &StringAspect::update);
- connect(d->m_checker.get(), &BoolAspect::changed, this, &StringAspect::changed);
- connect(d->m_checker.get(), &BoolAspect::changed, this, &StringAspect::checkedChanged);
+bool StringAspect::isChecked() const
+{
+ return d->m_checkerImpl.isChecked();
+}
- update();
+void StringAspect::setChecked(bool checked)
+{
+ return d->m_checkerImpl.setChecked(checked);
}
@@ -1365,11 +1335,348 @@ void StringAspect::makeCheckable(CheckBoxPlacement checkBoxPlacement,
\sa Utils::StringAspect
*/
+class Internal::FilePathAspectPrivate
+{
+public:
+ std::function<QString(const QString &)> m_displayFilter;
+
+ QString m_placeHolderText;
+ QString m_prompDialogFilter;
+ QString m_prompDialogTitle;
+ QStringList m_commandVersionArguments;
+ Key m_historyCompleterKey;
+ PathChooser::Kind m_expectedKind = PathChooser::File;
+ Environment m_environment;
+ QPointer<PathChooser> m_pathChooserDisplay;
+ MacroExpanderProvider m_expanderProvider;
+ FilePath m_baseFileName;
+ StringAspect::ValueAcceptor m_valueAcceptor;
+ std::optional<FancyLineEdit::ValidationFunction> m_validator;
+ std::function<void()> m_openTerminal;
+
+ CheckableAspectImplementation m_checkerImpl;
+
+ bool m_showToolTipOnLabel = false;
+ bool m_fileDialogOnly = false;
+ bool m_autoApplyOnEditingFinished = false;
+ bool m_allowPathFromDevice = true;
+ bool m_validatePlaceHolder = false;
+};
FilePathAspect::FilePathAspect(AspectContainer *container)
- : StringAspect(container)
+ : TypedAspect(container), d(new Internal::FilePathAspectPrivate)
+{
+ setSpan(2, 1); // Default: Label + something
+
+ addDataExtractor(this, &FilePathAspect::value, &Data::value);
+ addDataExtractor(this, &FilePathAspect::operator(), &Data::filePath);
+}
+
+FilePathAspect::~FilePathAspect() = default;
+
+/*!
+ Returns the value of this aspect as \c Utils::FilePath.
+
+ \note This simply uses \c FilePath::fromUserInput() for the
+ conversion. It does not use any check that the value is actually
+ a valid file path.
+*/
+
+FilePath FilePathAspect::operator()() const
+{
+ return FilePath::fromUserInput(TypedAspect::value());
+}
+
+FilePath FilePathAspect::expandedValue() const
{
- setDisplayStyle(PathChooserDisplay);
+ return FilePath::fromUserInput(TypedAspect::value());
+}
+
+QString FilePathAspect::value() const
+{
+ return TypedAspect::value();
+}
+
+/*!
+ Sets the value of this file path aspect to \a value.
+
+ \note This does not use any check that the value is actually
+ a file path.
+*/
+
+void FilePathAspect::setValue(const FilePath &filePath, Announcement howToAnnounce)
+{
+ TypedAspect::setValue(filePath.toUserOutput(), howToAnnounce);
+}
+
+void FilePathAspect::setValue(const QString &filePath, Announcement howToAnnounce)
+{
+ TypedAspect::setValue(filePath, howToAnnounce);
+}
+
+void FilePathAspect::setDefaultValue(const QString &filePath)
+{
+ TypedAspect::setDefaultValue(filePath);
+}
+
+/*!
+ Adds a check box with a \a checkerLabel according to \a checkBoxPlacement
+ to the line edit.
+
+ The state of the check box is made persistent when using a non-emtpy
+ \a checkerKey.
+*/
+void FilePathAspect::makeCheckable(CheckBoxPlacement checkBoxPlacement,
+ const QString &checkerLabel,
+ const Key &checkerKey)
+{
+ d->m_checkerImpl.makeCheckable(checkBoxPlacement, checkerLabel, checkerKey, this);
+}
+
+bool FilePathAspect::isChecked() const
+{
+ return d->m_checkerImpl.isChecked();
+}
+
+void FilePathAspect::setChecked(bool checked)
+{
+ return d->m_checkerImpl.setChecked(checked);
+}
+
+void FilePathAspect::setValueAcceptor(ValueAcceptor &&acceptor)
+{
+ d->m_valueAcceptor = std::move(acceptor);
+}
+
+bool FilePathAspect::guiToBuffer()
+{
+ if (d->m_pathChooserDisplay)
+ return updateStorage(m_buffer, d->m_pathChooserDisplay->lineEdit()->text());
+ return false;
+}
+
+bool FilePathAspect::bufferToInternal()
+{
+ if (d->m_valueAcceptor) {
+ if (const std::optional<QString> tmp = d->m_valueAcceptor(m_internal, m_buffer))
+ return updateStorage(m_internal, *tmp);
+ }
+ return updateStorage(m_internal, m_buffer);
+}
+
+bool FilePathAspect::internalToBuffer()
+{
+ const QString val = d->m_displayFilter ? d->m_displayFilter(m_internal) : m_internal;
+ return updateStorage(m_buffer, val);
+}
+
+void FilePathAspect::bufferToGui()
+{
+ if (d->m_pathChooserDisplay) {
+ d->m_pathChooserDisplay->lineEdit()->setText(m_buffer);
+ d->m_checkerImpl.updateWidgetFromCheckStatus(this, d->m_pathChooserDisplay.data());
+ }
+
+ validateInput();
+}
+
+PathChooser *FilePathAspect::pathChooser() const
+{
+ return d->m_pathChooserDisplay.data();
+}
+
+void FilePathAspect::addToLayout(Layouting::LayoutItem &parent)
+{
+ d->m_checkerImpl.addToLayoutFirst(parent);
+
+ const auto useMacroExpander = [this](QWidget *w) {
+ if (!d->m_expanderProvider)
+ return;
+ const auto chooser = new VariableChooser(w);
+ chooser->addSupportedWidget(w);
+ chooser->addMacroExpanderProvider(d->m_expanderProvider);
+ };
+
+ const QString displayedString = d->m_displayFilter ? d->m_displayFilter(value()) : value();
+
+ d->m_pathChooserDisplay = createSubWidget<PathChooser>();
+ d->m_pathChooserDisplay->setExpectedKind(d->m_expectedKind);
+ if (!d->m_historyCompleterKey.isEmpty())
+ d->m_pathChooserDisplay->setHistoryCompleter(d->m_historyCompleterKey);
+
+ if (d->m_validator)
+ d->m_pathChooserDisplay->setValidationFunction(*d->m_validator);
+ d->m_pathChooserDisplay->setEnvironment(d->m_environment);
+ d->m_pathChooserDisplay->setBaseDirectory(d->m_baseFileName);
+ d->m_pathChooserDisplay->setOpenTerminalHandler(d->m_openTerminal);
+ d->m_pathChooserDisplay->setPromptDialogFilter(d->m_prompDialogFilter);
+ d->m_pathChooserDisplay->setPromptDialogTitle(d->m_prompDialogTitle);
+ d->m_pathChooserDisplay->setCommandVersionArguments(d->m_commandVersionArguments);
+ d->m_pathChooserDisplay->setAllowPathFromDevice(d->m_allowPathFromDevice);
+ d->m_pathChooserDisplay->setReadOnly(isReadOnly());
+ d->m_pathChooserDisplay->lineEdit()->setValidatePlaceHolder(d->m_validatePlaceHolder);
+ if (defaultValue() == value())
+ d->m_pathChooserDisplay->setDefaultValue(defaultValue());
+ else
+ d->m_pathChooserDisplay->setFilePath(FilePath::fromUserInput(displayedString));
+ // do not override default value with placeholder, but use placeholder if default is empty
+ if (d->m_pathChooserDisplay->lineEdit()->placeholderText().isEmpty())
+ d->m_pathChooserDisplay->lineEdit()->setPlaceholderText(d->m_placeHolderText);
+ d->m_checkerImpl.updateWidgetFromCheckStatus(this, d->m_pathChooserDisplay.data());
+ addLabeledItem(parent, d->m_pathChooserDisplay);
+ useMacroExpander(d->m_pathChooserDisplay->lineEdit());
+ connect(d->m_pathChooserDisplay, &PathChooser::validChanged, this, &FilePathAspect::validChanged);
+ bufferToGui();
+ if (isAutoApply() && d->m_autoApplyOnEditingFinished) {
+ connect(d->m_pathChooserDisplay, &PathChooser::editingFinished,
+ this, &FilePathAspect::handleGuiChanged);
+ connect(d->m_pathChooserDisplay, &PathChooser::browsingFinished,
+ this, &FilePathAspect::handleGuiChanged);
+ } else {
+ connect(d->m_pathChooserDisplay, &PathChooser::textChanged,
+ this, &FilePathAspect::handleGuiChanged);
+ }
+
+ d->m_checkerImpl.addToLayoutLast(parent);
+}
+
+/*!
+ \reimp
+*/
+void FilePathAspect::fromMap(const Store &map)
+{
+ if (!settingsKey().isEmpty())
+ setValue(map.value(settingsKey(), defaultValue()).toString(), BeQuiet);
+ d->m_checkerImpl.fromMap(map);
+}
+
+/*!
+ \reimp
+*/
+void FilePathAspect::toMap(Store &map) const
+{
+ saveToMap(map, value(), defaultValue(), settingsKey());
+ d->m_checkerImpl.toMap(map);
+}
+
+void FilePathAspect::volatileToMap(Store &map) const
+{
+ saveToMap(map, volatileValue(), defaultValue(), settingsKey());
+ d->m_checkerImpl.volatileToMap(map);
+}
+
+void FilePathAspect::setPromptDialogFilter(const QString &filter)
+{
+ d->m_prompDialogFilter = filter;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setPromptDialogFilter(filter);
+}
+
+void FilePathAspect::setPromptDialogTitle(const QString &title)
+{
+ d->m_prompDialogTitle = title;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setPromptDialogTitle(title);
+}
+
+void FilePathAspect::setCommandVersionArguments(const QStringList &arguments)
+{
+ d->m_commandVersionArguments = arguments;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setCommandVersionArguments(arguments);
+}
+
+void FilePathAspect::setAllowPathFromDevice(bool allowPathFromDevice)
+{
+ d->m_allowPathFromDevice = allowPathFromDevice;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setAllowPathFromDevice(allowPathFromDevice);
+}
+
+void FilePathAspect::setValidatePlaceHolder(bool validatePlaceHolder)
+{
+ d->m_validatePlaceHolder = validatePlaceHolder;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->lineEdit()->setValidatePlaceHolder(validatePlaceHolder);
+}
+
+void FilePathAspect::setShowToolTipOnLabel(bool show)
+{
+ d->m_showToolTipOnLabel = show;
+ bufferToGui();
+}
+
+void FilePathAspect::setAutoApplyOnEditingFinished(bool applyOnEditingFinished)
+{
+ d->m_autoApplyOnEditingFinished = applyOnEditingFinished;
+}
+
+/*!
+ Sets \a expectedKind as expected kind for path chooser displays.
+
+ \sa Utils::PathChooser::setExpectedKind()
+*/
+void FilePathAspect::setExpectedKind(const PathChooser::Kind expectedKind)
+{
+ d->m_expectedKind = expectedKind;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setExpectedKind(expectedKind);
+}
+
+void FilePathAspect::setEnvironment(const Environment &env)
+{
+ d->m_environment = env;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setEnvironment(env);
+}
+
+void FilePathAspect::setBaseFileName(const FilePath &baseFileName)
+{
+ d->m_baseFileName = baseFileName;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setBaseDirectory(baseFileName);
+}
+
+void FilePathAspect::setPlaceHolderText(const QString &placeHolderText)
+{
+ d->m_placeHolderText = placeHolderText;
+}
+
+void FilePathAspect::setValidationFunction(const FancyLineEdit::ValidationFunction &validator)
+{
+ d->m_validator = validator;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setValidationFunction(*d->m_validator);
+}
+
+void FilePathAspect::setDisplayFilter(const std::function<QString (const QString &)> &displayFilter)
+{
+ d->m_displayFilter = displayFilter;
+}
+
+void FilePathAspect::setHistoryCompleter(const Key &historyCompleterKey)
+{
+ d->m_historyCompleterKey = historyCompleterKey;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setHistoryCompleter(historyCompleterKey);
+}
+
+void FilePathAspect::setMacroExpanderProvider(const MacroExpanderProvider &expanderProvider)
+{
+ d->m_expanderProvider = expanderProvider;
+}
+
+void FilePathAspect::validateInput()
+{
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->triggerChanged();
+}
+
+void FilePathAspect::setOpenTerminalHandler(const std::function<void ()> &openTerminal)
+{
+ d->m_openTerminal = openTerminal;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setOpenTerminalHandler(openTerminal);
}
/*!
@@ -1384,12 +1691,10 @@ FilePathAspect::FilePathAspect(AspectContainer *container)
*/
ColorAspect::ColorAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::ColorAspectPrivate)
+ : TypedAspect(container), d(new Internal::ColorAspectPrivate)
{
setDefaultValue(QColor::fromRgb(0, 0, 0));
setSpan(1, 1);
-
- addDataExtractor(this, &ColorAspect::value, &Data::value);
}
ColorAspect::~ColorAspect() = default;
@@ -1399,40 +1704,23 @@ void ColorAspect::addToLayout(Layouting::LayoutItem &parent)
QTC_CHECK(!d->m_colorButton);
d->m_colorButton = createSubWidget<QtColorButton>();
parent.addItem(d->m_colorButton.data());
- d->m_colorButton->setColor(value());
- if (isAutoApply()) {
- connect(d->m_colorButton.data(),
- &QtColorButton::colorChanged,
- this,
- [this](const QColor &color) { setValue(color); });
- }
-}
-
-QColor ColorAspect::value() const
-{
- return BaseAspect::value().value<QColor>();
-}
-void ColorAspect::setValue(const QColor &value)
-{
- if (BaseAspect::setValueQuietly(value))
- emit changed();
+ bufferToGui();
+ connect(d->m_colorButton.data(), &QtColorButton::colorChanged,
+ this, &ColorAspect::handleGuiChanged);
}
-QVariant ColorAspect::volatileValue() const
+bool ColorAspect::guiToBuffer()
{
- QTC_CHECK(!isAutoApply());
if (d->m_colorButton)
- return d->m_colorButton->color();
- QTC_CHECK(false);
- return {};
+ return updateStorage(m_buffer, d->m_colorButton->color());
+ return false;
}
-void ColorAspect::setVolatileValue(const QVariant &val)
+void ColorAspect::bufferToGui()
{
- QTC_CHECK(!isAutoApply());
if (d->m_colorButton)
- d->m_colorButton->setColor(val.value<QColor>());
+ d->m_colorButton->setColor(m_buffer);
}
/*!
@@ -1451,12 +1739,12 @@ void ColorAspect::setVolatileValue(const QVariant &val)
BoolAspect::BoolAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::BoolAspectPrivate)
+ : TypedAspect(container), d(new Internal::BoolAspectPrivate)
{
setDefaultValue(false);
setSpan(2, 1);
- addDataExtractor(this, &BoolAspect::value, &Data::value);
+ d->m_undoable.setSilently(false);
}
/*!
@@ -1464,45 +1752,53 @@ BoolAspect::BoolAspect(AspectContainer *container)
*/
BoolAspect::~BoolAspect() = default;
-/*!
- \reimp
-*/
-void BoolAspect::addToLayout(Layouting::LayoutItem &parent)
+void BoolAspect::addToLayoutHelper(Layouting::LayoutItem &parent, QAbstractButton *button)
{
- if (!d->m_buttonIsAdopted) {
- QTC_CHECK(!d->m_button);
- d->m_button = createSubWidget<QCheckBox>();
- }
switch (d->m_labelPlacement) {
- case LabelPlacement::AtCheckBoxWithoutDummyLabel:
- d->m_button->setText(labelText());
- parent.addItem(d->m_button.data());
+ case LabelPlacement::Compact:
+ button->setText(labelText());
+ parent.addItem(button);
break;
case LabelPlacement::AtCheckBox:
- d->m_button->setText(labelText());
+ button->setText(labelText());
parent.addItem(empty());
- parent.addItem(d->m_button.data());
+ parent.addItem(button);
break;
case LabelPlacement::InExtraLabel:
- addLabeledItem(parent, d->m_button);
+ addLabeledItem(parent, button);
break;
}
- d->m_button->setChecked(value());
- if (isAutoApply()) {
- connect(d->m_button.data(), &QAbstractButton::clicked,
- this, [this](bool val) { setValue(val); });
- }
- connect(d->m_button.data(), &QAbstractButton::clicked,
- this, &BoolAspect::volatileValueChanged);
+
+ connect(button, &QAbstractButton::clicked, this, [button, this] {
+ d->m_undoable.set(undoStack(), button->isChecked());
+ });
+
+ connect(&d->m_undoable.m_signal, &UndoSignaller::changed, button, [button, this] {
+ button->setChecked(d->m_undoable.get());
+ handleGuiChanged();
+ });
+}
+
+LayoutItem BoolAspect::adoptButton(QAbstractButton *button)
+{
+ LayoutItem parent;
+
+ addToLayoutHelper(parent, button);
+
+ bufferToGui();
+ return parent;
}
-void BoolAspect::adoptButton(QAbstractButton *button)
+/*!
+ \reimp
+*/
+void BoolAspect::addToLayout(Layouting::LayoutItem &parent)
{
- QTC_ASSERT(button, return);
- QTC_CHECK(!d->m_button);
- d->m_button = button;
- d->m_buttonIsAdopted = true;
- registerSubWidget(button);
+ QTC_ASSERT(m_buffer == m_internal, m_buffer = m_internal);
+
+ QCheckBox *checkBox = createSubWidget<QCheckBox>();
+ addToLayoutHelper(parent, checkBox);
+ bufferToGui();
}
std::function<void (QObject *)> BoolAspect::groupChecker()
@@ -1513,92 +1809,46 @@ std::function<void (QObject *)> BoolAspect::groupChecker()
registerSubWidget(groupBox);
groupBox->setCheckable(true);
groupBox->setChecked(value());
- d->m_groupBox = groupBox;
+
+ connect(groupBox, &QGroupBox::clicked, this, [groupBox, this] {
+ d->m_undoable.set(undoStack(), groupBox->isChecked());
+ });
+
+ connect(&d->m_undoable.m_signal, &UndoSignaller::changed, groupBox, [groupBox, this] {
+ groupBox->setChecked(d->m_undoable.get());
+ handleGuiChanged();
+ });
+ bufferToGui();
};
}
QAction *BoolAspect::action()
{
if (hasAction())
- return BaseAspect::action();
- auto act = BaseAspect::action(); // Creates it.
+ return TypedAspect::action();
+ auto act = TypedAspect::action(); // Creates it.
act->setCheckable(true);
- act->setChecked(value());
+ act->setChecked(m_internal);
act->setToolTip(toolTip());
connect(act, &QAction::triggered, this, [this](bool newValue) {
- // The check would be nice to have in simple conditions, but if we
- // have an action that's used both on a settings page and as action
- // in a menu like "Use FakeVim", isAutoApply() is false, and yet this
- // here can trigger.
- //QTC_CHECK(isAutoApply());
setValue(newValue);
});
return act;
}
-QVariant BoolAspect::volatileValue() const
-{
- if (d->m_button)
- return d->m_button->isChecked();
- if (d->m_groupBox)
- return d->m_groupBox->isChecked();
- QTC_CHECK(false);
- return {};
-}
-
-void BoolAspect::setVolatileValue(const QVariant &val)
-{
- if (d->m_button)
- d->m_button->setChecked(val.toBool());
- else if (d->m_groupBox)
- d->m_groupBox->setChecked(val.toBool());
-}
-
-void BoolAspect::emitChangedValue()
-{
- emit valueChanged(value());
-}
-
-
-/*!
- Returns the value of the boolean aspect as a boolean value.
-*/
-
-bool BoolAspect::value() const
-{
- return BaseAspect::value().toBool();
-}
-
-void BoolAspect::setValue(bool value)
-{
- if (BaseAspect::setValueQuietly(value)) {
- if (d->m_button)
- d->m_button->setChecked(value);
- //qDebug() << "SetValue: Changing" << labelText() << " to " << value;
- emit changed();
- //QTC_CHECK(!labelText().isEmpty());
- emit valueChanged(value);
- //qDebug() << "SetValue: Changed" << labelText() << " to " << value;
- if (hasAction()) {
- //qDebug() << "SetValue: Triggering " << labelText() << "with" << value;
- emit action()->triggered(value);
- }
- }
-}
-
-bool BoolAspect::defaultValue() const
+bool BoolAspect::guiToBuffer()
{
- return BaseAspect::defaultValue().toBool();
+ return updateStorage(m_buffer, d->m_undoable.get());
}
-void BoolAspect::setDefaultValue(bool val)
+void BoolAspect::bufferToGui()
{
- BaseAspect::setDefaultValue(val);
+ d->m_undoable.setWithoutUndo(m_buffer);
}
void BoolAspect::setLabel(const QString &labelText, LabelPlacement labelPlacement)
{
- BaseAspect::setLabelText(labelText);
+ TypedAspect::setLabelText(labelText);
d->m_labelPlacement = labelPlacement;
}
@@ -1635,7 +1885,7 @@ CheckableDecider BoolAspect::doNotAskAgainCheckableDecider()
*/
SelectionAspect::SelectionAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::SelectionAspectPrivate)
+ : TypedAspect(container), d(new Internal::SelectionAspectPrivate)
{
setSpan(2, 1);
}
@@ -1653,6 +1903,7 @@ void SelectionAspect::addToLayout(Layouting::LayoutItem &parent)
QTC_CHECK(d->m_buttonGroup == nullptr);
QTC_CHECK(!d->m_comboBox);
QTC_ASSERT(d->m_buttons.isEmpty(), d->m_buttons.clear());
+ QTC_ASSERT(m_buffer == m_internal, m_buffer = m_internal);
switch (d->m_displayStyle) {
case DisplayStyle::RadioButtons:
@@ -1667,58 +1918,49 @@ void SelectionAspect::addToLayout(Layouting::LayoutItem &parent)
parent.addItem(button);
d->m_buttons.append(button);
d->m_buttonGroup->addButton(button, i);
- if (isAutoApply()) {
- connect(button, &QAbstractButton::clicked, this, [this, i] {
- setValue(i);
- });
- }
}
+ bufferToGui();
+ connect(d->m_buttonGroup, &QButtonGroup::idClicked,
+ this, &SelectionAspect::handleGuiChanged);
break;
case DisplayStyle::ComboBox:
setLabelText(displayName());
d->m_comboBox = createSubWidget<QComboBox>();
for (int i = 0, n = d->m_options.size(); i < n; ++i)
d->m_comboBox->addItem(d->m_options.at(i).displayName);
- if (isAutoApply()) {
- connect(d->m_comboBox.data(), &QComboBox::activated,
- this, &SelectionAspect::setValue);
- }
- connect(d->m_comboBox.data(), &QComboBox::currentIndexChanged,
- this, &SelectionAspect::volatileValueChanged);
d->m_comboBox->setCurrentIndex(value());
addLabeledItem(parent, d->m_comboBox);
+ bufferToGui();
+ connect(d->m_comboBox.data(), &QComboBox::activated,
+ this, &SelectionAspect::handleGuiChanged);
break;
}
}
-QVariant SelectionAspect::volatileValue() const
+bool SelectionAspect::guiToBuffer()
{
+ const int old = m_buffer;
switch (d->m_displayStyle) {
case DisplayStyle::RadioButtons:
- QTC_ASSERT(d->m_buttonGroup, return {});
- return d->m_buttonGroup->checkedId();
+ if (d->m_buttonGroup)
+ m_buffer = d->m_buttonGroup->checkedId();
+ break;
case DisplayStyle::ComboBox:
- QTC_ASSERT(d->m_comboBox, return {});
- return d->m_comboBox->currentIndex();
+ if (d->m_comboBox)
+ m_buffer = d->m_comboBox->currentIndex();
+ break;
}
- return {};
+ return m_buffer != old;
}
-void SelectionAspect::setVolatileValue(const QVariant &val)
+void SelectionAspect::bufferToGui()
{
- switch (d->m_displayStyle) {
- case DisplayStyle::RadioButtons: {
- if (d->m_buttonGroup) {
- QAbstractButton *button = d->m_buttonGroup->button(val.toInt());
- QTC_ASSERT(button, return);
- button->setChecked(true);
- }
- break;
- }
- case DisplayStyle::ComboBox:
- if (d->m_comboBox)
- d->m_comboBox->setCurrentIndex(val.toInt());
- break;
+ if (d->m_buttonGroup) {
+ QAbstractButton *button = d->m_buttonGroup->button(m_buffer);
+ QTC_ASSERT(button, return);
+ button->setChecked(true);
+ } else if (d->m_comboBox) {
+ d->m_comboBox->setCurrentIndex(m_buffer);
}
}
@@ -1735,22 +1977,6 @@ void SelectionAspect::setDisplayStyle(SelectionAspect::DisplayStyle style)
d->m_displayStyle = style;
}
-int SelectionAspect::value() const
-{
- return BaseAspect::value().toInt();
-}
-
-void SelectionAspect::setValue(int value)
-{
- if (BaseAspect::setValueQuietly(value)) {
- if (d->m_buttonGroup && 0 <= value && value < d->m_buttons.size())
- d->m_buttons.at(value)->setChecked(true);
- else if (d->m_comboBox)
- d->m_comboBox->setCurrentIndex(value);
- emit changed();
- }
-}
-
void SelectionAspect::setStringValue(const QString &val)
{
const int index = indexForDisplay(val);
@@ -1758,20 +1984,15 @@ void SelectionAspect::setStringValue(const QString &val)
setValue(index);
}
-int SelectionAspect::defaultValue() const
-{
- return BaseAspect::defaultValue().toInt();
-}
-
void SelectionAspect::setDefaultValue(int val)
{
- BaseAspect::setDefaultValue(val);
+ TypedAspect::setDefaultValue(val);
}
// Note: This needs to be set after all options are added.
void SelectionAspect::setDefaultValue(const QString &val)
{
- BaseAspect::setDefaultValue(indexForDisplay(val));
+ TypedAspect::setDefaultValue(indexForDisplay(val));
}
QString SelectionAspect::stringValue() const
@@ -1838,7 +2059,7 @@ QVariant SelectionAspect::itemValueForIndex(int index) const
*/
MultiSelectionAspect::MultiSelectionAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::MultiSelectionAspectPrivate(this))
+ : TypedAspect(container), d(new Internal::MultiSelectionAspectPrivate(this))
{
setDefaultValue(QStringList());
setSpan(2, 1);
@@ -1861,17 +2082,13 @@ void MultiSelectionAspect::addToLayout(LayoutItem &builder)
switch (d->m_displayStyle) {
case DisplayStyle::ListView:
d->m_listView = createSubWidget<QListWidget>();
- for (const QString &val : std::as_const(d->m_allValues)) {
- auto item = new QListWidgetItem(val, d->m_listView);
- item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
- item->setCheckState(value().contains(item->text()) ? Qt::Checked : Qt::Unchecked);
- }
- connect(d->m_listView, &QListWidget::itemChanged, this,
- [this](QListWidgetItem *item) {
- if (d->setValueSelectedHelper(item->text(), item->checkState() & Qt::Checked))
- emit changed();
- });
+ for (const QString &val : std::as_const(d->m_allValues))
+ (void) new QListWidgetItem(val, d->m_listView);
addLabeledItem(builder, d->m_listView);
+
+ bufferToGui();
+ connect(d->m_listView, &QListWidget::itemChanged,
+ this, &MultiSelectionAspect::handleGuiChanged);
}
}
@@ -1906,25 +2123,32 @@ void MultiSelectionAspect::setDisplayStyle(MultiSelectionAspect::DisplayStyle st
d->m_displayStyle = style;
}
-QStringList MultiSelectionAspect::value() const
+void MultiSelectionAspect::bufferToGui()
{
- return BaseAspect::value().toStringList();
+ if (d->m_listView) {
+ const int n = d->m_listView->count();
+ QTC_CHECK(n == d->m_allValues.size());
+ for (int i = 0; i != n; ++i) {
+ auto item = d->m_listView->item(i);
+ item->setCheckState(m_buffer.contains(item->text()) ? Qt::Checked : Qt::Unchecked);
+ }
+ }
}
-void MultiSelectionAspect::setValue(const QStringList &value)
+bool MultiSelectionAspect::guiToBuffer()
{
- if (BaseAspect::setValueQuietly(value)) {
- if (d->m_listView) {
- const int n = d->m_listView->count();
- QTC_CHECK(n == d->m_allValues.size());
- for (int i = 0; i != n; ++i) {
- auto item = d->m_listView->item(i);
- item->setCheckState(value.contains(item->text()) ? Qt::Checked : Qt::Unchecked);
- }
- } else {
- emit changed();
+ if (d->m_listView) {
+ QStringList val;
+ const int n = d->m_listView->count();
+ QTC_CHECK(n == d->m_allValues.size());
+ for (int i = 0; i != n; ++i) {
+ auto item = d->m_listView->item(i);
+ if (item->checkState() == Qt::Checked)
+ val.append(item->text());
}
+ return updateStorage(m_buffer, val);
}
+ return false;
}
@@ -1945,12 +2169,9 @@ void MultiSelectionAspect::setValue(const QStringList &value)
// IntegerAspect
IntegerAspect::IntegerAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::IntegerAspectPrivate)
+ : TypedAspect(container), d(new Internal::IntegerAspectPrivate)
{
- setDefaultValue(qint64(0));
setSpan(2, 1);
-
- addDataExtractor(this, &IntegerAspect::value, &Data::value);
}
/*!
@@ -1975,48 +2196,21 @@ void IntegerAspect::addToLayout(Layouting::LayoutItem &parent)
int(d->m_maximumValue.value() / d->m_displayScaleFactor));
d->m_spinBox->setValue(int(value() / d->m_displayScaleFactor)); // Must happen after setRange()
addLabeledItem(parent, d->m_spinBox);
-
- if (isAutoApply()) {
- connect(d->m_spinBox.data(), &QSpinBox::valueChanged,
- this, [this] { setValue(d->m_spinBox->value() * d->m_displayScaleFactor); });
- }
-}
-
-QVariant IntegerAspect::volatileValue() const
-{
- QTC_CHECK(!isAutoApply());
- QTC_ASSERT(d->m_spinBox, return {});
- return d->m_spinBox->value() * d->m_displayScaleFactor;
+ connect(d->m_spinBox.data(), &QSpinBox::valueChanged,
+ this, &IntegerAspect::handleGuiChanged);
}
-void IntegerAspect::setVolatileValue(const QVariant &val)
+bool IntegerAspect::guiToBuffer()
{
- QTC_CHECK(!isAutoApply());
if (d->m_spinBox)
- d->m_spinBox->setValue(int(val.toLongLong() / d->m_displayScaleFactor));
-}
-
-qint64 IntegerAspect::value() const
-{
- return BaseAspect::value().toLongLong();
-}
-
-void IntegerAspect::setValue(qint64 value)
-{
- if (BaseAspect::setValueQuietly(value)) {
- if (d->m_spinBox)
- d->m_spinBox->setValue(value / d->m_displayScaleFactor);
- //qDebug() << "SetValue: Changing" << labelText() << " to " << value;
- emit changed();
- //QTC_CHECK(!labelText().isEmpty());
- emit valueChanged(value);
- //qDebug() << "SetValue: Changed" << labelText() << " to " << value;
- }
+ return updateStorage(m_buffer, d->m_spinBox->value() * d->m_displayScaleFactor);
+ return false;
}
-qint64 IntegerAspect::defaultValue() const
+void IntegerAspect::bufferToGui()
{
- return BaseAspect::defaultValue().toLongLong();
+ if (d->m_spinBox)
+ d->m_spinBox->setValue(m_buffer / d->m_displayScaleFactor);
}
void IntegerAspect::setRange(qint64 min, qint64 max)
@@ -2050,11 +2244,6 @@ void IntegerAspect::setDisplayScaleFactor(qint64 factor)
d->m_displayScaleFactor = factor;
}
-void IntegerAspect::setDefaultValue(qint64 defaultValue)
-{
- BaseAspect::setDefaultValue(defaultValue);
-}
-
void IntegerAspect::setSpecialValueText(const QString &specialText)
{
d->m_specialValueText = specialText;
@@ -2081,7 +2270,7 @@ void IntegerAspect::setSingleStep(qint64 step)
*/
DoubleAspect::DoubleAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::DoubleAspectPrivate)
+ : TypedAspect(container), d(new Internal::DoubleAspectPrivate)
{
setDefaultValue(double(0));
setSpan(2, 1);
@@ -2105,42 +2294,23 @@ void DoubleAspect::addToLayout(LayoutItem &builder)
d->m_spinBox->setSpecialValueText(d->m_specialValueText);
if (d->m_maximumValue && d->m_maximumValue)
d->m_spinBox->setRange(d->m_minimumValue.value(), d->m_maximumValue.value());
- d->m_spinBox->setValue(value()); // Must happen after setRange()!
+ bufferToGui(); // Must happen after setRange()!
addLabeledItem(builder, d->m_spinBox);
-
- if (isAutoApply()) {
- connect(d->m_spinBox.data(), &QDoubleSpinBox::valueChanged,
- this, [this] { setValue(d->m_spinBox->value()); });
- }
-}
-
-QVariant DoubleAspect::volatileValue() const
-{
- QTC_CHECK(!isAutoApply());
- QTC_ASSERT(d->m_spinBox, return {});
- return d->m_spinBox->value();
+ connect(d->m_spinBox.data(), &QDoubleSpinBox::valueChanged,
+ this, &DoubleAspect::handleGuiChanged);
}
-void DoubleAspect::setVolatileValue(const QVariant &val)
+bool DoubleAspect::guiToBuffer()
{
- QTC_CHECK(!isAutoApply());
if (d->m_spinBox)
- d->m_spinBox->setValue(val.toDouble());
-}
-
-double DoubleAspect::value() const
-{
- return BaseAspect::value().toDouble();
-}
-
-void DoubleAspect::setValue(double value)
-{
- BaseAspect::setValue(value);
+ return updateStorage(m_buffer, d->m_spinBox->value());
+ return false;
}
-double DoubleAspect::defaultValue() const
+void DoubleAspect::bufferToGui()
{
- return BaseAspect::defaultValue().toDouble();
+ if (d->m_spinBox)
+ d->m_spinBox->setValue(m_buffer);
}
void DoubleAspect::setRange(double min, double max)
@@ -2159,11 +2329,6 @@ void DoubleAspect::setSuffix(const QString &suffix)
d->m_suffix = suffix;
}
-void DoubleAspect::setDefaultValue(double defaultValue)
-{
- BaseAspect::setDefaultValue(defaultValue);
-}
-
void DoubleAspect::setSpecialValueText(const QString &specialText)
{
d->m_specialValueText = specialText;
@@ -2200,7 +2365,7 @@ TriStateAspect::TriStateAspect(AspectContainer *container,
TriState TriStateAspect::value() const
{
- return TriState::fromVariant(BaseAspect::value());
+ return TriState::fromInt(SelectionAspect::value());
}
void TriStateAspect::setValue(TriState value)
@@ -2210,12 +2375,12 @@ void TriStateAspect::setValue(TriState value)
TriState TriStateAspect::defaultValue() const
{
- return TriState::fromVariant(BaseAspect::defaultValue());
+ return TriState::fromInt(SelectionAspect::defaultValue());
}
void TriStateAspect::setDefaultValue(TriState value)
{
- BaseAspect::setDefaultValue(value.toVariant());
+ SelectionAspect::setDefaultValue(value.toInt());
}
const TriState TriState::Enabled{TriState::EnabledValue};
@@ -2224,7 +2389,11 @@ const TriState TriState::Default{TriState::DefaultValue};
TriState TriState::fromVariant(const QVariant &variant)
{
- int v = variant.toInt();
+ return fromInt(variant.toInt());
+}
+
+TriState TriState::fromInt(int v)
+{
QTC_ASSERT(v == EnabledValue || v == DisabledValue || v == DefaultValue, v = DefaultValue);
return TriState(Value(v));
}
@@ -2239,7 +2408,7 @@ TriState TriState::fromVariant(const QVariant &variant)
*/
StringListAspect::StringListAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::StringListAspectPrivate)
+ : TypedAspect(container), d(new Internal::StringListAspectPrivate)
{
setDefaultValue(QStringList());
}
@@ -2258,16 +2427,6 @@ void StringListAspect::addToLayout(LayoutItem &parent)
// TODO - when needed.
}
-QStringList StringListAspect::value() const
-{
- return BaseAspect::value().toStringList();
-}
-
-void StringListAspect::setValue(const QStringList &value)
-{
- BaseAspect::setValue(value);
-}
-
void StringListAspect::appendValue(const QString &s, bool allowDuplicates)
{
QStringList val = value();
@@ -2302,59 +2461,140 @@ void StringListAspect::removeValues(const QStringList &values)
}
/*!
- \class Utils::IntegerListAspect
- \internal
+ \class Utils::FilePathListAspect
\inmodule QtCreator
- \brief A string list aspect represents a property of some object
- that is a list of strings.
+ \brief A filepath list aspect represents a property of some object
+ that is a list of filepathList.
*/
-IntegersAspect::IntegersAspect(AspectContainer *container)
- : BaseAspect(container)
+FilePathListAspect::FilePathListAspect(AspectContainer *container)
+ : TypedAspect(container)
+ , d(new Internal::FilePathListAspectPrivate)
{
- setDefaultValue({});
+ setDefaultValue(QStringList());
}
-/*!
- \internal
-*/
-IntegersAspect::~IntegersAspect() = default;
+FilePathListAspect::~FilePathListAspect() = default;
-/*!
- \reimp
-*/
-void IntegersAspect::addToLayout(Layouting::LayoutItem &parent)
+FilePaths FilePathListAspect::operator()() const
{
- Q_UNUSED(parent)
- // TODO - when needed.
+ return Utils::transform(m_internal, &FilePath::fromUserInput);
+}
+
+bool FilePathListAspect::guiToBuffer()
+{
+ const QStringList newValue = d->undoable.get();
+ if (newValue != m_buffer) {
+ m_buffer = newValue;
+ return true;
+ }
+ return false;
+}
+
+void FilePathListAspect::bufferToGui()
+{
+ d->undoable.setWithoutUndo(m_buffer);
+}
+
+void FilePathListAspect::addToLayout(LayoutItem &parent)
+{
+ d->undoable.setSilently(value());
+
+ PathListEditor *editor = new PathListEditor;
+ editor->setPathList(value());
+ connect(editor, &PathListEditor::changed, this, [this, editor] {
+ d->undoable.set(undoStack(), editor->pathList());
+ });
+ connect(&d->undoable.m_signal, &UndoSignaller::changed, editor, [this, editor] {
+ if (editor->pathList() != d->undoable.get())
+ editor->setPathList(d->undoable.get());
+
+ handleGuiChanged();
+ });
+
+ editor->setToolTip(toolTip());
+ editor->setMaximumHeight(100);
+ editor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ editor->setPlaceholderText(d->placeHolderText);
+
+ registerSubWidget(editor);
+
+ parent.addItem(editor);
+}
+
+void FilePathListAspect::setPlaceHolderText(const QString &placeHolderText)
+{
+ d->placeHolderText = placeHolderText;
+
+ forEachSubWidget([placeHolderText](QWidget *widget) {
+ if (auto pathListEditor = qobject_cast<PathListEditor *>(widget)) {
+ pathListEditor->setPlaceholderText(placeHolderText);
+ }
+ });
}
-void IntegersAspect::emitChangedValue()
+void FilePathListAspect::appendValue(const FilePath &path, bool allowDuplicates)
{
- emit valueChanged(value());
+ const QString asString = path.toUserOutput();
+ QStringList val = value();
+ if (allowDuplicates || !val.contains(asString))
+ val.append(asString);
+ setValue(val);
}
-QList<int> IntegersAspect::value() const
+void FilePathListAspect::removeValue(const FilePath &s)
{
- return transform(BaseAspect::value().toList(),
- [](QVariant v) { return v.toInt(); });
+ QStringList val = value();
+ val.removeAll(s.toUserOutput());
+ setValue(val);
}
-void IntegersAspect::setValue(const QList<int> &value)
+void FilePathListAspect::appendValues(const FilePaths &paths, bool allowDuplicates)
{
- BaseAspect::setValue(transform(value, [](int i) { return QVariant::fromValue<int>(i); }));
+ QStringList val = value();
+
+ for (const FilePath &path : paths) {
+ const QString asString = path.toUserOutput();
+ if (allowDuplicates || !val.contains(asString))
+ val.append(asString);
+ }
+ setValue(val);
}
-QList<int> IntegersAspect::defaultValue() const
+void FilePathListAspect::removeValues(const FilePaths &paths)
{
- return transform(BaseAspect::defaultValue().toList(),
- [](QVariant v) { return v.toInt(); });
+ QStringList val = value();
+ for (const FilePath &path : paths)
+ val.removeAll(path.toUserOutput());
+ setValue(val);
}
-void IntegersAspect::setDefaultValue(const QList<int> &value)
+/*!
+ \class Utils::IntegerListAspect
+ \internal
+ \inmodule QtCreator
+
+ \brief A string list aspect represents a property of some object
+ that is a list of strings.
+*/
+
+IntegersAspect::IntegersAspect(AspectContainer *container)
+ : TypedAspect(container)
+{}
+
+/*!
+ \internal
+*/
+IntegersAspect::~IntegersAspect() = default;
+
+/*!
+ \reimp
+*/
+void IntegersAspect::addToLayout(Layouting::LayoutItem &parent)
{
- BaseAspect::setDefaultValue(transform(value, [](int i) { return QVariant::fromValue<int>(i); }));
+ Q_UNUSED(parent)
+ // TODO - when needed.
}
@@ -2399,6 +2639,10 @@ void TextDisplay::addToLayout(LayoutItem &parent)
// have a QWidget parent yet when used in a LayoutBuilder.
if (!isVisible())
d->m_label->setVisible(false);
+
+ connect(this, &TextDisplay::changed, d->m_label, [this] {
+ d->m_label->setText(d->m_message);
+ });
}
parent.addItem(d->m_label.data());
}
@@ -2417,6 +2661,7 @@ void TextDisplay::setIconType(InfoLabel::InfoType t)
void TextDisplay::setText(const QString &message)
{
d->m_message = message;
+ emit changed();
}
/*!
@@ -2429,21 +2674,17 @@ void TextDisplay::setText(const QString &message)
Sub-aspects ownership can be declared using \a setOwnsSubAspects.
*/
-namespace Internal {
-
-class AspectContainerPrivate
+class Internal::AspectContainerPrivate
{
public:
QList<BaseAspect *> m_items; // Both owned and non-owned.
QList<BaseAspect *> m_ownedItems; // Owned only.
- bool m_autoApply = true;
QStringList m_settingsGroup;
+ std::function<Layouting::LayoutItem ()> m_layouter;
};
-} // Internal
-
-AspectContainer::AspectContainer(QObject *parent)
- : QObject(parent), d(new Internal::AspectContainerPrivate)
+AspectContainer::AspectContainer()
+ : d(new Internal::AspectContainerPrivate)
{}
/*!
@@ -2459,7 +2700,7 @@ AspectContainer::~AspectContainer()
*/
void AspectContainer::registerAspect(BaseAspect *aspect, bool takeOwnership)
{
- aspect->setAutoApply(d->m_autoApply);
+ aspect->setAutoApply(isAutoApply());
d->m_items.append(aspect);
if (takeOwnership)
d->m_ownedItems.append(aspect);
@@ -2491,12 +2732,22 @@ AspectContainer::const_iterator AspectContainer::end() const
return d->m_items.cend();
}
+void AspectContainer::setLayouter(const std::function<Layouting::LayoutItem ()> &layouter)
+{
+ d->m_layouter = layouter;
+}
+
+std::function<LayoutItem ()> AspectContainer::layouter() const
+{
+ return d->m_layouter;
+}
+
const QList<BaseAspect *> &AspectContainer::aspects() const
{
return d->m_items;
}
-void AspectContainer::fromMap(const QVariantMap &map)
+void AspectContainer::fromMap(const Store &map)
{
for (BaseAspect *aspect : std::as_const(d->m_items))
aspect->fromMap(map);
@@ -2505,34 +2756,30 @@ void AspectContainer::fromMap(const QVariantMap &map)
}
-void AspectContainer::toMap(QVariantMap &map) const
+void AspectContainer::toMap(Store &map) const
{
for (BaseAspect *aspect : std::as_const(d->m_items))
aspect->toMap(map);
}
-void AspectContainer::readSettings(QSettings *settings)
+void AspectContainer::volatileToMap(Store &map) const
{
- for (const QString &group : d->m_settingsGroup)
- settings->beginGroup(group);
-
for (BaseAspect *aspect : std::as_const(d->m_items))
- aspect->readSettings(settings);
-
- for (int i = 0; i != d->m_settingsGroup.size(); ++i)
- settings->endGroup();
+ aspect->volatileToMap(map);
}
-void AspectContainer::writeSettings(QSettings *settings) const
+void AspectContainer::readSettings()
{
- for (const QString &group : d->m_settingsGroup)
- settings->beginGroup(group);
-
+ const SettingsGroupNester nester(d->m_settingsGroup);
for (BaseAspect *aspect : std::as_const(d->m_items))
- aspect->writeSettings(settings);
+ aspect->readSettings();
+}
- for (int i = 0; i != d->m_settingsGroup.size(); ++i)
- settings->endGroup();
+void AspectContainer::writeSettings() const
+{
+ const SettingsGroupNester nester(d->m_settingsGroup);
+ for (BaseAspect *aspect : std::as_const(d->m_items))
+ aspect->writeSettings();
}
void AspectContainer::setSettingsGroup(const QString &groupKey)
@@ -2545,6 +2792,11 @@ void AspectContainer::setSettingsGroups(const QString &groupKey, const QString &
d->m_settingsGroup = QStringList{groupKey, subGroupKey};
}
+QStringList AspectContainer::settingsGroups() const
+{
+ return d->m_settingsGroup;
+}
+
void AspectContainer::apply()
{
const bool willChange = isDirty();
@@ -2573,17 +2825,18 @@ void AspectContainer::finish()
void AspectContainer::reset()
{
for (BaseAspect *aspect : std::as_const(d->m_items))
- aspect->setValueQuietly(aspect->defaultValue());
+ aspect->setVariantValue(aspect->defaultVariantValue());
}
void AspectContainer::setAutoApply(bool on)
{
- d->m_autoApply = on;
+ BaseAspect::setAutoApply(on);
+
for (BaseAspect *aspect : std::as_const(d->m_items))
aspect->setAutoApply(on);
}
-bool AspectContainer::isDirty() const
+bool AspectContainer::isDirty()
{
for (BaseAspect *aspect : std::as_const(d->m_items)) {
if (aspect->isDirty())
@@ -2592,10 +2845,18 @@ bool AspectContainer::isDirty() const
return false;
}
+void AspectContainer::setUndoStack(QUndoStack *undoStack)
+{
+ BaseAspect::setUndoStack(undoStack);
+
+ for (BaseAspect *aspect : std::as_const(d->m_items))
+ aspect->setUndoStack(undoStack);
+}
+
bool AspectContainer::equals(const AspectContainer &other) const
{
// FIXME: Expensive, but should not really be needed in a fully aspectified world.
- QVariantMap thisMap, thatMap;
+ Store thisMap, thatMap;
toMap(thisMap);
other.toMap(thatMap);
return thisMap == thatMap;
@@ -2603,7 +2864,7 @@ bool AspectContainer::equals(const AspectContainer &other) const
void AspectContainer::copyFrom(const AspectContainer &other)
{
- QVariantMap map;
+ Store map;
other.toMap(map);
fromMap(map);
}
@@ -2630,6 +2891,55 @@ BaseAspect::Data::Ptr BaseAspect::extractData() const
return Data::Ptr(data);
}
+/*
+ Mirrors the internal volatile value to the GUI element if they are already
+ created.
+
+ No-op otherwise.
+*/
+void BaseAspect::bufferToGui()
+{
+}
+
+/*
+ Mirrors the data stored in GUI element if they are already created to
+ the internal volatile value.
+
+ No-op otherwise.
+
+ \return true when the buffered volatile value changed.
+*/
+bool BaseAspect::guiToBuffer()
+{
+ return false;
+}
+
+/*
+ Mirrors buffered volatile value to the internal value.
+ This function is used for \c apply().
+
+ \return true when the internal value changed.
+*/
+
+bool BaseAspect::bufferToInternal()
+{
+ return false;
+}
+
+
+bool BaseAspect::internalToBuffer()
+{
+ return false;
+}
+
+void BaseAspect::handleGuiChanged()
+{
+ if (guiToBuffer())
+ volatileValueChanged();
+ if (isAutoApply())
+ apply();
+}
+
void BaseAspect::addDataExtractorHelper(const DataExtractor &extractor) const
{
d->m_dataExtractors.append(extractor);
@@ -2680,4 +2990,430 @@ void BaseAspect::Data::Ptr::operator=(const Ptr &other)
m_data = other.m_data->clone();
}
+// SettingsGroupNester
+
+SettingsGroupNester::SettingsGroupNester(const QStringList &groups)
+ : m_groupCount(groups.size())
+{
+ QTC_ASSERT(theSettings, return);
+ for (const QString &group : groups)
+ theSettings->beginGroup(keyFromString(group));
+}
+
+SettingsGroupNester::~SettingsGroupNester()
+{
+ QTC_ASSERT(theSettings, return);
+ for (int i = 0; i != m_groupCount; ++i)
+ theSettings->endGroup();
+}
+
+class AddItemCommand : public QUndoCommand
+{
+public:
+ AddItemCommand(AspectList *aspect, const std::shared_ptr<BaseAspect> &item)
+ : m_aspect(aspect)
+ , m_item(item)
+ {}
+
+ void undo() override { m_aspect->actualRemoveItem(m_item); }
+ void redo() override { m_aspect->actualAddItem(m_item); }
+
+private:
+ AspectList *m_aspect;
+ std::shared_ptr<BaseAspect> m_item;
+};
+
+class RemoveItemCommand : public QUndoCommand
+{
+public:
+ RemoveItemCommand(AspectList *aspect, const std::shared_ptr<BaseAspect> &item)
+ : m_aspect(aspect)
+ , m_item(item)
+ {}
+
+ void undo() override { m_aspect->actualAddItem(m_item); }
+ void redo() override { m_aspect->actualRemoveItem(m_item); }
+
+private:
+ AspectList *m_aspect;
+ std::shared_ptr<BaseAspect> m_item;
+};
+
+class Internal::AspectListPrivate
+{
+public:
+ QList<std::shared_ptr<BaseAspect>> items;
+ QList<std::shared_ptr<BaseAspect>> volatileItems;
+ AspectList::CreateItem createItem;
+ AspectList::ItemCallback itemAdded;
+ AspectList::ItemCallback itemRemoved;
+};
+
+AspectList::AspectList(Utils::AspectContainer *container)
+ : Utils::BaseAspect(container)
+ , d(std::make_unique<Internal::AspectListPrivate>())
+{}
+
+AspectList::~AspectList() = default;
+
+void AspectList::fromMap(const Utils::Store &map)
+{
+ QTC_ASSERT(!settingsKey().isEmpty(), return);
+
+ QVariantList list = map[settingsKey()].toList();
+ d->volatileItems.clear();
+ for (const QVariant &entry : list) {
+ auto item = d->createItem();
+ item->setAutoApply(isAutoApply());
+ item->setUndoStack(undoStack());
+ item->fromMap(Utils::storeFromVariant(entry));
+ d->volatileItems.append(item);
+ }
+ d->items = d->volatileItems;
+}
+
+QVariantList AspectList::toList(bool v) const
+{
+ QVariantList list;
+ const auto &items = v ? d->volatileItems : d->items;
+
+ for (const std::shared_ptr<BaseAspect> &item : items) {
+ Utils::Store childStore;
+ if (v)
+ item->volatileToMap(childStore);
+ else
+ item->toMap(childStore);
+
+ list.append(Utils::variantFromStore(childStore));
+ }
+
+ return list;
+}
+
+void AspectList::toMap(Utils::Store &map) const
+{
+ QTC_ASSERT(!settingsKey().isEmpty(), return);
+ const Utils::Key key = settingsKey();
+ map[key] = toList(false);
+}
+
+void AspectList::volatileToMap(Utils::Store &map) const
+{
+ QTC_ASSERT(!settingsKey().isEmpty(), return);
+ const Utils::Key key = settingsKey();
+ map[key] = toList(true);
+}
+
+std::shared_ptr<BaseAspect> AspectList::actualAddItem(const std::shared_ptr<BaseAspect> &item)
+{
+ item->setAutoApply(isAutoApply());
+ item->setUndoStack(undoStack());
+
+ d->volatileItems.append(item);
+ if (d->itemAdded)
+ d->itemAdded(item);
+ emit volatileValueChanged();
+ if (isAutoApply())
+ d->items = d->volatileItems;
+ return item;
+}
+
+QList<std::shared_ptr<BaseAspect>> AspectList::items() const
+{
+ return d->items;
+}
+QList<std::shared_ptr<BaseAspect>> AspectList::volatileItems() const
+{
+ return d->volatileItems;
+}
+
+std::shared_ptr<BaseAspect> AspectList::createAndAddItem()
+{
+ return addItem(d->createItem());
+}
+
+std::shared_ptr<BaseAspect> AspectList::addItem(const std::shared_ptr<BaseAspect> &item)
+{
+ if (undoStack())
+ undoStack()->push(new AddItemCommand(this, item));
+ else
+ return actualAddItem(item);
+
+ return item;
+}
+
+void AspectList::actualRemoveItem(const std::shared_ptr<BaseAspect> &item)
+{
+ d->volatileItems.removeOne(item);
+ if (d->itemRemoved)
+ d->itemRemoved(item);
+ emit volatileValueChanged();
+ if (isAutoApply())
+ d->items = d->volatileItems;
+}
+
+void AspectList::removeItem(const std::shared_ptr<BaseAspect> &item)
+{
+ if (undoStack())
+ undoStack()->push(new RemoveItemCommand(this, item));
+ else
+ actualRemoveItem(item);
+}
+
+void AspectList::clear()
+{
+ if (undoStack()) {
+ undoStack()->beginMacro("Clear");
+
+ for (const std::shared_ptr<BaseAspect> &item : volatileItems())
+ undoStack()->push(new RemoveItemCommand(this, item));
+
+ undoStack()->endMacro();
+ } else {
+ for (const std::shared_ptr<BaseAspect> &item : volatileItems())
+ actualRemoveItem(item);
+ }
+}
+
+void AspectList::apply()
+{
+ d->items = d->volatileItems;
+ forEachItem<BaseAspect>([](const std::shared_ptr<BaseAspect> &aspect) { aspect->apply(); });
+ emit changed();
+}
+
+void AspectList::setCreateItemFunction(CreateItem createItem)
+{
+ d->createItem = createItem;
+}
+
+void AspectList::setItemAddedCallback(const ItemCallback &callback)
+{
+ d->itemAdded = callback;
+}
+void AspectList::setItemRemovedCallback(const ItemCallback &callback)
+{
+ d->itemRemoved = callback;
+}
+
+qsizetype AspectList::size() const
+{
+ return d->volatileItems.size();
+}
+
+bool AspectList::isDirty()
+{
+ if (d->items != d->volatileItems)
+ return true;
+
+ for (const std::shared_ptr<BaseAspect> &item : d->volatileItems) {
+ if (item->isDirty())
+ return true;
+ }
+ return false;
+}
+
+class ColoredRow : public QWidget
+{
+public:
+ ColoredRow(int idx, QWidget *parent = nullptr)
+ : QWidget(parent)
+ , m_index(idx)
+ {}
+ void paintEvent(QPaintEvent *event)
+ {
+ QPainter p(this);
+ QPalette pal = palette();
+ if (m_index % 2 == 0)
+ p.fillRect(event->rect(), pal.base());
+ else
+ p.fillRect(event->rect(), pal.alternateBase());
+ }
+
+private:
+ int m_index;
+};
+
+void AspectList::addToLayout(Layouting::LayoutItem &parent)
+{
+ using namespace Layouting;
+
+ QScrollArea *scrollArea = new QScrollArea;
+ scrollArea->setWidgetResizable(true);
+ scrollArea->setMaximumHeight(100);
+ scrollArea->setMinimumHeight(100);
+ scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ auto fill = [this, scrollArea]() mutable {
+ if (scrollArea->widget())
+ delete scrollArea->takeWidget();
+
+ auto add = new QPushButton(Tr::tr("Add"));
+ QObject::connect(add, &QPushButton::clicked, scrollArea, [this] {
+ addItem(d->createItem());
+ });
+
+ Column column{noMargin()};
+
+ forEachItem<BaseAspect>([&column, this](const std::shared_ptr<BaseAspect> &item, int idx) {
+ auto removeBtn = new IconButton;
+ removeBtn->setIcon(Utils::Icons::EDIT_CLEAR.icon());
+ removeBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ QObject::connect(removeBtn, &QPushButton::clicked, removeBtn, [this, item] {
+ removeItem(item);
+ });
+ ColoredRow *rowWdgt = new ColoredRow(idx);
+ // clang-format off
+ auto row = Row {
+ *item,
+ removeBtn,
+ spacing(5),
+ };
+ // clang-format on
+ row.attachTo(rowWdgt);
+ column.addItem(rowWdgt);
+ });
+
+ ColoredRow *rowWdgt = new ColoredRow(size());
+ Row{st, add}.attachTo(rowWdgt);
+ column.addItem(rowWdgt);
+
+ QWidget *contentWidget = column.emerge();
+ contentWidget->layout()->setSpacing(1);
+
+ scrollArea->setWidget(contentWidget);
+ };
+
+ fill();
+ QObject::connect(this, &AspectList::volatileValueChanged, scrollArea, fill);
+
+ parent.addItem(scrollArea);
+}
+
+StringSelectionAspect::StringSelectionAspect(AspectContainer *container)
+ : TypedAspect<QString>(container)
+{}
+
+QStandardItem *StringSelectionAspect::itemById(const QString &id)
+{
+ for (int i = 0; i < m_model->rowCount(); ++i) {
+ auto cur = m_model->item(i);
+ if (cur->data() == id)
+ return cur;
+ }
+
+ return nullptr;
+}
+
+void StringSelectionAspect::bufferToGui()
+{
+ if (!m_model) {
+ m_undoable.setSilently(m_buffer);
+ return;
+ }
+
+ auto selected = itemById(m_buffer);
+ if (selected) {
+ m_undoable.setSilently(selected->data().toString());
+ m_selectionModel->setCurrentIndex(selected->index(),
+ QItemSelectionModel::SelectionFlag::ClearAndSelect);
+ return;
+ }
+
+ if (m_model->rowCount() > 0) {
+ m_undoable.setSilently(m_model->item(0)->data().toString());
+ m_selectionModel->setCurrentIndex(m_model->item(0)->index(),
+ QItemSelectionModel::SelectionFlag::ClearAndSelect);
+ } else {
+ m_undoable.setSilently(m_buffer);
+ m_selectionModel->setCurrentIndex(QModelIndex(), QItemSelectionModel::SelectionFlag::Clear);
+ }
+
+ handleGuiChanged();
+}
+
+bool StringSelectionAspect::guiToBuffer()
+{
+ if (!m_model)
+ return false;
+
+ auto oldBuffer = m_buffer;
+
+ m_buffer = m_undoable.get();
+
+ return oldBuffer != m_buffer;
+}
+
+void StringSelectionAspect::addToLayout(Layouting::LayoutItem &parent)
+{
+ QTC_ASSERT(m_fillCallback, return);
+
+ auto cb = [this](const QList<QStandardItem *> &items) {
+ m_model->clear();
+ for (QStandardItem *item : items)
+ m_model->appendRow(item);
+
+ bufferToGui();
+ };
+
+ if (!m_model) {
+ m_model = new QStandardItemModel(this);
+ m_selectionModel = new QItemSelectionModel(m_model);
+
+ connect(this, &StringSelectionAspect::refillRequested, this, [this, cb] {
+ m_fillCallback(cb);
+ });
+
+ m_fillCallback(cb);
+ }
+
+ QComboBox *comboBox = new QComboBox();
+ comboBox->setInsertPolicy(QComboBox::InsertPolicy::NoInsert);
+ comboBox->setEditable(true);
+ comboBox->completer()->setCompletionMode(QCompleter::PopupCompletion);
+ comboBox->completer()->setFilterMode(Qt::MatchContains);
+
+ comboBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
+ comboBox->setCurrentText(value());
+ comboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+
+ comboBox->setModel(m_model);
+
+ connect(m_selectionModel,
+ &QItemSelectionModel::currentChanged,
+ comboBox,
+ [comboBox](QModelIndex currentIdx) {
+ if (currentIdx.isValid() && comboBox->currentIndex() != currentIdx.row())
+ comboBox->setCurrentIndex(currentIdx.row());
+ });
+
+ connect(comboBox, &QComboBox::activated, this, [this](int idx) {
+ QModelIndex modelIdx = m_model->index(idx, 0);
+ if (!modelIdx.isValid())
+ return;
+
+ QString newValue = m_model->index(idx, 0).data(Qt::UserRole + 1).toString();
+ if (newValue.isEmpty())
+ return;
+
+ m_undoable.set(undoStack(), newValue);
+ bufferToGui();
+ });
+
+ connect(&m_undoable.m_signal, &UndoSignaller::changed, comboBox, [this, comboBox]() {
+ auto item = itemById(m_undoable.get());
+ if (item)
+ m_selectionModel->setCurrentIndex(item->index(), QItemSelectionModel::ClearAndSelect);
+ else
+ comboBox->setCurrentText(m_undoable.get());
+
+ handleGuiChanged();
+ });
+
+ if (m_selectionModel->currentIndex().isValid())
+ comboBox->setCurrentIndex(m_selectionModel->currentIndex().row());
+
+ return addLabeledItem(parent, comboBox);
+}
+
} // namespace Utils
diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h
index 146e89198d3..e46ce5ab9b8 100644
--- a/src/libs/utils/aspects.h
+++ b/src/libs/utils/aspects.h
@@ -8,17 +8,27 @@
#include "infolabel.h"
#include "macroexpander.h"
#include "pathchooser.h"
+#include "qtcsettings.h"
+#include "store.h"
#include <functional>
#include <memory>
#include <optional>
+#include <QUndoCommand>
+
QT_BEGIN_NAMESPACE
class QAction;
class QSettings;
+class QUndoStack;
+class QStandardItem;
+class QStandardItemModel;
+class QItemSelectionModel;
QT_END_NAMESPACE
-namespace Layouting { class LayoutItem; }
+namespace Layouting {
+class LayoutItem;
+}
namespace Utils {
@@ -32,12 +42,16 @@ class BaseAspectPrivate;
class BoolAspectPrivate;
class ColorAspectPrivate;
class DoubleAspectPrivate;
+class FilePathAspectPrivate;
+class FilePathListAspectPrivate;
class IntegerAspectPrivate;
class MultiSelectionAspectPrivate;
class SelectionAspectPrivate;
class StringAspectPrivate;
class StringListAspectPrivate;
class TextDisplayPrivate;
+class CheckableAspectImplementation;
+class AspectListPrivate;
} // Internal
class QTCREATOR_UTILS_EXPORT BaseAspect : public QObject
@@ -51,16 +65,19 @@ public:
Id id() const;
void setId(Id id);
- QVariant value() const;
- void setValue(const QVariant &value);
- bool setValueQuietly(const QVariant &value);
+ enum Announcement { DoEmit, BeQuiet };
+
+ virtual QVariant volatileVariantValue() const;
+ virtual QVariant variantValue() const;
+ virtual void setVariantValue(const QVariant &value, Announcement = DoEmit);
- QVariant defaultValue() const;
- void setDefaultValue(const QVariant &value);
+ virtual QVariant defaultVariantValue() const;
+ virtual void setDefaultVariantValue(const QVariant &value);
+ virtual bool isDefaultValue() const;
- QString settingsKey() const;
- void setSettingsKey(const QString &settingsKey);
- void setSettingsKey(const QString &group, const QString &key);
+ Key settingsKey() const;
+ void setSettingsKey(const Key &settingsKey);
+ void setSettingsKey(const Key &group, const Key &key);
QString displayName() const;
void setDisplayName(const QString &displayName);
@@ -72,7 +89,10 @@ public:
void setVisible(bool visible);
bool isAutoApply() const;
- void setAutoApply(bool on);
+ virtual void setAutoApply(bool on);
+
+ virtual void setUndoStack(QUndoStack *undoStack);
+ QUndoStack *undoStack() const;
bool isEnabled() const;
void setEnabled(bool enabled);
@@ -94,18 +114,17 @@ public:
virtual QAction *action();
- virtual void fromMap(const QVariantMap &map);
- virtual void toMap(QVariantMap &map) const;
- virtual void toActiveMap(QVariantMap &map) const { toMap(map); }
+ AspectContainer *container() const;
- virtual void addToLayout(Layouting::LayoutItem &parent);
+ virtual void fromMap(const Store &map);
+ virtual void toMap(Store &map) const;
+ virtual void toActiveMap(Store &map) const { toMap(map); }
+ virtual void volatileToMap(Store &map) const;
- virtual QVariant volatileValue() const;
- virtual void setVolatileValue(const QVariant &val);
- virtual void emitChangedValue() {}
+ virtual void addToLayout(Layouting::LayoutItem &parent);
- virtual void readSettings(const QSettings *settings);
- virtual void writeSettings(QSettings *settings) const;
+ virtual void readSettings();
+ virtual void writeSettings() const;
using SavedValueTransformation = std::function<QVariant(const QVariant &)>;
void setFromSettingsTransformation(const SavedValueTransformation &transform);
@@ -116,9 +135,22 @@ public:
virtual void apply();
virtual void cancel();
virtual void finish();
- virtual bool isDirty() const;
+ virtual bool isDirty();
bool hasAction() const;
+ struct QTCREATOR_UTILS_EXPORT Changes
+ {
+ Changes();
+
+ unsigned internalFromOutside : 1;
+ unsigned internalFromBuffer : 1;
+ unsigned bufferFromOutside : 1;
+ unsigned bufferFromInternal : 1;
+ unsigned bufferFromGui : 1;
+ };
+
+ void announceChanges(Changes changes, Announcement howToAnnounce = DoEmit);
+
class QTCREATOR_UTILS_EXPORT Data
{
public:
@@ -162,13 +194,30 @@ public:
Data::Ptr extractData() const;
+ static void setQtcSettings(QtcSettings *settings);
+ static QtcSettings *qtcSettings();
+
+ // This is expensive. Do not use without good reason
+ void writeToSettingsImmediatly() const;
+
signals:
- void changed();
+ void changed(); // "internal"
+ void volatileValueChanged();
void labelLinkActivated(const QString &link);
+ void checkedChanged();
+ void enabledChanged();
+ void labelTextChanged();
+ void labelPixmapChanged();
protected:
- QLabel *label() const;
- void setupLabel();
+ virtual bool internalToBuffer();
+ virtual bool bufferToInternal();
+ virtual void bufferToGui();
+ virtual bool guiToBuffer();
+
+ virtual void handleGuiChanged();
+
+ QLabel *createLabel();
void addLabeledItem(Layouting::LayoutItem &parent, QWidget *widget);
void setDataCreatorHelper(const DataCreator &creator) const;
@@ -198,29 +247,183 @@ protected:
}
void registerSubWidget(QWidget *widget);
- static void saveToMap(QVariantMap &data, const QVariant &value,
- const QVariant &defaultValue, const QString &key);
+ static void saveToMap(Store &data, const QVariant &value,
+ const QVariant &defaultValue, const Key &key);
+
+ void forEachSubWidget(const std::function<void(QWidget *)> &func);
+
+protected:
+ template <class Value>
+ static bool updateStorage(Value &target, const Value &val)
+ {
+ if (target == val)
+ return false;
+ target = val;
+ return true;
+ }
private:
std::unique_ptr<Internal::BaseAspectPrivate> d;
+ friend class Internal::CheckableAspectImplementation;
};
QTCREATOR_UTILS_EXPORT void createItem(Layouting::LayoutItem *item, const BaseAspect &aspect);
QTCREATOR_UTILS_EXPORT void createItem(Layouting::LayoutItem *item, const BaseAspect *aspect);
-class QTCREATOR_UTILS_EXPORT BoolAspect : public BaseAspect
+template <typename ValueType>
+class TypedAspect : public BaseAspect
{
- Q_OBJECT
-
public:
- BoolAspect(AspectContainer *container = nullptr);
- ~BoolAspect() override;
+ TypedAspect(AspectContainer *container = nullptr)
+ : BaseAspect(container)
+ {
+ addDataExtractor(this, &TypedAspect::value, &Data::value);
+ }
struct Data : BaseAspect::Data
{
- bool value;
+ ValueType value;
};
+ ValueType operator()() const { return m_internal; }
+ ValueType value() const { return m_internal; }
+ ValueType defaultValue() const { return m_default; }
+ ValueType volatileValue() const { return m_buffer; }
+
+ // We assume that this is only used in the ctor and no signalling is needed.
+ // If it is used elsewhere changes have to be detected and signalled externally.
+ void setDefaultValue(const ValueType &value)
+ {
+ m_default = value;
+ m_internal = value;
+ if (internalToBuffer()) // Might be more than a plain copy.
+ bufferToGui();
+ }
+
+ bool isDefaultValue() const override
+ {
+ return m_default == m_internal;
+ }
+
+ void setValue(const ValueType &value, Announcement howToAnnounce = DoEmit)
+ {
+ Changes changes;
+ changes.internalFromOutside = updateStorage(m_internal, value);
+ if (internalToBuffer()) {
+ changes.bufferFromInternal = true;
+ bufferToGui();
+ }
+ announceChanges(changes, howToAnnounce);
+ }
+
+ void setVolatileValue(const ValueType &value, Announcement howToAnnounce = DoEmit)
+ {
+ Changes changes;
+ if (updateStorage(m_buffer, value)) {
+ changes.bufferFromOutside = true;
+ bufferToGui();
+ }
+ if (isAutoApply() && bufferToInternal())
+ changes.internalFromBuffer = true;
+ announceChanges(changes, howToAnnounce);
+ }
+
+protected:
+ bool isDirty() override
+ {
+ return m_internal != m_buffer;
+ }
+
+ bool internalToBuffer() override
+ {
+ return updateStorage(m_buffer, m_internal);
+ }
+
+ bool bufferToInternal() override
+ {
+ return updateStorage(m_internal, m_buffer);
+ }
+
+ QVariant variantValue() const override
+ {
+ return QVariant::fromValue<ValueType>(m_internal);
+ }
+
+ QVariant volatileVariantValue() const override
+ {
+ return QVariant::fromValue<ValueType>(m_buffer);
+ }
+
+ void setVariantValue(const QVariant &value, Announcement howToAnnounce = DoEmit) override
+ {
+ setValue(value.value<ValueType>(), howToAnnounce);
+ }
+
+ QVariant defaultVariantValue() const override
+ {
+ return QVariant::fromValue<ValueType>(m_default);
+ }
+
+ void setDefaultVariantValue(const QVariant &value) override
+ {
+ setDefaultValue(value.value<ValueType>());
+ }
+
+ ValueType m_default{};
+ ValueType m_internal{};
+ ValueType m_buffer{};
+};
+
+template <typename ValueType>
+class FlexibleTypedAspect : public TypedAspect<ValueType>
+{
+public:
+ using Base = TypedAspect<ValueType>;
+ using Updater = std::function<bool(ValueType &, const ValueType &)>;
+
+ using Base::Base;
+
+ void setInternalToBuffer(const Updater &updater) { m_internalToBuffer = updater; }
+ void setBufferToInternal(const Updater &updater) { m_bufferToInternal = updater; }
+ void setInternalToExternal(const Updater &updater) { m_internalToExternal = updater; }
+
+protected:
+ bool internalToBuffer() override
+ {
+ if (m_internalToBuffer)
+ return m_internalToBuffer(Base::m_buffer, Base::m_internal);
+ return Base::internalToBuffer();
+ }
+
+ bool bufferToInternal() override
+ {
+ if (m_bufferToInternal)
+ return m_bufferToInternal(Base::m_internal, Base::m_buffer);
+ return Base::bufferToInternal();
+ }
+
+ ValueType expandedValue()
+ {
+ if (!m_internalToExternal)
+ return Base::m_internal;
+ ValueType val;
+ m_internalToExternal(val, Base::m_internal);
+ return val;
+ }
+
+ Updater m_internalToBuffer;
+ Updater m_bufferToInternal;
+ Updater m_internalToExternal;
+};
+
+class QTCREATOR_UTILS_EXPORT BoolAspect : public TypedAspect<bool>
+{
+ Q_OBJECT
+
+public:
+ BoolAspect(AspectContainer *container = nullptr);
+ ~BoolAspect() override;
+
void addToLayout(Layouting::LayoutItem &parent) override;
std::function<void(QObject *)> groupChecker();
@@ -229,32 +432,23 @@ public:
QAction *action() override;
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
- void emitChangedValue() override;
-
- bool operator()() const { return value(); }
- bool value() const;
- void setValue(bool val);
- bool defaultValue() const;
- void setDefaultValue(bool val);
-
- enum class LabelPlacement { AtCheckBox, AtCheckBoxWithoutDummyLabel, InExtraLabel };
+ enum class LabelPlacement { AtCheckBox, Compact, InExtraLabel };
void setLabel(const QString &labelText,
LabelPlacement labelPlacement = LabelPlacement::InExtraLabel);
void setLabelPlacement(LabelPlacement labelPlacement);
- void adoptButton(QAbstractButton *button);
-
-signals:
- void valueChanged(bool newValue);
- void volatileValueChanged(bool newValue);
+ Layouting::LayoutItem adoptButton(QAbstractButton *button);
private:
+ void addToLayoutHelper(Layouting::LayoutItem &parent, QAbstractButton *button);
+
+ void bufferToGui() override;
+ bool guiToBuffer() override;
+
std::unique_ptr<Internal::BoolAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT ColorAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT ColorAspect : public TypedAspect<QColor>
{
Q_OBJECT
@@ -262,24 +456,16 @@ public:
ColorAspect(AspectContainer *container = nullptr);
~ColorAspect() override;
- struct Data : BaseAspect::Data
- {
- QColor value;
- };
-
void addToLayout(Layouting::LayoutItem &parent) override;
- QColor value() const;
- void setValue(const QColor &val);
-
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
-
private:
+ void bufferToGui() override;
+ bool guiToBuffer() override;
+
std::unique_ptr<Internal::ColorAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT SelectionAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT SelectionAspect : public TypedAspect<int>
{
Q_OBJECT
@@ -288,20 +474,13 @@ public:
~SelectionAspect() override;
void addToLayout(Layouting::LayoutItem &parent) override;
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
void finish() override;
- int operator()() const { return value(); }
- int value() const;
- void setValue(int val);
-
QString stringValue() const;
void setStringValue(const QString &val);
- int defaultValue() const;
- void setDefaultValue(int val);
void setDefaultValue(const QString &val);
+ void setDefaultValue(int val);
QVariant itemValue() const;
@@ -327,14 +506,15 @@ public:
int indexForItemValue(const QVariant &value) const;
QVariant itemValueForIndex(int index) const;
-signals:
- void volatileValueChanged(int newValue);
+protected:
+ void bufferToGui() override;
+ bool guiToBuffer() override;
private:
std::unique_ptr<Internal::SelectionAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT MultiSelectionAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT MultiSelectionAspect : public TypedAspect<QStringList>
{
Q_OBJECT
@@ -347,17 +527,21 @@ public:
enum class DisplayStyle { ListView };
void setDisplayStyle(DisplayStyle style);
- QStringList value() const;
- void setValue(const QStringList &val);
-
QStringList allValues() const;
void setAllValues(const QStringList &val);
+protected:
+ void bufferToGui() override;
+ bool guiToBuffer() override;
+
private:
std::unique_ptr<Internal::MultiSelectionAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT StringAspect : public BaseAspect
+enum class UncheckedSemantics { Disabled, ReadOnly };
+enum class CheckBoxPlacement { Top, Right };
+
+class QTCREATOR_UTILS_EXPORT StringAspect : public TypedAspect<QString>
{
Q_OBJECT
@@ -365,98 +549,132 @@ public:
StringAspect(AspectContainer *container = nullptr);
~StringAspect() override;
- struct Data : BaseAspect::Data
- {
- QString value;
- FilePath filePath;
- };
-
void addToLayout(Layouting::LayoutItem &parent) override;
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
- void emitChangedValue() override;
+ QString operator()() const { return expandedValue(); }
+ QString expandedValue() const;
// Hook between UI and StringAspect:
using ValueAcceptor = std::function<std::optional<QString>(const QString &, const QString &)>;
void setValueAcceptor(ValueAcceptor &&acceptor);
- QString operator()() const { return value(); }
- QString value() const;
- void setValue(const QString &val);
-
- QString defaultValue() const;
- void setDefaultValue(const QString &val);
-
void setShowToolTipOnLabel(bool show);
-
void setDisplayFilter(const std::function<QString (const QString &)> &displayFilter);
void setPlaceHolderText(const QString &placeHolderText);
- void setPromptDialogFilter(const QString &filter);
- void setPromptDialogTitle(const QString &title);
- void setCommandVersionArguments(const QStringList &arguments);
- void setHistoryCompleter(const QString &historyCompleterKey);
- void setExpectedKind(const PathChooser::Kind expectedKind);
- void setEnvironment(const Environment &env);
- void setBaseFileName(const FilePath &baseFileName);
- void setUndoRedoEnabled(bool readOnly);
+ void setHistoryCompleter(const Key &historyCompleterKey);
void setAcceptRichText(bool acceptRichText);
void setMacroExpanderProvider(const MacroExpanderProvider &expanderProvider);
void setUseGlobalMacroExpander();
void setUseResetButton();
void setValidationFunction(const FancyLineEdit::ValidationFunction &validator);
- void setOpenTerminalHandler(const std::function<void()> &openTerminal);
void setAutoApplyOnEditingFinished(bool applyOnEditingFinished);
void setElideMode(Qt::TextElideMode elideMode);
- void setAllowPathFromDevice(bool allowPathFromDevice);
- void setValidatePlaceHolder(bool validatePlaceHolder);
- void validateInput();
-
- enum class UncheckedSemantics { Disabled, ReadOnly };
- enum class CheckBoxPlacement { Top, Right };
- void setUncheckedSemantics(UncheckedSemantics semantics);
+ void makeCheckable(CheckBoxPlacement checkBoxPlacement, const QString &optionalLabel, const Key &optionalBaseKey);
bool isChecked() const;
void setChecked(bool checked);
- void makeCheckable(CheckBoxPlacement checkBoxPlacement, const QString &optionalLabel,
- const QString &optionalBaseKey);
enum DisplayStyle {
LabelDisplay,
LineEditDisplay,
TextEditDisplay,
- PathChooserDisplay
+ PasswordLineEditDisplay,
};
void setDisplayStyle(DisplayStyle style);
- void fromMap(const QVariantMap &map) override;
- void toMap(QVariantMap &map) const override;
-
- FilePath filePath() const;
- void setFilePath(const FilePath &value);
- void setDefaultFilePath(const FilePath &value);
-
- PathChooser *pathChooser() const; // Avoid to use.
+ void fromMap(const Utils::Store &map) override;
+ void toMap(Utils::Store &map) const override;
+ void volatileToMap(Utils::Store &map) const override;
signals:
- void checkedChanged();
- void valueChanged(const QString &newValue);
+ void validChanged(bool validState);
+ void elideModeChanged(Qt::TextElideMode elideMode);
+ void historyCompleterKeyChanged(const Key &historyCompleterKey);
+ void acceptRichTextChanged(bool acceptRichText);
+ void validationFunctionChanged(const FancyLineEdit::ValidationFunction &validator);
+ void placeholderTextChanged(const QString &placeholderText);
protected:
- void update();
+ void bufferToGui() override;
+ bool guiToBuffer() override;
+
+ bool internalToBuffer() override;
+ bool bufferToInternal() override;
std::unique_ptr<Internal::StringAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT FilePathAspect : public StringAspect
+class QTCREATOR_UTILS_EXPORT FilePathAspect : public TypedAspect<QString>
{
+ Q_OBJECT
+
public:
FilePathAspect(AspectContainer *container = nullptr);
+ ~FilePathAspect();
+
+ struct Data : BaseAspect::Data
+ {
+ QString value;
+ FilePath filePath;
+ };
+
+ FilePath operator()() const;
+ FilePath expandedValue() const;
+ QString value() const;
+ void setValue(const FilePath &filePath, Announcement howToAnnounce = DoEmit);
+ void setValue(const QString &filePath, Announcement howToAnnounce = DoEmit);
+ void setDefaultValue(const QString &filePath);
+
+ void setPromptDialogFilter(const QString &filter);
+ void setPromptDialogTitle(const QString &title);
+ void setCommandVersionArguments(const QStringList &arguments);
+ void setAllowPathFromDevice(bool allowPathFromDevice);
+ void setValidatePlaceHolder(bool validatePlaceHolder);
+ void setOpenTerminalHandler(const std::function<void()> &openTerminal);
+ void setExpectedKind(const PathChooser::Kind expectedKind);
+ void setEnvironment(const Environment &env);
+ void setBaseFileName(const FilePath &baseFileName);
+
+ void setPlaceHolderText(const QString &placeHolderText);
+ void setValidationFunction(const FancyLineEdit::ValidationFunction &validator);
+ void setDisplayFilter(const std::function<QString (const QString &)> &displayFilter);
+ void setHistoryCompleter(const Key &historyCompleterKey);
+ void setMacroExpanderProvider(const MacroExpanderProvider &expanderProvider);
+ void setShowToolTipOnLabel(bool show);
+ void setAutoApplyOnEditingFinished(bool applyOnEditingFinished);
+
+ void validateInput();
+
+ void makeCheckable(CheckBoxPlacement checkBoxPlacement, const QString &optionalLabel, const Key &optionalBaseKey);
+ bool isChecked() const;
+ void setChecked(bool checked);
+
+ // Hook between UI and StringAspect:
+ using ValueAcceptor = std::function<std::optional<QString>(const QString &, const QString &)>;
+ void setValueAcceptor(ValueAcceptor &&acceptor);
+
+ PathChooser *pathChooser() const; // Avoid to use.
+
+ void addToLayout(Layouting::LayoutItem &parent) override;
+
+ void fromMap(const Utils::Store &map) override;
+ void toMap(Utils::Store &map) const override;
+ void volatileToMap(Utils::Store &map) const override;
- FilePath operator()() const { return filePath(); }
+signals:
+ void validChanged(bool validState);
+
+protected:
+ void bufferToGui() override;
+ bool guiToBuffer() override;
+
+ bool internalToBuffer() override;
+ bool bufferToInternal() override;
+
+ std::unique_ptr<Internal::FilePathAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT IntegerAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT IntegerAspect : public TypedAspect<qint64>
{
Q_OBJECT
@@ -466,16 +684,6 @@ public:
void addToLayout(Layouting::LayoutItem &parent) override;
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
-
- qint64 operator()() const { return value(); }
- qint64 value() const;
- void setValue(qint64 val);
-
- qint64 defaultValue() const;
- void setDefaultValue(qint64 defaultValue);
-
void setRange(qint64 min, qint64 max);
void setLabel(const QString &label); // FIXME: Use setLabelText
void setPrefix(const QString &prefix);
@@ -487,14 +695,15 @@ public:
struct Data : BaseAspect::Data { qint64 value = 0; };
-signals:
- void valueChanged(int newValue);
+protected:
+ void bufferToGui() override;
+ bool guiToBuffer() override;
private:
std::unique_ptr<Internal::IntegerAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT DoubleAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT DoubleAspect : public TypedAspect<double>
{
Q_OBJECT
@@ -504,22 +713,16 @@ public:
void addToLayout(Layouting::LayoutItem &parent) override;
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
-
- double operator()() const { return value(); }
- double value() const;
- void setValue(double val);
-
- double defaultValue() const;
- void setDefaultValue(double defaultValue);
-
void setRange(double min, double max);
void setPrefix(const QString &prefix);
void setSuffix(const QString &suffix);
void setSpecialValueText(const QString &specialText);
void setSingleStep(double step);
+protected:
+ void bufferToGui() override;
+ bool guiToBuffer() override;
+
private:
std::unique_ptr<Internal::DoubleAspectPrivate> d;
};
@@ -534,6 +737,7 @@ public:
int toInt() const { return int(m_value); }
QVariant toVariant() const { return int(m_value); }
+ static TriState fromInt(int value);
static TriState fromVariant(const QVariant &variant);
static const TriState Enabled;
@@ -557,6 +761,7 @@ public:
const QString &offString = {},
const QString &defaultString = {});
+ TriState operator()() const { return value(); }
TriState value() const;
void setValue(TriState setting);
@@ -564,7 +769,7 @@ public:
void setDefaultValue(TriState setting);
};
-class QTCREATOR_UTILS_EXPORT StringListAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT StringListAspect : public TypedAspect<QStringList>
{
Q_OBJECT
@@ -574,9 +779,6 @@ public:
void addToLayout(Layouting::LayoutItem &parent) override;
- QStringList value() const;
- void setValue(const QStringList &val);
-
void appendValue(const QString &value, bool allowDuplicates = true);
void removeValue(const QString &value);
void appendValues(const QStringList &values, bool allowDuplicates = true);
@@ -586,26 +788,40 @@ private:
std::unique_ptr<Internal::StringListAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT IntegersAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT FilePathListAspect : public TypedAspect<QStringList>
{
Q_OBJECT
public:
- IntegersAspect(AspectContainer *container = nullptr);
- ~IntegersAspect() override;
+ FilePathListAspect(AspectContainer *container = nullptr);
+ ~FilePathListAspect() override;
+
+ FilePaths operator()() const;
+
+ bool guiToBuffer() override;
+ void bufferToGui() override;
void addToLayout(Layouting::LayoutItem &parent) override;
- void emitChangedValue() override;
+ void setPlaceHolderText(const QString &placeHolderText);
- QList<int> operator()() const { return value(); }
- QList<int> value() const;
- void setValue(const QList<int> &value);
+ void appendValue(const FilePath &path, bool allowDuplicates = true);
+ void removeValue(const FilePath &path);
+ void appendValues(const FilePaths &values, bool allowDuplicates = true);
+ void removeValues(const FilePaths &values);
- QList<int> defaultValue() const;
- void setDefaultValue(const QList<int> &value);
+private:
+ std::unique_ptr<Internal::FilePathListAspectPrivate> d;
+};
-signals:
- void valueChanged(const QList<int> &values);
+class QTCREATOR_UTILS_EXPORT IntegersAspect : public TypedAspect<QList<int>>
+{
+ Q_OBJECT
+
+public:
+ IntegersAspect(AspectContainer *container = nullptr);
+ ~IntegersAspect() override;
+
+ void addToLayout(Layouting::LayoutItem &parent) override;
};
class QTCREATOR_UTILS_EXPORT TextDisplay : public BaseAspect
@@ -646,12 +862,24 @@ private:
QList<BaseAspect::Data::Ptr> m_data; // Owned.
};
-class QTCREATOR_UTILS_EXPORT AspectContainer : public QObject
+class QTCREATOR_UTILS_EXPORT SettingsGroupNester
+{
+ Q_DISABLE_COPY_MOVE(SettingsGroupNester)
+
+public:
+ explicit SettingsGroupNester(const QStringList &groups);
+ ~SettingsGroupNester();
+
+private:
+ const int m_groupCount;
+};
+
+class QTCREATOR_UTILS_EXPORT AspectContainer : public BaseAspect
{
Q_OBJECT
public:
- AspectContainer(QObject *parent = nullptr);
+ AspectContainer();
~AspectContainer();
AspectContainer(const AspectContainer &) = delete;
@@ -660,32 +888,27 @@ public:
void registerAspect(BaseAspect *aspect, bool takeOwnership = false);
void registerAspects(const AspectContainer &aspects);
- template <class Aspect, typename ...Args>
- Aspect *addAspect(Args && ...args)
- {
- auto aspect = new Aspect(args...);
- registerAspect(aspect, true);
- return aspect;
- }
+ void fromMap(const Utils::Store &map) override;
+ void toMap(Utils::Store &map) const override;
+ void volatileToMap(Utils::Store &map) const override;
- void fromMap(const QVariantMap &map);
- void toMap(QVariantMap &map) const;
-
- void readSettings(QSettings *settings);
- void writeSettings(QSettings *settings) const;
+ void readSettings() override;
+ void writeSettings() const override;
void setSettingsGroup(const QString &groupKey);
void setSettingsGroups(const QString &groupKey, const QString &subGroupKey);
+ QStringList settingsGroups() const;
- void apply();
- void cancel();
- void finish();
+ void apply() override;
+ void cancel() override;
+ void finish() override;
void reset();
bool equals(const AspectContainer &other) const;
void copyFrom(const AspectContainer &other);
- void setAutoApply(bool on);
- bool isDirty() const;
+ void setAutoApply(bool on) override;
+ bool isDirty() override;
+ void setUndoStack(QUndoStack *undoStack) override;
template <typename T> T *aspect() const
{
@@ -712,6 +935,9 @@ public:
const_iterator begin() const;
const_iterator end() const;
+ void setLayouter(const std::function<Layouting::LayoutItem()> &layouter);
+ std::function<Layouting::LayoutItem()> layouter() const;
+
signals:
void applied();
void changed();
@@ -721,4 +947,170 @@ private:
std::unique_ptr<Internal::AspectContainerPrivate> d;
};
+// Because QObject cannot be a template
+class QTCREATOR_UTILS_EXPORT UndoSignaller : public QObject
+{
+ Q_OBJECT
+public:
+ void emitChanged() { emit changed(); }
+signals:
+ void changed();
+};
+
+template<class T>
+class QTCREATOR_UTILS_EXPORT UndoableValue
+{
+public:
+ class UndoCmd : public QUndoCommand
+ {
+ public:
+ UndoCmd(UndoableValue<T> *value, const T &oldValue, const T &newValue)
+ : m_value(value)
+ , m_oldValue(oldValue)
+ , m_newValue(newValue)
+ {}
+
+ void undo() override { m_value->setInternal(m_oldValue); }
+ void redo() override { m_value->setInternal(m_newValue); }
+
+ private:
+ UndoableValue<T> *m_value;
+ T m_oldValue;
+ T m_newValue;
+ };
+
+ void set(QUndoStack *stack, const T &value)
+ {
+ if (m_value == value)
+ return;
+
+ if (stack)
+ stack->push(new UndoCmd(this, m_value, value));
+ else
+ setInternal(value);
+ }
+
+ void setSilently(const T &value) { m_value = value; }
+ void setWithoutUndo(const T &value) { setInternal(value); }
+
+ T get() const { return m_value; }
+
+ UndoSignaller m_signal;
+
+private:
+ void setInternal(const T &value)
+ {
+ m_value = value;
+ m_signal.emitChanged();
+ }
+
+private:
+ T m_value;
+};
+
+class QTCREATOR_UTILS_EXPORT AspectList : public Utils::BaseAspect
+{
+public:
+ using CreateItem = std::function<std::shared_ptr<BaseAspect>()>;
+ using ItemCallback = std::function<void(std::shared_ptr<BaseAspect>)>;
+
+ AspectList(Utils::AspectContainer *container = nullptr);
+ ~AspectList() override;
+
+ void fromMap(const Utils::Store &map) override;
+ void toMap(Utils::Store &map) const override;
+
+ void volatileToMap(Utils::Store &map) const override;
+ QVariantList toList(bool v) const;
+
+ QList<std::shared_ptr<BaseAspect>> items() const;
+ QList<std::shared_ptr<BaseAspect>> volatileItems() const;
+
+ std::shared_ptr<BaseAspect> createAndAddItem();
+ std::shared_ptr<BaseAspect> addItem(const std::shared_ptr<BaseAspect> &item);
+ std::shared_ptr<BaseAspect> actualAddItem(const std::shared_ptr<BaseAspect> &item);
+
+ void removeItem(const std::shared_ptr<BaseAspect> &item);
+ void actualRemoveItem(const std::shared_ptr<BaseAspect> &item);
+ void clear();
+
+ void apply() override;
+
+ void setCreateItemFunction(CreateItem createItem);
+
+ template<class T>
+ void forEachItem(std::function<void(const std::shared_ptr<T> &)> callback)
+ {
+ for (const auto &item : volatileItems())
+ callback(std::static_pointer_cast<T>(item));
+ }
+
+ template<class T>
+ void forEachItem(std::function<void(const std::shared_ptr<T> &, int)> callback)
+ {
+ int idx = 0;
+ for (const auto &item : volatileItems())
+ callback(std::static_pointer_cast<T>(item), idx++);
+ }
+
+ void setItemAddedCallback(const ItemCallback &callback);
+ void setItemRemovedCallback(const ItemCallback &callback);
+
+ template<class T>
+ void setItemAddedCallback(const std::function<void(const std::shared_ptr<T>)> &callback)
+ {
+ setItemAddedCallback([callback](const std::shared_ptr<BaseAspect> &item) {
+ callback(std::static_pointer_cast<T>(item));
+ });
+ }
+
+ template<class T>
+ void setItemRemovedCallback(const std::function<void(const std::shared_ptr<T>)> &callback)
+ {
+ setItemRemovedCallback([callback](const std::shared_ptr<BaseAspect> &item) {
+ callback(std::static_pointer_cast<T>(item));
+ });
+ }
+
+ qsizetype size() const;
+ bool isDirty() override;
+
+ QVariant volatileVariantValue() const override { return {}; }
+
+ void addToLayout(Layouting::LayoutItem &parent) override;
+
+private:
+ std::unique_ptr<Internal::AspectListPrivate> d;
+};
+
+class QTCREATOR_UTILS_EXPORT StringSelectionAspect : public Utils::TypedAspect<QString>
+{
+ Q_OBJECT
+public:
+ StringSelectionAspect(Utils::AspectContainer *container = nullptr);
+
+ void addToLayout(Layouting::LayoutItem &parent) override;
+
+ using ResultCallback = std::function<void(QList<QStandardItem *> items)>;
+ using FillCallback = std::function<void(ResultCallback)>;
+ void setFillCallback(FillCallback callback) { m_fillCallback = callback; }
+
+ void refill() { emit refillRequested(); }
+
+ void bufferToGui() override;
+ bool guiToBuffer() override;
+
+signals:
+ void refillRequested();
+
+private:
+ QStandardItem *itemById(const QString &id);
+
+ FillCallback m_fillCallback;
+ QStandardItemModel *m_model{nullptr};
+ QItemSelectionModel *m_selectionModel{nullptr};
+
+ Utils::UndoableValue<QString> m_undoable;
+};
+
} // namespace Utils
diff --git a/src/libs/utils/async.h b/src/libs/utils/async.h
index f8dc6813a7b..64ade0a9e3b 100644
--- a/src/libs/utils/async.h
+++ b/src/libs/utils/async.h
@@ -210,6 +210,7 @@ public:
void start() final { this->task()->start(); }
};
-} // namespace Utils
+template <typename T>
+using AsyncTask = Tasking::CustomTask<AsyncTaskAdapter<T>>;
-TASKING_DECLARE_TEMPLATE_TASK(AsyncTask, Utils::AsyncTaskAdapter);
+} // namespace Utils
diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp
index 14d17257841..8719bfc9b59 100644
--- a/src/libs/utils/basetreeview.cpp
+++ b/src/libs/utils/basetreeview.cpp
@@ -18,7 +18,6 @@
#include <QMap>
#include <QMenu>
#include <QMouseEvent>
-#include <QSettings>
#include <QSortFilterProxyModel>
#include <QTimer>
@@ -92,13 +91,13 @@ public:
m_userHandled.clear();
if (m_settings && !m_settingsKey.isEmpty()) {
m_settings->beginGroup(m_settingsKey);
- QVariantList l = m_settings->value(QLatin1String(ColumnKey)).toList();
- QTC_ASSERT(l.size() % 2 == 0, qDebug() << m_settingsKey; l.append(0));
+ QVariantList l = m_settings->value(ColumnKey).toList();
+ QTC_ASSERT(l.size() % 2 == 0, qDebug() << m_settingsKey.view(); l.append(0));
for (int i = 0; i < l.size(); i += 2) {
int column = l.at(i).toInt();
int width = l.at(i + 1).toInt();
- QTC_ASSERT(column >= 0 && column < 20, qDebug() << m_settingsKey << column; continue);
- QTC_ASSERT(width > 0 && width < 10000, qDebug() << m_settingsKey << width; continue);
+ QTC_ASSERT(column >= 0 && column < 20, qDebug() << m_settingsKey.view() << column; continue);
+ QTC_ASSERT(width > 0 && width < 10000, qDebug() << m_settingsKey.view() << width; continue);
m_userHandled[column] = width;
}
m_settings->endGroup();
@@ -138,7 +137,7 @@ public:
l.append(column);
l.append(width);
}
- QtcSettings::setValueWithDefault(m_settings, ColumnKey, l);
+ m_settings->setValueWithDefault(ColumnKey, l);
m_settings->endGroup();
}
}
@@ -306,9 +305,9 @@ public:
public:
BaseTreeView *q;
QMap<int, int> m_userHandled; // column -> width, "not present" means "automatic"
- QSettings *m_settings = nullptr;
+ QtcSettings *m_settings = nullptr;
QTimer m_settingsTimer;
- QString m_settingsKey;
+ Key m_settingsKey;
bool m_expectUserChanges = false;
ProgressIndicator *m_progressIndicator = nullptr;
int m_spanColumn = -1;
@@ -345,7 +344,6 @@ BaseTreeView::BaseTreeView(QWidget *parent)
setRootIsDecorated(false);
setIconSize(QSize(16, 16));
setSelectionMode(QAbstractItemView::ExtendedSelection);
- setUniformRowHeights(true);
setItemDelegate(new BaseTreeViewDelegate(this));
setAlternatingRowColors(false);
@@ -561,11 +559,11 @@ void BaseTreeView::refreshSpanColumn()
d->rebalanceColumns();
}
-void BaseTreeView::setSettings(QSettings *settings, const QByteArray &key)
+void BaseTreeView::setSettings(QtcSettings *settings, const QByteArray &key)
{
QTC_ASSERT(!d->m_settings, qDebug() << "DUPLICATED setSettings" << key);
d->m_settings = settings;
- d->m_settingsKey = QString::fromLatin1(key);
+ d->m_settingsKey = key;
d->readSettings();
}
diff --git a/src/libs/utils/basetreeview.h b/src/libs/utils/basetreeview.h
index 9c8096fc4fc..a127d1087a2 100644
--- a/src/libs/utils/basetreeview.h
+++ b/src/libs/utils/basetreeview.h
@@ -7,12 +7,10 @@
#include "itemviews.h"
-QT_BEGIN_NAMESPACE
-class QSettings;
-QT_END_NAMESPACE
-
namespace Utils {
+class QtcSettings;
+
namespace Internal { class BaseTreeViewPrivate; }
class QTCREATOR_UTILS_EXPORT BaseTreeView : public TreeView
@@ -34,7 +32,7 @@ public:
BaseTreeView(QWidget *parent = nullptr);
~BaseTreeView() override;
- void setSettings(QSettings *settings, const QByteArray &key);
+ void setSettings(Utils::QtcSettings *settings, const QByteArray &key);
void setModel(QAbstractItemModel *model) override;
void mousePressEvent(QMouseEvent *ev) override;
diff --git a/src/libs/utils/changeset.cpp b/src/libs/utils/changeset.cpp
index fbdd45455d5..b5d3dc2f93a 100644
--- a/src/libs/utils/changeset.cpp
+++ b/src/libs/utils/changeset.cpp
@@ -318,6 +318,12 @@ void ChangeSet::apply(QTextCursor *textCursor)
m_cursor = nullptr;
}
+void ChangeSet::apply(QTextDocument *document)
+{
+ QTextCursor c(document);
+ apply(&c);
+}
+
QString ChangeSet::textAt(int pos, int length)
{
if (m_string) {
@@ -334,10 +340,8 @@ void ChangeSet::apply_helper()
{
// convert all ops to replace
QList<EditOp> replaceList;
- {
- while (!m_operationList.isEmpty())
- convertToReplace(m_operationList.takeFirst(), &replaceList);
- }
+ while (!m_operationList.isEmpty())
+ convertToReplace(m_operationList.takeFirst(), &replaceList);
// execute replaces
if (m_cursor)
diff --git a/src/libs/utils/changeset.h b/src/libs/utils/changeset.h
index a6853c75f5d..4afaefab463 100644
--- a/src/libs/utils/changeset.h
+++ b/src/libs/utils/changeset.h
@@ -10,6 +10,7 @@
QT_BEGIN_NAMESPACE
class QTextCursor;
+class QTextDocument;
QT_END_NAMESPACE
namespace Utils {
@@ -76,6 +77,7 @@ public:
void apply(QString *s);
void apply(QTextCursor *textCursor);
+ void apply(QTextDocument *document);
private:
// length-based API.
@@ -101,6 +103,8 @@ private:
bool m_error;
};
+using EditOperations = QList<ChangeSet::EditOp>;
+
inline bool operator<(const ChangeSet::Range &r1, const ChangeSet::Range &r2)
{
return r1.start < r2.start;
diff --git a/src/libs/utils/checkablemessagebox.cpp b/src/libs/utils/checkablemessagebox.cpp
index d3ede7d4e7e..8e43debc4f7 100644
--- a/src/libs/utils/checkablemessagebox.cpp
+++ b/src/libs/utils/checkablemessagebox.cpp
@@ -5,6 +5,7 @@
#include "hostosinfo.h"
#include "qtcassert.h"
+#include "qtcsettings.h"
#include "utilstr.h"
#include <QApplication>
@@ -12,7 +13,6 @@
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
-#include <QSettings>
#include <QStyle>
#include <QTextEdit>
@@ -32,7 +32,7 @@ static const char kDoNotAskAgainKey[] = "DoNotAskAgain";
namespace Utils {
-static QSettings *theSettings;
+static QtcSettings *theSettings;
static QMessageBox::StandardButton exec(
QWidget *parent,
@@ -53,15 +53,18 @@ static QMessageBox::StandardButton exec(
msgBox.setTextFormat(Qt::RichText);
msgBox.setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
if (HostOsInfo::isMacHost()) {
// Message boxes on macOS cannot display links.
// If the message contains a link, we need to disable native dialogs.
- if (text.contains("<a ")) {
-#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
+ if (text.contains("<a "))
+ msgBox.setOptions(QMessageBox::Option::DontUseNativeDialog);
+
+ // Workaround for QTBUG-118241
+ if (!buttonTextOverrides.isEmpty())
msgBox.setOptions(QMessageBox::Option::DontUseNativeDialog);
-#endif
- }
}
+#endif
if (decider.shouldAskAgain) {
if (!decider.shouldAskAgain())
@@ -86,17 +89,17 @@ static QMessageBox::StandardButton exec(
return clickedBtn;
}
-CheckableDecider::CheckableDecider(const QString &settingsSubKey)
+CheckableDecider::CheckableDecider(const Key &settingsSubKey)
{
QTC_ASSERT(theSettings, return);
shouldAskAgain = [settingsSubKey] {
- theSettings->beginGroup(QLatin1String(kDoNotAskAgainKey));
+ theSettings->beginGroup(kDoNotAskAgainKey);
bool shouldNotAsk = theSettings->value(settingsSubKey, false).toBool();
theSettings->endGroup();
return !shouldNotAsk;
};
doNotAskAgain = [settingsSubKey] {
- theSettings->beginGroup(QLatin1String(kDoNotAskAgainKey));
+ theSettings->beginGroup(kDoNotAskAgainKey);
theSettings->setValue(settingsSubKey, true);
theSettings->endGroup();
};
@@ -160,8 +163,8 @@ QMessageBox::StandardButton CheckableMessageBox::information(
void CheckableMessageBox::resetAllDoNotAskAgainQuestions()
{
QTC_ASSERT(theSettings, return);
- theSettings->beginGroup(QLatin1String(kDoNotAskAgainKey));
- theSettings->remove(QString());
+ theSettings->beginGroup(kDoNotAskAgainKey);
+ theSettings->remove(Key());
theSettings->endGroup();
}
@@ -172,7 +175,7 @@ void CheckableMessageBox::resetAllDoNotAskAgainQuestions()
bool CheckableMessageBox::hasSuppressedQuestions()
{
QTC_ASSERT(theSettings, return false);
- theSettings->beginGroup(QLatin1String(kDoNotAskAgainKey));
+ theSettings->beginGroup(kDoNotAskAgainKey);
const bool hasSuppressed = !theSettings->childKeys().isEmpty()
|| !theSettings->childGroups().isEmpty();
theSettings->endGroup();
@@ -195,7 +198,7 @@ QString CheckableMessageBox::msgDoNotShowAgain()
return Tr::tr("Do not &show again");
}
-void CheckableMessageBox::initialize(QSettings *settings)
+void CheckableMessageBox::initialize(QtcSettings *settings)
{
theSettings = settings;
}
diff --git a/src/libs/utils/checkablemessagebox.h b/src/libs/utils/checkablemessagebox.h
index 297ff22b623..de5f73ca90a 100644
--- a/src/libs/utils/checkablemessagebox.h
+++ b/src/libs/utils/checkablemessagebox.h
@@ -8,17 +8,16 @@
#include <QMap>
#include <QMessageBox>
-QT_BEGIN_NAMESPACE
-class QSettings;
-QT_END_NAMESPACE
-
namespace Utils {
+class Key;
+class QtcSettings;
+
class QTCREATOR_UTILS_EXPORT CheckableDecider
{
public:
CheckableDecider() = default;
- CheckableDecider(const QString &settingsSubKey);
+ CheckableDecider(const Key &settingsSubKey);
CheckableDecider(bool *doNotAskAgain);
CheckableDecider(const std::function<bool()> &should, const std::function<void()> &doNot)
: shouldAskAgain(should), doNotAskAgain(doNot)
@@ -58,7 +57,7 @@ public:
static QString msgDoNotAskAgain();
static QString msgDoNotShowAgain();
- static void initialize(QSettings *settings);
+ static void initialize(QtcSettings *settings);
};
} // namespace Utils
diff --git a/src/libs/utils/commandline.cpp b/src/libs/utils/commandline.cpp
index 60b8d72eed2..8e6bc60277e 100644
--- a/src/libs/utils/commandline.cpp
+++ b/src/libs/utils/commandline.cpp
@@ -182,7 +182,7 @@ static QStringList doSplitArgsWin(const QString &args, ProcessArgs::SplitError *
if (inquote) {
if (err)
*err = ProcessArgs::BadQuoting;
- return QStringList();
+ return {};
}
break;
}
@@ -265,7 +265,7 @@ static QStringList splitArgsWin(const QString &_args, bool abortOnMeta,
err = &perr;
QString args = prepareArgsWin(_args, &perr, env, pwd).toWindowsArgs();
if (*err != ProcessArgs::SplitOk)
- return QStringList();
+ return {};
return doSplitArgsWin(args, err);
} else {
QString args = _args;
@@ -470,12 +470,12 @@ static QStringList splitArgsUnix(const QString &args, bool abortOnMeta,
quoteerr:
if (err)
*err = ProcessArgs::BadQuoting;
- return QStringList();
+ return {};
metaerr:
if (err)
*err = ProcessArgs::FoundMeta;
- return QStringList();
+ return {};
}
inline static bool isSpecialCharUnix(ushort c)
diff --git a/src/libs/utils/commandline.h b/src/libs/utils/commandline.h
index d7fc0a066be..52ff8c5496f 100644
--- a/src/libs/utils/commandline.h
+++ b/src/libs/utils/commandline.h
@@ -8,7 +8,6 @@
#include "filepath.h"
#include "hostosinfo.h"
-#include <QList>
#include <QPair>
#include <QStringList>
diff --git a/src/libs/utils/delegates.cpp b/src/libs/utils/delegates.cpp
index 3b0623027b6..b384faba571 100644
--- a/src/libs/utils/delegates.cpp
+++ b/src/libs/utils/delegates.cpp
@@ -151,7 +151,7 @@ void PathChooserDelegate::updateEditorGeometry(QWidget *editor, const QStyleOpti
editor->setGeometry(option.rect);
}
-void PathChooserDelegate::setHistoryCompleter(const QString &key)
+void PathChooserDelegate::setHistoryCompleter(const Key &key)
{
m_historyKey = key;
}
diff --git a/src/libs/utils/delegates.h b/src/libs/utils/delegates.h
index ff012152f5f..328798b4b8d 100644
--- a/src/libs/utils/delegates.h
+++ b/src/libs/utils/delegates.h
@@ -52,12 +52,12 @@ public:
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &index) const override;
- void setHistoryCompleter(const QString &key);
+ void setHistoryCompleter(const Key &key);
private:
PathChooser::Kind m_kind = PathChooser::ExistingDirectory;
QString m_filter;
- QString m_historyKey;
+ Key m_historyKey;
};
class QTCREATOR_UTILS_EXPORT CompleterDelegate : public QStyledItemDelegate
diff --git a/src/libs/utils/detailsbutton.h b/src/libs/utils/detailsbutton.h
index 2f49980dbd5..1e222a0bcd1 100644
--- a/src/libs/utils/detailsbutton.h
+++ b/src/libs/utils/detailsbutton.h
@@ -15,8 +15,6 @@ QT_END_NAMESPACE
namespace Utils {
class QTCREATOR_UTILS_EXPORT FadingPanel : public QWidget
{
- Q_OBJECT
-
public:
FadingPanel(QWidget *parent = nullptr)
: QWidget(parent)
@@ -27,7 +25,6 @@ public:
class QTCREATOR_UTILS_EXPORT FadingWidget : public FadingPanel
{
- Q_OBJECT
public:
FadingWidget(QWidget *parent = nullptr);
void fadeTo(qreal value) override;
diff --git a/src/libs/utils/devicefileaccess.cpp b/src/libs/utils/devicefileaccess.cpp
index 07600599884..a38a3617a7e 100644
--- a/src/libs/utils/devicefileaccess.cpp
+++ b/src/libs/utils/devicefileaccess.cpp
@@ -18,10 +18,10 @@
#include <QCoreApplication>
#include <QOperatingSystemVersion>
+#include <QRandomGenerator>
#include <QRegularExpression>
#include <QStorageInfo>
#include <QTemporaryFile>
-#include <QRandomGenerator>
#ifdef Q_OS_WIN
#ifdef QTCREATOR_PCH_H
@@ -113,14 +113,22 @@ bool DeviceFileAccess::hasHardLinks(const FilePath &filePath) const
return false;
}
-bool DeviceFileAccess::ensureWritableDirectory(const FilePath &filePath) const
+expected_str<void> DeviceFileAccess::ensureWritableDirectory(const FilePath &filePath) const
{
if (isWritableDirectory(filePath))
- return true;
- if (exists(filePath))
- return false;
+ return {};
+
+ if (exists(filePath)) {
+ return make_unexpected(Tr::tr("Path \"%1\" exists but is not a writable directory.")
+ .arg(filePath.toUserOutput()));
+ }
+
+ const bool result = createDirectory(filePath);
+ if (result)
+ return {};
- return createDirectory(filePath);
+ return make_unexpected(
+ Tr::tr("Failed to create directory \"%1\".").arg(filePath.toUserOutput()));
}
bool DeviceFileAccess::ensureExistingFile(const FilePath &filePath) const
@@ -169,31 +177,24 @@ expected_str<void> DeviceFileAccess::copyFile(const FilePath &filePath, const Fi
expected_str<void> copyRecursively_fallback(const FilePath &src, const FilePath &target)
{
- QString error;
+ expected_str<void> result;
src.iterateDirectory(
- [&target, &src, &error](const FilePath &path) {
+ [&target, &src, &result](const FilePath &path) {
const FilePath relative = path.relativePathFrom(src);
const FilePath targetPath = target.pathAppended(relative.path());
-
- if (!targetPath.parentDir().ensureWritableDir()) {
- error = QString("Could not create directory %1")
- .arg(targetPath.parentDir().toUserOutput());
+ result = targetPath.parentDir().ensureWritableDir();
+ if (!result)
return IterationPolicy::Stop;
- }
- const expected_str<void> result = path.copyFile(targetPath);
- if (!result) {
- error = result.error();
+ result = path.copyFile(targetPath);
+ if (!result)
return IterationPolicy::Stop;
- }
+
return IterationPolicy::Continue;
},
{{"*"}, QDir::NoDotAndDotDot | QDir::Files, QDirIterator::Subdirectories});
- if (error.isEmpty())
- return {};
-
- return make_unexpected(error);
+ return result;
}
expected_str<void> DeviceFileAccess::copyRecursively(const FilePath &src,
@@ -203,12 +204,12 @@ expected_str<void> DeviceFileAccess::copyRecursively(const FilePath &src,
return make_unexpected(
Tr::tr("Cannot copy from \"%1\", it is not a directory.").arg(src.toUserOutput()));
}
-
- if (!target.ensureWritableDir()) {
- return make_unexpected(
- Tr::tr("Cannot copy \"%1\" to \"%2\", it is not a writable directory.")
- .arg(src.toUserOutput())
- .arg(target.toUserOutput()));
+ const expected_str<void> result = target.ensureWritableDir();
+ if (!result) {
+ return make_unexpected(Tr::tr("Cannot copy \"%1\" to \"%2\": %3")
+ .arg(src.toUserOutput())
+ .arg(target.toUserOutput())
+ .arg(result.error()));
}
#ifdef UTILS_STATIC_LIBRARY
@@ -389,7 +390,6 @@ expected_str<FilePath> DeviceFileAccess::createTempFile(const FilePath &filePath
Tr::tr("createTempFile is not implemented for \"%1\".").arg(filePath.toUserOutput()));
}
-
// DesktopDeviceFileAccess
DesktopDeviceFileAccess::~DesktopDeviceFileAccess() = default;
@@ -516,15 +516,23 @@ bool DesktopDeviceFileAccess::hasHardLinks(const FilePath &filePath) const
return false;
}
-bool DesktopDeviceFileAccess::ensureWritableDirectory(const FilePath &filePath) const
+expected_str<void> DesktopDeviceFileAccess::ensureWritableDirectory(const FilePath &filePath) const
{
const QFileInfo fi(filePath.path());
if (fi.isDir() && fi.isWritable())
- return true;
- if (fi.exists())
- return false;
+ return {};
+
+ if (fi.exists()) {
+ return make_unexpected(Tr::tr("Path \"%1\" exists but is not a writable directory.")
+ .arg(filePath.toUserOutput()));
+ }
- return QDir().mkpath(filePath.path());
+ const bool result = QDir().mkpath(filePath.path());
+ if (result)
+ return {};
+
+ return make_unexpected(
+ Tr::tr("Failed to create directory \"%1\".").arg(filePath.toUserOutput()));
}
bool DesktopDeviceFileAccess::ensureExistingFile(const FilePath &filePath) const
@@ -713,10 +721,11 @@ expected_str<qint64> DesktopDeviceFileAccess::writeFileContents(const FilePath &
qint64 res = file.write(data);
if (res != data.size())
return make_unexpected(
- Tr::tr("Could not write to file \"%1\" (only %2 of %3 bytes written).")
+ Tr::tr("Could not write to file \"%1\" (only %2 of %n byte(s) written).",
+ nullptr,
+ data.size())
.arg(filePath.toUserOutput())
- .arg(res)
- .arg(data.size()));
+ .arg(res));
return res;
}
@@ -954,7 +963,9 @@ expected_str<void> UnixDeviceFileAccess::copyFile(const FilePath &filePath,
if (result.exitCode != 0) {
return make_unexpected(Tr::tr("Failed to copy file \"%1\" to \"%2\": %3")
- .arg(filePath.toUserOutput(), target.toUserOutput(), QString::fromUtf8(result.stdErr)));
+ .arg(filePath.toUserOutput(),
+ target.toUserOutput(),
+ QString::fromUtf8(result.stdErr)));
}
return {};
}
@@ -1089,7 +1100,8 @@ QStringList UnixDeviceFileAccess::statArgs(const FilePath &filePath,
const QString &linuxFormat,
const QString &macFormat) const
{
- return (filePath.osType() == OsTypeMac ? QStringList{"-f", macFormat} : QStringList{"-c", linuxFormat})
+ return (filePath.osType() == OsTypeMac ? QStringList{"-f", macFormat}
+ : QStringList{"-c", linuxFormat})
<< "-L" << filePath.path();
}
@@ -1182,8 +1194,8 @@ bool UnixDeviceFileAccess::iterateWithFind(const FilePath &filePath,
// TODO: Using stat -L will always return the link target, not the link itself.
// We may wan't to add the information that it is a link at some point.
- const QString statFormat = filePath.osType() == OsTypeMac
- ? QLatin1String("-f \"%p %m %z\"") : QLatin1String("-c \"%f %Y %s\"");
+ const QString statFormat = filePath.osType() == OsTypeMac ? QLatin1String("-f \"%p %m %z\"")
+ : QLatin1String("-c \"%f %Y %s\"");
if (callBack.index() == 1)
cmdLine.addArgs(QString(R"(-exec echo -n \"{}\"" " \; -exec stat -L %1 "{}" \;)")
@@ -1211,24 +1223,23 @@ bool UnixDeviceFileAccess::iterateWithFind(const FilePath &filePath,
const int modeBase = filePath.osType() == OsTypeMac ? 8 : 16;
- const auto toFilePath =
- [&filePath, &callBack, modeBase](const QString &entry) {
- if (callBack.index() == 0)
- return std::get<0>(callBack)(filePath.withNewPath(entry));
+ const auto toFilePath = [&filePath, &callBack, modeBase](const QString &entry) {
+ if (callBack.index() == 0)
+ return std::get<0>(callBack)(filePath.withNewPath(entry));
- const QString fileName = entry.mid(1, entry.lastIndexOf('\"') - 1);
- const QString infos = entry.mid(fileName.length() + 3);
+ const QString fileName = entry.mid(1, entry.lastIndexOf('\"') - 1);
+ const QString infos = entry.mid(fileName.length() + 3);
- const FilePathInfo fi = FileUtils::filePathInfoFromTriple(infos, modeBase);
- if (!fi.fileFlags)
- return IterationPolicy::Continue;
+ const FilePathInfo fi = FileUtils::filePathInfoFromTriple(infos, modeBase);
+ if (!fi.fileFlags)
+ return IterationPolicy::Continue;
- const FilePath fp = filePath.withNewPath(fileName);
- // Do not return the entry for the directory we are searching in.
- if (fp.path() == filePath.path())
- return IterationPolicy::Continue;
- return std::get<1>(callBack)(fp, fi);
- };
+ const FilePath fp = filePath.withNewPath(fileName);
+ // Do not return the entry for the directory we are searching in.
+ if (fp.path() == filePath.path())
+ return IterationPolicy::Continue;
+ return std::get<1>(callBack)(fp, fi);
+ };
// Remove the first line, this can be the directory we are searching in.
// as long as we do not specify "mindepth > 0"
@@ -1247,7 +1258,8 @@ void UnixDeviceFileAccess::findUsingLs(const QString &current,
const FileFilter &filter,
QStringList *found) const
{
- const RunResult result = runInShell({"ls", {"-1", "-a", "-p", "--", current}, OsType::OsTypeLinux});
+ const RunResult result = runInShell(
+ {"ls", {"-1", "-a", "-p", "--", current}, OsType::OsTypeLinux});
const QStringList entries = QString::fromUtf8(result.stdOut).split('\n', Qt::SkipEmptyParts);
for (QString entry : entries) {
const QChar last = entry.back();
@@ -1326,4 +1338,4 @@ Environment UnixDeviceFileAccess::deviceEnvironment() const
return Environment(out.split('\n', Qt::SkipEmptyParts), OsTypeLinux);
}
-} // Utils
+} // namespace Utils
diff --git a/src/libs/utils/devicefileaccess.h b/src/libs/utils/devicefileaccess.h
index 0f8282477f6..6dddbc70045 100644
--- a/src/libs/utils/devicefileaccess.h
+++ b/src/libs/utils/devicefileaccess.h
@@ -35,7 +35,7 @@ protected:
virtual bool isDirectory(const FilePath &filePath) const;
virtual bool isSymLink(const FilePath &filePath) const;
virtual bool hasHardLinks(const FilePath &filePath) const;
- virtual bool ensureWritableDirectory(const FilePath &filePath) const;
+ virtual expected_str<void> ensureWritableDirectory(const FilePath &filePath) const;
virtual bool ensureExistingFile(const FilePath &filePath) const;
virtual bool createDirectory(const FilePath &filePath) const;
virtual bool exists(const FilePath &filePath) const;
@@ -92,7 +92,7 @@ protected:
bool isDirectory(const FilePath &filePath) const override;
bool isSymLink(const FilePath &filePath) const override;
bool hasHardLinks(const FilePath &filePath) const override;
- bool ensureWritableDirectory(const FilePath &filePath) const override;
+ expected_str<void> ensureWritableDirectory(const FilePath &filePath) const override;
bool ensureExistingFile(const FilePath &filePath) const override;
bool createDirectory(const FilePath &filePath) const override;
bool exists(const FilePath &filePath) const override;
diff --git a/src/libs/utils/deviceshell.cpp b/src/libs/utils/deviceshell.cpp
index 99ddecdeec9..6d99d399841 100644
--- a/src/libs/utils/deviceshell.cpp
+++ b/src/libs/utils/deviceshell.cpp
@@ -6,6 +6,7 @@
#include "process.h"
#include "processinterface.h"
#include "qtcassert.h"
+#include "utilstr.h"
#include <QLoggingCategory>
@@ -154,22 +155,12 @@ CommandLine DeviceShell::createFallbackCommand(const CommandLine &cmd)
}
/*!
- * \brief DeviceShell::startupFailed
- *
- * Override to display custom error messages
- */
-void DeviceShell::startupFailed(const CommandLine &cmdLine)
-{
- qCWarning(deviceShellLog) << "Failed to start shell via:" << cmdLine.toUserOutput();
-}
-
-/*!
* \brief DeviceShell::start
* \return Returns true if starting the Shell process succeeded
*
* \note You have to call this function when deriving from DeviceShell. Current implementations call the function from their constructor.
*/
-bool DeviceShell::start()
+expected_str<void> DeviceShell::start()
{
m_shellProcess = std::make_unique<Process>();
connect(m_shellProcess.get(), &Process::done, m_shellProcess.get(),
@@ -185,19 +176,21 @@ bool DeviceShell::start()
// Moving the process into its own thread ...
m_shellProcess->moveToThread(&m_thread);
- bool result = false;
+ expected_str<void> result;
QMetaObject::invokeMethod(
m_shellProcess.get(),
- [this] {
- qCDebug(deviceShellLog) << "Starting shell process:" << m_shellProcess->commandLine().toUserOutput();
+ [this]() -> expected_str<void> {
+ qCDebug(deviceShellLog)
+ << "Starting shell process:" << m_shellProcess->commandLine().toUserOutput();
m_shellProcess->start();
if (!m_shellProcess->waitForStarted()) {
closeShellProcess();
- return false;
+ return make_unexpected(Tr::tr("The process failed to start."));
}
- if (installShellScript()) {
+ auto installResult = installShellScript();
+ if (installResult) {
connect(m_shellProcess.get(),
&Process::readyReadStandardOutput,
m_shellProcess.get(),
@@ -210,66 +203,67 @@ bool DeviceShell::start()
qCWarning(deviceShellLog)
<< "Received unexpected output on stderr:" << stdErr;
});
+
+ connect(m_shellProcess.get(), &Process::done, m_shellProcess.get(), [this] {
+ if (m_shellProcess->resultData().m_exitCode != EXIT_SUCCESS
+ || m_shellProcess->resultData().m_exitStatus != QProcess::NormalExit) {
+ qCWarning(deviceShellLog) << "Shell exited with error code:"
+ << m_shellProcess->resultData().m_exitCode << "("
+ << m_shellProcess->exitMessage() << ")";
+ }
+ });
+
+ return {};
} else if (m_shellProcess->isRunning()) {
m_shellProcess->kill();
- m_shellProcess.reset();
- return false;
}
+ const QString stdErr = m_shellProcess->readAllStandardError();
+ m_shellProcess.reset();
- connect(m_shellProcess.get(), &Process::done, m_shellProcess.get(), [this] {
- if (m_shellProcess->resultData().m_exitCode != EXIT_SUCCESS
- || m_shellProcess->resultData().m_exitStatus != QProcess::NormalExit) {
- qCWarning(deviceShellLog) << "Shell exited with error code:"
- << m_shellProcess->resultData().m_exitCode << "("
- << m_shellProcess->exitMessage() << ")";
- }
- });
-
- return true;
+ return make_unexpected(Tr::tr("Failed to install shell script: %1\n%2")
+ .arg(installResult.error())
+ .arg(stdErr));
},
Qt::BlockingQueuedConnection,
&result);
- if (!result) {
- startupFailed(cmdLine);
- }
-
return result;
}
-bool DeviceShell::checkCommand(const QByteArray &command)
+expected_str<QByteArray> DeviceShell::checkCommand(const QByteArray &command)
{
- const QByteArray checkCmd = "(which " + command + " || echo '<missing>')\n";
+ const QByteArray checkCmd = "(type " + command + " || echo '<missing>')\n";
m_shellProcess->writeRaw(checkCmd);
if (!m_shellProcess->waitForReadyRead()) {
- qCWarning(deviceShellLog) << "Timeout while trying to check for" << command;
- return false;
+ return make_unexpected(
+ Tr::tr("Timeout while trying to check for %1.").arg(QString::fromUtf8(command)));
}
QByteArray out = m_shellProcess->readAllRawStandardOutput();
if (out.contains("<missing>")) {
m_shellScriptState = State::Failed;
- qCWarning(deviceShellLog) << "Command" << command << "was not found";
m_missingFeatures.append(QString::fromUtf8(command));
- return false;
+ return make_unexpected(
+ Tr::tr("Command \"%1\" was not found.").arg(QString::fromUtf8(command)));
}
- return true;
+ return out;
}
-bool DeviceShell::installShellScript()
+expected_str<void> DeviceShell::installShellScript()
{
if (m_forceFailScriptInstallation) {
m_shellScriptState = State::Failed;
- return false;
+ return make_unexpected(Tr::tr("Script installation was forced to fail."));
}
static const QList<QByteArray> requiredCommands
= {"base64", "cat", "echo", "kill", "mkfifo", "mktemp", "rm"};
for (const QByteArray &command : requiredCommands) {
- if (!checkCommand(command))
- return false;
+ auto checkResult = checkCommand(command);
+ if (!checkResult)
+ return make_unexpected(checkResult.error());
}
const static QByteArray shellScriptBase64 = FilePath(":/utils/scripts/deviceshell.sh")
@@ -286,19 +280,18 @@ bool DeviceShell::installShellScript()
while (m_shellScriptState == State::Unknown) {
if (!m_shellProcess->waitForReadyRead(5000)) {
- qCWarning(deviceShellLog) << "Timeout while waiting for shell script installation";
- return false;
+ return make_unexpected(Tr::tr("Timeout while waiting for shell script installation."));
}
QByteArray out = m_shellProcess->readAllRawStandardError();
if (out.contains("SCRIPT_INSTALLED") && !out.contains("ERROR_INSTALL_SCRIPT")) {
m_shellScriptState = State::Succeeded;
- return true;
+ return {};
}
if (out.contains("ERROR_INSTALL_SCRIPT")) {
m_shellScriptState = State::Failed;
- qCWarning(deviceShellLog) << "Failed installing device shell script";
- return false;
+ return make_unexpected(
+ Tr::tr("Failed to install shell script: %1").arg(QString::fromUtf8(out)));
}
if (!out.isEmpty()) {
qCWarning(deviceShellLog)
@@ -306,7 +299,7 @@ bool DeviceShell::installShellScript()
}
}
- return true;
+ return {};
}
void DeviceShell::closeShellProcess()
diff --git a/src/libs/utils/deviceshell.h b/src/libs/utils/deviceshell.h
index e5bc4ad7afe..73d9805e104 100644
--- a/src/libs/utils/deviceshell.h
+++ b/src/libs/utils/deviceshell.h
@@ -3,9 +3,9 @@
#pragma once
-#include "utils_global.h"
-
+#include "expected.h"
#include "fileutils.h"
+#include "utils_global.h"
#include <QHash>
#include <QMutex>
@@ -39,7 +39,7 @@ public:
DeviceShell(bool forceFailScriptInstallation = false);
virtual ~DeviceShell();
- bool start();
+ expected_str<void> start();
RunResult runInShell(const CommandLine &cmd, const QByteArray &stdInData = {});
@@ -51,7 +51,6 @@ signals:
void done(const ProcessResultData &resultData);
protected:
- virtual void startupFailed(const CommandLine &cmdLine);
RunResult run(const CommandLine &cmd, const QByteArray &stdInData = {});
void close();
@@ -60,12 +59,12 @@ private:
virtual void setupShellProcess(Process *shellProcess);
virtual CommandLine createFallbackCommand(const CommandLine &cmdLine);
- bool installShellScript();
+ expected_str<void> installShellScript();
void closeShellProcess();
void onReadyRead();
- bool checkCommand(const QByteArray &command);
+ expected_str<QByteArray> checkCommand(const QByteArray &command);
private:
struct CommandRun : public RunResult
diff --git a/src/libs/utils/differ.cpp b/src/libs/utils/differ.cpp
index f929efbeeb0..bc7dda6f302 100644
--- a/src/libs/utils/differ.cpp
+++ b/src/libs/utils/differ.cpp
@@ -13,7 +13,6 @@ publication by Neil Fraser: http://neil.fraser.name/writing/diff/
#include "utilstr.h"
-#include <QList>
#include <QMap>
#include <QPair>
#include <QRegularExpression>
@@ -579,7 +578,7 @@ static QList<Diff> decodeExpandedWhitespace(const QList<Diff> &input,
const int replacementSize = it.value().first;
const int reversePosition = diffCount + counter - it.key();
if (reversePosition < replacementSize)
- return QList<Diff>(); // replacement exceeds one Diff
+ return {}; // replacement exceeds one Diff
const QString replacement = it.value().second;
const int updatedDiffCount = diff.text.size();
diff.text.replace(updatedDiffCount - reversePosition,
@@ -978,7 +977,7 @@ Differ::DiffMode Differ::diffMode() const
QList<Diff> Differ::preprocess1AndDiff(const QString &text1, const QString &text2)
{
if (text1.isNull() && text2.isNull())
- return QList<Diff>();
+ return {};
if (text1 == text2) {
QList<Diff> diffList;
@@ -1075,7 +1074,7 @@ QList<Diff> Differ::diffMyers(const QString &text1, const QString &text2)
if (m_future && m_future->isCanceled()) {
delete [] forwardV;
delete [] reverseV;
- return QList<Diff>();
+ return {};
}
// going forward
for (int k = qMax(-d, kMinForward + qAbs(d + kMinForward) % 2);
diff --git a/src/libs/utils/displayname.cpp b/src/libs/utils/displayname.cpp
index b4082a60922..a2f622143c6 100644
--- a/src/libs/utils/displayname.cpp
+++ b/src/libs/utils/displayname.cpp
@@ -35,13 +35,13 @@ bool DisplayName::usesDefaultValue() const
return m_value.isEmpty();
}
-void DisplayName::toMap(QVariantMap &map, const QString &key) const
+void DisplayName::toMap(Store &map, const Key &key) const
{
- if (!usesDefaultValue())
+ if (m_forceSerialization || !usesDefaultValue())
map.insert(key, m_value);
}
-void DisplayName::fromMap(const QVariantMap &map, const QString &key)
+void DisplayName::fromMap(const Store &map, const Key &key)
{
m_value = map.value(key).toString();
}
diff --git a/src/libs/utils/displayname.h b/src/libs/utils/displayname.h
index c1e7f7b10a3..fd4977c7586 100644
--- a/src/libs/utils/displayname.h
+++ b/src/libs/utils/displayname.h
@@ -5,8 +5,7 @@
#include "utils_global.h"
-#include <QString>
-#include <QVariantMap>
+#include "store.h"
namespace Utils {
@@ -22,13 +21,15 @@ public:
QString value() const;
QString defaultValue() const { return m_defaultValue; }
bool usesDefaultValue() const;
+ void forceSerialization() { m_forceSerialization = true; }
- void toMap(QVariantMap &map, const QString &key) const;
- void fromMap(const QVariantMap &map, const QString &key);
+ void toMap(Store &map, const Key &key) const;
+ void fromMap(const Store &map, const Key &key);
private:
QString m_value;
QString m_defaultValue;
+ bool m_forceSerialization = false;
};
bool QTCREATOR_UTILS_EXPORT operator==(const DisplayName &dn1, const DisplayName &dn2);
diff --git a/src/libs/utils/dropsupport.cpp b/src/libs/utils/dropsupport.cpp
index 6def3fd1aff..7416edf9c37 100644
--- a/src/libs/utils/dropsupport.cpp
+++ b/src/libs/utils/dropsupport.cpp
@@ -10,7 +10,7 @@
#include <QDropEvent>
#include <QTimer>
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MACOS
// for file drops from Finder, working around QTBUG-40449
#include "fileutils_mac.h"
#endif
@@ -63,7 +63,7 @@ DropSupport::DropSupport(QWidget *parentWidget, const DropFilterFunction &filter
QStringList DropSupport::mimeTypesForFilePaths()
{
- return QStringList("text/uri-list");
+ return {"text/uri-list"};
}
bool DropSupport::isFileDrop(QDropEvent *event)
@@ -181,7 +181,7 @@ void DropMimeData::addFile(const FilePath &filePath, int line, int column)
{
// standard mime data
QList<QUrl> currentUrls = urls();
- currentUrls.append(QUrl::fromLocalFile(filePath.toString()));
+ currentUrls.append(filePath.toUrl());
setUrls(currentUrls);
// special mime data
m_files.append(DropSupport::FileSpec(filePath, line, column));
diff --git a/src/libs/utils/elfreader.h b/src/libs/utils/elfreader.h
index d1506c81f00..a254b8e221e 100644
--- a/src/libs/utils/elfreader.h
+++ b/src/libs/utils/elfreader.h
@@ -10,8 +10,8 @@
#include <QByteArray>
#include <QCoreApplication>
#include <QFile>
+#include <QList>
#include <QSharedPointer>
-#include <QVector>
namespace Utils {
@@ -130,8 +130,8 @@ public:
QByteArray debugLink;
QByteArray buildId;
DebugSymbolsType symbolsType = UnknownSymbols;
- QVector<ElfSectionHeader> sectionHeaders;
- QVector<ElfProgramHeader> programHeaders;
+ QList<ElfSectionHeader> sectionHeaders;
+ QList<ElfProgramHeader> programHeaders;
};
class QTCREATOR_UTILS_EXPORT ElfReader
diff --git a/src/libs/utils/environment.cpp b/src/libs/utils/environment.cpp
index b9af2dea928..d71d76c8b8a 100644
--- a/src/libs/utils/environment.cpp
+++ b/src/libs/utils/environment.cpp
@@ -24,7 +24,7 @@ namespace Utils {
static QReadWriteLock s_envMutex;
Q_GLOBAL_STATIC_WITH_ARGS(Environment, staticSystemEnvironment,
(QProcessEnvironment::systemEnvironment().toStringList()))
-Q_GLOBAL_STATIC(QVector<EnvironmentProvider>, environmentProviders)
+Q_GLOBAL_STATIC(QList<EnvironmentProvider>, environmentProviders)
Environment::Environment()
: m_dict(HostOsInfo::hostOs())
@@ -149,6 +149,11 @@ void Environment::prependOrSetPath(const FilePath &value)
prependOrSet("PATH", value.nativePath(), OsSpecificAspects::pathListSeparator(osType()));
}
+void Environment::prependOrSetPath(const QString &directories)
+{
+ prependOrSet("PATH", directories, OsSpecificAspects::pathListSeparator(osType()));
+}
+
void Environment::appendOrSet(const QString &key, const QString &value, const QString &sep)
{
addItem(Item{std::in_place_index_t<AppendOrSet>(), key, value, sep});
@@ -220,11 +225,12 @@ QString Environment::expandedValueForKey(const QString &key) const
FilePath Environment::searchInPath(const QString &executable,
const FilePaths &additionalDirs,
- const FilePathPredicate &filter) const
+ const FilePathPredicate &filter,
+ FilePath::MatchScope scope) const
{
const FilePath exec = FilePath::fromUserInput(expandVariables(executable));
const FilePaths dirs = path() + additionalDirs;
- return exec.searchInDirectories(dirs, filter, FilePath::WithAnySuffix);
+ return exec.searchInDirectories(dirs, filter, scope);
}
FilePaths Environment::path() const
@@ -352,7 +358,7 @@ void EnvironmentProvider::addProvider(EnvironmentProvider &&provider)
environmentProviders->append(std::move(provider));
}
-const QVector<EnvironmentProvider> EnvironmentProvider::providers()
+const QList<EnvironmentProvider> EnvironmentProvider::providers()
{
return *environmentProviders;
}
diff --git a/src/libs/utils/environment.h b/src/libs/utils/environment.h
index 63fe697bd6e..679b28f0e08 100644
--- a/src/libs/utils/environment.h
+++ b/src/libs/utils/environment.h
@@ -48,6 +48,7 @@ public:
void appendOrSetPath(const FilePath &value);
void prependOrSetPath(const FilePath &value);
+ void prependOrSetPath(const QString &directories); // Could be several ':'/';' separated entries.
void prependOrSetLibrarySearchPath(const FilePath &value);
void prependOrSetLibrarySearchPaths(const FilePaths &values);
@@ -60,7 +61,8 @@ public:
FilePath searchInPath(const QString &executable,
const FilePaths &additionalDirs = FilePaths(),
- const FilePathPredicate &func = {}) const;
+ const FilePathPredicate &func = {},
+ FilePath::MatchScope = FilePath::WithAnySuffix) const;
FilePaths path() const;
FilePaths pathListValue(const QString &varName) const;
@@ -134,7 +136,7 @@ public:
std::function<Environment()> environment;
static void addProvider(EnvironmentProvider &&provider);
- static const QVector<EnvironmentProvider> providers();
+ static const QList<EnvironmentProvider> providers();
static std::optional<EnvironmentProvider> provider(const QByteArray &id);
};
diff --git a/src/libs/utils/environmentdialog.h b/src/libs/utils/environmentdialog.h
index 5c60f3d2a09..335ba7ffe58 100644
--- a/src/libs/utils/environmentdialog.h
+++ b/src/libs/utils/environmentdialog.h
@@ -7,18 +7,16 @@
#include "environmentfwd.h"
#include "namevaluesdialog.h"
-#include <thread>
namespace Utils {
class QTCREATOR_UTILS_EXPORT EnvironmentDialog : public NameValuesDialog
{
- Q_OBJECT
public:
static std::optional<EnvironmentItems> getEnvironmentItems(QWidget *parent = nullptr,
- const EnvironmentItems &initial = {},
- const QString &placeholderText = {},
- Polisher polish = {});
+ const EnvironmentItems &initial = {},
+ const QString &placeholderText = {},
+ Polisher polish = {});
};
} // namespace Utils
diff --git a/src/libs/utils/environmentfwd.h b/src/libs/utils/environmentfwd.h
index 2975cbb64a7..51089eeee19 100644
--- a/src/libs/utils/environmentfwd.h
+++ b/src/libs/utils/environmentfwd.h
@@ -3,7 +3,7 @@
#pragma once
-#include <QVector>
+#include <QList>
QT_BEGIN_NAMESPACE
class QTreeView;
@@ -12,7 +12,7 @@ QT_END_NAMESPACE
namespace Utils {
class NameValueDictionary;
class NameValueItem;
-using NameValueItems = QVector<NameValueItem>;
+using NameValueItems = QList<NameValueItem>;
class Environment;
using EnvironmentItem = NameValueItem;
diff --git a/src/libs/utils/environmentmodel.h b/src/libs/utils/environmentmodel.h
index 46c16b4e73c..82bf98d43f5 100644
--- a/src/libs/utils/environmentmodel.h
+++ b/src/libs/utils/environmentmodel.h
@@ -11,8 +11,6 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT EnvironmentModel : public NameValueModel
{
- Q_OBJECT
-
public:
Environment baseEnvironment() const;
void setBaseEnvironment(const Environment &env);
diff --git a/src/libs/utils/execmenu.cpp b/src/libs/utils/execmenu.cpp
index d607a8de69a..13d79152953 100644
--- a/src/libs/utils/execmenu.cpp
+++ b/src/libs/utils/execmenu.cpp
@@ -3,6 +3,8 @@
#include "execmenu.h"
+#include "tooltip/tooltip.h"
+
#include <QMenu>
#include <QPoint>
#include <QRect>
@@ -41,4 +43,14 @@ QAction *execMenuAtWidget(QMenu *menu, QWidget *widget)
return menu->exec(p);
}
+/*!
+ Adds tool tips to the menu that show the actions tool tip when hovering over an entry.
+ */
+void addToolTipsToMenu(QMenu *menu)
+{
+ QObject::connect(menu, &QMenu::hovered, menu, [menu](QAction *action) {
+ ToolTip::show(menu->mapToGlobal(menu->actionGeometry(action).topRight()), action->toolTip());
+ });
+}
+
} // namespace Utils
diff --git a/src/libs/utils/execmenu.h b/src/libs/utils/execmenu.h
index 90fac94c0e8..9ad63d88ead 100644
--- a/src/libs/utils/execmenu.h
+++ b/src/libs/utils/execmenu.h
@@ -14,5 +14,6 @@ QT_END_NAMESPACE
namespace Utils {
QTCREATOR_UTILS_EXPORT QAction *execMenuAtWidget(QMenu *menu, QWidget *widget);
+QTCREATOR_UTILS_EXPORT void addToolTipsToMenu(QMenu *menu);
} // namespace Utils
diff --git a/src/libs/utils/faketooltip.h b/src/libs/utils/faketooltip.h
index 7df85a816ec..1f8f3acc57c 100644
--- a/src/libs/utils/faketooltip.h
+++ b/src/libs/utils/faketooltip.h
@@ -11,8 +11,6 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT FakeToolTip : public QWidget
{
- Q_OBJECT
-
public:
explicit FakeToolTip(QWidget *parent = nullptr);
diff --git a/src/libs/utils/fancylineedit.cpp b/src/libs/utils/fancylineedit.cpp
index 2bf50a70fa1..a3acaad0f44 100644
--- a/src/libs/utils/fancylineedit.cpp
+++ b/src/libs/utils/fancylineedit.cpp
@@ -7,19 +7,23 @@
#include "execmenu.h"
#include "historycompleter.h"
#include "hostosinfo.h"
+#include "icon.h"
#include "qtcassert.h"
-#include "utilsicons.h"
#include "utilstr.h"
+#include <solutions/spinner/spinner.h>
+
#include <QApplication>
+#include <QFutureWatcher>
#include <QKeyEvent>
#include <QKeySequence>
#include <QMenu>
-#include <QShortcut>
-#include <QStylePainter>
#include <QPropertyAnimation>
+#include <QShortcut>
#include <QStyle>
#include <QStyleOptionFocusRect>
+#include <QStylePainter>
+#include <QTimer>
#include <QValidator>
#include <QWindow>
@@ -45,8 +49,7 @@
\li A history completer.
- \li The ability to validate the contents of the text field by overriding
- virtual \c validate() function in derived clases.
+ \li The ability to validate the contents of the text field by setting the \a validationFunction.
\endlist
When invalid, the text color will turn red and a tooltip will
@@ -99,7 +102,7 @@ public:
bool eventFilter(QObject *obj, QEvent *event) override;
FancyLineEdit *m_lineEdit;
- IconButton *m_iconbutton[2];
+ FancyIconButton *m_iconbutton[2];
HistoryCompleter *m_historyCompleter = nullptr;
QShortcut m_completionShortcut;
FancyLineEdit::ValidationFunction m_validationFunction = &FancyLineEdit::validateWithValidator;
@@ -120,23 +123,35 @@ public:
const QColor m_errorTextColor;
const QColor m_placeholderTextColor;
QString m_errorMessage;
+
+ SpinnerSolution::Spinner *m_spinner = nullptr;
+ QTimer m_spinnerDelayTimer;
+
+ std::unique_ptr<QFutureWatcher<FancyLineEdit::AsyncValidationResult>> m_validatorWatcher;
};
-FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) :
- QObject(parent),
- m_lineEdit(parent),
- m_completionShortcut(completionShortcut()->key(), parent),
- m_okTextColor(creatorTheme()->color(Theme::TextColorNormal)),
- m_errorTextColor(creatorTheme()->color(Theme::TextColorError)),
- m_placeholderTextColor(QApplication::palette().color(QPalette::PlaceholderText))
+FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent)
+ : QObject(parent)
+ , m_lineEdit(parent)
+ , m_completionShortcut(completionShortcut()->key(), parent)
+ , m_okTextColor(creatorTheme()->color(Theme::TextColorNormal))
+ , m_errorTextColor(creatorTheme()->color(Theme::TextColorError))
+ , m_placeholderTextColor(QApplication::palette().color(QPalette::PlaceholderText))
+ , m_spinner(new SpinnerSolution::Spinner(SpinnerSolution::SpinnerSize::Small, m_lineEdit))
+{
+ m_spinner->setVisible(false);
+ m_spinnerDelayTimer.setInterval(200);
+ m_spinnerDelayTimer.setSingleShot(true);
+ connect(&m_spinnerDelayTimer, &QTimer::timeout, m_spinner, [spinner = m_spinner] {
+ spinner->setVisible(true);
+ });
-{
m_completionShortcut.setContext(Qt::WidgetShortcut);
connect(completionShortcut(), &CompletionShortcut::keyChanged,
&m_completionShortcut, &QShortcut::setKey);
for (int i = 0; i < 2; ++i) {
- m_iconbutton[i] = new IconButton(parent);
+ m_iconbutton[i] = new FancyIconButton(parent);
m_iconbutton[i]->installEventFilter(this);
m_iconbutton[i]->hide();
m_iconbutton[i]->setAutoHide(false);
@@ -331,7 +346,7 @@ bool FancyLineEdit::hasAutoHideButton(Side side) const
return d->m_iconbutton[side]->hasAutoHide();
}
-void FancyLineEdit::setHistoryCompleter(const QString &historyKey, bool restoreLastItemFromHistory)
+void FancyLineEdit::setHistoryCompleter(const Key &historyKey, bool restoreLastItemFromHistory)
{
QTC_ASSERT(!d->m_historyCompleter, return);
d->m_historyCompleter = new HistoryCompleter(historyKey, this);
@@ -413,15 +428,13 @@ void FancyLineEdit::setFiltering(bool on)
d->m_isFiltering = on;
if (on) {
d->m_lastFilterText = text();
- // KDE has custom icons for this. Notice that icon namings are counter intuitive.
- // If these icons are not available we use the freedesktop standard name before
- // falling back to a bundled resource.
- QIcon icon = QIcon::fromTheme(layoutDirection() == Qt::LeftToRight ?
- QLatin1String("edit-clear-locationbar-rtl") :
- QLatin1String("edit-clear-locationbar-ltr"),
- QIcon::fromTheme(QLatin1String("edit-clear"),
- Icons::EDIT_CLEAR.icon()));
-
+ // KDE has custom icons for this. The "ltr" and "rtl" suffixes describe the direction
+ // into which the arrows are pointing. They do not describe which writing direction they
+ // are intended to be used for.
+ const QLatin1String pointingWest("edit-clear-locationbar-rtl");
+ const QLatin1String pointingEast("edit-clear-locationbar-ltr");
+ const QIcon icon = Icon::fromTheme(layoutDirection() == Qt::LeftToRight ? pointingWest
+ : pointingEast);
setButtonIcon(Right, icon);
setButtonVisible(Right, true);
setPlaceholderText(Tr::tr("Filter"));
@@ -475,21 +488,20 @@ void FancyLineEdit::setValidatePlaceHolder(bool on)
d->m_validatePlaceHolder = on;
}
-void FancyLineEdit::validate()
+void FancyLineEdit::handleValidationResult(AsyncValidationResult result, const QString &oldText)
{
- const QString t = text();
+ d->m_spinner->setVisible(false);
+ d->m_spinnerDelayTimer.stop();
- if (d->m_isFiltering){
- if (t != d->m_lastFilterText) {
- d->m_lastFilterText = t;
- emit filterChanged(t);
- }
- }
+ const QString newText = result ? *result : oldText;
+ if (!result)
+ d->m_errorMessage = result.error();
+ else
+ d->m_errorMessage.clear();
- d->m_errorMessage.clear();
// Are we displaying the placeholder text?
- const bool isDisplayingPlaceholderText = !placeholderText().isEmpty() && t.isEmpty();
- const bool validates = d->m_validationFunction(this, &d->m_errorMessage);
+ const bool isDisplayingPlaceholderText = !placeholderText().isEmpty() && newText.isEmpty();
+ const bool validates = result.has_value();
const State newState = isDisplayingPlaceholderText ? DisplayingPlaceholderText
: (validates ? Valid : Invalid);
if (!validates || d->m_toolTipSet) {
@@ -504,18 +516,20 @@ void FancyLineEdit::validate()
d->m_firstChange = false;
QPalette p = palette();
- p.setColor(QPalette::Active, QPalette::Text,
- newState == Invalid ? d->m_errorTextColor : d->m_okTextColor);
- p.setColor(QPalette::Active, QPalette::PlaceholderText,
- validates || !d->m_validatePlaceHolder
- ? d->m_placeholderTextColor : d->m_errorTextColor);
+ p.setColor(QPalette::Active,
+ QPalette::Text,
+ newState == Invalid ? d->m_errorTextColor : d->m_okTextColor);
+ p.setColor(QPalette::Active,
+ QPalette::PlaceholderText,
+ validates || !d->m_validatePlaceHolder ? d->m_placeholderTextColor
+ : d->m_errorTextColor);
setPalette(p);
if (validHasChanged)
emit validChanged(newState == Valid);
}
- const QString fixedString = fixInputString(t);
- if (t != fixedString) {
+ const QString fixedString = fixInputString(newText);
+ if (newText != fixedString) {
const int cursorPos = cursorPosition();
QSignalBlocker blocker(this);
setText(fixedString);
@@ -523,15 +537,79 @@ void FancyLineEdit::validate()
}
// Check buttons.
- if (d->m_oldText.isEmpty() || t.isEmpty()) {
+ if (d->m_oldText.isEmpty() || newText.isEmpty()) {
for (auto &button : std::as_const(d->m_iconbutton)) {
if (button->hasAutoHide())
- button->animateShow(!t.isEmpty());
+ button->animateShow(!newText.isEmpty());
+ }
+ d->m_oldText = newText;
+ }
+
+ handleChanged(newText);
+}
+
+void FancyLineEdit::validate()
+{
+ if (d->m_validationFunction.index() == 0) {
+ AsyncValidationFunction &validationFunction = std::get<0>(d->m_validationFunction);
+ if (!validationFunction)
+ return;
+
+ if (d->m_validatorWatcher)
+ d->m_validatorWatcher->cancel();
+
+ const QString oldText = text();
+
+ if (d->m_isFiltering) {
+ if (oldText != d->m_lastFilterText) {
+ d->m_lastFilterText = oldText;
+ emit filterChanged(oldText);
+ }
}
- d->m_oldText = t;
+
+ d->m_validatorWatcher = std::make_unique<QFutureWatcher<AsyncValidationResult>>();
+ connect(d->m_validatorWatcher.get(),
+ &QFutureWatcher<AsyncValidationResult>::finished,
+ this,
+ [this, oldText]() {
+ FancyLineEdit::AsyncValidationResult result = d->m_validatorWatcher->result();
+
+ handleValidationResult(result, oldText);
+ });
+
+ d->m_spinnerDelayTimer.start();
+
+ AsyncValidationFuture future = validationFunction(text());
+ d->m_validatorWatcher->setFuture(future);
+
+ return;
}
- handleChanged(t);
+ if (d->m_validationFunction.index() == 1) {
+ auto &validationFunction = std::get<1>(d->m_validationFunction);
+ if (!validationFunction)
+ return;
+
+ const QString t = text();
+
+ if (d->m_isFiltering) {
+ if (t != d->m_lastFilterText) {
+ d->m_lastFilterText = t;
+ emit filterChanged(t);
+ }
+ }
+
+ QString error;
+ const bool validates = validationFunction(this, &error);
+ expected_str<QString> result;
+
+ if (validates)
+ result = t;
+ else
+ result = make_unexpected(error);
+
+ handleValidationResult(result, t);
+ }
}
QString FancyLineEdit::fixInputString(const QString &string)
@@ -543,14 +621,14 @@ QString FancyLineEdit::fixInputString(const QString &string)
// IconButton - helper class to represent a clickable icon
//
-IconButton::IconButton(QWidget *parent)
- : QAbstractButton(parent), m_autoHide(false)
+FancyIconButton::FancyIconButton(QWidget *parent)
+ : QAbstractButton(parent)
{
setCursor(Qt::ArrowCursor);
setFocusPolicy(Qt::NoFocus);
}
-void IconButton::paintEvent(QPaintEvent *)
+void FancyIconButton::paintEvent(QPaintEvent *)
{
const qreal pixelRatio = window()->windowHandle()->devicePixelRatio();
const QPixmap iconPixmap = icon().pixmap(sizeHint(), pixelRatio,
@@ -577,7 +655,7 @@ void IconButton::paintEvent(QPaintEvent *)
}
}
-void IconButton::animateShow(bool visible)
+void FancyIconButton::animateShow(bool visible)
{
QPropertyAnimation *animation = new QPropertyAnimation(this, "iconOpacity");
animation->setDuration(FADE_TIME);
@@ -585,13 +663,13 @@ void IconButton::animateShow(bool visible)
animation->start(QAbstractAnimation::DeleteWhenStopped);
}
-QSize IconButton::sizeHint() const
+QSize FancyIconButton::sizeHint() const
{
QWindow *window = this->window()->windowHandle();
return icon().actualSize(window, QSize(32, 16)); // Find flags icon can be wider than 16px
}
-void IconButton::keyPressEvent(QKeyEvent *ke)
+void FancyIconButton::keyPressEvent(QKeyEvent *ke)
{
QAbstractButton::keyPressEvent(ke);
if (!ke->modifiers() && (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return))
@@ -600,7 +678,7 @@ void IconButton::keyPressEvent(QKeyEvent *ke)
ke->accept();
}
-void IconButton::keyReleaseEvent(QKeyEvent *ke)
+void FancyIconButton::keyReleaseEvent(QKeyEvent *ke)
{
QAbstractButton::keyReleaseEvent(ke);
// do not forward to line edit
diff --git a/src/libs/utils/fancylineedit.h b/src/libs/utils/fancylineedit.h
index eb54bc8d866..a8bd9501274 100644
--- a/src/libs/utils/fancylineedit.h
+++ b/src/libs/utils/fancylineedit.h
@@ -6,8 +6,11 @@
#include "utils_global.h"
#include "completinglineedit.h"
+#include "expected.h"
+#include "storekey.h"
#include <QAbstractButton>
+#include <QFuture>
#include <functional>
@@ -20,13 +23,13 @@ namespace Utils {
class FancyLineEditPrivate;
-class QTCREATOR_UTILS_EXPORT IconButton: public QAbstractButton
+class QTCREATOR_UTILS_EXPORT FancyIconButton : public QAbstractButton
{
Q_OBJECT
Q_PROPERTY(float iconOpacity READ iconOpacity WRITE setIconOpacity)
Q_PROPERTY(bool autoHide READ hasAutoHide WRITE setAutoHide)
public:
- explicit IconButton(QWidget *parent = nullptr);
+ explicit FancyIconButton(QWidget *parent = nullptr);
void paintEvent(QPaintEvent *event) override;
float iconOpacity() { return m_iconOpacity; }
void setIconOpacity(float value) { m_iconOpacity = value; update(); }
@@ -42,8 +45,8 @@ protected:
void keyReleaseEvent(QKeyEvent *ke) override;
private:
- float m_iconOpacity;
- bool m_autoHide;
+ float m_iconOpacity = 1.0f;
+ bool m_autoHide = false;
QIcon m_icon;
};
@@ -84,7 +87,7 @@ public:
// Completion
// Enable a history completer with a history of entries.
- void setHistoryCompleter(const QString &historyKey, bool restoreLastItemFromHistory = false);
+ void setHistoryCompleter(const Utils::Key &historyKey, bool restoreLastItemFromHistory = false);
// Sets a completer that is not a history completer.
void setSpecialCompleter(QCompleter *completer);
@@ -98,7 +101,12 @@ public:
// Validation
// line edit, (out)errorMessage -> valid?
- using ValidationFunction = std::function<bool(FancyLineEdit *, QString *)>;
+ using AsyncValidationResult = Utils::expected_str<QString>;
+ using AsyncValidationFuture = QFuture<AsyncValidationResult>;
+ using AsyncValidationFunction = std::function<AsyncValidationFuture(QString)>;
+ using SynchronousValidationFunction = std::function<bool(FancyLineEdit *, QString *)>;
+ using ValidationFunction = std::variant<AsyncValidationFunction, SynchronousValidationFunction>;
+
enum State { Invalid, DisplayingPlaceholderText, Valid };
State state() const;
@@ -138,6 +146,8 @@ protected:
private:
void iconClicked(FancyLineEdit::Side);
+ void handleValidationResult(AsyncValidationResult result, const QString &oldText);
+
static bool validateWithValidator(FancyLineEdit *edit, QString *errorMessage);
// Unimplemented, to force the user to make a decision on
// whether to use setHistoryCompleter() or setSpecialCompleter().
diff --git a/src/libs/utils/fancymainwindow.cpp b/src/libs/utils/fancymainwindow.cpp
index 323e2508eba..ad5e4ed9c3a 100644
--- a/src/libs/utils/fancymainwindow.cpp
+++ b/src/libs/utils/fancymainwindow.cpp
@@ -5,6 +5,7 @@
#include "algorithm.h"
#include "qtcassert.h"
+#include "qtcsettings.h"
#include "stringutils.h"
#include "utilstr.h"
@@ -16,7 +17,6 @@
#include <QLabel>
#include <QMenu>
#include <QPainter>
-#include <QSettings>
#include <QStyle>
#include <QStyleOption>
#include <QTimer>
@@ -169,6 +169,11 @@ public:
setLayout(layout);
setProperty("managed_titlebar", 1);
+
+ connect(parent, &QDockWidget::featuresChanged, this, [this, parent] {
+ m_closeButton->setVisible(parent->features().testFlag(QDockWidget::DockWidgetClosable));
+ m_floatButton->setVisible(parent->features().testFlag(QDockWidget::DockWidgetFloatable));
+ });
}
void enterEvent(QEnterEvent *event) override
@@ -187,8 +192,11 @@ public:
{
bool clickable = isClickable();
m_titleLabel->setVisible(clickable);
- m_floatButton->setVisible(clickable);
- m_closeButton->setVisible(clickable);
+
+ m_floatButton->setVisible(clickable
+ && q->features().testFlag(QDockWidget::DockWidgetFloatable));
+ m_closeButton->setVisible(clickable
+ && q->features().testFlag(QDockWidget::DockWidgetClosable));
}
bool isClickable() const
@@ -349,7 +357,8 @@ FancyMainWindowPrivate::FancyMainWindowPrivate(FancyMainWindow *parent) :
});
QObject::connect(&m_showCentralWidget, &QAction::toggled, q, [this](bool visible) {
- q->centralWidget()->setVisible(visible);
+ if (q->centralWidget())
+ q->centralWidget()->setVisible(visible);
});
}
@@ -434,53 +443,70 @@ void FancyMainWindow::handleVisibilityChanged(bool visible)
d->m_handleDockVisibilityChanges = true;
}
-void FancyMainWindow::saveSettings(QSettings *settings) const
+void FancyMainWindow::saveSettings(QtcSettings *settings) const
{
- const QHash<QString, QVariant> hash = saveSettings();
+ const QHash<Key, QVariant> hash = saveSettings();
for (auto it = hash.cbegin(), end = hash.cend(); it != end; ++it)
settings->setValue(it.key(), it.value());
}
-void FancyMainWindow::restoreSettings(const QSettings *settings)
+void FancyMainWindow::restoreSettings(const QtcSettings *settings)
{
- QHash<QString, QVariant> hash;
- const QStringList childKeys = settings->childKeys();
- for (const QString &key : childKeys)
+ QHash<Key, QVariant> hash;
+ const KeyList childKeys = settings->childKeys();
+ for (const Key &key : childKeys)
hash.insert(key, settings->value(key));
restoreSettings(hash);
}
-QHash<QString, QVariant> FancyMainWindow::saveSettings() const
+QHash<Key, QVariant> FancyMainWindow::saveSettings() const
{
- QHash<QString, QVariant> settings;
- settings.insert(QLatin1String(StateKey), saveState(settingsVersion));
- settings.insert(QLatin1String(AutoHideTitleBarsKey),
- d->m_autoHideTitleBars.isChecked());
+ QHash<Key, QVariant> settings;
+ settings.insert(StateKey, saveState(settingsVersion));
+ settings.insert(AutoHideTitleBarsKey, d->m_autoHideTitleBars.isChecked());
settings.insert(ShowCentralWidgetKey, d->m_showCentralWidget.isChecked());
for (QDockWidget *dockWidget : dockWidgets()) {
- settings.insert(dockWidget->objectName(),
+ settings.insert(keyFromString(dockWidget->objectName()),
dockWidget->property(dockWidgetActiveState));
}
return settings;
}
-void FancyMainWindow::restoreSettings(const QHash<QString, QVariant> &settings)
+void FancyMainWindow::restoreSettings(const QHash<Key, QVariant> &settings)
{
- QByteArray ba = settings.value(QLatin1String(StateKey), QByteArray()).toByteArray();
- if (!ba.isEmpty())
- restoreState(ba, settingsVersion);
- bool on = settings.value(QLatin1String(AutoHideTitleBarsKey), true).toBool();
+ QByteArray ba = settings.value(StateKey, QByteArray()).toByteArray();
+ if (!ba.isEmpty()) {
+ if (!restoreState(ba, settingsVersion))
+ qWarning() << "Restoring the state of dock widgets failed.";
+ }
+ bool on = settings.value(AutoHideTitleBarsKey, true).toBool();
d->m_autoHideTitleBars.setChecked(on);
d->m_showCentralWidget.setChecked(settings.value(ShowCentralWidgetKey, true).toBool());
for (QDockWidget *widget : dockWidgets()) {
widget->setProperty(dockWidgetActiveState,
- settings.value(widget->objectName(), false));
+ settings.value(keyFromString(widget->objectName()), false));
+ }
+}
+
+static void findDockChildren(QWidget *parent, QList<QDockWidget *> &result)
+{
+ for (QObject *child : parent->children()) {
+ QWidget *childWidget = qobject_cast<QWidget *>(child);
+ if (!childWidget)
+ continue;
+
+ if (auto dockWidget = qobject_cast<QDockWidget *>(child))
+ result.append(dockWidget);
+ else if (!qobject_cast<QMainWindow *>(child))
+ findDockChildren(qobject_cast<QWidget *>(child), result);
}
}
const QList<QDockWidget *> FancyMainWindow::dockWidgets() const
{
- return findChildren<QDockWidget *>();
+ QList<QDockWidget *> result;
+ findDockChildren((QWidget *) this, result);
+ return result;
}
bool FancyMainWindow::autoHideTitleBars() const
diff --git a/src/libs/utils/fancymainwindow.h b/src/libs/utils/fancymainwindow.h
index 19618bb41c4..40066de95f6 100644
--- a/src/libs/utils/fancymainwindow.h
+++ b/src/libs/utils/fancymainwindow.h
@@ -5,15 +5,14 @@
#include "utils_global.h"
-#include <QMainWindow>
+#include "storekey.h"
-QT_BEGIN_NAMESPACE
-class QSettings;
-QT_END_NAMESPACE
+#include <QMainWindow>
namespace Utils {
struct FancyMainWindowPrivate;
+class QtcSettings;
class QTCREATOR_UTILS_EXPORT FancyMainWindow : public QMainWindow
{
@@ -30,10 +29,10 @@ public:
void setTrackingEnabled(bool enabled);
- void saveSettings(QSettings *settings) const;
- void restoreSettings(const QSettings *settings);
- QHash<QString, QVariant> saveSettings() const;
- void restoreSettings(const QHash<QString, QVariant> &settings);
+ void saveSettings(QtcSettings *settings) const;
+ void restoreSettings(const QtcSettings *settings);
+ QHash<Key, QVariant> saveSettings() const;
+ void restoreSettings(const QHash<Key, QVariant> &settings);
// Additional context menu actions
QAction *menuSeparator1() const;
diff --git a/src/libs/utils/fileinprojectfinder.cpp b/src/libs/utils/fileinprojectfinder.cpp
index 957f694179b..29e0f6d7c2c 100644
--- a/src/libs/utils/fileinprojectfinder.cpp
+++ b/src/libs/utils/fileinprojectfinder.cpp
@@ -477,7 +477,7 @@ FilePath chooseFileFromList(const FilePaths &candidates)
filesMenu.addAction(candidate.toUserOutput());
if (const QAction * const action = filesMenu.exec(QCursor::pos()))
return FilePath::fromUserInput(action->text());
- return FilePath();
+ return {};
}
} // namespace Utils
diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp
index 3995ddde3a7..8b898344278 100644
--- a/src/libs/utils/filepath.cpp
+++ b/src/libs/utils/filepath.cpp
@@ -225,7 +225,7 @@ bool FilePath::isRootPath() const
return true;
}
- return *this == FilePath::fromString(QDir::rootPath());
+ return *this == HostOsInfo::root();
}
QString FilePath::encodedHost() const
@@ -476,37 +476,13 @@ void FilePath::setParts(const QStringView scheme, const QStringView host, QStrin
}
/*!
- Returns a bool indicating whether a file or directory with this FilePath exists.
-*/
-bool FilePath::exists() const
-{
- return fileAccess()->exists(*this);
-}
-
-/*!
- Returns a bool indicating whether this is a writable directory.
-*/
-bool FilePath::isWritableDir() const
-{
- return fileAccess()->isWritableDirectory(*this);
-}
-
-/*!
- Returns a bool indicating whether this is a writable file.
-*/
-bool FilePath::isWritableFile() const
-{
- return fileAccess()->isWritableFile(*this);
-}
-
-/*!
\brief Re-uses or creates a directory in this location.
Returns true if the directory is writable afterwards.
\sa createDir()
*/
-bool FilePath::ensureWritableDir() const
+expected_str<void> FilePath::ensureWritableDir() const
{
return fileAccess()->ensureWritableDirectory(*this);
}
@@ -517,14 +493,6 @@ bool FilePath::ensureExistingFile() const
}
/*!
- Returns a bool indicating whether this is an executable file.
-*/
-bool FilePath::isExecutableFile() const
-{
- return fileAccess()->isExecutableFile(*this);
-}
-
-/*!
Returns a bool indicating on whether a process with this FilePath's
native path is likely to start.
@@ -540,13 +508,16 @@ std::optional<FilePath> FilePath::refersToExecutableFile(MatchScope matchScope)
expected_str<FilePath> FilePath::tmpDir() const
{
if (needsDevice()) {
- const Environment env = deviceEnvironment();
- if (env.hasKey("TMPDIR"))
- return withNewPath(env.value("TMPDIR")).cleanPath();
- if (env.hasKey("TEMP"))
- return withNewPath(env.value("TEMP")).cleanPath();
- if (env.hasKey("TMP"))
- return withNewPath(env.value("TMP")).cleanPath();
+ const expected_str<Environment> env = deviceEnvironmentWithError();
+ if (!env)
+ return make_unexpected(env.error());
+
+ if (env->hasKey("TMPDIR"))
+ return withNewPath(env->value("TMPDIR")).cleanPath();
+ if (env->hasKey("TEMP"))
+ return withNewPath(env->value("TEMP")).cleanPath();
+ if (env->hasKey("TMP"))
+ return withNewPath(env->value("TMP")).cleanPath();
if (osType() != OsTypeWindows)
return withNewPath("/tmp");
@@ -571,31 +542,6 @@ expected_str<FilePath> FilePath::createTempFile() const
return fileAccess()->createTempFile(*this);
}
-bool FilePath::isReadableFile() const
-{
- return fileAccess()->isReadableFile(*this);
-}
-
-bool FilePath::isReadableDir() const
-{
- return fileAccess()->isReadableDirectory(*this);
-}
-
-bool FilePath::isFile() const
-{
- return fileAccess()->isFile(*this);
-}
-
-bool FilePath::isDir() const
-{
- return fileAccess()->isDirectory(*this);
-}
-
-bool FilePath::isSymLink() const
-{
- return fileAccess()->isSymLink(*this);
-}
-
bool FilePath::hasHardLinks() const
{
return fileAccess()->hasHardLinks(*this);
@@ -682,11 +628,6 @@ expected_str<qint64> FilePath::writeFileContents(const QByteArray &data, qint64
return fileAccess()->writeFileContents(*this, data, offset);
}
-FilePathInfo FilePath::filePathInfo() const
-{
- return fileAccess()->filePathInfo(*this);
-}
-
FileStreamHandle FilePath::asyncCopy(const FilePath &target, QObject *context,
const CopyContinuation &cont) const
{
@@ -806,6 +747,11 @@ FilePath FilePath::withExecutableSuffix() const
return withNewPath(OsSpecificAspects::withExecutableSuffix(osType(), path()));
}
+FilePath FilePath::withSuffix(const QString &suffix) const
+{
+ return withNewPath(path() + suffix);
+}
+
static bool startsWithWindowsDriveLetterAndSlash(QStringView path)
{
return path.size() > 2 && path[1] == ':' && path[2] == '/' && isWindowsDriveLetter(path[0]);
@@ -1005,12 +951,12 @@ FilePath FilePath::parentDir() const
{
const QString basePath = path();
if (basePath.isEmpty())
- return FilePath();
+ return {};
const QString path = basePath + QLatin1String("/..");
const QString parent = doCleanPath(path);
if (parent == path)
- return FilePath();
+ return {};
return withNewPath(parent);
}
@@ -1043,7 +989,7 @@ const QString &FilePath::specialRootName()
const QString &FilePath::specialRootPath()
{
- static const QString rootPath = QDir::rootPath() + u"__qtc_devices__";
+ static const QString rootPath = HostOsInfo::root().path() + u"__qtc_devices__";
return rootPath;
}
@@ -1055,7 +1001,7 @@ const QString &FilePath::specialDeviceRootName()
const QString &FilePath::specialDeviceRootPath()
{
- static const QString deviceRootPath = QDir::rootPath() + u"__qtc_devices__/device";
+ static const QString deviceRootPath = HostOsInfo::root().path() + u"__qtc_devices__/device";
return deviceRootPath;
}
@@ -1228,13 +1174,115 @@ DeviceFileAccess *FilePath::fileAccess() const
static DeviceFileAccess dummy;
const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
QTC_ASSERT_EXPECTED(access, return &dummy);
- return *access ? *access : &dummy;
+ return *access;
}
bool FilePath::hasFileAccess() const
{
const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
- return access && access.value();
+ return access.has_value();
+}
+
+FilePathInfo FilePath::filePathInfo() const
+{
+ const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
+ if (!access)
+ return {};
+ return (*access)->filePathInfo(*this);
+}
+
+/*!
+ Returns a bool indicating whether a file or directory with this FilePath exists.
+*/
+bool FilePath::exists() const
+{
+ const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
+ if (!access)
+ return false;
+
+ return (*access)->exists(*this);
+}
+
+/*!
+ Returns a bool indicating whether this is an executable file.
+*/
+bool FilePath::isExecutableFile() const
+{
+ const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
+ if (!access)
+ return false;
+
+ return (*access)->isExecutableFile(*this);
+}
+
+/*!
+ Returns a bool indicating whether this is a writable directory.
+*/
+bool FilePath::isWritableDir() const
+{
+ const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
+ if (!access)
+ return false;
+
+ return (*access)->isWritableDirectory(*this);
+}
+
+/*!
+ Returns a bool indicating whether this is a writable file.
+*/
+bool FilePath::isWritableFile() const
+{
+ const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
+ if (!access)
+ return false;
+
+ return (*access)->isWritableFile(*this);
+}
+
+
+bool FilePath::isReadableFile() const
+{
+ const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
+ if (!access)
+ return false;
+
+ return (*access)->isReadableFile(*this);
+}
+
+bool FilePath::isReadableDir() const
+{
+ const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
+ if (!access)
+ return false;
+
+ return (*access)->isReadableDirectory(*this);
+}
+
+bool FilePath::isFile() const
+{
+ const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
+ if (!access)
+ return false;
+
+ return (*access)->isFile(*this);
+}
+
+bool FilePath::isDir() const
+{
+ const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
+ if (!access)
+ return false;
+
+ return (*access)->isDirectory(*this);
+}
+
+bool FilePath::isSymLink() const
+{
+ const expected_str<DeviceFileAccess *> access = getFileAccess(*this);
+ if (!access)
+ return false;
+
+ return (*access)->isSymLink(*this);
}
/*!
@@ -1512,11 +1560,6 @@ QString FilePath::calcRelativePath(const QString &absolutePath, const QString &a
*/
FilePath FilePath::withNewMappedPath(const FilePath &newPath) const
{
- const bool sameDevice = newPath.scheme() == scheme() && newPath.host() == host();
- if (sameDevice)
- return newPath;
- // TODO: converting paths between different non local devices is still unsupported
- QTC_CHECK(!newPath.needsDevice() || !needsDevice());
FilePath res;
res.setParts(scheme(), host(), fileAccess()->mapToDevicePath(newPath.path()));
return res;
@@ -1671,6 +1714,13 @@ FilePaths FilePath::searchAllInPath(const FilePaths &additionalDirs,
Environment FilePath::deviceEnvironment() const
{
+ expected_str<Environment> env = deviceEnvironmentWithError();
+ QTC_ASSERT_EXPECTED(env, return {});
+ return *env;
+}
+
+expected_str<Environment> FilePath::deviceEnvironmentWithError() const
+{
if (needsDevice()) {
QTC_ASSERT(s_deviceHooks.environment, return {});
return s_deviceHooks.environment(*this);
@@ -1751,6 +1801,13 @@ FilePath FilePath::stringAppended(const QString &str) const
return FilePath::fromString(toString() + str);
}
+std::optional<FilePath> FilePath::tailRemoved(const QString &str) const
+{
+ if (pathView().endsWith(str))
+ return withNewPath(pathView().chopped(str.size()).toString());
+ return {};
+}
+
QDateTime FilePath::lastModified() const
{
return fileAccess()->lastModified(*this);
@@ -2124,6 +2181,7 @@ FileFilter::FileFilter(const QStringList &nameFilters,
fileFilters(fileFilters),
iteratorFlags(flags)
{
+ QTC_CHECK(this->fileFilters != QDir::Filters());
}
QStringList FileFilter::asFindArguments(const QString &path) const
diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h
index f313ba5ff92..a35a3a09403 100644
--- a/src/libs/utils/filepath.h
+++ b/src/libs/utils/filepath.h
@@ -97,6 +97,7 @@ public:
[[nodiscard]] FilePath pathAppended(const QString &str) const;
[[nodiscard]] FilePath stringAppended(const QString &str) const;
+ [[nodiscard]] std::optional<FilePath> tailRemoved(const QString &str) const;
bool startsWith(const QString &s) const;
bool endsWith(const QString &s) const;
bool contains(const QString &s) const;
@@ -108,7 +109,7 @@ public:
bool isWritableDir() const;
bool isWritableFile() const;
- bool ensureWritableDir() const;
+ expected_str<void> ensureWritableDir() const;
bool ensureExistingFile() const;
bool isExecutableFile() const;
bool isReadableFile() const;
@@ -159,9 +160,11 @@ public:
[[nodiscard]] FilePath symLinkTarget() const;
[[nodiscard]] FilePath resolveSymlinks() const;
[[nodiscard]] FilePath withExecutableSuffix() const;
+ [[nodiscard]] FilePath withSuffix(const QString &suffix) const;
[[nodiscard]] FilePath relativeChildPath(const FilePath &parent) const;
[[nodiscard]] FilePath relativePathFrom(const FilePath &anchor) const;
[[nodiscard]] Environment deviceEnvironment() const;
+ [[nodiscard]] expected_str<Environment> deviceEnvironmentWithError() const;
[[nodiscard]] FilePaths devicePathEnvironmentVariable() const;
[[nodiscard]] FilePath withNewPath(const QString &newPath) const;
[[nodiscard]] FilePath withNewMappedPath(const FilePath &newPath) const;
@@ -299,7 +302,7 @@ public:
std::function<expected_str<DeviceFileAccess *>(const FilePath &)> fileAccess;
std::function<QString(const FilePath &)> deviceDisplayName;
std::function<bool(const FilePath &, const FilePath &)> ensureReachable;
- std::function<Environment(const FilePath &)> environment;
+ std::function<expected_str<Environment>(const FilePath &)> environment;
std::function<bool(const FilePath &left, const FilePath &right)> isSameDevice;
std::function<expected_str<FilePath>(const FilePath &)> localSource;
std::function<void(const FilePath &, const Environment &)> openTerminal;
diff --git a/src/libs/utils/filesearch.cpp b/src/libs/utils/filesearch.cpp
index a72ddc6ab04..f97934cde40 100644
--- a/src/libs/utils/filesearch.cpp
+++ b/src/libs/utils/filesearch.cpp
@@ -4,135 +4,57 @@
#include "filesearch.h"
#include "algorithm.h"
-#include "filepath.h"
-#include "mapreduce.h"
+#include "async.h"
#include "qtcassert.h"
-#include "searchresultitem.h"
#include "stringutils.h"
#include "utilstr.h"
#include <QLoggingCategory>
-#include <QMutex>
#include <QRegularExpression>
+#include <QScopeGuard>
#include <QTextCodec>
-#include <cctype>
-
Q_LOGGING_CATEGORY(searchLog, "qtc.utils.filesearch", QtWarningMsg)
-using namespace Utils;
-
-static inline QString msgCanceled(const QString &searchTerm, int numMatches, int numFilesSearched)
-{
- return Tr::tr("%1: canceled. %n occurrences found in %2 files.",
- nullptr, numMatches).arg(searchTerm).arg(numFilesSearched);
-}
-
-static inline QString msgFound(const QString &searchTerm, int numMatches, int numFilesSearched)
-{
- return Tr::tr("%1: %n occurrences found in %2 files.",
- nullptr, numMatches).arg(searchTerm).arg(numFilesSearched);
-}
-
-namespace {
+namespace Utils {
const int MAX_LINE_SIZE = 400;
-QString clippedText(const QString &text, int maxLength)
+static QString clippedText(const QString &text, int maxLength)
{
if (text.length() > maxLength)
return text.left(maxLength) + QChar(0x2026); // '...'
return text;
}
-// returns success
-static bool getFileContent(const FilePath &filePath,
- QTextCodec *encoding,
- QString *tempString,
- const QMap<FilePath, QString> &fileToContentsMap)
+QTextDocument::FindFlags textDocumentFlagsForFindFlags(FindFlags flags)
{
- if (fileToContentsMap.contains(filePath)) {
- *tempString = fileToContentsMap.value(filePath);
- } else {
- const expected_str<QByteArray> content = filePath.fileContents();
- if (!content)
- return false;
- *tempString = QTC_GUARD(encoding) ? encoding->toUnicode(*content)
- : QTextCodec::codecForLocale()->toUnicode(*content);
- }
- return true;
+ QTextDocument::FindFlags textDocFlags;
+ if (flags & FindBackward)
+ textDocFlags |= QTextDocument::FindBackward;
+ if (flags & FindCaseSensitively)
+ textDocFlags |= QTextDocument::FindCaseSensitively;
+ if (flags & FindWholeWords)
+ textDocFlags |= QTextDocument::FindWholeWords;
+ return textDocFlags;
}
-class FileSearch
-{
-public:
- FileSearch(const QString &searchTerm,
- QTextDocument::FindFlags flags,
- const QMap<FilePath, QString> &fileToContentsMap);
- void operator()(QFutureInterface<SearchResultItems> &futureInterface,
- const FileIterator::Item &item) const;
-
-private:
- QMap<FilePath, QString> fileToContentsMap;
- QString searchTermLower;
- QString searchTermUpper;
- int termMaxIndex;
- const QChar *termData;
- const QChar *termDataLower;
- const QChar *termDataUpper;
- bool caseSensitive;
- bool wholeWord;
-};
-
-class FileSearchRegExp
+static SearchResultItems searchWithoutRegExp(const QFuture<void> &future, const QString &searchTerm,
+ FindFlags flags, const FilePath &filePath,
+ const QString &contents)
{
-public:
- FileSearchRegExp(const QString &searchTerm,
- QTextDocument::FindFlags flags,
- const QMap<FilePath, QString> &fileToContentsMap);
- FileSearchRegExp(const FileSearchRegExp &other);
- void operator()(QFutureInterface<SearchResultItems> &futureInterface,
- const FileIterator::Item &item) const;
+ const bool caseSensitive = (flags & QTextDocument::FindCaseSensitively);
+ const bool wholeWord = (flags & QTextDocument::FindWholeWords);
+ const QString searchTermLower = searchTerm.toLower();
+ const QString searchTermUpper = searchTerm.toUpper();
+ const int termMaxIndex = searchTerm.length() - 1;
+ const QChar *termData = searchTerm.constData();
+ const QChar *termDataLower = searchTermLower.constData();
+ const QChar *termDataUpper = searchTermUpper.constData();
-private:
- QRegularExpressionMatch doGuardedMatch(const QString &line, int offset) const;
-
- QMap<FilePath, QString> fileToContentsMap;
- QRegularExpression expression;
- mutable QMutex mutex;
-};
-
-FileSearch::FileSearch(const QString &searchTerm,
- QTextDocument::FindFlags flags,
- const QMap<FilePath, QString> &fileToContentsMap)
-{
- this->fileToContentsMap = fileToContentsMap;
- caseSensitive = (flags & QTextDocument::FindCaseSensitively);
- wholeWord = (flags & QTextDocument::FindWholeWords);
- searchTermLower = searchTerm.toLower();
- searchTermUpper = searchTerm.toUpper();
- termMaxIndex = searchTerm.length() - 1;
- termData = searchTerm.constData();
- termDataLower = searchTermLower.constData();
- termDataUpper = searchTermUpper.constData();
-}
-
-void FileSearch::operator()(QFutureInterface<SearchResultItems> &futureInterface,
- const FileIterator::Item &item) const
-{
- if (futureInterface.isCanceled())
- return;
- qCDebug(searchLog) << "Searching in" << item.filePath;
- futureInterface.setProgressRange(0, 1);
- futureInterface.setProgressValue(0);
SearchResultItems results;
- QString tempString;
- if (!getFileContent(item.filePath, item.encoding, &tempString, fileToContentsMap)) {
- qCDebug(searchLog) << "- failed to get content for" << item.filePath;
- futureInterface.cancel(); // failure
- return;
- }
- QTextStream stream(&tempString);
+ QString copy = contents;
+ QTextStream stream(&copy);
int lineNr = 0;
while (!stream.atEnd()) {
@@ -144,30 +66,30 @@ void FileSearch::operator()(QFutureInterface<SearchResultItems> &futureInterface
for (const QChar *regionPtr = chunkPtr; regionPtr + termMaxIndex <= chunkEnd; ++regionPtr) {
const QChar *regionEnd = regionPtr + termMaxIndex;
if ( /* optimization check for start and end of region */
- // case sensitive
- (caseSensitive && *regionPtr == termData[0]
- && *regionEnd == termData[termMaxIndex])
- ||
- // case insensitive
- (!caseSensitive && (*regionPtr == termDataLower[0]
- || *regionPtr == termDataUpper[0])
- && (*regionEnd == termDataLower[termMaxIndex]
- || *regionEnd == termDataUpper[termMaxIndex]))
- ) {
+ // case sensitive
+ (caseSensitive && *regionPtr == termData[0]
+ && *regionEnd == termData[termMaxIndex])
+ ||
+ // case insensitive
+ (!caseSensitive && (*regionPtr == termDataLower[0]
+ || *regionPtr == termDataUpper[0])
+ && (*regionEnd == termDataLower[termMaxIndex]
+ || *regionEnd == termDataUpper[termMaxIndex]))
+ ) {
bool equal = true;
// whole word check
const QChar *beforeRegion = regionPtr - 1;
const QChar *afterRegion = regionEnd + 1;
if (wholeWord
- && (((beforeRegion >= chunkPtr)
- && (beforeRegion->isLetterOrNumber()
- || ((*beforeRegion) == QLatin1Char('_'))))
- ||
- ((afterRegion <= chunkEnd)
- && (afterRegion->isLetterOrNumber()
- || ((*afterRegion) == QLatin1Char('_'))))
- )) {
+ && (((beforeRegion >= chunkPtr)
+ && (beforeRegion->isLetterOrNumber()
+ || ((*beforeRegion) == QLatin1Char('_'))))
+ ||
+ ((afterRegion <= chunkEnd)
+ && (afterRegion->isLetterOrNumber()
+ || ((*afterRegion) == QLatin1Char('_'))))
+ )) {
equal = false;
} else {
// check all chars
@@ -176,14 +98,14 @@ void FileSearch::operator()(QFutureInterface<SearchResultItems> &futureInterface
regionCursor < regionEnd;
++regionCursor, ++regionIndex) {
if ( // case sensitive
- (caseSensitive
- && *regionCursor != termData[regionIndex])
- ||
- // case insensitive
- (!caseSensitive
- && *regionCursor != termDataLower[regionIndex]
- && *regionCursor != termDataUpper[regionIndex])
- ) {
+ (caseSensitive
+ && *regionCursor != termData[regionIndex])
+ ||
+ // case insensitive
+ (!caseSensitive
+ && *regionCursor != termDataLower[regionIndex]
+ && *regionCursor != termDataUpper[regionIndex])
+ ) {
equal = false;
break;
}
@@ -191,7 +113,7 @@ void FileSearch::operator()(QFutureInterface<SearchResultItems> &futureInterface
}
if (equal) {
SearchResultItem result;
- result.setFilePath(item.filePath);
+ result.setFilePath(filePath);
result.setMainRange(lineNr, regionPtr - chunkPtr, termMaxIndex + 1);
result.setDisplayText(clippedText(chunk, MAX_LINE_SIZE));
result.setUserData(QStringList());
@@ -201,77 +123,45 @@ void FileSearch::operator()(QFutureInterface<SearchResultItems> &futureInterface
}
}
}
- if (futureInterface.isPaused())
- futureInterface.waitForResume();
- if (futureInterface.isCanceled())
- break;
- }
- if (!futureInterface.isCanceled()) {
- futureInterface.reportResult(results);
- futureInterface.setProgressValue(1);
+ if (future.isCanceled())
+ return {};
}
- qCDebug(searchLog) << "- finished searching in" << item.filePath;
-}
-
-FileSearchRegExp::FileSearchRegExp(const QString &searchTerm,
- QTextDocument::FindFlags flags,
- const QMap<FilePath, QString> &fileToContentsMap)
-{
- this->fileToContentsMap = fileToContentsMap;
- QString term = searchTerm;
- if (flags & QTextDocument::FindWholeWords)
- term = QString::fromLatin1("\\b%1\\b").arg(term);
- const QRegularExpression::PatternOptions patternOptions = (flags & QTextDocument::FindCaseSensitively)
- ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption;
- expression = QRegularExpression(term, patternOptions);
-}
-
-FileSearchRegExp::FileSearchRegExp(const FileSearchRegExp &other)
- : fileToContentsMap(other.fileToContentsMap),
- expression(other.expression)
-{
+ if (future.isCanceled())
+ return {};
+ return results;
}
-QRegularExpressionMatch FileSearchRegExp::doGuardedMatch(const QString &line, int offset) const
-{
- QMutexLocker lock(&mutex);
- return expression.match(line, offset);
-}
-
-void FileSearchRegExp::operator()(QFutureInterface<SearchResultItems> &futureInterface,
- const FileIterator::Item &item) const
+static SearchResultItems searchWithRegExp(const QFuture<void> &future, const QString &searchTerm,
+ FindFlags flags, const FilePath &filePath,
+ const QString &contents)
{
+ const QString term = flags & QTextDocument::FindWholeWords
+ ? QString::fromLatin1("\\b%1\\b").arg(searchTerm) : searchTerm;
+ const QRegularExpression::PatternOptions patternOptions = (flags & FindCaseSensitively)
+ ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption;
+ const QRegularExpression expression = QRegularExpression(term, patternOptions);
if (!expression.isValid()) {
- futureInterface.cancel();
- return;
+ QFuture<void> nonConstFuture = future;
+ nonConstFuture.cancel();
+ return {};
}
- if (futureInterface.isCanceled())
- return;
- qCDebug(searchLog) << "Searching in" << item.filePath;
- futureInterface.setProgressRange(0, 1);
- futureInterface.setProgressValue(0);
+
SearchResultItems results;
- QString tempString;
- if (!getFileContent(item.filePath, item.encoding, &tempString, fileToContentsMap)) {
- qCDebug(searchLog) << "- failed to get content for" << item.filePath;
- futureInterface.cancel(); // failure
- return;
- }
- QTextStream stream(&tempString);
+ QString copy = contents;
+ QTextStream stream(&copy);
int lineNr = 0;
- QString line;
QRegularExpressionMatch match;
while (!stream.atEnd()) {
++lineNr;
- line = stream.readLine();
+ const QString line = stream.readLine();
const QString resultItemText = clippedText(line, MAX_LINE_SIZE);
int lengthOfLine = line.size();
int pos = 0;
- while ((match = doGuardedMatch(line, pos)).hasMatch()) {
+ while ((match = expression.match(line, pos)).hasMatch()) {
pos = match.capturedStart();
SearchResultItem result;
- result.setFilePath(item.filePath);
+ result.setFilePath(filePath);
result.setMainRange(lineNr, pos, match.capturedLength());
result.setDisplayText(resultItemText);
result.setUserData(match.capturedTexts());
@@ -283,110 +173,187 @@ void FileSearchRegExp::operator()(QFutureInterface<SearchResultItems> &futureInt
if (pos >= lengthOfLine)
break;
}
- if (futureInterface.isPaused())
- futureInterface.waitForResume();
- if (futureInterface.isCanceled())
- break;
+ if (future.isCanceled())
+ return {};
}
- if (!futureInterface.isCanceled()) {
- futureInterface.reportResult(results);
- futureInterface.setProgressValue(1);
- }
- qCDebug(searchLog) << "- finished searching in" << item.filePath;
+ if (future.isCanceled())
+ return {};
+ return results;
}
-struct SearchState
+static SearchResultItems searchInContents(const QFuture<void> &future, const QString &searchTerm,
+ FindFlags flags, const FilePath &filePath,
+ const QString &contents)
{
- SearchState(const QString &term, FileIterator *iterator) : searchTerm(term), files(iterator) {}
- QString searchTerm;
- FileIterator *files = nullptr;
- SearchResultItems cachedResults;
- int numFilesSearched = 0;
- int numMatches = 0;
-};
+ if (flags & FindRegularExpression)
+ return searchWithRegExp(future, searchTerm, flags, filePath, contents);
+ return searchWithoutRegExp(future, searchTerm, flags, filePath, contents);
+}
-SearchState initFileSearch(QFutureInterface<SearchResultItems> &futureInterface,
- const QString &searchTerm, FileIterator *files)
+void searchInContents(QPromise<SearchResultItems> &promise, const QString &searchTerm,
+ FindFlags flags, const FilePath &filePath, const QString &contents)
{
- futureInterface.setProgressRange(0, files->maxProgress());
- futureInterface.setProgressValueAndText(files->currentProgress(), msgFound(searchTerm, 0, 0));
- return SearchState(searchTerm, files);
+ const QFuture<void> future(promise.future());
+ const SearchResultItems results = searchInContents(future, searchTerm, flags, filePath,
+ contents);
+ if (!promise.isCanceled())
+ promise.addResult(results);
}
-void collectSearchResults(QFutureInterface<SearchResultItems> &futureInterface,
- SearchState &state,
- const SearchResultItems &results)
+static inline QString msgCanceled(const QString &searchTerm, int numMatches, int numFilesSearched)
{
- state.numMatches += results.size();
- state.cachedResults << results;
- state.numFilesSearched += 1;
- if (futureInterface.isProgressUpdateNeeded()
- || futureInterface.progressValue() == 0 /*workaround for regression in Qt*/) {
- if (!state.cachedResults.isEmpty()) {
- futureInterface.reportResult(state.cachedResults);
- state.cachedResults.clear();
- }
- futureInterface.setProgressRange(0, state.files->maxProgress());
- futureInterface.setProgressValueAndText(state.files->currentProgress(),
- msgFound(state.searchTerm,
- state.numMatches,
- state.numFilesSearched));
+ return Tr::tr("%1: canceled. %n occurrences found in %2 files.",
+ nullptr, numMatches).arg(searchTerm).arg(numFilesSearched);
+}
+
+static inline QString msgFound(const QString &searchTerm, int numMatches, int numFilesSearched)
+{
+ return Tr::tr("%1: %n occurrences found in %2 files.",
+ nullptr, numMatches).arg(searchTerm).arg(numFilesSearched);
+}
+
+static bool getFileContent(const FilePath &filePath, QTextCodec *encoding,
+ QString *tempString, const QMap<FilePath, QString> &fileToContentsMap)
+{
+ if (fileToContentsMap.contains(filePath)) {
+ *tempString = fileToContentsMap.value(filePath);
+ } else {
+ const expected_str<QByteArray> content = filePath.fileContents();
+ if (!content)
+ return false;
+ *tempString = QTC_GUARD(encoding) ? encoding->toUnicode(*content)
+ : QTextCodec::codecForLocale()->toUnicode(*content);
}
+ return true;
}
-void cleanUpFileSearch(QFutureInterface<SearchResultItems> &futureInterface,
- SearchState &state)
+static void fileSearch(QPromise<SearchResultItems> &promise,
+ const FileContainerIterator::Item &item, const QString &searchTerm,
+ FindFlags flags, const QMap<FilePath, QString> &fileToContentsMap)
{
- if (!state.cachedResults.isEmpty()) {
- futureInterface.reportResult(state.cachedResults);
- state.cachedResults.clear();
+ if (promise.isCanceled())
+ return;
+ qCDebug(searchLog) << "Searching in" << item.filePath;
+ promise.setProgressRange(0, 1);
+ promise.setProgressValue(0);
+ QString contents;
+ if (!getFileContent(item.filePath, item.encoding, &contents, fileToContentsMap)) {
+ qCDebug(searchLog) << "- failed to get content for" << item.filePath;
+ promise.future().cancel(); // failure
+ return;
}
- if (futureInterface.isCanceled()) {
- futureInterface.setProgressValueAndText(state.files->currentProgress(),
- msgCanceled(state.searchTerm,
- state.numMatches,
- state.numFilesSearched));
- } else {
- futureInterface.setProgressValueAndText(state.files->currentProgress(),
- msgFound(state.searchTerm,
- state.numMatches,
- state.numFilesSearched));
+
+ const QFuture<void> future(promise.future());
+ const SearchResultItems results = searchInContents(future, searchTerm, flags, item.filePath,
+ contents);
+ if (!promise.isCanceled()) {
+ promise.addResult(results);
+ promise.setProgressValue(1);
}
- delete state.files;
+ qCDebug(searchLog) << "- finished searching in" << item.filePath;
}
-} // namespace
+static void findInFilesImpl(QPromise<SearchResultItems> &promise, const QString &searchTerm,
+ const FileContainer &container, FindFlags flags,
+ const QMap<FilePath, QString> &fileToContentsMap)
+{
+ QEventLoop loop;
+ // The states transition exactly in this order:
+ enum State { BelowLimit, AboveLimit, Resumed };
+ State state = BelowLimit;
+ int reportedItemsCount = 0;
+ int searchedFilesCount = 0;
+
+ const int progressMaximum = container.progressMaximum();
+ promise.setProgressRange(0, progressMaximum);
+ promise.setProgressValueAndText(0, msgFound(searchTerm, 0, 0));
+ const int threadsCount = qMax(1, QThread::idealThreadCount() / 2);
+ QSet<QFutureWatcher<SearchResultItems> *> watchers;
+ FutureSynchronizer futureSynchronizer;
+
+ const auto cleanup = qScopeGuard([&] {
+ qDeleteAll(watchers);
+ const QString message = promise.isCanceled()
+ ? msgCanceled(searchTerm, reportedItemsCount, searchedFilesCount)
+ : msgFound(searchTerm, reportedItemsCount, searchedFilesCount);
+ promise.setProgressValueAndText(progressMaximum, message);
+ });
-QFuture<SearchResultItems> Utils::findInFiles(const QString &searchTerm,
- FileIterator *files,
- QTextDocument::FindFlags flags,
- const QMap<FilePath, QString> &fileToContentsMap)
-{
- return mapReduce(files->begin(), files->end(),
- [searchTerm, files](QFutureInterface<SearchResultItems> &futureInterface) {
- return initFileSearch(futureInterface, searchTerm, files);
- },
- FileSearch(searchTerm, flags, fileToContentsMap),
- &collectSearchResults,
- &cleanUpFileSearch);
+ FileContainerIterator it = container.begin();
+ const FileContainerIterator itEnd = container.end();
+ if (it == itEnd)
+ return;
+
+ std::function<void()> scheduleNext;
+ scheduleNext = [&] {
+ if (promise.isCanceled() || (it == itEnd && watchers.isEmpty())) {
+ loop.quit();
+ return;
+ }
+ if (it == itEnd)
+ return;
+
+ if (state == AboveLimit)
+ return;
+
+ if (watchers.size() == threadsCount)
+ return;
+
+ const FileContainerIterator::Item item = *it;
+ const int progress = it.progressValue();
+ ++it;
+ const QFuture<SearchResultItems> future
+ = Utils::asyncRun(fileSearch, item, searchTerm, flags, fileToContentsMap);
+ QFutureWatcher<SearchResultItems> *watcher = new QFutureWatcher<SearchResultItems>;
+ QObject::connect(watcher, &QFutureWatcherBase::finished, &loop,
+ [watcher, progress, &searchTerm, &reportedItemsCount, &searchedFilesCount, &state,
+ &watchers, &promise, &scheduleNext] {
+ const QFuture<SearchResultItems> future = watcher->future();
+ if (future.resultCount()) {
+ const SearchResultItems items = future.result();
+ reportedItemsCount += items.size();
+ if (state == BelowLimit && reportedItemsCount > 200000)
+ state = AboveLimit;
+ if (!items.isEmpty())
+ promise.addResult(items);
+ }
+ ++searchedFilesCount;
+ promise.setProgressValueAndText(progress, msgFound(searchTerm, reportedItemsCount,
+ searchedFilesCount));
+ watcher->deleteLater();
+ watchers.remove(watcher);
+ scheduleNext();
+ });
+ watcher->setFuture(future);
+ futureSynchronizer.addFuture(future);
+ watchers.insert(watcher);
+ scheduleNext();
+ };
+
+ QFutureWatcher<void> watcher;
+ QObject::connect(&watcher, &QFutureWatcherBase::canceled, &loop, &QEventLoop::quit);
+ QObject::connect(&watcher, &QFutureWatcherBase::resumed, &loop, [&state, &scheduleNext] {
+ state = Resumed;
+ scheduleNext();
+ });
+
+ watcher.setFuture(QFuture<void>(promise.future()));
+
+ if (promise.isCanceled())
+ return;
+
+ QTimer::singleShot(0, &loop, scheduleNext);
+ loop.exec(QEventLoop::ExcludeUserInputEvents);
}
-QFuture<SearchResultItems> Utils::findInFilesRegExp(
- const QString &searchTerm,
- FileIterator *files,
- QTextDocument::FindFlags flags,
- const QMap<FilePath, QString> &fileToContentsMap)
+QFuture<SearchResultItems> findInFiles(const QString &searchTerm, const FileContainer &container,
+ FindFlags flags,
+ const QMap<FilePath, QString> &fileToContentsMap)
{
- return mapReduce(files->begin(), files->end(),
- [searchTerm, files](QFutureInterface<SearchResultItems> &futureInterface) {
- return initFileSearch(futureInterface, searchTerm, files);
- },
- FileSearchRegExp(searchTerm, flags, fileToContentsMap),
- &collectSearchResults,
- &cleanUpFileSearch);
+ return Utils::asyncRun(findInFilesImpl, searchTerm, container, flags, fileToContentsMap);
}
-QString Utils::expandRegExpReplacement(const QString &replaceText, const QStringList &capturedTexts)
+QString expandRegExpReplacement(const QString &replaceText, const QStringList &capturedTexts)
{
// handles \1 \\ \& \t \n $1 $$ $&
QString result;
@@ -435,9 +402,7 @@ QString Utils::expandRegExpReplacement(const QString &replaceText, const QString
return result;
}
-namespace Utils {
-namespace Internal {
-QString matchCaseReplacement(const QString &originalText, const QString &replaceText)
+static QString matchCaseReplacementHelper(const QString &originalText, const QString &replaceText)
{
if (originalText.isEmpty() || replaceText.isEmpty())
return replaceText;
@@ -472,7 +437,6 @@ QString matchCaseReplacement(const QString &originalText, const QString &replace
return replaceText; // mixed
}
}
-} // namespace
static QList<QRegularExpression> filtersToRegExps(const QStringList &filters)
{
@@ -519,7 +483,6 @@ QStringList splitFilterUiText(const QString &text)
return Utils::filtered(trimmedPortableParts, [](const QString &s) { return !s.isEmpty(); });
}
-
QString msgFilePatternLabel()
{
return Tr::tr("Fi&le pattern:");
@@ -532,7 +495,7 @@ QString msgExclusionPatternLabel()
QString msgFilePatternToolTip(InclusionType inclusionType)
{
- return Tr::tr("List of comma separated wildcard filters. ")
+ return Tr::tr("List of comma separated wildcard filters.") + " "
+ (inclusionType == InclusionType::Included
? Tr::tr("Files with file name or full file path matching any filter are included.")
: Tr::tr("Files with file name or full file path matching any filter are excluded."));
@@ -559,96 +522,95 @@ QString matchCaseReplacement(const QString &originalText, const QString &replace
//keep prefix and suffix, and do actual replacement on the 'middle' of the string
return originalText.left(prefixLen)
- + Internal::matchCaseReplacement(originalText.mid(prefixLen, originalTextLen - prefixLen - suffixLen),
- replaceText.mid(prefixLen, replaceTextLen - prefixLen - suffixLen))
+ + matchCaseReplacementHelper(originalText.mid(prefixLen, originalTextLen - prefixLen - suffixLen),
+ replaceText.mid(prefixLen, replaceTextLen - prefixLen - suffixLen))
+ originalText.right(suffixLen);
-
-}
-
-// #pragma mark -- FileIterator
-
-void FileIterator::advance(FileIterator::const_iterator *it) const
-{
- if (it->m_index < 0) // == end
- return;
- ++it->m_index;
- const_cast<FileIterator *>(this)->update(it->m_index);
- if (it->m_index >= currentFileCount())
- it->m_index = -1; // == end
}
-FileIterator::const_iterator FileIterator::begin() const
+void FileContainerIterator::operator++()
{
- const_cast<FileIterator *>(this)->update(0);
- if (currentFileCount() == 0)
- return end();
- return FileIterator::const_iterator(this, 0/*index*/);
+ QTC_ASSERT(m_data.m_container, return);
+ QTC_ASSERT(m_data.m_index >= 0, return);
+ QTC_ASSERT(m_data.m_advancer, return);
+ m_data.m_advancer(&m_data);
}
-FileIterator::const_iterator FileIterator::end() const
+int FileContainerIterator::progressMaximum() const
{
- return FileIterator::const_iterator(this, -1/*end*/);
+ return m_data.m_container ? m_data.m_container->progressMaximum() : 0;
}
-// #pragma mark -- FileListIterator
-
-QList<FileIterator::Item> constructItems(const FilePaths &fileList,
- const QList<QTextCodec *> &encodings)
+static QList<FileContainerIterator::Item> toFileListCache(const FilePaths &fileList,
+ const QList<QTextCodec *> &encodings)
{
- QList<FileIterator::Item> items;
+ QList<FileContainerIterator::Item> items;
items.reserve(fileList.size());
QTextCodec *defaultEncoding = QTextCodec::codecForLocale();
for (int i = 0; i < fileList.size(); ++i)
- items.append(FileIterator::Item(fileList.at(i), encodings.value(i, defaultEncoding)));
+ items.append({fileList.at(i), encodings.value(i, defaultEncoding)});
return items;
}
-FileListIterator::FileListIterator(const FilePaths &fileList, const QList<QTextCodec *> &encodings)
- : m_items(constructItems(fileList, encodings))
+static FileContainerIterator::Advancer fileListAdvancer(
+ const QList<FileContainerIterator::Item> &items)
{
+ return [items](FileContainerIterator::Data *iterator) {
+ ++iterator->m_index;
+ if (iterator->m_index >= items.size() || iterator->m_index < 0) {
+ iterator->m_value = {};
+ iterator->m_index = -1;
+ iterator->m_progressValue = items.size();
+ return;
+ }
+ iterator->m_value = items.at(iterator->m_index);
+ iterator->m_progressValue = iterator->m_index;
+ };
}
-void FileListIterator::update(int requestedIndex)
+static FileContainer::AdvancerProvider fileListAdvancerProvider(const FilePaths &fileList,
+ const QList<QTextCodec *> &encodings)
{
- if (requestedIndex > m_maxIndex)
- m_maxIndex = requestedIndex;
+ const auto initialCache = toFileListCache(fileList, encodings);
+ return [=] { return fileListAdvancer(initialCache); };
}
-int FileListIterator::currentFileCount() const
-{
- return m_items.size();
-}
+FileListContainer::FileListContainer(const FilePaths &fileList,
+ const QList<QTextCodec *> &encodings)
+ : FileContainer(fileListAdvancerProvider(fileList, encodings), fileList.size()) {}
-const FileIterator::Item &FileListIterator::itemAt(int index) const
-{
- return m_items.at(index);
-}
+const int s_progressMaximum = 1000;
-int FileListIterator::maxProgress() const
+struct SubDirCache
{
- return m_items.size();
-}
+ SubDirCache(const FilePaths &directories, const QStringList &filters,
+ const QStringList &exclusionFilters, QTextCodec *encoding);
-int FileListIterator::currentProgress() const
-{
- return m_maxIndex + 1;
-}
+ std::optional<FileContainerIterator::Item> updateCache(int advanceIntoIndex,
+ const SubDirCache &initialCache);
-// #pragma mark -- SubDirFileIterator
-
-namespace {
- const int MAX_PROGRESS = 1000;
-}
+ std::function<FilePaths(const FilePaths &)> m_filterFiles;
+ QTextCodec *m_encoding = nullptr;
+ QStack<FilePath> m_dirs;
+ QSet<FilePath> m_knownDirs;
+ QStack<qreal> m_progressValues;
+ QStack<bool> m_processedValues;
+ qreal m_progress = 0;
+ QList<FileContainerIterator::Item> m_items;
+ // When forward iterating, we construct some results for the future iterations
+ // and keep them in m_items cache. Later, when we iterated over all from the cache,
+ // we don't want to keep the cache anymore, so we are clearing it.
+ // In order to match the iterator's index with the position inside m_items cache,
+ // we need to remember how many items were removed from the cache and subtract
+ // this value from the iterator's index when a new advance comes.
+ int m_removedItemsCount = 0;
+};
-SubDirFileIterator::SubDirFileIterator(const FilePaths &directories,
- const QStringList &filters,
- const QStringList &exclusionFilters,
- QTextCodec *encoding)
+SubDirCache::SubDirCache(const FilePaths &directories, const QStringList &filters,
+ const QStringList &exclusionFilters, QTextCodec *encoding)
: m_filterFiles(filterFilesFunction(filters, exclusionFilters))
- , m_progress(0)
+ , m_encoding(encoding == nullptr ? QTextCodec::codecForLocale() : encoding)
{
- m_encoding = (encoding == nullptr ? QTextCodec::codecForLocale() : encoding);
- qreal maxPer = qreal(MAX_PROGRESS) / directories.count();
+ const qreal maxPer = qreal(s_progressMaximum) / directories.count();
for (const FilePath &directoryEntry : directories) {
if (!directoryEntry.isEmpty()) {
const FilePath canonicalPath = directoryEntry.canonicalPath();
@@ -662,18 +624,22 @@ SubDirFileIterator::SubDirFileIterator(const FilePaths &directories,
}
}
-SubDirFileIterator::~SubDirFileIterator()
+std::optional<FileContainerIterator::Item> SubDirCache::updateCache(int advanceIntoIndex,
+ const SubDirCache &initialCache)
{
- qDeleteAll(m_items);
-}
+ QTC_ASSERT(advanceIntoIndex >= 0, return {});
+ if (advanceIntoIndex < m_removedItemsCount)
+ *this = initialCache; // Regenerate the cache from scratch
+ const int currentIndex = advanceIntoIndex - m_removedItemsCount;
+ if (currentIndex < m_items.size())
+ return m_items.at(currentIndex);
-void SubDirFileIterator::update(int index)
-{
- if (index < m_items.size())
- return;
- // collect files from the directories until we have enough for the given index
- while (!m_dirs.isEmpty() && index >= m_items.size()) {
- FilePath dir = m_dirs.pop();
+ m_removedItemsCount += m_items.size();
+ m_items.clear();
+ const int newCurrentIndex = advanceIntoIndex - m_removedItemsCount;
+
+ while (!m_dirs.isEmpty() && newCurrentIndex >= m_items.size()) {
+ const FilePath dir = m_dirs.pop();
const qreal dirProgressMax = m_progressValues.pop();
const bool processed = m_processedValues.pop();
if (dir.exists()) {
@@ -681,8 +647,9 @@ void SubDirFileIterator::update(int index)
using CanonicalDir = FilePath;
std::vector<std::pair<Dir, CanonicalDir>> subDirs;
if (!processed) {
- for (const FilePath &entry :
- dir.dirEntries(QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot)) {
+ const FilePaths entries = dir.dirEntries(QDir::Dirs | QDir::Hidden
+ | QDir::NoDotAndDotDot);
+ for (const FilePath &entry : entries) {
const FilePath canonicalDir = entry.canonicalPath();
if (!m_knownDirs.contains(canonicalDir))
subDirs.emplace_back(entry, canonicalDir);
@@ -693,11 +660,11 @@ void SubDirFileIterator::update(int index)
const FilePaths filePaths = m_filterFiles(allFilePaths);
m_items.reserve(m_items.size() + filePaths.size());
Utils::reverseForeach(filePaths, [this](const FilePath &file) {
- m_items.append(new Item(file, m_encoding));
+ m_items.append({file, m_encoding});
});
m_progress += dirProgressMax;
} else {
- qreal subProgress = dirProgressMax/(subDirs.size()+1);
+ const qreal subProgress = dirProgressMax / (subDirs.size() + 1);
m_dirs.push(dir);
m_progressValues.push(subProgress);
m_processedValues.push(true);
@@ -713,28 +680,41 @@ void SubDirFileIterator::update(int index)
m_progress += dirProgressMax;
}
}
- if (index >= m_items.size())
- m_progress = MAX_PROGRESS;
-}
+ if (newCurrentIndex < m_items.size())
+ return m_items.at(newCurrentIndex);
-int SubDirFileIterator::currentFileCount() const
-{
- return m_items.size();
+ m_progress = s_progressMaximum;
+ return {};
}
-const FileIterator::Item &SubDirFileIterator::itemAt(int index) const
+static FileContainerIterator::Advancer subDirAdvancer(const SubDirCache &initialCache)
{
- return *m_items.at(index);
+ const std::shared_ptr<SubDirCache> sharedCache(new SubDirCache(initialCache));
+ return [=](FileContainerIterator::Data *iterator) {
+ ++iterator->m_index;
+ const std::optional<FileContainerIterator::Item> item
+ = sharedCache->updateCache(iterator->m_index, initialCache);
+ if (!item) {
+ iterator->m_value = {};
+ iterator->m_index = -1;
+ iterator->m_progressValue = s_progressMaximum;
+ return;
+ }
+ iterator->m_value = *item;
+ iterator->m_progressValue = qMin(qRound(sharedCache->m_progress), s_progressMaximum);
+ };
}
-int SubDirFileIterator::maxProgress() const
+static FileContainer::AdvancerProvider subDirAdvancerProvider(const FilePaths &directories,
+ const QStringList &filters, const QStringList &exclusionFilters, QTextCodec *encoding)
{
- return MAX_PROGRESS;
+ const SubDirCache initialCache(directories, filters, exclusionFilters, encoding);
+ return [=] { return subDirAdvancer(initialCache); };
}
-int SubDirFileIterator::currentProgress() const
-{
- return qMin(qRound(m_progress), MAX_PROGRESS);
-}
+SubDirFileContainer::SubDirFileContainer(const FilePaths &directories, const QStringList &filters,
+ const QStringList &exclusionFilters, QTextCodec *encoding)
+ : FileContainer(subDirAdvancerProvider(directories, filters, exclusionFilters, encoding),
+ s_progressMaximum) {}
-}
+} // namespace Utils
diff --git a/src/libs/utils/filesearch.h b/src/libs/utils/filesearch.h
index fc6ce62ab0b..2d2155a723c 100644
--- a/src/libs/utils/filesearch.h
+++ b/src/libs/utils/filesearch.h
@@ -9,8 +9,7 @@
#include "searchresultitem.h"
#include <QMap>
-#include <QSet>
-#include <QStack>
+#include <QPromise>
#include <QTextDocument>
#include <functional>
@@ -23,6 +22,22 @@ QT_END_NAMESPACE
namespace Utils {
+enum FindFlag {
+ FindBackward = 0x01,
+ FindCaseSensitively = 0x02,
+ FindWholeWords = 0x04,
+ FindRegularExpression = 0x08,
+ FindPreserveCase = 0x10
+};
+Q_DECLARE_FLAGS(FindFlags, FindFlag)
+
+QTCREATOR_UTILS_EXPORT
+QTextDocument::FindFlags textDocumentFlagsForFindFlags(FindFlags flags);
+
+QTCREATOR_UTILS_EXPORT
+void searchInContents(QPromise<SearchResultItems> &promise, const QString &searchTerm,
+ FindFlags flags, const FilePath &filePath, const QString &contents);
+
QTCREATOR_UTILS_EXPORT
std::function<FilePaths(const FilePaths &)> filterFilesFunction(const QStringList &filters,
const QStringList &exclusionFilters);
@@ -44,125 +59,105 @@ enum class InclusionType {
QTCREATOR_UTILS_EXPORT
QString msgFilePatternToolTip(InclusionType inclusionType = InclusionType::Included);
-class QTCREATOR_UTILS_EXPORT FileIterator
+class FileContainer;
+
+class QTCREATOR_UTILS_EXPORT FileContainerIterator
{
public:
class Item
{
public:
- Item() = default;
- Item(const FilePath &path, QTextCodec *codec)
- : filePath(path)
- , encoding(codec)
- {}
- FilePath filePath;
+ FilePath filePath {};
QTextCodec *encoding = nullptr;
};
- using value_type = Item;
+ class Data;
+ using Advancer = std::function<void(Data *)>;
- class const_iterator
+ class Data
{
public:
- using iterator_category = std::forward_iterator_tag;
- using value_type = Item;
- using difference_type = std::ptrdiff_t;
- using pointer = const value_type*;
- using reference = const value_type&;
-
- const_iterator() = default;
- const_iterator(const FileIterator *parent, int id)
- : m_parent(parent), m_index(id)
- {}
- const_iterator(const const_iterator &) = default;
- const_iterator &operator=(const const_iterator &) = default;
-
- reference operator*() const { return m_parent->itemAt(m_index); }
- pointer operator->() const { return &m_parent->itemAt(m_index); }
- void operator++() { m_parent->advance(this); }
- bool operator==(const const_iterator &other) const
- {
- return m_parent == other.m_parent && m_index == other.m_index;
- }
- bool operator!=(const const_iterator &other) const { return !operator==(other); }
-
- const FileIterator *m_parent = nullptr;
- int m_index = -1; // -1 == end
+ const FileContainer *m_container = nullptr;
+ int m_progressValue = 0;
+ Advancer m_advancer = {};
+ int m_index = -1; // end iterator
+ Item m_value = {};
};
- virtual ~FileIterator() = default;
- const_iterator begin() const;
- const_iterator end() const;
+ using value_type = Item;
+ using pointer = const value_type *;
+ using reference = const value_type &;
+ using iterator_category = std::forward_iterator_tag;
+ using difference_type = std::ptrdiff_t;
- virtual int maxProgress() const = 0;
- virtual int currentProgress() const = 0;
+ FileContainerIterator() = default;
- void advance(const_iterator *it) const;
- virtual const Item &itemAt(int index) const = 0;
+ reference operator*() const { return m_data.m_value; }
+ pointer operator->() const { return &m_data.m_value; }
+ void operator++();
-protected:
- virtual void update(int requestedIndex) = 0;
- virtual int currentFileCount() const = 0;
+ bool operator==(const FileContainerIterator &other) const {
+ return m_data.m_container == other.m_data.m_container
+ && m_data.m_index == other.m_data.m_index;
+ }
+ bool operator!=(const FileContainerIterator &other) const { return !operator==(other); }
+ int progressValue() const { return m_data.m_progressValue; }
+ int progressMaximum() const;
+
+private:
+ friend class FileContainer;
+ FileContainerIterator(const Data &data) : m_data(data) {}
+ Data m_data;
};
-class QTCREATOR_UTILS_EXPORT FileListIterator : public FileIterator
+class QTCREATOR_UTILS_EXPORT FileContainer
{
public:
- explicit FileListIterator(const FilePaths &fileList = {},
- const QList<QTextCodec *> &encodings = {});
-
- int maxProgress() const override;
- int currentProgress() const override;
+ using AdvancerProvider = std::function<FileContainerIterator::Advancer()>;
+
+ FileContainer() = default;
+
+ FileContainerIterator begin() const {
+ if (!m_provider)
+ return end();
+ const FileContainerIterator::Advancer advancer = m_provider();
+ if (!advancer)
+ return end();
+ FileContainerIterator iterator({this, 0, advancer});
+ advancer(&iterator.m_data);
+ return iterator;
+ }
+ FileContainerIterator end() const { return FileContainerIterator({this, m_progressMaximum}); }
+ int progressMaximum() const { return m_progressMaximum; }
protected:
- void update(int requestedIndex) override;
- int currentFileCount() const override;
- const Item &itemAt(int index) const override;
+ FileContainer(const AdvancerProvider &provider, int progressMaximum)
+ : m_provider(provider)
+ , m_progressMaximum(progressMaximum) {}
private:
- const QList<Item> m_items;
- int m_maxIndex = -1;
+ friend class FileContainerIterator;
+ AdvancerProvider m_provider;
+ int m_progressMaximum = 0;
};
-class QTCREATOR_UTILS_EXPORT SubDirFileIterator : public FileIterator
+class QTCREATOR_UTILS_EXPORT FileListContainer : public FileContainer
{
public:
- SubDirFileIterator(const FilePaths &directories,
- const QStringList &filters,
- const QStringList &exclusionFilters,
- QTextCodec *encoding = nullptr);
- ~SubDirFileIterator() override;
-
- int maxProgress() const override;
- int currentProgress() const override;
-
-protected:
- void update(int requestedIndex) override;
- int currentFileCount() const override;
- const Item &itemAt(int index) const override;
+ FileListContainer(const FilePaths &fileList, const QList<QTextCodec *> &encodings);
+};
-private:
- std::function<FilePaths(const FilePaths &)> m_filterFiles;
- QTextCodec *m_encoding;
- QStack<FilePath> m_dirs;
- QSet<FilePath> m_knownDirs;
- QStack<qreal> m_progressValues;
- QStack<bool> m_processedValues;
- qreal m_progress;
- // Use heap allocated objects directly because we want references to stay valid even after resize
- QList<Item *> m_items;
+class QTCREATOR_UTILS_EXPORT SubDirFileContainer : public FileContainer
+{
+public:
+ SubDirFileContainer(const FilePaths &directories,
+ const QStringList &filters,
+ const QStringList &exclusionFilters,
+ QTextCodec *encoding = nullptr);
};
QTCREATOR_UTILS_EXPORT QFuture<SearchResultItems> findInFiles(const QString &searchTerm,
- FileIterator *files,
- QTextDocument::FindFlags flags,
- const QMap<FilePath, QString> &fileToContentsMap = {});
-
-QTCREATOR_UTILS_EXPORT QFuture<SearchResultItems> findInFilesRegExp(
- const QString &searchTerm,
- FileIterator *files,
- QTextDocument::FindFlags flags,
- const QMap<FilePath, QString> &fileToContentsMap = {});
+ const FileContainer &container, FindFlags flags, const QMap<FilePath, QString> &fileToContentsMap);
QTCREATOR_UTILS_EXPORT QString expandRegExpReplacement(const QString &replaceText,
const QStringList &capturedTexts);
@@ -170,3 +165,6 @@ QTCREATOR_UTILS_EXPORT QString matchCaseReplacement(const QString &originalText,
const QString &replaceText);
} // namespace Utils
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(Utils::FindFlags)
+Q_DECLARE_METATYPE(Utils::FindFlags)
diff --git a/src/libs/utils/filestreamer.cpp b/src/libs/utils/filestreamer.cpp
index eb9e057c1a1..24587563019 100644
--- a/src/libs/utils/filestreamer.cpp
+++ b/src/libs/utils/filestreamer.cpp
@@ -304,12 +304,8 @@ public:
void start() override { task()->start(); }
};
-} // namespace Utils
-
-TASKING_DECLARE_TASK(FileStreamReaderTask, Utils::FileStreamReaderAdapter);
-TASKING_DECLARE_TASK(FileStreamWriterTask, Utils::FileStreamWriterAdapter);
-
-namespace Utils {
+using FileStreamReaderTask = CustomTask<FileStreamReaderAdapter>;
+using FileStreamWriterTask = CustomTask<FileStreamWriterAdapter>;
static Group sameRemoteDeviceTransferTask(const FilePath &source, const FilePath &destination)
{
@@ -355,7 +351,7 @@ static Group interDeviceTransferTask(const FilePath &source, const FilePath &des
Storage(storage),
FileStreamWriterTask(setupWriter),
Group {
- WaitForBarrierTask(writerReadyBarrier),
+ waitForBarrierTask(writerReadyBarrier),
FileStreamReaderTask(setupReader, finalizeReader, finalizeReader)
}
};
diff --git a/src/libs/utils/filestreamer.h b/src/libs/utils/filestreamer.h
index a5b6ff4f256..828f27be8e1 100644
--- a/src/libs/utils/filestreamer.h
+++ b/src/libs/utils/filestreamer.h
@@ -58,6 +58,6 @@ public:
void start() override { task()->start(); }
};
-} // namespace Utils
+using FileStreamerTask = Tasking::CustomTask<FileStreamerTaskAdapter>;
-TASKING_DECLARE_TASK(FileStreamerTask, Utils::FileStreamerTaskAdapter);
+} // namespace Utils
diff --git a/src/libs/utils/filesystemmodel.cpp b/src/libs/utils/filesystemmodel.cpp
index 9a10f3b91fc..fb0441185d1 100644
--- a/src/libs/utils/filesystemmodel.cpp
+++ b/src/libs/utils/filesystemmodel.cpp
@@ -1053,10 +1053,8 @@ FileSystemNode *FileSystemModelPrivate::node(const QString &path, bool fetch) co
elementPath = host;
elementPath.append(separator);
} else {
- if (!pathElements.at(0).contains(QLatin1Char(':'))) {
- QString rootPath = QDir(longPath).rootPath();
- pathElements.prepend(rootPath);
- }
+ if (!pathElements.at(0).contains(QLatin1Char(':')))
+ pathElements.prepend(HostOsInfo::root().path());
if (pathElements.at(0).endsWith(QLatin1Char('/')))
pathElements[0].chop(1);
}
@@ -2520,7 +2518,7 @@ QStringList FileSystemModelPrivate::unwatchPathsAt(const QModelIndex &index)
QTC_CHECK(useFileSystemWatcher());
const FileSystemNode *indexNode = node(index);
if (indexNode == nullptr)
- return QStringList();
+ return {};
const Qt::CaseSensitivity caseSensitivity = indexNode->caseSensitive()
? Qt::CaseSensitive : Qt::CaseInsensitive;
const QString path = indexNode->fileInfo().absoluteFilePath();
diff --git a/src/libs/utils/filesystemwatcher.cpp b/src/libs/utils/filesystemwatcher.cpp
index 155f83fba03..7933d31543e 100644
--- a/src/libs/utils/filesystemwatcher.cpp
+++ b/src/libs/utils/filesystemwatcher.cpp
@@ -275,7 +275,7 @@ void FileSystemWatcher::addFiles(const QStringList &files, WatchMode wm)
d->m_files.insert(file, WatchEntry(file, wm));
const int count = ++d->m_staticData->m_fileCount[file];
- Q_ASSERT(count > 0);
+ QTC_CHECK(count > 0);
if (count == 1) {
toAdd << file;
@@ -284,7 +284,7 @@ void FileSystemWatcher::addFiles(const QStringList &files, WatchMode wm)
if (!fi.exists()) {
const QString directory = fi.path();
const int dirCount = ++d->m_staticData->m_directoryCount[directory];
- Q_ASSERT(dirCount > 0);
+ QTC_CHECK(dirCount > 0);
if (dirCount == 1)
toAdd << directory;
@@ -315,7 +315,7 @@ void FileSystemWatcher::removeFiles(const QStringList &files)
d->m_files.erase(it);
const int count = --(d->m_staticData->m_fileCount[file]);
- Q_ASSERT(count >= 0);
+ QTC_CHECK(count >= 0);
if (!count) {
toRemove << file;
@@ -324,7 +324,7 @@ void FileSystemWatcher::removeFiles(const QStringList &files)
if (!fi.exists()) {
const QString directory = fi.path();
const int dirCount = --d->m_staticData->m_directoryCount[directory];
- Q_ASSERT(dirCount >= 0);
+ QTC_CHECK(dirCount >= 0);
if (!dirCount)
toRemove << directory;
@@ -381,7 +381,7 @@ void FileSystemWatcher::addDirectories(const QStringList &directories, WatchMode
d->m_directories.insert(directory, WatchEntry(directory, wm));
const int count = ++d->m_staticData->m_directoryCount[directory];
- Q_ASSERT(count > 0);
+ QTC_CHECK(count > 0);
if (count == 1)
toAdd << directory;
@@ -411,7 +411,7 @@ void FileSystemWatcher::removeDirectories(const QStringList &directories)
d->m_directories.erase(it);
const int count = --d->m_staticData->m_directoryCount[directory];
- Q_ASSERT(count >= 0);
+ QTC_CHECK(count >= 0);
if (!count)
toRemove << directory;
@@ -428,27 +428,23 @@ QStringList FileSystemWatcher::directories() const
void FileSystemWatcher::slotFileChanged(const QString &path)
{
const auto it = d->m_files.find(path);
- QStringList toAdd;
if (it != d->m_files.end() && it.value().trigger(path)) {
qCDebug(fileSystemWatcherLog)
<< this << "triggers on file" << it.key()
<< it.value().watchMode
<< it.value().modifiedTime.toString(Qt::ISODate);
- d->fileChanged(path);
QFileInfo fi(path);
if (!fi.exists()) {
const QString directory = fi.path();
const int dirCount = ++d->m_staticData->m_directoryCount[directory];
- Q_ASSERT(dirCount > 0);
+ QTC_CHECK(dirCount > 0);
if (dirCount == 1)
- toAdd << directory;
+ d->m_staticData->m_watcher->addPath(directory);
}
+ d->fileChanged(path);
}
-
- if (!toAdd.isEmpty())
- d->m_staticData->m_watcher->addPaths(toAdd);
}
void FileSystemWatcher::slotDirectoryChanged(const QString &path)
@@ -474,20 +470,17 @@ void FileSystemWatcher::slotDirectoryChanged(const QString &path)
for (const QString &rejected : d->m_staticData->m_watcher->addPaths(toReadd))
toReadd.removeOne(rejected);
- QStringList toRemove;
// If we've successfully added the file, that means it was deleted and replaced.
for (const QString &reAdded : std::as_const(toReadd)) {
- d->fileChanged(reAdded);
const QString directory = QFileInfo(reAdded).path();
const int dirCount = --d->m_staticData->m_directoryCount[directory];
- Q_ASSERT(dirCount >= 0);
+ QTC_CHECK(dirCount >= 0);
if (!dirCount)
- toRemove << directory;
- }
+ d->m_staticData->m_watcher->removePath(directory);
- if (!toRemove.isEmpty())
- d->m_staticData->m_watcher->removePaths(toRemove);
+ d->fileChanged(reAdded);
+ }
}
}
diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp
index 4f67ee8105a..3d8f074962e 100644
--- a/src/libs/utils/fileutils.cpp
+++ b/src/libs/utils/fileutils.cpp
@@ -6,6 +6,7 @@
#include "algorithm.h"
#include "devicefileaccess.h"
+#include "environment.h"
#include "qtcassert.h"
#include "utilstr.h"
@@ -721,7 +722,7 @@ bool FileUtils::copyRecursively(
bool FileUtils::copyIfDifferent(const FilePath &srcFilePath, const FilePath &tgtFilePath)
{
- QTC_ASSERT(srcFilePath.exists(), return false);
+ QTC_ASSERT(srcFilePath.exists(), qDebug() << srcFilePath.toUserOutput(); return false);
QTC_ASSERT(srcFilePath.isSameDevice(tgtFilePath), return false);
if (tgtFilePath.exists()) {
@@ -843,4 +844,18 @@ qint64 FileUtils::bytesAvailableFromDFOutput(const QByteArray &dfOutput)
return -1;
}
+FilePaths FileUtils::usefulExtraSearchPaths()
+{
+ if (HostOsInfo::isMacHost()) {
+ return {"/opt/homebrew/bin"};
+ } else if (HostOsInfo::isWindowsHost()) {
+ const QString programData =
+ qtcEnvironmentVariable("ProgramData",
+ qtcEnvironmentVariable("ALLUSERSPROFILE", "C:/ProgramData"));
+ return {FilePath::fromUserInput(programData) / "chocolatey/bin"};
+ }
+
+ return {};
+}
+
} // namespace Utils
diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h
index a1a7ffef977..316030b0397 100644
--- a/src/libs/utils/fileutils.h
+++ b/src/libs/utils/fileutils.h
@@ -85,6 +85,9 @@ public:
static FilePathInfo filePathInfoFromTriple(const QString &infos, int modeBase);
+ //! Returns known paths like /opt/homebrew on macOS that might not be in PATH
+ static FilePaths usefulExtraSearchPaths();
+
#ifdef QT_WIDGETS_LIB
static void setDialogParentGetter(const std::function<QWidget *()> &getter);
diff --git a/src/libs/utils/filewizardpage.cpp b/src/libs/utils/filewizardpage.cpp
index a883f960566..4d2dba6ab30 100644
--- a/src/libs/utils/filewizardpage.cpp
+++ b/src/libs/utils/filewizardpage.cpp
@@ -50,9 +50,10 @@ FileWizardPage::FileWizardPage(QWidget *parent) :
d->m_defaultSuffixLabel = new QLabel;
d->m_nameLabel = new QLabel;
d->m_nameLineEdit = new FileNameValidatingLineEdit;
- d->m_nameLineEdit->setObjectName("nameLineEdit");
+ d->m_nameLineEdit->setObjectName("nameLineEdit"); // used by Squish
d->m_pathLabel = new QLabel;
d->m_pathChooser = new PathChooser;
+ d->m_pathChooser->setObjectName("fullPathChooser"); // used by Squish
d->m_pathChooser->setExpectedKind(PathChooser::Directory);
d->m_nameLabel->setText(Tr::tr("File name:"));
diff --git a/src/libs/utils/fixedsizeclicklabel.cpp b/src/libs/utils/fixedsizeclicklabel.cpp
deleted file mode 100644
index 090ea1ca4a6..00000000000
--- a/src/libs/utils/fixedsizeclicklabel.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "fixedsizeclicklabel.h"
-
-#include <QMouseEvent>
-
-/*!
- \class Utils::FixedSizeClickLabel
-
- \brief The FixedSizeClickLabel class is a label with a size hint derived from a sample text
- that can be different to the text that is shown.
-
- For convenience it also has a clicked signal that is emitted whenever the label receives a mouse
- click.
-
- \inmodule Qt Creator
-*/
-
-/*!
- \fn Utils::FixedSizeClickLabel::clicked()
-
- This signal is emitted when the label is clicked with the left mouse button.
-*/
-
-/*!
- \property Utils::FixedSizeClickLabel::maxText
-
- This property holds the text that is used to calculate the label's size hint.
-*/
-
-namespace Utils {
-
-/*!
- Constructs a FixedSizeClickLabel with the parent \a parent.
-*/
-FixedSizeClickLabel::FixedSizeClickLabel(QWidget *parent)
- : QLabel(parent)
-{
-}
-
-/*!
- Sets the label's text to \a text, and changes the size hint of the label to the size of
- \a maxText.
-
- \sa maxText
- \sa setMaxText
-*/
-void FixedSizeClickLabel::setText(const QString &text, const QString &maxText)
-{
- QLabel::setText(text);
- m_maxText = maxText;
-}
-
-/*!
- \reimp
-*/
-QSize FixedSizeClickLabel::sizeHint() const
-{
- return fontMetrics().boundingRect(m_maxText).size();
-}
-
-QString FixedSizeClickLabel::maxText() const
-{
- return m_maxText;
-}
-
-void FixedSizeClickLabel::setMaxText(const QString &maxText)
-{
- m_maxText = maxText;
-}
-
-/*!
- \reimp
-*/
-void FixedSizeClickLabel::mousePressEvent(QMouseEvent *ev)
-{
- QLabel::mousePressEvent(ev);
- if (ev->button() == Qt::LeftButton)
- m_pressed = true;
-}
-
-/*!
- \reimp
-*/
-void FixedSizeClickLabel::mouseReleaseEvent(QMouseEvent *ev)
-{
- QLabel::mouseReleaseEvent(ev);
- if (ev->button() != Qt::LeftButton)
- return;
- if (m_pressed && rect().contains(ev->pos()))
- emit clicked();
- m_pressed = false;
-}
-
-} // namespace Utils
diff --git a/src/libs/utils/fixedsizeclicklabel.h b/src/libs/utils/fixedsizeclicklabel.h
deleted file mode 100644
index b663efc47a8..00000000000
--- a/src/libs/utils/fixedsizeclicklabel.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include "utils_global.h"
-
-#include <QLabel>
-
-namespace Utils {
-
-class QTCREATOR_UTILS_EXPORT FixedSizeClickLabel : public QLabel
-{
- Q_OBJECT
- Q_PROPERTY(QString maxText READ maxText WRITE setMaxText DESIGNABLE true)
-
-public:
- explicit FixedSizeClickLabel(QWidget *parent = nullptr);
-
- void setText(const QString &text, const QString &maxText);
- using QLabel::setText;
- QSize sizeHint() const override;
-
- QString maxText() const;
- void setMaxText(const QString &maxText);
-
-protected:
- void mousePressEvent(QMouseEvent *ev) override;
- void mouseReleaseEvent(QMouseEvent *ev) override;
-
-signals:
- void clicked();
-
-private:
- QString m_maxText;
- bool m_pressed = false;
-};
-
-} // namespace Utils
diff --git a/src/libs/utils/fsengine/fileiconprovider.cpp b/src/libs/utils/fsengine/fileiconprovider.cpp
index cd2cc060a21..9d2a7c8c050 100644
--- a/src/libs/utils/fsengine/fileiconprovider.cpp
+++ b/src/libs/utils/fsengine/fileiconprovider.cpp
@@ -85,7 +85,31 @@ public:
m_suffixCache.insert(suffix, iconFilePath);
}
- void registerIconOverlayForMimeType(const QIcon &icon, const Utils::MimeType &mimeType)
+ void registerIconOverlayForMimeType(const QIcon &icon, const QString &mimeName)
+ {
+ // avoid accessing the MIME database right away
+ m_mimeUpdater.append([this, icon, mimeName] {
+ addIconOverlayForMimeType(icon, Utils::mimeTypeForName(mimeName));
+ });
+ }
+
+ void registerIconForMimeType(const QIcon &icon, const QString &mimeName)
+ {
+ // avoid accessing the MIME database right away
+ m_mimeUpdater.append(
+ [this, icon, mimeName] { addIconForMimeType(icon, Utils::mimeTypeForName(mimeName)); });
+ }
+
+ void registerIconOverlayForMimeType(const QString &iconFilePath, const QString &mimeName)
+ {
+ // avoid accessing the MIME database right away
+ m_mimeUpdater.append([this, iconFilePath, mimeName] {
+ addIconOverlayForMimeType(iconFilePath, Utils::mimeTypeForName(mimeName));
+ });
+ }
+
+private:
+ void addIconOverlayForMimeType(const QIcon &icon, const Utils::MimeType &mimeType)
{
const QStringList suffixes = mimeType.suffixes();
for (const QString &suffix : suffixes) {
@@ -99,16 +123,31 @@ public:
}
}
- void registerIconOverlayForMimeType(const QString &iconFilePath, const Utils::MimeType &mimeType)
+ void addIconOverlayForMimeType(const QString &iconFilePath, const Utils::MimeType &mimeType)
{
const QStringList suffixes = mimeType.suffixes();
for (const QString &suffix : suffixes)
registerIconOverlayForSuffix(iconFilePath, suffix);
}
+ void addIconForMimeType(const QIcon &icon, const Utils::MimeType &mimeType)
+ {
+ const QStringList suffixes = mimeType.suffixes();
+ for (const QString &suffix : suffixes)
+ m_suffixCache.insert(suffix, icon);
+ }
+
+ void ensureMimeOverlays() const
+ {
+ for (const std::function<void()> &f : m_mimeUpdater)
+ f();
+ m_mimeUpdater.clear();
+ }
+
// Mapping of file suffix to icon.
mutable QHash<QString, Item> m_suffixCache;
mutable QHash<QString, Item> m_filenameCache;
+ mutable QList<std::function<void()>> m_mimeUpdater;
// QAbstractFileIconProvider interface
public:
@@ -165,11 +204,9 @@ static const QIcon &dirIcon()
return icon;
}
-QIcon FileIconProviderImplementation::icon(const QFileInfo &fi) const
+QIcon FileIconProviderImplementation::icon(const FilePath &filePath) const
{
- qCDebug(fileIconProvider) << "FileIconProvider::icon" << fi.absoluteFilePath();
-
- const FilePath filePath = FilePath::fromString(fi.filePath());
+ qCDebug(fileIconProvider) << "FileIconProvider::icon" << filePath.absoluteFilePath();
if (filePath.isEmpty())
return unknownFileIcon();
@@ -181,17 +218,19 @@ QIcon FileIconProviderImplementation::icon(const QFileInfo &fi) const
return dirIcon();
}
- bool isDir = fi.isDir();
+ const bool isDir = filePath.isDir();
// Check for cached overlay icons by file suffix.
- const QString filename = !isDir ? fi.fileName() : QString();
+ const QString filename = !isDir ? filePath.fileName() : QString();
if (!filename.isEmpty()) {
const std::optional<QIcon> icon = getIcon(m_filenameCache, filename);
if (icon)
return *icon;
}
- const QString suffix = !isDir ? fi.suffix() : QString();
+ ensureMimeOverlays();
+
+ const QString suffix = !isDir ? filePath.suffix() : QString();
if (!suffix.isEmpty()) {
const std::optional<QIcon> icon = getIcon(m_suffixCache, suffix);
if (icon)
@@ -213,11 +252,11 @@ QIcon FileIconProviderImplementation::icon(const QFileInfo &fi) const
return icon;
}
-QIcon FileIconProviderImplementation::icon(const FilePath &filePath) const
+QIcon FileIconProviderImplementation::icon(const QFileInfo &fi) const
{
- qCDebug(fileIconProvider) << "FileIconProvider::icon" << filePath.absoluteFilePath();
+ qCDebug(fileIconProvider) << "FileIconProvider::icon" << fi.absoluteFilePath();
- return icon(QFileInfo(filePath.toFSPathString()));
+ return icon(FilePath::fromString(fi.filePath()));
}
/*!
@@ -278,7 +317,12 @@ void registerIconOverlayForSuffix(const QString &path, const QString &suffix)
*/
void registerIconOverlayForMimeType(const QIcon &icon, const QString &mimeType)
{
- instance()->registerIconOverlayForMimeType(icon, Utils::mimeTypeForName(mimeType));
+ instance()->registerIconOverlayForMimeType(icon, mimeType);
+}
+
+void registerIconForMimeType(const QIcon &icon, const QString &mimeType)
+{
+ instance()->registerIconForMimeType(icon, mimeType);
}
/*!
@@ -287,7 +331,7 @@ void registerIconOverlayForMimeType(const QIcon &icon, const QString &mimeType)
*/
void registerIconOverlayForMimeType(const QString &path, const QString &mimeType)
{
- instance()->registerIconOverlayForMimeType(path, Utils::mimeTypeForName(mimeType));
+ instance()->registerIconOverlayForMimeType(path, mimeType);
}
void registerIconOverlayForFilename(const QString &path, const QString &filename)
diff --git a/src/libs/utils/fsengine/fileiconprovider.h b/src/libs/utils/fsengine/fileiconprovider.h
index 60479220cd8..5db70e62587 100644
--- a/src/libs/utils/fsengine/fileiconprovider.h
+++ b/src/libs/utils/fsengine/fileiconprovider.h
@@ -37,6 +37,8 @@ QTCREATOR_UTILS_EXPORT void registerIconOverlayForMimeType(const QIcon &icon,
QTCREATOR_UTILS_EXPORT QIcon directoryIcon(const QString &overlay);
+QTCREATOR_UTILS_EXPORT void registerIconForMimeType(const QIcon &icon, const QString &mimeType);
+
} // namespace FileIconProvider
} // namespace Utils
diff --git a/src/libs/utils/fsengine/fileiteratordevicesappender.h b/src/libs/utils/fsengine/fileiteratordevicesappender.h
index 9aec917d6b7..a28f1190806 100644
--- a/src/libs/utils/fsengine/fileiteratordevicesappender.h
+++ b/src/libs/utils/fsengine/fileiteratordevicesappender.h
@@ -4,6 +4,7 @@
#pragma once
#include "../filepath.h"
+#include "../hostosinfo.h"
#include <QtCore/private/qabstractfileengine_p.h>
@@ -97,7 +98,7 @@ private:
// We only need QDir::cleanPath here, as the path is always
// a fs engine path and will not contain scheme:// etc.
const QString p = QDir::cleanPath(path());
- if (p.compare(QDir::rootPath(), Qt::CaseInsensitive) == 0)
+ if (p.compare(HostOsInfo::root().path(), Qt::CaseInsensitive) == 0)
m_status = State::IteratingRoot;
((*m_baseIterator).*get(QAFEITag()))(p);
diff --git a/src/libs/utils/fsengine/fsenginehandler.cpp b/src/libs/utils/fsengine/fsenginehandler.cpp
index e020eebddac..2f828537d19 100644
--- a/src/libs/utils/fsengine/fsenginehandler.cpp
+++ b/src/libs/utils/fsengine/fsenginehandler.cpp
@@ -10,6 +10,7 @@
#include "fsengine.h"
#include "../algorithm.h"
+#include "../hostosinfo.h"
namespace Utils::Internal {
@@ -33,6 +34,18 @@ static FilePath removeDoubleSlash(const QString &fileName)
return FilePath::fromString(result);
}
+static bool isRootPath(const QString &fileName)
+{
+ if (HostOsInfo::isWindowsHost()) {
+ static const QChar lowerDriveLetter = HostOsInfo::root().path().front().toUpper();
+ static const QChar upperDriveLetter = HostOsInfo::root().path().front().toLower();
+ return fileName.size() == 3 && fileName[1] == ':' && fileName[2] == '/'
+ && (fileName[0] == lowerDriveLetter || fileName[0] == upperDriveLetter);
+ }
+
+ return fileName.size() == 1 && fileName[0] == '/';
+}
+
QAbstractFileEngine *FSEngineHandler::create(const QString &fileName) const
{
if (fileName.startsWith(':'))
@@ -71,7 +84,7 @@ QAbstractFileEngine *FSEngineHandler::create(const QString &fileName) const
return new FSEngineImpl(removeDoubleSlash(fileName));
}
- if (fixedFileName.compare(QDir::rootPath(), Qt::CaseInsensitive) == 0)
+ if (isRootPath(fixedFileName))
return new RootInjectFSEngine(fileName);
return nullptr;
diff --git a/src/libs/utils/functiontraits.h b/src/libs/utils/functiontraits.h
deleted file mode 100644
index 8b052d3e882..00000000000
--- a/src/libs/utils/functiontraits.h
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include <tuple>
-
-namespace Utils {
-
-/*
- struct functionTraits<Function>
- {
- using ResultType; // Return type of Function
- struct argument<unsigned index>
- {
- using type; // type of Function argument at index (starting with 0)
- }
- }
-
- struct functionTakesArgument<Function, unsigned index, ArgumentType>;
-
- Is derived from std::true_type if Function takes an argument of type ArgumentType at index.
- Otherwise derived from std::false_type.
-*/
-
-////////////////////
-// functionTraits
-////////////////////
-
-// for callables. defined below.
-template <typename Callable>
-struct functionTraits;
-
-// function
-template <typename Result, typename... Args>
-struct functionTraits<Result(Args...)>
-{
- using ResultType = Result;
- static const unsigned arity = sizeof...(Args); // TODO const -> constexpr with MSVC2015
-
- template <unsigned i>
- struct argument
- {
- using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
- };
-};
-
-// function pointer
-template <typename Result, typename... Args>
-struct functionTraits<Result(*)(Args...)> : public functionTraits<Result(Args...)>
-{
-};
-
-// const function pointer
-template <typename Result, typename... Args>
-struct functionTraits<Result(* const)(Args...)> : public functionTraits<Result(Args...)>
-{
-};
-
-// member function
-template <typename Type, typename Result, typename... Args>
-struct functionTraits<Result(Type::*)(Args...)> : public functionTraits<Result(Type&,Args...)>
-{
-};
-
-// const member function
-template <typename Type, typename Result, typename... Args>
-struct functionTraits<Result(Type::*)(Args...) const> : public functionTraits<Result(Type&,Args...)>
-{
-};
-
-// const pointer to member function
-template <typename Type, typename Result, typename... Args>
-struct functionTraits<Result(Type::* const)(Args...)> : public functionTraits<Result(Type&,Args...)>
-{
-};
-
-// const pointer to const member function
-template <typename Type, typename Result, typename... Args>
-struct functionTraits<Result(Type::* const)(Args...) const> : public functionTraits<Result(Type&,Args...)>
-{
-};
-
-// TODO: enable lvalue and rvalue ref member function later (MSVC 2015?)
-//// lvalue ref member function
-//template <typename Type, typename Result, typename... Args>
-//struct functionTraits<Result(Type::*)(Args...) &> : public functionTraits<Result(Type&,Args...)>
-//{
-//};
-
-//// const lvalue ref member function
-//template <typename Type, typename Result, typename... Args>
-//struct functionTraits<Result(Type::*)(Args...) const &> : public functionTraits<Result(Type&,Args...)>
-//{
-//};
-
-//// rvalue ref member function
-//template <typename Type, typename Result, typename... Args>
-//struct functionTraits<Result(Type::*)(Args...) &&> : public functionTraits<Result(Type&,Args...)>
-//{
-//};
-
-// callables. only works if operator() is not overloaded.
-template <typename Callable>
-struct functionTraits
-{
- using callableTraits = functionTraits<decltype(&Callable::operator())>;
- using ResultType = typename callableTraits::ResultType;
- static const unsigned arity = callableTraits::arity - 1; // ignore object pointer arg // TODO const -> constexpr with MSVC2015
-
- template <unsigned i>
- struct argument
- {
- using type = typename callableTraits::template argument<i+1>::type; // ignore object pointer arg
- };
-};
-
-// lvalue ref callables
-template <typename Callable>
-struct functionTraits<Callable&> : public functionTraits<Callable>
-{
-};
-
-// const lvalue ref callables
-template <typename Callable>
-struct functionTraits<const Callable&> : public functionTraits<Callable>
-{
-};
-
-// rvalue ref callables
-template <typename Callable>
-struct functionTraits<Callable&&> : public functionTraits<Callable>
-{
-};
-
-template <typename F>
-using functionResult_t = typename functionTraits<F>::ResultType;
-
-////////////////////
-// functionTakesArgument
-////////////////////
-namespace Internal {
-
-template <typename HasArity/*true_type or false_type*/,
- typename Function, unsigned index, typename T>
-struct functionTakesArgumentArityDispatch;
-
-template <typename Function, unsigned index, typename T>
-struct functionTakesArgumentArityDispatch<std::false_type, Function, index, T>
- : public std::false_type
-{
-};
-
-template <typename Function, unsigned index, typename T>
-struct functionTakesArgumentArityDispatch<std::true_type, Function, index, T>
- : public std::is_same<T, typename functionTraits<Function>::template argument<index>::type>
-{
-};
-
-} // Internal
-
-template <typename Function, unsigned index, typename T>
-struct functionTakesArgument : public Internal::functionTakesArgumentArityDispatch<
- std::integral_constant<bool, (functionTraits<Function>::arity > index)>,
- Function, index, T>
-{
-};
-
-} // Utils
diff --git a/src/libs/utils/fuzzymatcher.h b/src/libs/utils/fuzzymatcher.h
index dc665ec8648..88c5269870d 100644
--- a/src/libs/utils/fuzzymatcher.h
+++ b/src/libs/utils/fuzzymatcher.h
@@ -7,7 +7,7 @@
#include "utils_global.h"
-#include <QVector>
+#include <QList>
QT_BEGIN_NAMESPACE
class QRegularExpression;
@@ -26,8 +26,8 @@ public:
class HighlightingPositions {
public:
- QVector<int> starts;
- QVector<int> lengths;
+ QList<int> starts;
+ QList<int> lengths;
};
static QRegularExpression createRegExp(
diff --git a/src/libs/utils/highlightingitemdelegate.cpp b/src/libs/utils/highlightingitemdelegate.cpp
index 22d55e23bf0..7fe0507311a 100644
--- a/src/libs/utils/highlightingitemdelegate.cpp
+++ b/src/libs/utils/highlightingitemdelegate.cpp
@@ -134,12 +134,12 @@ void HighlightingItemDelegate::drawText(QPainter *painter,
if (index.model()->hasChildren(index))
text += " (" + QString::number(index.model()->rowCount(index)) + ')';
- QVector<int> searchTermStarts =
- index.model()->data(index, int(HighlightingItemRole::StartColumn)).value<QVector<int>>();
- QVector<int> searchTermLengths =
- index.model()->data(index, int(HighlightingItemRole::Length)).value<QVector<int>>();
+ QList<int> searchTermStarts
+ = index.model()->data(index, int(HighlightingItemRole::StartColumn)).value<QList<int>>();
+ QList<int> searchTermLengths
+ = index.model()->data(index, int(HighlightingItemRole::Length)).value<QList<int>>();
- QVector<QTextLayout::FormatRange> formats;
+ QList<QTextLayout::FormatRange> formats;
const QString extraText
= index.model()->data(index, int(HighlightingItemRole::DisplayExtra)).toString();
@@ -230,7 +230,7 @@ QSizeF doTextLayout(QTextLayout *textLayout, int lineWidth)
void HighlightingItemDelegate::drawDisplay(QPainter *painter,
const QStyleOptionViewItem &option,
const QRect &rect, const QString &text,
- const QVector<QTextLayout::FormatRange> &format) const
+ const QList<QTextLayout::FormatRange> &format) const
{
QPalette::ColorGroup cg = option.state & QStyle::State_Enabled
? QPalette::Normal : QPalette::Disabled;
diff --git a/src/libs/utils/highlightingitemdelegate.h b/src/libs/utils/highlightingitemdelegate.h
index cbda7042c26..ed47f18cca2 100644
--- a/src/libs/utils/highlightingitemdelegate.h
+++ b/src/libs/utils/highlightingitemdelegate.h
@@ -36,7 +36,7 @@ private:
const QRect &rect, const QModelIndex &index) const;
using QItemDelegate::drawDisplay;
void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect,
- const QString &text, const QVector<QTextLayout::FormatRange> &format) const;
+ const QString &text, const QList<QTextLayout::FormatRange> &format) const;
QString m_tabString;
};
diff --git a/src/libs/utils/historycompleter.cpp b/src/libs/utils/historycompleter.cpp
index f8c93b9fbef..8eff3fdad82 100644
--- a/src/libs/utils/historycompleter.cpp
+++ b/src/libs/utils/historycompleter.cpp
@@ -30,8 +30,8 @@ public:
void addEntry(const QString &str);
QStringList list;
- QString historyKey;
- QString historyKeyIsLastItemEmpty;
+ Key historyKey;
+ Key historyKeyIsLastItemEmpty;
int maxLines = 6;
bool isLastItemEmpty = isLastItemEmptyDefault;
};
@@ -174,17 +174,16 @@ void HistoryCompleterPrivate::addEntry(const QString &str)
isLastItemEmptyDefault);
}
-HistoryCompleter::HistoryCompleter(const QString &historyKey, QObject *parent)
+HistoryCompleter::HistoryCompleter(const Key &historyKey, QObject *parent)
: QCompleter(parent),
d(new HistoryCompleterPrivate)
{
QTC_ASSERT(!historyKey.isEmpty(), return);
QTC_ASSERT(theSettings, return);
- d->historyKey = QLatin1String("CompleterHistory/") + historyKey;
+ d->historyKey = "CompleterHistory/" + historyKey;
d->list = theSettings->value(d->historyKey).toStringList();
- d->historyKeyIsLastItemEmpty = QLatin1String("CompleterHistory/")
- + historyKey + QLatin1String(".IsLastItemEmpty");
+ d->historyKeyIsLastItemEmpty = "CompleterHistory/" + historyKey + ".IsLastItemEmpty";
d->isLastItemEmpty = theSettings->value(d->historyKeyIsLastItemEmpty, isLastItemEmptyDefault)
.toBool();
@@ -208,10 +207,10 @@ QString HistoryCompleter::historyItem() const
return d->list.at(0);
}
-bool HistoryCompleter::historyExistsFor(const QString &historyKey)
+bool HistoryCompleter::historyExistsFor(const Key &historyKey)
{
QTC_ASSERT(theSettings, return false);
- const QString fullKey = QLatin1String("CompleterHistory/") + historyKey;
+ const Key fullKey = "CompleterHistory/" + historyKey;
return theSettings->value(fullKey).isValid();
}
diff --git a/src/libs/utils/historycompleter.h b/src/libs/utils/historycompleter.h
index 81335413edc..4afb3f420ca 100644
--- a/src/libs/utils/historycompleter.h
+++ b/src/libs/utils/historycompleter.h
@@ -5,6 +5,8 @@
#include "utils_global.h"
+#include "storekey.h"
+
#include <QCompleter>
namespace Utils {
@@ -15,15 +17,15 @@ namespace Internal { class HistoryCompleterPrivate; }
class QTCREATOR_UTILS_EXPORT HistoryCompleter : public QCompleter
{
- Q_OBJECT
-
public:
static void setSettings(QtcSettings *settings);
- HistoryCompleter(const QString &historyKey, QObject *parent = nullptr);
+ HistoryCompleter(const Key &historyKey, QObject *parent = nullptr);
bool removeHistoryItem(int index);
QString historyItem() const;
bool hasHistory() const { return historySize() > 0; }
- static bool historyExistsFor(const QString &historyKey);
+ static bool historyExistsFor(const Key &historyKey);
+ void clearHistory();
+ void addEntry(const QString &str);
private:
~HistoryCompleter() override;
@@ -31,10 +33,6 @@ private:
int maximalHistorySize() const;
void setMaximalHistorySize(int numberOfEntries);
-public Q_SLOTS:
- void clearHistory();
- void addEntry(const QString &str);
-
private:
Internal::HistoryCompleterPrivate *d;
};
diff --git a/src/libs/utils/hostosinfo.cpp b/src/libs/utils/hostosinfo.cpp
index bf038ea82d2..d8361266f08 100644
--- a/src/libs/utils/hostosinfo.cpp
+++ b/src/libs/utils/hostosinfo.cpp
@@ -3,8 +3,11 @@
#include "hostosinfo.h"
+#include "filepath.h"
#include "utilstr.h"
+#include <QDir>
+
#if !defined(QT_NO_OPENGL) && defined(QT_GUI_LIB)
#include <QOpenGLContext>
#endif
@@ -21,7 +24,7 @@
#include <sys/sysctl.h>
#endif
-using namespace Utils;
+namespace Utils {
Qt::CaseSensitivity HostOsInfo::m_overrideFileNameCaseSensitivity = Qt::CaseSensitive;
bool HostOsInfo::m_useOverrideFileNameCaseSensitivity = false;
@@ -116,3 +119,11 @@ std::optional<quint64> HostOsInfo::totalMemoryInstalledInBytes()
#endif
return {};
}
+
+const FilePath &HostOsInfo::root()
+{
+ static const FilePath rootDir = FilePath::fromUserInput(QDir::rootPath());
+ return rootDir;
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/hostosinfo.h b/src/libs/utils/hostosinfo.h
index 090bf9e6d4a..44880f7885c 100644
--- a/src/libs/utils/hostosinfo.h
+++ b/src/libs/utils/hostosinfo.h
@@ -21,6 +21,8 @@ QT_END_NAMESPACE
namespace Utils {
+class FilePath;
+
class QTCREATOR_UTILS_EXPORT HostOsInfo
{
public:
@@ -86,6 +88,8 @@ public:
static std::optional<quint64> totalMemoryInstalledInBytes();
+ static const FilePath &root();
+
private:
static Qt::CaseSensitivity m_overrideFileNameCaseSensitivity;
static bool m_useOverrideFileNameCaseSensitivity;
diff --git a/src/libs/utils/icon.cpp b/src/libs/utils/icon.cpp
index 4ce143b56c7..5bd862c8f14 100644
--- a/src/libs/utils/icon.cpp
+++ b/src/libs/utils/icon.cpp
@@ -6,6 +6,7 @@
#include "qtcassert.h"
#include "theme/theme.h"
#include "stylehelper.h"
+#include "utilsicons.h"
#include <QApplication>
#include <QDebug>
@@ -36,7 +37,7 @@ static QPixmap maskToColorAndAlpha(const QPixmap &mask, const QColor &color)
using MaskAndColor = QPair<QPixmap, QColor>;
using MasksAndColors = QList<MaskAndColor>;
-static MasksAndColors masksAndColors(const QVector<IconMaskAndColor> &icon, int dpr)
+static MasksAndColors masksAndColors(const QList<IconMaskAndColor> &icon, int dpr)
{
MasksAndColors result;
for (const IconMaskAndColor &i: icon) {
@@ -134,15 +135,15 @@ static QPixmap masksToIcon(const MasksAndColors &masks, const QPixmap &combinedM
Icon::Icon() = default;
-Icon::Icon(QVector<IconMaskAndColor> args, Icon::IconStyleOptions style)
- : m_iconSourceList(std::move(args))
+Icon::Icon(const QList<IconMaskAndColor> &args, Icon::IconStyleOptions style)
+ : m_iconSourceList(args)
, m_style(style)
{
}
Icon::Icon(const FilePath &imageFileName)
+ : m_iconSourceList({{imageFileName, Theme::Color(-1)}})
{
- m_iconSourceList.append({imageFileName, Theme::Color(-1)});
}
QIcon Icon::icon() const
@@ -234,4 +235,52 @@ QIcon Icon::combinedIcon(const QList<Icon> &icons)
return combinedIcon(qIcons);
}
+QIcon Icon::fromTheme(const QString &name)
+{
+ static QHash<QString, QIcon> cache;
+
+ auto found = cache.find(name);
+ if (found != cache.end())
+ return *found;
+
+ QIcon icon = QIcon::fromTheme(name);
+ if (name == "go-next") {
+ cache.insert(name, !icon.isNull() ? icon : QIcon(":/utils/images/arrow.png"));
+ } else if (name == "document-open") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::OPENFILE.icon());
+ } else if (name == "edit-copy") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::COPY.icon());
+ } else if (name == "document-new") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::NEWFILE.icon());
+ } else if (name == "document-save") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::SAVEFILE.icon());
+ } else if (name == "edit-undo") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::UNDO.icon());
+ } else if (name == "edit-redo") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::REDO.icon());
+ } else if (name == "edit-cut") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::CUT.icon());
+ } else if (name == "edit-paste") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::PASTE.icon());
+ } else if (name == "zoom-in") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::ZOOMIN_TOOLBAR.icon());
+ } else if (name == "zoom-out") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::ZOOMOUT_TOOLBAR.icon());
+ } else if (name == "zoom-original") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::EYE_OPEN_TOOLBAR.icon());
+ } else if (name == "edit-clear") {
+ cache.insert(name, !icon.isNull() ? icon : Icons::EDIT_CLEAR.icon());
+ } else if (name == "edit-clear-locationbar-rtl") {
+ // KDE has custom icons for this. If these icons are not available we use the freedesktop
+ // standard name "edit-clear" before falling back to a bundled resource.
+ cache.insert(name, !icon.isNull() ? icon : fromTheme("edit-clear"));
+ } else if (name == "edit-clear-locationbar-ltr") {
+ cache.insert(name, !icon.isNull() ? icon : fromTheme("edit-clear"));
+ } else {
+ cache.insert(name, icon);
+ }
+
+ return cache[name];
+}
+
} // namespace Utils
diff --git a/src/libs/utils/icon.h b/src/libs/utils/icon.h
index c2c5e7a3de5..d26668082bf 100644
--- a/src/libs/utils/icon.h
+++ b/src/libs/utils/icon.h
@@ -9,8 +9,8 @@
#include "theme/theme.h"
#include <QIcon>
+#include <QList>
#include <QPair>
-#include <QVector>
QT_BEGIN_NAMESPACE
class QColor;
@@ -40,7 +40,7 @@ public:
Q_DECLARE_FLAGS(IconStyleOptions, IconStyleOption)
Icon();
- Icon(QVector<IconMaskAndColor> args, IconStyleOptions style = ToolBarStyle);
+ Icon(const QList<IconMaskAndColor> &args, IconStyleOptions style = ToolBarStyle);
Icon(const FilePath &imageFileName);
QIcon icon() const;
@@ -61,8 +61,10 @@ public:
static QIcon combinedIcon(const QList<QIcon> &icons);
static QIcon combinedIcon(const QList<Icon> &icons);
+ static QIcon fromTheme(const QString &name);
+
private:
- QVector<IconMaskAndColor> m_iconSourceList;
+ QList<IconMaskAndColor> m_iconSourceList;
IconStyleOptions m_style = None;
mutable int m_lastDevicePixelRatio = -1;
mutable QIcon m_lastIcon;
diff --git a/src/libs/utils/iconbutton.cpp b/src/libs/utils/iconbutton.cpp
new file mode 100644
index 00000000000..746cf0ecb1c
--- /dev/null
+++ b/src/libs/utils/iconbutton.cpp
@@ -0,0 +1,62 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "iconbutton.h"
+
+#include "stylehelper.h"
+#include "theme/theme.h"
+
+#include <QEnterEvent>
+#include <QEvent>
+#include <QPainter>
+
+namespace Utils {
+
+IconButton::IconButton(QWidget *parent)
+ : QAbstractButton(parent)
+{
+ setAttribute(Qt::WA_Hover);
+}
+
+void IconButton::paintEvent(QPaintEvent *e)
+{
+ Q_UNUSED(e);
+
+ QPainter p(this);
+ QRect r(QPoint(), size());
+
+ if (m_containsMouse && isEnabled()) {
+ QColor c = creatorTheme()->color(Theme::TextColorDisabled);
+ c.setAlphaF(c.alphaF() * .5);
+ StyleHelper::drawPanelBgRect(&p, r, c);
+ }
+
+ icon().paint(&p, r, Qt::AlignCenter);
+}
+
+void IconButton::enterEvent(QEnterEvent *e)
+{
+ m_containsMouse = true;
+ e->accept();
+ update();
+}
+
+void IconButton::leaveEvent(QEvent *e)
+{
+ m_containsMouse = false;
+ e->accept();
+ update();
+}
+
+QSize IconButton::sizeHint() const
+{
+ QWindow *window = this->window()->windowHandle();
+ QSize s = icon().actualSize(window, QSize(32, 16)) + QSize(8, 8);
+
+ if (StyleHelper::toolbarStyle() == StyleHelper::ToolbarStyleRelaxed)
+ s += QSize(5, 5);
+
+ return s;
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/iconbutton.h b/src/libs/utils/iconbutton.h
new file mode 100644
index 00000000000..db615eefb11
--- /dev/null
+++ b/src/libs/utils/iconbutton.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "utils_global.h"
+
+#include <QAbstractButton>
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT IconButton : public QAbstractButton
+{
+public:
+ IconButton(QWidget *parent = nullptr);
+
+ void paintEvent(QPaintEvent *e) override;
+ void enterEvent(QEnterEvent *e) override;
+ void leaveEvent(QEvent *e) override;
+
+ QSize sizeHint() const override;
+
+private:
+ bool m_containsMouse{false};
+};
+
+} // namespace Utils
diff --git a/src/libs/utils/id.cpp b/src/libs/utils/id.cpp
index bc40c154611..383d992da0d 100644
--- a/src/libs/utils/id.cpp
+++ b/src/libs/utils/id.cpp
@@ -158,6 +158,12 @@ QString Id::toString() const
return QString::fromUtf8(stringFromId.value(m_id).str);
}
+/*! \internal */
+Key Id::toKey() const
+{
+ return name();
+}
+
/*!
Creates an id from a string representation.
diff --git a/src/libs/utils/id.h b/src/libs/utils/id.h
index 60351dad902..d1ac2355dd7 100644
--- a/src/libs/utils/id.h
+++ b/src/libs/utils/id.h
@@ -5,6 +5,8 @@
#include "utils_global.h"
+#include "storekey.h"
+
#include <QList>
#include <QMetaType>
#include <QString>
@@ -30,6 +32,7 @@ public:
QByteArray name() const;
QString toString() const; // Avoid.
+ Key toKey() const; // FIXME: Replace uses with .name() after Store/key transition.
QVariant toSetting() const; // Good to use.
QString suffixAfter(Id baseId) const;
bool isValid() const { return m_id; }
diff --git a/src/libs/utils/images/continue_1_small.png b/src/libs/utils/images/continue_1_small.png
new file mode 100644
index 00000000000..6a78780905c
--- /dev/null
+++ b/src/libs/utils/images/continue_1_small.png
Binary files differ
diff --git a/src/libs/utils/images/continue_1_small@2x.png b/src/libs/utils/images/continue_1_small@2x.png
new file mode 100644
index 00000000000..d4235bd5653
--- /dev/null
+++ b/src/libs/utils/images/continue_1_small@2x.png
Binary files differ
diff --git a/src/libs/utils/images/continue_2_small.png b/src/libs/utils/images/continue_2_small.png
new file mode 100644
index 00000000000..876cb829bf5
--- /dev/null
+++ b/src/libs/utils/images/continue_2_small.png
Binary files differ
diff --git a/src/libs/utils/images/continue_2_small@2x.png b/src/libs/utils/images/continue_2_small@2x.png
new file mode 100644
index 00000000000..5794fa039ed
--- /dev/null
+++ b/src/libs/utils/images/continue_2_small@2x.png
Binary files differ
diff --git a/src/libs/utils/images/debugger_overlay_small.png b/src/libs/utils/images/debugger_overlay_small.png
new file mode 100644
index 00000000000..809bf347326
--- /dev/null
+++ b/src/libs/utils/images/debugger_overlay_small.png
Binary files differ
diff --git a/src/libs/utils/images/debugger_overlay_small@2x.png b/src/libs/utils/images/debugger_overlay_small@2x.png
new file mode 100644
index 00000000000..c24c861cbbb
--- /dev/null
+++ b/src/libs/utils/images/debugger_overlay_small@2x.png
Binary files differ
diff --git a/src/libs/utils/infobar.cpp b/src/libs/utils/infobar.cpp
index 430a294adcd..37daa486def 100644
--- a/src/libs/utils/infobar.cpp
+++ b/src/libs/utils/infobar.cpp
@@ -13,7 +13,6 @@
#include <QHBoxLayout>
#include <QLabel>
#include <QPainter>
-#include <QSettings>
#include <QToolButton>
#include <QVBoxLayout>
@@ -22,7 +21,7 @@ static const char C_SUPPRESSED_WARNINGS[] = "SuppressedWarnings";
namespace Utils {
QSet<Id> InfoBar::globallySuppressed;
-QSettings *InfoBar::m_settings = nullptr;
+QtcSettings *InfoBar::m_settings = nullptr;
class InfoBarWidget : public QWidget
{
@@ -184,17 +183,17 @@ void InfoBar::globallyUnsuppressInfo(Id id)
writeGloballySuppressedToSettings();
}
-void InfoBar::initialize(QSettings *settings)
+void InfoBar::initialize(QtcSettings *settings)
{
m_settings = settings;
if (QTC_GUARD(m_settings)) {
- const QStringList list = m_settings->value(QLatin1String(C_SUPPRESSED_WARNINGS)).toStringList();
+ const QStringList list = m_settings->value(C_SUPPRESSED_WARNINGS).toStringList();
globallySuppressed = transform<QSet>(list, Id::fromString);
}
}
-QSettings *InfoBar::settings()
+QtcSettings *InfoBar::settings()
{
return m_settings;
}
@@ -216,7 +215,7 @@ void InfoBar::writeGloballySuppressedToSettings()
if (!m_settings)
return;
const QStringList list = transform<QList>(globallySuppressed, &Id::toString);
- QtcSettings::setValueWithDefault(m_settings, C_SUPPRESSED_WARNINGS, list);
+ m_settings->setValueWithDefault(C_SUPPRESSED_WARNINGS, list);
}
diff --git a/src/libs/utils/infobar.h b/src/libs/utils/infobar.h
index 11657375c5b..c59e6164ab4 100644
--- a/src/libs/utils/infobar.h
+++ b/src/libs/utils/infobar.h
@@ -6,6 +6,7 @@
#include "utils_global.h"
#include "id.h"
+#include "qtcsettings.h"
#include <QObject>
#include <QSet>
@@ -102,8 +103,8 @@ public:
static void clearGloballySuppressed();
static bool anyGloballySuppressed();
- static void initialize(QSettings *settings);
- static QSettings *settings();
+ static void initialize(QtcSettings *settings);
+ static QtcSettings *settings();
signals:
void changed();
@@ -116,15 +117,13 @@ private:
QSet<Id> m_suppressed;
static QSet<Id> globallySuppressed;
- static QSettings *m_settings;
+ static QtcSettings *m_settings;
friend class InfoBarDisplay;
};
class QTCREATOR_UTILS_EXPORT InfoBarDisplay : public QObject
{
- Q_OBJECT
-
public:
InfoBarDisplay(QObject *parent = nullptr);
void setTarget(QBoxLayout *layout, int index);
diff --git a/src/libs/utils/itemviews.cpp b/src/libs/utils/itemviews.cpp
index 27f7cbb4281..c043b07ff52 100644
--- a/src/libs/utils/itemviews.cpp
+++ b/src/libs/utils/itemviews.cpp
@@ -3,6 +3,8 @@
#include "itemviews.h"
+namespace Utils {
+
/*!
\class Utils::TreeView
\inmodule QtCreator
@@ -12,6 +14,8 @@
platforms where the default is different. Use with care.
Also adds sane keyboard navigation for mac.
+
+ Note: This uses setUniformRowHeights(true) by default.
*/
/*!
@@ -23,6 +27,8 @@
platforms where the default is different. Use with care.
Also adds sane keyboard navigation for mac.
+
+ Note: This uses setUniformRowHeights(true) by default.
*/
/*!
@@ -46,3 +52,25 @@
Also adds sane keyboard navigation for mac.
*/
+
+TreeView::TreeView(QWidget *parent)
+ : View<QTreeView>(parent)
+{
+ setUniformRowHeights(true);
+}
+
+TreeWidget::TreeWidget(QWidget *parent)
+ : View<QTreeWidget>(parent)
+{
+ setUniformRowHeights(true);
+}
+
+ListView::ListView(QWidget *parent)
+ : View<QListView>(parent)
+{}
+
+ListWidget::ListWidget(QWidget *parent)
+ : View<QListWidget>(parent)
+{}
+
+} // Utils
diff --git a/src/libs/utils/itemviews.h b/src/libs/utils/itemviews.h
index 8b5074b20cc..50e8a4af01e 100644
--- a/src/libs/utils/itemviews.h
+++ b/src/libs/utils/itemviews.h
@@ -63,38 +63,26 @@ public:
class QTCREATOR_UTILS_EXPORT TreeView : public View<QTreeView>
{
- Q_OBJECT
public:
- TreeView(QWidget *parent = nullptr)
- : View<QTreeView>(parent)
- {}
+ TreeView(QWidget *parent = nullptr);
};
class QTCREATOR_UTILS_EXPORT TreeWidget : public View<QTreeWidget>
{
- Q_OBJECT
public:
- TreeWidget(QWidget *parent = nullptr)
- : View<QTreeWidget>(parent)
- {}
+ TreeWidget(QWidget *parent = nullptr);
};
class QTCREATOR_UTILS_EXPORT ListView : public View<QListView>
{
- Q_OBJECT
public:
- ListView(QWidget *parent = nullptr)
- : View<QListView>(parent)
- {}
+ ListView(QWidget *parent = nullptr);
};
class QTCREATOR_UTILS_EXPORT ListWidget : public View<QListWidget>
{
- Q_OBJECT
public:
- ListWidget(QWidget *parent = nullptr)
- : View<QListWidget>(parent)
- {}
+ ListWidget(QWidget *parent = nullptr);
};
} // Utils
diff --git a/src/libs/utils/json.cpp b/src/libs/utils/json.cpp
deleted file mode 100644
index 5afd4a685b7..00000000000
--- a/src/libs/utils/json.cpp
+++ /dev/null
@@ -1,722 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "json.h"
-
-#include "fileutils.h"
-#include "qtcassert.h"
-
-#include <QDir>
-#include <QJsonDocument>
-
-using namespace Utils;
-
-JsonMemoryPool::~JsonMemoryPool()
-{
- for (char *obj : std::as_const(_objs)) {
- reinterpret_cast<JsonValue *>(obj)->~JsonValue();
- delete[] obj;
- }
-}
-
-JsonValue::JsonValue(Kind kind)
- : m_kind(kind)
-{}
-
-JsonValue::~JsonValue() = default;
-
-JsonValue *JsonValue::create(const QString &s, JsonMemoryPool *pool)
-{
- const QJsonDocument document = QJsonDocument::fromJson(s.toUtf8());
- if (document.isNull())
- return nullptr;
-
- return build(document.toVariant(), pool);
-}
-
-void *JsonValue::operator new(size_t size, JsonMemoryPool *pool)
-{ return pool->allocate(size); }
-
-void JsonValue::operator delete(void *)
-{ }
-
-void JsonValue::operator delete(void *, JsonMemoryPool *)
-{ }
-
-QString JsonValue::kindToString(JsonValue::Kind kind)
-{
- if (kind == String)
- return QLatin1String("string");
- if (kind == Double)
- return QLatin1String("number");
- if (kind == Int)
- return QLatin1String("integer");
- if (kind == Object)
- return QLatin1String("object");
- if (kind == Array)
- return QLatin1String("array");
- if (kind == Boolean)
- return QLatin1String("boolean");
- if (kind == Null)
- return QLatin1String("null");
-
- return QLatin1String("unknown");
-}
-
-JsonValue *JsonValue::build(const QVariant &variant, JsonMemoryPool *pool)
-{
- switch (variant.typeId()) {
-
- case QVariant::List: {
- auto newValue = new (pool) JsonArrayValue;
- const QList<QVariant> list = variant.toList();
- for (const QVariant &element : list)
- newValue->addElement(build(element, pool));
- return newValue;
- }
-
- case QVariant::Map: {
- auto newValue = new (pool) JsonObjectValue;
- const QVariantMap variantMap = variant.toMap();
- for (QVariantMap::const_iterator it = variantMap.begin(); it != variantMap.end(); ++it)
- newValue->addMember(it.key(), build(it.value(), pool));
- return newValue;
- }
-
- case QVariant::String:
- return new (pool) JsonStringValue(variant.toString());
-
- case QVariant::Int:
- return new (pool) JsonIntValue(variant.toInt());
-
- case QVariant::Double:
- return new (pool) JsonDoubleValue(variant.toDouble());
-
- case QVariant::Bool:
- return new (pool) JsonBooleanValue(variant.toBool());
-
- case QVariant::Invalid:
- return new (pool) JsonNullValue;
-
- default:
- break;
- }
-
- return nullptr;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-QString JsonSchema::kType() { return QStringLiteral("type"); }
-QString JsonSchema::kProperties() { return QStringLiteral("properties"); }
-QString JsonSchema::kPatternProperties() { return QStringLiteral("patternProperties"); }
-QString JsonSchema::kAdditionalProperties() { return QStringLiteral("additionalProperties"); }
-QString JsonSchema::kItems() { return QStringLiteral("items"); }
-QString JsonSchema::kAdditionalItems() { return QStringLiteral("additionalItems"); }
-QString JsonSchema::kRequired() { return QStringLiteral("required"); }
-QString JsonSchema::kDependencies() { return QStringLiteral("dependencies"); }
-QString JsonSchema::kMinimum() { return QStringLiteral("minimum"); }
-QString JsonSchema::kMaximum() { return QStringLiteral("maximum"); }
-QString JsonSchema::kExclusiveMinimum() { return QStringLiteral("exclusiveMinimum"); }
-QString JsonSchema::kExclusiveMaximum() { return QStringLiteral("exclusiveMaximum"); }
-QString JsonSchema::kMinItems() { return QStringLiteral("minItems"); }
-QString JsonSchema::kMaxItems() { return QStringLiteral("maxItems"); }
-QString JsonSchema::kUniqueItems() { return QStringLiteral("uniqueItems"); }
-QString JsonSchema::kPattern() { return QStringLiteral("pattern"); }
-QString JsonSchema::kMinLength() { return QStringLiteral("minLength"); }
-QString JsonSchema::kMaxLength() { return QStringLiteral("maxLength"); }
-QString JsonSchema::kTitle() { return QStringLiteral("title"); }
-QString JsonSchema::kDescription() { return QStringLiteral("description"); }
-QString JsonSchema::kExtends() { return QStringLiteral("extends"); }
-QString JsonSchema::kRef() { return QStringLiteral("$ref"); }
-
-JsonSchema::JsonSchema(JsonObjectValue *rootObject, const JsonSchemaManager *manager)
- : m_manager(manager)
-{
- enter(rootObject);
-}
-
-bool JsonSchema::isTypeConstrained() const
-{
- // Simple types
- if (JsonStringValue *sv = getStringValue(kType(), currentValue()))
- return isCheckableType(sv->value());
-
- // Union types
- if (JsonArrayValue *av = getArrayValue(kType(), currentValue())) {
- QTC_ASSERT(currentIndex() != -1, return false);
- QTC_ASSERT(av->elements().at(currentIndex())->kind() == JsonValue::String, return false);
- JsonStringValue *sv = av->elements().at(currentIndex())->toString();
- return isCheckableType(sv->value());
- }
-
- return false;
-}
-
-bool JsonSchema::acceptsType(const QString &type) const
-{
- // Simple types
- if (JsonStringValue *sv = getStringValue(kType(), currentValue()))
- return typeMatches(sv->value(), type);
-
- // Union types
- if (JsonArrayValue *av = getArrayValue(kType(), currentValue())) {
- QTC_ASSERT(currentIndex() != -1, return false);
- QTC_ASSERT(av->elements().at(currentIndex())->kind() == JsonValue::String, return false);
- JsonStringValue *sv = av->elements().at(currentIndex())->toString();
- return typeMatches(sv->value(), type);
- }
-
- return false;
-}
-
-QStringList JsonSchema::validTypes(JsonObjectValue *v)
-{
- QStringList all;
-
- if (JsonStringValue *sv = getStringValue(kType(), v))
- all.append(sv->value());
-
- if (JsonObjectValue *ov = getObjectValue(kType(), v))
- return validTypes(ov);
-
- if (JsonArrayValue *av = getArrayValue(kType(), v)) {
- const QList<JsonValue *> elements = av->elements();
- for (JsonValue *v : elements) {
- if (JsonStringValue *sv = v->toString())
- all.append(sv->value());
- else if (JsonObjectValue *ov = v->toObject())
- all.append(validTypes(ov));
- }
- }
-
- return all;
-}
-
-bool JsonSchema::typeMatches(const QString &expected, const QString &actual)
-{
- if (expected == QLatin1String("number") && actual == QLatin1String("integer"))
- return true;
-
- return expected == actual;
-}
-
-bool JsonSchema::isCheckableType(const QString &s)
-{
- return s == QLatin1String("string")
- || s == QLatin1String("number")
- || s == QLatin1String("integer")
- || s == QLatin1String("boolean")
- || s == QLatin1String("object")
- || s == QLatin1String("array")
- || s == QLatin1String("null");
-}
-
-QStringList JsonSchema::validTypes() const
-{
- return validTypes(currentValue());
-}
-
-bool JsonSchema::hasTypeSchema() const
-{
- return getObjectValue(kType(), currentValue());
-}
-
-void JsonSchema::enterNestedTypeSchema()
-{
- QTC_ASSERT(hasTypeSchema(), return);
-
- enter(getObjectValue(kType(), currentValue()));
-}
-
-QStringList JsonSchema::properties(JsonObjectValue *v) const
-{
- using Members = QHash<QString, JsonValue *>;
-
- QStringList all;
-
- if (JsonObjectValue *ov = getObjectValue(kProperties(), v)) {
- const Members members = ov->members();
- const Members::ConstIterator cend = members.constEnd();
- for (Members::ConstIterator it = members.constBegin(); it != cend; ++it)
- if (hasPropertySchema(it.key()))
- all.append(it.key());
- }
-
- if (JsonObjectValue *base = resolveBase(v))
- all.append(properties(base));
-
- return all;
-}
-
-QStringList JsonSchema::properties() const
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Object)), return QStringList());
-
- return properties(currentValue());
-}
-
-JsonObjectValue *JsonSchema::propertySchema(const QString &property,
- JsonObjectValue *v) const
-{
- if (JsonObjectValue *ov = getObjectValue(kProperties(), v)) {
- JsonValue *member = ov->member(property);
- if (member && member->kind() == JsonValue::Object)
- return member->toObject();
- }
-
- if (JsonObjectValue *base = resolveBase(v))
- return propertySchema(property, base);
-
- return nullptr;
-}
-
-bool JsonSchema::hasPropertySchema(const QString &property) const
-{
- return propertySchema(property, currentValue());
-}
-
-void JsonSchema::enterNestedPropertySchema(const QString &property)
-{
- QTC_ASSERT(hasPropertySchema(property), return);
-
- JsonObjectValue *schema = propertySchema(property, currentValue());
-
- enter(schema);
-}
-
-/*!
- * An array schema is allowed to have its \e items specification in the form of
- * another schema
- * or in the form of an array of schemas [Sec. 5.5]. This functions checks whether this is case
- * in which the items are a schema.
- *
- * Returns whether or not the items from the array are a schema.
- */
-bool JsonSchema::hasItemSchema() const
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Array)), return false);
-
- return getObjectValue(kItems(), currentValue());
-}
-
-void JsonSchema::enterNestedItemSchema()
-{
- QTC_ASSERT(hasItemSchema(), return);
-
- enter(getObjectValue(kItems(), currentValue()));
-}
-
-/*!
- * An array schema is allowed to have its \e items specification in the form of another schema
- * or in the form of an array of schemas [Sec. 5.5]. This functions checks whether this is case
- * in which the items are an array of schemas.
- *
- * Returns whether or not the items from the array are a an array of schemas.
- */
-bool JsonSchema::hasItemArraySchema() const
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Array)), return false);
-
- return getArrayValue(kItems(), currentValue());
-}
-
-int JsonSchema::itemArraySchemaSize() const
-{
- QTC_ASSERT(hasItemArraySchema(), return false);
-
- return getArrayValue(kItems(), currentValue())->size();
-}
-
-/*!
- * When evaluating the items of an array it might be necessary to \e enter a
- * particular schema,
- * since this API assumes that there's always a valid schema in context (the one the user is
- * interested on). This shall only happen if the item at the supplied array index is of type
- * object, which is then assumed to be a schema.
- *
- * The function also marks the context as being inside an array evaluation.
- *
- * Returns whether it was necessary to enter a schema for the supplied
- * array \a index, false if index is out of bounds.
- */
-bool JsonSchema::maybeEnterNestedArraySchema(int index)
-{
- QTC_ASSERT(itemArraySchemaSize(), return false);
- QTC_ASSERT(index >= 0 && index < itemArraySchemaSize(), return false);
-
- JsonValue *v = getArrayValue(kItems(), currentValue())->elements().at(index);
-
- return maybeEnter(v, Array, index);
-}
-
-/*!
- * The type of a schema can be specified in the form of a union type, which is basically an
- * array of allowed types for the particular instance [Sec. 5.1]. This function checks whether
- * the current schema is one of such.
- *
- * Returns whether or not the current schema specifies a union type.
- */
-bool JsonSchema::hasUnionSchema() const
-{
- return getArrayValue(kType(), currentValue());
-}
-
-int JsonSchema::unionSchemaSize() const
-{
- return getArrayValue(kType(), currentValue())->size();
-}
-
-/*!
- * When evaluating union types it might be necessary to enter a particular
- * schema, since this
- * API assumes that there's always a valid schema in context (the one the user is interested on).
- * This shall only happen if the item at the supplied union \a index, which is then assumed to be
- * a schema.
- *
- * The function also marks the context as being inside an union evaluation.
- *
- * Returns whether or not it was necessary to enter a schema for the
- * supplied union index.
- */
-bool JsonSchema::maybeEnterNestedUnionSchema(int index)
-{
- QTC_ASSERT(unionSchemaSize(), return false);
- QTC_ASSERT(index >= 0 && index < unionSchemaSize(), return false);
-
- JsonValue *v = getArrayValue(kType(), currentValue())->elements().at(index);
-
- return maybeEnter(v, Union, index);
-}
-
-void JsonSchema::leaveNestedSchema()
-{
- QTC_ASSERT(!m_schemas.isEmpty(), return);
-
- leave();
-}
-
-bool JsonSchema::required() const
-{
- if (JsonBooleanValue *bv = getBooleanValue(kRequired(), currentValue()))
- return bv->value();
-
- return false;
-}
-
-bool JsonSchema::hasMinimum() const
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
-
- return getDoubleValue(kMinimum(), currentValue());
-}
-
-double JsonSchema::minimum() const
-{
- QTC_ASSERT(hasMinimum(), return 0);
-
- return getDoubleValue(kMinimum(), currentValue())->value();
-}
-
-bool JsonSchema::hasExclusiveMinimum()
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
-
- if (JsonBooleanValue *bv = getBooleanValue(kExclusiveMinimum(), currentValue()))
- return bv->value();
-
- return false;
-}
-
-bool JsonSchema::hasMaximum() const
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
-
- return getDoubleValue(kMaximum(), currentValue());
-}
-
-double JsonSchema::maximum() const
-{
- QTC_ASSERT(hasMaximum(), return 0);
-
- return getDoubleValue(kMaximum(), currentValue())->value();
-}
-
-bool JsonSchema::hasExclusiveMaximum()
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Int)), return false);
-
- if (JsonBooleanValue *bv = getBooleanValue(kExclusiveMaximum(), currentValue()))
- return bv->value();
-
- return false;
-}
-
-QString JsonSchema::pattern() const
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::String)), return QString());
-
- if (JsonStringValue *sv = getStringValue(kPattern(), currentValue()))
- return sv->value();
-
- return QString();
-}
-
-int JsonSchema::minimumLength() const
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::String)), return -1);
-
- if (JsonDoubleValue *dv = getDoubleValue(kMinLength(), currentValue()))
- return dv->value();
-
- return -1;
-}
-
-int JsonSchema::maximumLength() const
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::String)), return -1);
-
- if (JsonDoubleValue *dv = getDoubleValue(kMaxLength(), currentValue()))
- return dv->value();
-
- return -1;
-}
-
-bool JsonSchema::hasAdditionalItems() const
-{
- QTC_ASSERT(acceptsType(JsonValue::kindToString(JsonValue::Array)), return false);
-
- return currentValue()->member(kAdditionalItems());
-}
-
-bool JsonSchema::maybeSchemaName(const QString &s)
-{
- if (s.isEmpty() || s == QLatin1String("any"))
- return false;
-
- return !isCheckableType(s);
-}
-
-JsonObjectValue *JsonSchema::rootValue() const
-{
- QTC_ASSERT(!m_schemas.isEmpty(), return nullptr);
-
- return m_schemas.first().m_value;
-}
-
-JsonObjectValue *JsonSchema::currentValue() const
-{
- QTC_ASSERT(!m_schemas.isEmpty(), return nullptr);
-
- return m_schemas.last().m_value;
-}
-
-int JsonSchema::currentIndex() const
-{
- QTC_ASSERT(!m_schemas.isEmpty(), return 0);
-
- return m_schemas.last().m_index;
-}
-
-void JsonSchema::evaluate(EvaluationMode eval, int index)
-{
- QTC_ASSERT(!m_schemas.isEmpty(), return);
-
- m_schemas.last().m_eval = eval;
- m_schemas.last().m_index = index;
-}
-
-void JsonSchema::enter(JsonObjectValue *ov, EvaluationMode eval, int index)
-{
- Context context;
- context.m_eval = eval;
- context.m_index = index;
- context.m_value = resolveReference(ov);
-
- m_schemas.push_back(context);
-}
-
-bool JsonSchema::maybeEnter(JsonValue *v, EvaluationMode eval, int index)
-{
- evaluate(eval, index);
-
- if (v->kind() == JsonValue::Object) {
- enter(v->toObject());
- return true;
- }
-
- if (v->kind() == JsonValue::String) {
- const QString &s = v->toString()->value();
- if (maybeSchemaName(s)) {
- JsonSchema *schema = m_manager->schemaByName(s);
- if (schema) {
- enter(schema->rootValue());
- return true;
- }
- }
- }
-
- return false;
-}
-
-void JsonSchema::leave()
-{
- QTC_ASSERT(!m_schemas.isEmpty(), return);
-
- m_schemas.pop_back();
-}
-
-JsonObjectValue *JsonSchema::resolveReference(JsonObjectValue *ov) const
-{
- if (JsonStringValue *sv = getStringValue(kRef(), ov)) {
- JsonSchema *referenced = m_manager->schemaByName(sv->value());
- if (referenced)
- return referenced->rootValue();
- }
-
- return ov;
-}
-
-JsonObjectValue *JsonSchema::resolveBase(JsonObjectValue *ov) const
-{
- if (JsonValue *v = ov->member(kExtends())) {
- if (v->kind() == JsonValue::String) {
- JsonSchema *schema = m_manager->schemaByName(v->toString()->value());
- if (schema)
- return schema->rootValue();
- } else if (v->kind() == JsonValue::Object) {
- return resolveReference(v->toObject());
- }
- }
-
- return nullptr;
-}
-
-JsonStringValue *JsonSchema::getStringValue(const QString &name, JsonObjectValue *value)
-{
- JsonValue *v = value->member(name);
- if (!v)
- return nullptr;
-
- return v->toString();
-}
-
-JsonObjectValue *JsonSchema::getObjectValue(const QString &name, JsonObjectValue *value)
-{
- JsonValue *v = value->member(name);
- if (!v)
- return nullptr;
-
- return v->toObject();
-}
-
-JsonBooleanValue *JsonSchema::getBooleanValue(const QString &name, JsonObjectValue *value)
-{
- JsonValue *v = value->member(name);
- if (!v)
- return nullptr;
-
- return v->toBoolean();
-}
-
-JsonArrayValue *JsonSchema::getArrayValue(const QString &name, JsonObjectValue *value)
-{
- JsonValue *v = value->member(name);
- if (!v)
- return nullptr;
-
- return v->toArray();
-}
-
-JsonDoubleValue *JsonSchema::getDoubleValue(const QString &name, JsonObjectValue *value)
-{
- JsonValue *v = value->member(name);
- if (!v)
- return nullptr;
-
- return v->toDouble();
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-JsonSchemaManager::JsonSchemaManager(const QStringList &searchPaths)
- : m_searchPaths(searchPaths)
-{
- for (const QString &path : searchPaths) {
- QDir dir(path);
- if (!dir.exists())
- continue;
- dir.setNameFilters(QStringList(QLatin1String("*.json")));
- const QList<QFileInfo> entries = dir.entryInfoList();
- for (const QFileInfo &fi : entries)
- m_schemas.insert(fi.baseName(), JsonSchemaData(fi.absoluteFilePath()));
- }
-}
-
-JsonSchemaManager::~JsonSchemaManager()
-{
- for (const JsonSchemaData &schemaData : std::as_const(m_schemas))
- delete schemaData.m_schema;
-}
-
-/*!
- * Tries to find a JSON schema to validate \a fileName against. According
- * to the specification, how the schema/instance association is done is implementation defined.
- * Currently we use a quite naive approach which is simply based on file names. Specifically,
- * if one opens a foo.json file we'll look for a schema named foo.json. We should probably
- * investigate alternative settings later.
- *
- * Returns a valid schema or 0.
- */
-JsonSchema *JsonSchemaManager::schemaForFile(const QString &fileName) const
-{
- QString baseName(QFileInfo(fileName).baseName());
-
- return schemaByName(baseName);
-}
-
-JsonSchema *JsonSchemaManager::schemaByName(const QString &baseName) const
-{
- QHash<QString, JsonSchemaData>::iterator it = m_schemas.find(baseName);
- if (it == m_schemas.end()) {
- for (const QString &path : m_searchPaths) {
- QFileInfo candidate(path + baseName + ".json");
- if (candidate.exists()) {
- m_schemas.insert(baseName, candidate.absoluteFilePath());
- break;
- }
- }
- }
-
- it = m_schemas.find(baseName);
- if (it == m_schemas.end())
- return nullptr;
-
- JsonSchemaData *schemaData = &it.value();
- if (!schemaData->m_schema) {
- // Schemas are built on-demand.
- QFileInfo currentSchema(schemaData->m_absoluteFileName);
- Q_ASSERT(currentSchema.exists());
- if (schemaData->m_lastParseAttempt.isNull()
- || schemaData->m_lastParseAttempt < currentSchema.lastModified()) {
- schemaData->m_schema = parseSchema(currentSchema.absoluteFilePath());
- }
- }
-
- return schemaData->m_schema;
-}
-
-JsonSchema *JsonSchemaManager::parseSchema(const QString &schemaFileName) const
-{
- FileReader reader;
- if (reader.fetch(FilePath::fromString(schemaFileName), QIODevice::Text)) {
- const QString &contents = QString::fromUtf8(reader.data());
- JsonValue *json = JsonValue::create(contents, &m_pool);
- if (json && json->kind() == JsonValue::Object)
- return new JsonSchema(json->toObject(), this);
- }
-
- return nullptr;
-}
diff --git a/src/libs/utils/json.h b/src/libs/utils/json.h
deleted file mode 100644
index 96a06772083..00000000000
--- a/src/libs/utils/json.h
+++ /dev/null
@@ -1,398 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include "utils_global.h"
-
-#include <QDateTime>
-#include <QHash>
-#include <QStringList>
-#include <QVector>
-
-QT_BEGIN_NAMESPACE
-class QVariant;
-QT_END_NAMESPACE
-
-namespace Utils {
-
-class JsonStringValue;
-class JsonDoubleValue;
-class JsonIntValue;
-class JsonObjectValue;
-class JsonArrayValue;
-class JsonBooleanValue;
-class JsonNullValue;
-
-class QTCREATOR_UTILS_EXPORT JsonMemoryPool
-{
-public:
- ~JsonMemoryPool();
-
- inline void *allocate(size_t size)
- {
- auto obj = new char[size];
- _objs.append(obj);
- return obj;
- }
-
-private:
- QVector<char *> _objs;
-};
-
-/*!
- * \brief The JsonValue class
- */
-class QTCREATOR_UTILS_EXPORT JsonValue
-{
-public:
- enum Kind {
- String,
- Double,
- Int,
- Object,
- Array,
- Boolean,
- Null,
- Unknown
- };
-
- virtual ~JsonValue();
-
- Kind kind() const { return m_kind; }
- static QString kindToString(Kind kind);
-
- virtual JsonStringValue *toString() { return nullptr; }
- virtual JsonDoubleValue *toDouble() { return nullptr; }
- virtual JsonIntValue *toInt() { return nullptr; }
- virtual JsonObjectValue *toObject() { return nullptr; }
- virtual JsonArrayValue *toArray() { return nullptr; }
- virtual JsonBooleanValue *toBoolean() { return nullptr; }
- virtual JsonNullValue *toNull() { return nullptr; }
-
- static JsonValue *create(const QString &s, JsonMemoryPool *pool);
- void *operator new(size_t size, JsonMemoryPool *pool);
- void operator delete(void *);
- void operator delete(void *, JsonMemoryPool *);
-
-protected:
- JsonValue(Kind kind);
-
-private:
- static JsonValue *build(const QVariant &varixant, JsonMemoryPool *pool);
-
- Kind m_kind;
-};
-
-
-/*!
- * \brief The JsonStringValue class
- */
-class QTCREATOR_UTILS_EXPORT JsonStringValue : public JsonValue
-{
-public:
- JsonStringValue(const QString &value)
- : JsonValue(String)
- , m_value(value)
- {}
-
- JsonStringValue *toString() override { return this; }
-
- const QString &value() const { return m_value; }
-
-private:
- QString m_value;
-};
-
-
-/*!
- * \brief The JsonDoubleValue class
- */
-class QTCREATOR_UTILS_EXPORT JsonDoubleValue : public JsonValue
-{
-public:
- JsonDoubleValue(double value)
- : JsonValue(Double)
- , m_value(value)
- {}
-
- JsonDoubleValue *toDouble() override { return this; }
-
- double value() const { return m_value; }
-
-private:
- double m_value;
-};
-
-/*!
- * \brief The JsonIntValue class
- */
-class QTCREATOR_UTILS_EXPORT JsonIntValue : public JsonValue
-{
-public:
- JsonIntValue(int value)
- : JsonValue(Int)
- , m_value(value)
- {}
-
- JsonIntValue *toInt() override { return this; }
-
- int value() const { return m_value; }
-
-private:
- int m_value;
-};
-
-
-/*!
- * \brief The JsonObjectValue class
- */
-class QTCREATOR_UTILS_EXPORT JsonObjectValue : public JsonValue
-{
-public:
- JsonObjectValue()
- : JsonValue(Object)
- {}
-
- JsonObjectValue *toObject() override { return this; }
-
- void addMember(const QString &name, JsonValue *value) { m_members.insert(name, value); }
- bool hasMember(const QString &name) const { return m_members.contains(name); }
- JsonValue *member(const QString &name) const { return m_members.value(name); }
- QHash<QString, JsonValue *> members() const { return m_members; }
- bool isEmpty() const { return m_members.isEmpty(); }
-
-protected:
- JsonObjectValue(Kind kind)
- : JsonValue(kind)
- {}
-
-private:
- QHash<QString, JsonValue *> m_members;
-};
-
-
-/*!
- * \brief The JsonArrayValue class
- */
-class QTCREATOR_UTILS_EXPORT JsonArrayValue : public JsonValue
-{
-public:
- JsonArrayValue()
- : JsonValue(Array)
- {}
-
- JsonArrayValue *toArray() override { return this; }
-
- void addElement(JsonValue *value) { m_elements.append(value); }
- QList<JsonValue *> elements() const { return m_elements; }
- int size() const { return m_elements.size(); }
-
-private:
- QList<JsonValue *> m_elements;
-};
-
-
-/*!
- * \brief The JsonBooleanValue class
- */
-class QTCREATOR_UTILS_EXPORT JsonBooleanValue : public JsonValue
-{
-public:
- JsonBooleanValue(bool value)
- : JsonValue(Boolean)
- , m_value(value)
- {}
-
- JsonBooleanValue *toBoolean() override { return this; }
-
- bool value() const { return m_value; }
-
-private:
- bool m_value;
-};
-
-class QTCREATOR_UTILS_EXPORT JsonNullValue : public JsonValue
-{
-public:
- JsonNullValue()
- : JsonValue(Null)
- {}
-
- JsonNullValue *toNull() override { return this; }
-};
-
-class JsonSchemaManager;
-
-/*!
- * \brief The JsonSchema class
- *
- * [NOTE: This is an incomplete implementation and a work in progress.]
- *
- * This class provides an interface for traversing and evaluating a JSON schema, as described
- * in the draft http://tools.ietf.org/html/draft-zyp-json-schema-03.
- *
- * JSON schemas are recursive in concept. This means that a particular attribute from a schema
- * might be also another schema. Therefore, the basic working principle of this API is that
- * from within some schema, one can investigate its attributes and if necessary "enter" a
- * corresponding nested schema. Afterwards, it's expected that one would "leave" such nested
- * schema.
- *
- * All functions assume that the current "context" is a valid schema. Once an instance of this
- * class is created the root schema is put on top of the stack.
- *
- */
-class QTCREATOR_UTILS_EXPORT JsonSchema
-{
-public:
- bool isTypeConstrained() const;
- bool acceptsType(const QString &type) const;
- QStringList validTypes() const;
-
- // Applicable on schemas of any type.
- bool required() const;
-
- bool hasTypeSchema() const;
- void enterNestedTypeSchema();
-
- bool hasUnionSchema() const;
- int unionSchemaSize() const;
- bool maybeEnterNestedUnionSchema(int index);
-
- void leaveNestedSchema();
-
- // Applicable on schemas of type number/integer.
- bool hasMinimum() const;
- bool hasMaximum() const;
- bool hasExclusiveMinimum();
- bool hasExclusiveMaximum();
- double minimum() const;
- double maximum() const;
-
- // Applicable on schemas of type string.
- QString pattern() const;
- int minimumLength() const;
- int maximumLength() const;
-
- // Applicable on schemas of type object.
- QStringList properties() const;
- bool hasPropertySchema(const QString &property) const;
- void enterNestedPropertySchema(const QString &property);
-
- // Applicable on schemas of type array.
- bool hasAdditionalItems() const;
-
- bool hasItemSchema() const;
- void enterNestedItemSchema();
-
- bool hasItemArraySchema() const;
- int itemArraySchemaSize() const;
- bool maybeEnterNestedArraySchema(int index);
-
-private:
- friend class JsonSchemaManager;
- JsonSchema(JsonObjectValue *rootObject, const JsonSchemaManager *manager);
- Q_DISABLE_COPY(JsonSchema)
-
- enum EvaluationMode {
- Normal,
- Array,
- Union
- };
-
- void enter(JsonObjectValue *ov, EvaluationMode eval = Normal, int index = -1);
- bool maybeEnter(JsonValue *v, EvaluationMode eval, int index);
- void evaluate(EvaluationMode eval, int index);
- void leave();
-
- JsonObjectValue *resolveReference(JsonObjectValue *ov) const;
- JsonObjectValue *resolveBase(JsonObjectValue *ov) const;
-
- JsonObjectValue *currentValue() const;
- int currentIndex() const;
-
- JsonObjectValue *rootValue() const;
-
- static JsonStringValue *getStringValue(const QString &name, JsonObjectValue *value);
- static JsonObjectValue *getObjectValue(const QString &name, JsonObjectValue *value);
- static JsonBooleanValue *getBooleanValue(const QString &name, JsonObjectValue *value);
- static JsonArrayValue *getArrayValue(const QString &name, JsonObjectValue *value);
- static JsonDoubleValue *getDoubleValue(const QString &name, JsonObjectValue *value);
-
- static QStringList validTypes(JsonObjectValue *v);
- static bool typeMatches(const QString &expected, const QString &actual);
- static bool isCheckableType(const QString &s);
-
- QStringList properties(JsonObjectValue *v) const;
- JsonObjectValue *propertySchema(const QString &property, JsonObjectValue *v) const;
- // TODO: Similar functions for other attributes which require looking into base schemas.
-
- static bool maybeSchemaName(const QString &s);
-
- static QString kType();
- static QString kProperties();
- static QString kPatternProperties();
- static QString kAdditionalProperties();
- static QString kItems();
- static QString kAdditionalItems();
- static QString kRequired();
- static QString kDependencies();
- static QString kMinimum();
- static QString kMaximum();
- static QString kExclusiveMinimum();
- static QString kExclusiveMaximum();
- static QString kMinItems();
- static QString kMaxItems();
- static QString kUniqueItems();
- static QString kPattern();
- static QString kMinLength();
- static QString kMaxLength();
- static QString kTitle();
- static QString kDescription();
- static QString kExtends();
- static QString kRef();
-
- struct Context
- {
- JsonObjectValue *m_value;
- EvaluationMode m_eval;
- int m_index;
- };
-
- QVector<Context> m_schemas;
- const JsonSchemaManager *m_manager;
-};
-
-
-/*!
- * \brief The JsonSchemaManager class
- */
-class QTCREATOR_UTILS_EXPORT JsonSchemaManager
-{
-public:
- JsonSchemaManager(const QStringList &searchPaths);
- ~JsonSchemaManager();
-
- JsonSchema *schemaForFile(const QString &fileName) const;
- JsonSchema *schemaByName(const QString &baseName) const;
-
-private:
- struct JsonSchemaData
- {
- JsonSchemaData(const QString &absoluteFileName, JsonSchema *schema = nullptr)
- : m_absoluteFileName(absoluteFileName)
- , m_schema(schema)
- {}
- QString m_absoluteFileName;
- JsonSchema *m_schema;
- QDateTime m_lastParseAttempt;
- };
-
- JsonSchema *parseSchema(const QString &schemaFileName) const;
-
- QStringList m_searchPaths;
- mutable QHash<QString, JsonSchemaData> m_schemas;
- mutable JsonMemoryPool m_pool;
-};
-
-} // namespace Utils
diff --git a/src/libs/utils/launcherinterface.cpp b/src/libs/utils/launcherinterface.cpp
index 218286521db..d188e224fc1 100644
--- a/src/libs/utils/launcherinterface.cpp
+++ b/src/libs/utils/launcherinterface.cpp
@@ -82,9 +82,13 @@ void LauncherInterfacePrivate::doStart()
connect(m_process, &QProcess::readyReadStandardError,
this, &LauncherInterfacePrivate::handleProcessStderr);
#ifdef Q_OS_UNIX
+# if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
+ m_process->setUnixProcessParameters(QProcess::UnixProcessFlag::CreateNewSession);
+# else
m_process->setChildProcessModifier([] {
setpgid(0, 0);
});
+# endif
#endif
m_process->start(launcherFilePath(), QStringList(m_server->fullServerName()));
diff --git a/src/libs/utils/launchersocket.h b/src/libs/utils/launchersocket.h
index be1b7f7f9ba..54c212c479b 100644
--- a/src/libs/utils/launchersocket.h
+++ b/src/libs/utils/launchersocket.h
@@ -128,7 +128,6 @@ private:
class LauncherHandle : public QObject
{
- Q_OBJECT
public:
// Called from caller's thread, moved to launcher's thread afterwards.
LauncherHandle(quintptr token) : m_token(token) {}
diff --git a/src/libs/utils/layoutbuilder.cpp b/src/libs/utils/layoutbuilder.cpp
index 4d4f01ddbe4..31c67e4d0f6 100644
--- a/src/libs/utils/layoutbuilder.cpp
+++ b/src/libs/utils/layoutbuilder.cpp
@@ -3,20 +3,22 @@
#include "layoutbuilder.h"
+#include <QApplication>
#include <QDebug>
#include <QFormLayout>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QPushButton>
-#include <QStackedLayout>
#include <QSpacerItem>
#include <QSpinBox>
#include <QSplitter>
+#include <QStackedLayout>
+#include <QStackedWidget>
#include <QStyle>
#include <QTabWidget>
#include <QTextEdit>
-#include <QApplication>
+#include <QToolBar>
namespace Layouting {
@@ -220,8 +222,8 @@ LayoutItem::~LayoutItem() = default;
struct ResultItem
{
ResultItem() = default;
- explicit ResultItem(QLayout *l) : layout(l) {}
- explicit ResultItem(QWidget *w) : widget(w) {}
+ explicit ResultItem(QLayout *l) : layout(l), empty(!l) {}
+ explicit ResultItem(QWidget *w) : widget(w), empty(!w) {}
QString text;
QLayout *layout = nullptr;
@@ -236,7 +238,7 @@ struct Slice
{
Slice() = default;
Slice(QLayout *l) : layout(l) {}
- Slice(QWidget *w) : widget(w) {}
+ Slice(QWidget *w, bool isLayouting=false) : widget(w), isLayouting(isLayouting) {}
QLayout *layout = nullptr;
QWidget *widget = nullptr;
@@ -247,6 +249,7 @@ struct Slice
int currentGridColumn = 0;
int currentGridRow = 0;
bool isFormAlignment = false;
+ bool isLayouting = false;
Qt::Alignment align = {}; // Can be changed to
// Grid or Form
@@ -395,14 +398,6 @@ void Slice::flush()
for (const ResultItem &item : std::as_const(pendingItems))
addItemToFlowLayout(flowLayout, item);
- } else if (auto stackLayout = qobject_cast<QStackedLayout *>(layout)) {
- for (const ResultItem &item : std::as_const(pendingItems)) {
- if (item.widget)
- stackLayout->addWidget(item.widget);
- else
- QTC_CHECK(false);
- }
-
} else {
QTC_CHECK(false);
}
@@ -572,9 +567,26 @@ void LayoutItem::attachTo(QWidget *w) const
QWidget *LayoutItem::emerge()
{
- auto w = new QWidget;
- attachTo(w);
- return w;
+ LayoutBuilder builder;
+
+ builder.stack.append(Slice());
+ addItemHelper(builder, *this);
+
+ if (builder.stack.empty())
+ return nullptr;
+
+ QTC_ASSERT(builder.stack.last().pendingItems.size() == 1, return nullptr);
+ ResultItem ri = builder.stack.last().pendingItems.takeFirst();
+
+ QTC_ASSERT(ri.layout || ri.widget, return nullptr);
+
+ if (ri.layout) {
+ auto w = new QWidget;
+ w->setLayout(ri.layout);
+ return w;
+ }
+
+ return ri.widget;
}
static void layoutExit(LayoutBuilder &builder)
@@ -583,12 +595,32 @@ static void layoutExit(LayoutBuilder &builder)
QLayout *layout = builder.stack.last().layout;
builder.stack.pop_back();
- if (QWidget *widget = builder.stack.last().widget)
+ if (builder.stack.last().isLayouting) {
+ builder.stack.last().pendingItems.append(ResultItem(layout));
+ } else if (QWidget *widget = builder.stack.last().widget) {
widget->setLayout(layout);
- else
+ } else
builder.stack.last().pendingItems.append(ResultItem(layout));
}
+template<class T>
+static void layoutingWidgetExit(LayoutBuilder &builder)
+{
+ const Slice slice = builder.stack.last();
+ T *w = qobject_cast<T *>(slice.widget);
+ for (const ResultItem &ri : slice.pendingItems) {
+ if (ri.widget) {
+ w->addWidget(ri.widget);
+ } else if (ri.layout) {
+ auto child = new QWidget;
+ child->setLayout(ri.layout);
+ w->addWidget(child);
+ }
+ }
+ builder.stack.pop_back();
+ builder.stack.last().pendingItems.append(ResultItem(w));
+}
+
static void widgetExit(LayoutBuilder &builder)
{
QWidget *widget = builder.stack.last().widget;
@@ -638,13 +670,6 @@ Form::Form(std::initializer_list<LayoutItem> items)
onExit = layoutExit;
}
-Stack::Stack(std::initializer_list<LayoutItem> items)
-{
- subItems = items;
- onAdd = [](LayoutBuilder &builder) { builder.stack.append(new QStackedLayout); };
- onExit = layoutExit;
-}
-
LayoutItem br()
{
LayoutItem item;
@@ -736,6 +761,18 @@ Group::Group(std::initializer_list<LayoutItem> items)
setupWidget<QGroupBox>(this);
}
+Stack::Stack(std::initializer_list<LayoutItem> items)
+{
+ // We use a QStackedWidget instead of a QStackedLayout here because the latter will call
+ // "setVisible()" when a child is added, which can lead to the widget being spawned as a
+ // top-level widget. This can lead to the focus shifting away from the main application.
+ subItems = items;
+ onAdd = [](LayoutBuilder &builder) {
+ builder.stack.append(Slice(new QStackedWidget, true));
+ };
+ onExit = layoutingWidgetExit<QStackedWidget>;
+}
+
PushButton::PushButton(std::initializer_list<LayoutItem> items)
{
this->subItems = items;
@@ -760,18 +797,20 @@ Splitter::Splitter(std::initializer_list<LayoutItem> items)
onAdd = [](LayoutBuilder &builder) {
auto splitter = new QSplitter;
splitter->setOrientation(Qt::Vertical);
- builder.stack.append(splitter);
+ builder.stack.append(Slice(splitter, true));
};
- onExit = [](LayoutBuilder &builder) {
- const Slice slice = builder.stack.last();
- QSplitter *splitter = qobject_cast<QSplitter *>(slice.widget);
- for (const ResultItem &ri : slice.pendingItems) {
- if (ri.widget)
- splitter->addWidget(ri.widget);
- }
- builder.stack.pop_back();
- builder.stack.last().pendingItems.append(ResultItem(splitter));
+ onExit = layoutingWidgetExit<QSplitter>;
+}
+
+ToolBar::ToolBar(std::initializer_list<LayoutItem> items)
+{
+ subItems = items;
+ onAdd = [](LayoutBuilder &builder) {
+ auto toolbar = new QToolBar;
+ toolbar->setOrientation(Qt::Horizontal);
+ builder.stack.append(Slice(toolbar, true));
};
+ onExit = layoutingWidgetExit<QToolBar>;
}
TabWidget::TabWidget(std::initializer_list<LayoutItem> items)
@@ -798,6 +837,13 @@ Tab::Tab(const QString &tabName, const LayoutItem &item)
};
}
+// Special If
+
+If::If(bool condition, const LayoutItems &items, const LayoutItems &other)
+{
+ subItems.append(condition ? items : other);
+}
+
// Special Application
Application::Application(std::initializer_list<LayoutItem> items)
@@ -833,6 +879,17 @@ LayoutItem title(const QString &title)
};
}
+LayoutItem windowTitle(const QString &windowTitle)
+{
+ return [windowTitle](QObject *target) {
+ if (auto widget = qobject_cast<QWidget *>(target)) {
+ widget->setWindowTitle(windowTitle);
+ } else {
+ QTC_CHECK(false);
+ }
+ };
+}
+
LayoutItem text(const QString &text)
{
return [text](QObject *target) {
@@ -890,6 +947,18 @@ LayoutItem columnStretch(int column, int stretch)
};
}
+LayoutItem fieldGrowthPolicy(QFormLayout::FieldGrowthPolicy policy)
+{
+ return [policy](QObject *target) {
+ if (auto form = qobject_cast<QFormLayout *>(target)) {
+ form->setFieldGrowthPolicy(policy);
+ } else {
+ QTC_CHECK(false);
+ }
+ };
+}
+
+
// Id based setters
LayoutItem id(ID &out)
diff --git a/src/libs/utils/layoutbuilder.h b/src/libs/utils/layoutbuilder.h
index 4a756139897..c9fac7d8383 100644
--- a/src/libs/utils/layoutbuilder.h
+++ b/src/libs/utils/layoutbuilder.h
@@ -3,6 +3,7 @@
#pragma once
+#include <QFormLayout>
#include <QList>
#include <QString>
#include <QtGlobal>
@@ -140,6 +141,12 @@ public:
Tab(const QString &tabName, const LayoutItem &item);
};
+class QTCREATOR_UTILS_EXPORT If : public LayoutItem
+{
+public:
+ If(bool condition, const LayoutItems &item, const LayoutItems &other = {});
+};
+
class QTCREATOR_UTILS_EXPORT Group : public LayoutItem
{
public:
@@ -170,6 +177,12 @@ public:
Splitter(std::initializer_list<LayoutItem> items);
};
+class QTCREATOR_UTILS_EXPORT ToolBar : public LayoutItem
+{
+public:
+ ToolBar(std::initializer_list<LayoutItem> items);
+};
+
class QTCREATOR_UTILS_EXPORT TabWidget : public LayoutItem
{
public:
@@ -215,6 +228,8 @@ QTCREATOR_UTILS_EXPORT LayoutItem resize(int, int);
QTCREATOR_UTILS_EXPORT LayoutItem columnStretch(int column, int stretch);
QTCREATOR_UTILS_EXPORT LayoutItem spacing(int);
QTCREATOR_UTILS_EXPORT LayoutItem windowTitle(const QString &windowTitle);
+QTCREATOR_UTILS_EXPORT LayoutItem fieldGrowthPolicy(QFormLayout::FieldGrowthPolicy policy);
+
// "Getters"
diff --git a/src/libs/utils/link.h b/src/libs/utils/link.h
index 00194654c97..57fb4c896fd 100644
--- a/src/libs/utils/link.h
+++ b/src/libs/utils/link.h
@@ -38,14 +38,19 @@ public:
bool operator==(const Link &other) const
{
- return targetFilePath == other.targetFilePath
- && targetLine == other.targetLine
- && targetColumn == other.targetColumn
- && linkTextStart == other.linkTextStart
- && linkTextEnd == other.linkTextEnd;
+ return hasSameLocation(other)
+ && linkTextStart == other.linkTextStart
+ && linkTextEnd == other.linkTextEnd;
}
bool operator!=(const Link &other) const { return !(*this == other); }
+ bool hasSameLocation(const Link &other) const
+ {
+ return targetFilePath == other.targetFilePath
+ && targetLine == other.targetLine
+ && targetColumn == other.targetColumn;
+ }
+
friend size_t qHash(const Link &l, uint seed = 0)
{ return qHashMulti(seed, l.targetFilePath, l.targetLine, l.targetColumn); }
diff --git a/src/libs/utils/macroexpander.cpp b/src/libs/utils/macroexpander.cpp
index 3ab7d92e9a6..f6d3dad3623 100644
--- a/src/libs/utils/macroexpander.cpp
+++ b/src/libs/utils/macroexpander.cpp
@@ -88,10 +88,10 @@ public:
QHash<QByteArray, MacroExpander::StringFunction> m_map;
QHash<QByteArray, MacroExpander::PrefixFunction> m_prefixMap;
- QVector<MacroExpander::ResolverFunction> m_extraResolvers;
+ QList<MacroExpander::ResolverFunction> m_extraResolvers;
QMap<QByteArray, QString> m_descriptions;
QString m_displayName;
- QVector<MacroExpanderProvider> m_subProviders;
+ QList<MacroExpanderProvider> m_subProviders;
bool m_accumulating = false;
bool m_aborted = false;
diff --git a/src/libs/utils/macroexpander.h b/src/libs/utils/macroexpander.h
index 12172a5e17e..adde4db1d3f 100644
--- a/src/libs/utils/macroexpander.h
+++ b/src/libs/utils/macroexpander.h
@@ -7,7 +7,6 @@
#include <QCoreApplication>
#include <QList>
-#include <QVector>
#include <functional>
@@ -18,7 +17,7 @@ namespace Internal { class MacroExpanderPrivate; }
class FilePath;
class MacroExpander;
using MacroExpanderProvider = std::function<MacroExpander *()>;
-using MacroExpanderProviders = QVector<MacroExpanderProvider>;
+using MacroExpanderProviders = QList<MacroExpanderProvider>;
class QTCREATOR_UTILS_EXPORT MacroExpander
{
diff --git a/src/libs/utils/mapreduce.h b/src/libs/utils/mapreduce.h
deleted file mode 100644
index 891f0083c52..00000000000
--- a/src/libs/utils/mapreduce.h
+++ /dev/null
@@ -1,594 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include "utils_global.h"
-
-#include "algorithm.h"
-#include "runextensions.h"
-
-#include <QFutureWatcher>
-
-#include <iterator>
-
-namespace Utils {
-
-enum class MapReduceOption
-{
- Ordered,
- Unordered
-};
-
-namespace Internal {
-
-class QTCREATOR_UTILS_EXPORT MapReduceObject : public QObject
-{
- Q_OBJECT
-};
-
-template <typename ForwardIterator, typename MapResult, typename MapFunction, typename State, typename ReduceResult, typename ReduceFunction>
-class MapReduceBase : public MapReduceObject
-{
-protected:
- static const int MAX_PROGRESS = 1000000;
- // either const or non-const reference wrapper for items from the iterator
- using ItemReferenceWrapper = std::reference_wrapper<
- std::remove_reference_t<typename std::iterator_traits<ForwardIterator>::reference>>;
-
-public:
- MapReduceBase(QFutureInterface<ReduceResult> &futureInterface, ForwardIterator begin, ForwardIterator end,
- MapFunction &&map, State &state, ReduceFunction &&reduce,
- MapReduceOption option, QThreadPool *pool, int size)
- : m_futureInterface(futureInterface),
- m_iterator(begin),
- m_end(end),
- m_map(std::forward<MapFunction>(map)),
- m_state(state),
- m_reduce(std::forward<ReduceFunction>(reduce)),
- m_threadPool(pool),
- m_handleProgress(size >= 0),
- m_size(size),
- m_option(option)
- {
- if (!m_threadPool)
- m_threadPool = new QThreadPool(this);
- if (m_handleProgress) // progress is handled by us
- m_futureInterface.setProgressRange(0, MAX_PROGRESS);
- connect(&m_selfWatcher, &QFutureWatcher<void>::canceled,
- this, &MapReduceBase::cancelAll);
- m_selfWatcher.setFuture(QFuture<void>(futureInterface.future()));
- }
-
- void exec()
- {
- // do not enter event loop for empty containers or if already canceled
- if (!m_futureInterface.isCanceled() && schedule())
- m_loop.exec();
- }
-
-protected:
- virtual void reduce(QFutureWatcher<MapResult> *watcher, int index) = 0;
-
- bool schedule()
- {
- bool didSchedule = false;
- while (m_iterator != m_end
- && m_mapWatcher.size() < std::max(m_threadPool->maxThreadCount(), 1)) {
- didSchedule = true;
- auto watcher = new QFutureWatcher<MapResult>();
- connect(watcher, &QFutureWatcher<MapResult>::finished, this, [this, watcher] {
- mapFinished(watcher);
- });
- if (m_handleProgress) {
- connect(watcher, &QFutureWatcher<MapResult>::progressValueChanged,
- this, &MapReduceBase::updateProgress);
- connect(watcher, &QFutureWatcher<MapResult>::progressRangeChanged,
- this, &MapReduceBase::updateProgress);
- }
- m_mapWatcher.append(watcher);
- m_watcherIndex.append(m_currentIndex);
- ++m_currentIndex;
- watcher->setFuture(runAsync(m_threadPool, std::cref(m_map),
- ItemReferenceWrapper(*m_iterator)));
- ++m_iterator;
- }
- return didSchedule;
- }
-
- void mapFinished(QFutureWatcher<MapResult> *watcher)
- {
- int index = m_mapWatcher.indexOf(watcher);
- int watcherIndex = m_watcherIndex.at(index);
- m_mapWatcher.removeAt(index); // remove so we can schedule next one
- m_watcherIndex.removeAt(index);
- bool didSchedule = false;
- if (!m_futureInterface.isCanceled()) {
- // first schedule the next map...
- didSchedule = schedule();
- ++m_successfullyFinishedMapCount;
- updateProgress();
- // ...then reduce
- reduce(watcher, watcherIndex);
- }
- delete watcher;
- if (!didSchedule && m_mapWatcher.isEmpty())
- m_loop.quit();
- }
-
- void updateProgress()
- {
- if (!m_handleProgress) // cannot compute progress
- return;
- if (m_size == 0 || m_successfullyFinishedMapCount == m_size) {
- m_futureInterface.setProgressValue(MAX_PROGRESS);
- return;
- }
- if (!m_futureInterface.isProgressUpdateNeeded())
- return;
- const double progressPerMap = MAX_PROGRESS / double(m_size);
- double progress = m_successfullyFinishedMapCount * progressPerMap;
- for (const QFutureWatcher<MapResult> *watcher : std::as_const(m_mapWatcher)) {
- if (watcher->progressMinimum() != watcher->progressMaximum()) {
- const double range = watcher->progressMaximum() - watcher->progressMinimum();
- progress += (watcher->progressValue() - watcher->progressMinimum()) / range * progressPerMap;
- }
- }
- m_futureInterface.setProgressValue(int(progress));
- }
-
- void cancelAll()
- {
- for (QFutureWatcher<MapResult> *watcher : std::as_const(m_mapWatcher))
- watcher->cancel();
- }
-
- QFutureWatcher<void> m_selfWatcher;
- QFutureInterface<ReduceResult> &m_futureInterface;
- ForwardIterator m_iterator;
- const ForwardIterator m_end;
- MapFunction m_map;
- State &m_state;
- ReduceFunction m_reduce;
- QEventLoop m_loop;
- QThreadPool *m_threadPool; // for reusing threads
- QList<QFutureWatcher<MapResult> *> m_mapWatcher;
- QList<int> m_watcherIndex;
- int m_currentIndex = 0;
- const bool m_handleProgress;
- const int m_size;
- int m_successfullyFinishedMapCount = 0;
- MapReduceOption m_option;
-};
-
-// non-void result of map function.
-template <typename ForwardIterator, typename MapResult, typename MapFunction, typename State, typename ReduceResult, typename ReduceFunction>
-class MapReduce : public MapReduceBase<ForwardIterator, MapResult, MapFunction, State, ReduceResult, ReduceFunction>
-{
- using BaseType = MapReduceBase<ForwardIterator, MapResult, MapFunction, State, ReduceResult, ReduceFunction>;
-public:
- MapReduce(QFutureInterface<ReduceResult> &futureInterface, ForwardIterator begin, ForwardIterator end,
- MapFunction &&map, State &state, ReduceFunction &&reduce, MapReduceOption option,
- QThreadPool *pool, int size)
- : BaseType(futureInterface, begin, end, std::forward<MapFunction>(map), state,
- std::forward<ReduceFunction>(reduce), option, pool, size)
- {
- }
-
-protected:
- void reduce(QFutureWatcher<MapResult> *watcher, int index) override
- {
- if (BaseType::m_option == MapReduceOption::Unordered) {
- reduceOne(watcher->future().results());
- } else {
- if (m_nextIndex == index) {
- // handle this result and all directly following
- reduceOne(watcher->future().results());
- ++m_nextIndex;
- while (!m_pendingResults.isEmpty() && m_pendingResults.firstKey() == m_nextIndex) {
- reduceOne(m_pendingResults.take(m_nextIndex));
- ++m_nextIndex;
- }
- } else {
- // add result to pending results
- m_pendingResults.insert(index, watcher->future().results());
- }
- }
- }
-
-private:
- void reduceOne(const QList<MapResult> &results)
- {
- const int resultCount = results.size();
- for (int i = 0; i < resultCount; ++i) {
- Internal::runAsyncImpl(BaseType::m_futureInterface, BaseType::m_reduce,
- BaseType::m_state, results.at(i));
- }
- }
-
- QMap<int, QList<MapResult>> m_pendingResults;
- int m_nextIndex = 0;
-};
-
-// specialization for void result of map function. Reducing is a no-op.
-template <typename ForwardIterator, typename MapFunction, typename State, typename ReduceResult, typename ReduceFunction>
-class MapReduce<ForwardIterator, void, MapFunction, State, ReduceResult, ReduceFunction> : public MapReduceBase<ForwardIterator, void, MapFunction, State, ReduceResult, ReduceFunction>
-{
- using BaseType = MapReduceBase<ForwardIterator, void, MapFunction, State, ReduceResult, ReduceFunction>;
-public:
- MapReduce(QFutureInterface<ReduceResult> &futureInterface, ForwardIterator begin, ForwardIterator end,
- MapFunction &&map, State &state, ReduceFunction &&reduce, MapReduceOption option,
- QThreadPool *pool, int size)
- : BaseType(futureInterface, begin, end, std::forward<MapFunction>(map), state,
- std::forward<ReduceFunction>(reduce), option, pool, size)
- {
- }
-
-protected:
- void reduce(QFutureWatcher<void> *, int) override
- {
- }
-
-};
-
-template <typename ResultType, typename Function, typename... Args>
-functionResult_t<Function>
-callWithMaybeFutureInterfaceDispatch(std::false_type, QFutureInterface<ResultType> &,
- Function &&function, Args&&... args)
-{
- return function(std::forward<Args>(args)...);
-}
-
-template <typename ResultType, typename Function, typename... Args>
-functionResult_t<Function>
-callWithMaybeFutureInterfaceDispatch(std::true_type, QFutureInterface<ResultType> &futureInterface,
- Function &&function, Args&&... args)
-{
- return function(futureInterface, std::forward<Args>(args)...);
-}
-
-template <typename ResultType, typename Function, typename... Args>
-functionResult_t<Function>
-callWithMaybeFutureInterface(QFutureInterface<ResultType> &futureInterface,
- Function &&function, Args&&... args)
-{
- return callWithMaybeFutureInterfaceDispatch(
- functionTakesArgument<Function, 0, QFutureInterface<ResultType>&>(),
- futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
-}
-
-template <typename ForwardIterator, typename InitFunction, typename MapFunction, typename ReduceResult,
- typename ReduceFunction, typename CleanUpFunction>
-void blockingIteratorMapReduce(QFutureInterface<ReduceResult> &futureInterface, ForwardIterator begin, ForwardIterator end,
- InitFunction &&init, MapFunction &&map,
- ReduceFunction &&reduce, CleanUpFunction &&cleanup,
- MapReduceOption option, QThreadPool *pool, int size)
-{
- auto state = callWithMaybeFutureInterface<ReduceResult, InitFunction>
- (futureInterface, std::forward<InitFunction>(init));
- MapReduce<ForwardIterator, typename Internal::resultType<MapFunction>::type, MapFunction, decltype(state), ReduceResult, ReduceFunction>
- mr(futureInterface, begin, end, std::forward<MapFunction>(map), state,
- std::forward<ReduceFunction>(reduce), option, pool, size);
- mr.exec();
- callWithMaybeFutureInterface<ReduceResult, CleanUpFunction, std::remove_reference_t<decltype(state)>&>
- (futureInterface, std::forward<CleanUpFunction>(cleanup), state);
-}
-
-template <typename Container, typename InitFunction, typename MapFunction, typename ReduceResult,
- typename ReduceFunction, typename CleanUpFunction>
-void blockingContainerMapReduce(QFutureInterface<ReduceResult> &futureInterface, Container &&container,
- InitFunction &&init, MapFunction &&map,
- ReduceFunction &&reduce, CleanUpFunction &&cleanup,
- MapReduceOption option, QThreadPool *pool)
-{
- blockingIteratorMapReduce(futureInterface, std::begin(container), std::end(container),
- std::forward<InitFunction>(init), std::forward<MapFunction>(map),
- std::forward<ReduceFunction>(reduce),
- std::forward<CleanUpFunction>(cleanup),
- option, pool, static_cast<int>(container.size()));
-}
-
-template <typename Container, typename InitFunction, typename MapFunction, typename ReduceResult,
- typename ReduceFunction, typename CleanUpFunction>
-void blockingContainerRefMapReduce(QFutureInterface<ReduceResult> &futureInterface,
- std::reference_wrapper<Container> containerWrapper,
- InitFunction &&init, MapFunction &&map,
- ReduceFunction &&reduce, CleanUpFunction &&cleanup,
- MapReduceOption option, QThreadPool *pool)
-{
- blockingContainerMapReduce(futureInterface, containerWrapper.get(),
- std::forward<InitFunction>(init), std::forward<MapFunction>(map),
- std::forward<ReduceFunction>(reduce),
- std::forward<CleanUpFunction>(cleanup),
- option, pool);
-}
-
-template <typename ReduceResult>
-static void *dummyInit() { return nullptr; }
-
-// copies or moves state to member, and then moves it to the result of the call operator
-template <typename State>
-struct StateWrapper {
- using StateResult = std::decay_t<State>; // State is const& or & for lvalues
- StateWrapper(State &&state) : m_state(std::forward<State>(state)) { }
- StateResult operator()()
- {
- return std::move(m_state); // invalidates m_state
- }
-
- StateResult m_state;
-};
-
-// copies or moves reduce function to member, calls the reduce function with state and mapped value
-template <typename StateResult, typename MapResult, typename ReduceFunction>
-struct ReduceWrapper {
- using Reduce = std::decay_t<ReduceFunction>;
- ReduceWrapper(ReduceFunction &&reduce) : m_reduce(std::forward<ReduceFunction>(reduce)) { }
- void operator()(QFutureInterface<StateResult> &, StateResult &state, const MapResult &mapResult)
- {
- m_reduce(state, mapResult);
- }
-
- Reduce m_reduce;
-};
-
-template <typename MapResult>
-struct DummyReduce {
- MapResult operator()(void *, const MapResult &result) const { return result; }
-};
-template <>
-struct DummyReduce<void> {
- void operator()() const { } // needed for resultType<DummyReduce> with MSVC2013
-};
-
-template <typename ReduceResult>
-static void dummyCleanup(void *) { }
-
-template <typename StateResult>
-static void cleanupReportingState(QFutureInterface<StateResult> &fi, StateResult &state)
-{
- fi.reportResult(state);
-}
-
-} // Internal
-
-template <typename ForwardIterator, typename InitFunction, typename MapFunction,
- typename ReduceFunction, typename CleanUpFunction,
- typename ReduceResult = typename Internal::resultType<ReduceFunction>::type>
-QFuture<ReduceResult>
-mapReduce(ForwardIterator begin, ForwardIterator end, InitFunction &&init, MapFunction &&map,
- ReduceFunction &&reduce, CleanUpFunction &&cleanup,
- MapReduceOption option = MapReduceOption::Unordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority,
- int size = -1)
-{
- return runAsync(priority,
- Internal::blockingIteratorMapReduce<
- ForwardIterator,
- std::decay_t<InitFunction>,
- std::decay_t<MapFunction>,
- std::decay_t<ReduceResult>,
- std::decay_t<ReduceFunction>,
- std::decay_t<CleanUpFunction>>,
- begin, end, std::forward<InitFunction>(init), std::forward<MapFunction>(map),
- std::forward<ReduceFunction>(reduce), std::forward<CleanUpFunction>(cleanup),
- option, pool, size);
-}
-
-/*!
- Calls the map function on all items in \a container in parallel through Utils::runAsync.
-
- The reduce function is called in the mapReduce thread with each of the reported results from
- the map function, in arbitrary order, but never in parallel.
- It gets passed a reference to a user defined state object, and a result from the map function.
- If it takes a QFutureInterface reference as its first argument, it can report results
- for the mapReduce operation through that. Otherwise, any values returned by the reduce function
- are reported as results of the mapReduce operation.
-
- The init function is called in the mapReduce thread before the actual mapping starts,
- and must return the initial state object for the reduce function. It gets the QFutureInterface
- of the mapReduce operation passed as an argument.
-
- The cleanup function is called in the mapReduce thread after all map and reduce calls have
- finished, with the QFutureInterface of the mapReduce operation and the final state object
- as arguments, and can be used to clean up any resources, or report a final result of the
- mapReduce.
-
- Container<ItemType>
-
- StateType InitFunction(QFutureInterface<ReduceResultType>&)
- or
- StateType InitFunction()
-
- void MapFunction(QFutureInterface<MapResultType>&, const ItemType&)
- or
- MapResultType MapFunction(const ItempType&)
-
- void ReduceFunction(QFutureInterface<ReduceResultType>&, StateType&, const MapResultType&)
- or
- ReduceResultType ReduceFunction(StateType&, const MapResultType&)
-
- void CleanUpFunction(QFutureInterface<ReduceResultType>&, StateType&)
- or
- void CleanUpFunction(StateType&)
-
- Notes:
- \list
- \li Container can be a move-only type or a temporary. If it is a lvalue reference, it will
- be copied to the mapReduce thread. You can avoid that by using
- the version that takes iterators, or by using std::ref/cref to pass a reference_wrapper.
- \li ItemType can be a move-only type, if the map function takes (const) references to ItemType.
- \li StateType can be a move-only type.
- \li The init, map, reduce and cleanup functions can be move-only types and are moved to the
- mapReduce thread if they are rvalues.
- \endlist
-
- */
-template <typename Container, typename InitFunction, typename MapFunction,
- typename ReduceFunction, typename CleanUpFunction,
- typename ReduceResult = typename Internal::resultType<ReduceFunction>::type>
-QFuture<ReduceResult>
-mapReduce(Container &&container, InitFunction &&init, MapFunction &&map,
- ReduceFunction &&reduce, CleanUpFunction &&cleanup,
- MapReduceOption option = MapReduceOption::Unordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority)
-{
- return runAsync(priority,
- Internal::blockingContainerMapReduce<
- std::decay_t<Container>,
- std::decay_t<InitFunction>,
- std::decay_t<MapFunction>,
- std::decay_t<ReduceResult>,
- std::decay_t<ReduceFunction>,
- std::decay_t<CleanUpFunction>>,
- std::forward<Container>(container),
- std::forward<InitFunction>(init), std::forward<MapFunction>(map),
- std::forward<ReduceFunction>(reduce), std::forward<CleanUpFunction>(cleanup),
- option, pool);
-}
-
-template <typename Container, typename InitFunction, typename MapFunction,
- typename ReduceFunction, typename CleanUpFunction,
- typename ReduceResult = typename Internal::resultType<ReduceFunction>::type>
-QFuture<ReduceResult>
-mapReduce(std::reference_wrapper<Container> containerWrapper, InitFunction &&init, MapFunction &&map,
- ReduceFunction &&reduce, CleanUpFunction &&cleanup,
- MapReduceOption option = MapReduceOption::Unordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority)
-{
- return runAsync(priority,
- Internal::blockingContainerRefMapReduce<
- Container,
- std::decay_t<InitFunction>,
- std::decay_t<MapFunction>,
- std::decay_t<ReduceResult>,
- std::decay_t<ReduceFunction>,
- std::decay_t<CleanUpFunction>>,
- containerWrapper,
- std::forward<InitFunction>(init), std::forward<MapFunction>(map),
- std::forward<ReduceFunction>(reduce), std::forward<CleanUpFunction>(cleanup),
- option, pool);
-}
-
-template <typename ForwardIterator, typename MapFunction, typename State, typename ReduceFunction,
- typename StateResult = std::decay_t<State>, // State = T& or const T& for lvalues, so decay that away
- typename MapResult = typename Internal::resultType<MapFunction>::type>
-QFuture<StateResult>
-mapReduce(ForwardIterator begin, ForwardIterator end, MapFunction &&map, State &&initialState,
- ReduceFunction &&reduce, MapReduceOption option = MapReduceOption::Unordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority,
- int size = -1)
-{
- return mapReduce(begin, end,
- Internal::StateWrapper<State>(std::forward<State>(initialState)),
- std::forward<MapFunction>(map),
- Internal::ReduceWrapper<StateResult, MapResult, ReduceFunction>(std::forward<ReduceFunction>(reduce)),
- &Internal::cleanupReportingState<StateResult>,
- option, pool, priority, size);
-}
-
-template <typename Container, typename MapFunction, typename State, typename ReduceFunction,
- typename StateResult = std::decay_t<State>, // State = T& or const T& for lvalues, so decay that away
- typename MapResult = typename Internal::resultType<MapFunction>::type>
-QFuture<StateResult>
-mapReduce(Container &&container, MapFunction &&map, State &&initialState, ReduceFunction &&reduce,
- MapReduceOption option = MapReduceOption::Unordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority)
-{
- return mapReduce(std::forward<Container>(container),
- Internal::StateWrapper<State>(std::forward<State>(initialState)),
- std::forward<MapFunction>(map),
- Internal::ReduceWrapper<StateResult, MapResult, ReduceFunction>(std::forward<ReduceFunction>(reduce)),
- &Internal::cleanupReportingState<StateResult>,
- option, pool, priority);
-}
-
-template <typename ForwardIterator, typename MapFunction, typename State, typename ReduceFunction,
- typename StateResult = std::decay_t<State>, // State = T& or const T& for lvalues, so decay that away
- typename MapResult = typename Internal::resultType<MapFunction>::type>
-Q_REQUIRED_RESULT
-StateResult
-mappedReduced(ForwardIterator begin, ForwardIterator end, MapFunction &&map, State &&initialState,
- ReduceFunction &&reduce, MapReduceOption option = MapReduceOption::Unordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority,
- int size = -1)
-{
- return mapReduce(begin, end,
- std::forward<MapFunction>(map), std::forward<State>(initialState),
- std::forward<ReduceFunction>(reduce),
- option, pool, priority, size).result();
-}
-
-template <typename Container, typename MapFunction, typename State, typename ReduceFunction,
- typename StateResult = std::decay_t<State>, // State = T& or const T& for lvalues, so decay that away
- typename MapResult = typename Internal::resultType<MapFunction>::type>
-Q_REQUIRED_RESULT
-StateResult
-mappedReduced(Container &&container, MapFunction &&map, State &&initialState, ReduceFunction &&reduce,
- MapReduceOption option = MapReduceOption::Unordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority)
-{
- return mapReduce(std::forward<Container>(container), std::forward<MapFunction>(map),
- std::forward<State>(initialState), std::forward<ReduceFunction>(reduce),
- option, pool, priority).result();
-}
-
-template <typename ForwardIterator, typename MapFunction,
- typename MapResult = typename Internal::resultType<MapFunction>::type>
-QFuture<MapResult>
-map(ForwardIterator begin, ForwardIterator end, MapFunction &&map,
- MapReduceOption option = MapReduceOption::Ordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority,
- int size = -1)
-{
- return mapReduce(begin, end,
- &Internal::dummyInit<MapResult>,
- std::forward<MapFunction>(map),
- Internal::DummyReduce<MapResult>(),
- &Internal::dummyCleanup<MapResult>,
- option, pool, priority, size);
-}
-
-template <typename Container, typename MapFunction,
- typename MapResult = typename Internal::resultType<MapFunction>::type>
-QFuture<MapResult>
-map(Container &&container, MapFunction &&map, MapReduceOption option = MapReduceOption::Ordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority)
-{
- return mapReduce(std::forward<Container>(container),
- Internal::dummyInit<MapResult>,
- std::forward<MapFunction>(map),
- Internal::DummyReduce<MapResult>(),
- Internal::dummyCleanup<MapResult>,
- option, pool, priority);
-}
-
-template <template<typename> class ResultContainer, typename ForwardIterator, typename MapFunction,
- typename MapResult = typename Internal::resultType<MapFunction>::type>
-Q_REQUIRED_RESULT
-ResultContainer<MapResult>
-mapped(ForwardIterator begin, ForwardIterator end, MapFunction &&mapFun,
- MapReduceOption option = MapReduceOption::Ordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority, int size = -1)
-{
- return Utils::transform<ResultContainer>(map(begin, end,
- std::forward<MapFunction>(mapFun),
- option, pool, priority, size).results(),
- [](const MapResult &r) { return r; });
-}
-
-template <template<typename> class ResultContainer, typename Container, typename MapFunction,
- typename MapResult = typename Internal::resultType<MapFunction>::type>
-Q_REQUIRED_RESULT
-ResultContainer<MapResult>
-mapped(Container &&container, MapFunction &&mapFun,
- MapReduceOption option = MapReduceOption::Ordered,
- QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority)
-{
- return Utils::transform<ResultContainer>(map(container,
- std::forward<MapFunction>(mapFun),
- option, pool, priority).results(),
- [](const MapResult &r) { return r; });
-}
-
-} // Utils
diff --git a/src/libs/utils/mimetypes2/mimedatabase.cpp b/src/libs/utils/mimetypes2/mimedatabase.cpp
index b703421d96f..60f3fbf0db5 100644
--- a/src/libs/utils/mimetypes2/mimedatabase.cpp
+++ b/src/libs/utils/mimetypes2/mimedatabase.cpp
@@ -13,6 +13,8 @@
#include "algorithm.h"
+#include <nanotrace/nanotrace.h>
+
#include <QFile>
#include <QFileInfo>
#include <QStandardPaths>
@@ -90,6 +92,7 @@ static void updateOverriddenMimeTypes(std::vector<std::unique_ptr<MimeProviderBa
void MimeDatabasePrivate::loadProviders()
{
+ NANOTRACE_SCOPE("Utils", "MimeDatabasePrivate::loadProviders");
#if 0
// We use QStandardPaths every time to check if new files appeared
const QStringList mimeDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime"), QStandardPaths::LocateDirectory);
@@ -223,7 +226,7 @@ MimeType MimeDatabasePrivate::mimeTypeForName(const QString &nameOrAlias)
QStringList MimeDatabasePrivate::mimeTypeForFileName(const QString &fileName)
{
if (fileName.endsWith(QLatin1Char('/')))
- return QStringList() << QLatin1String("inode/directory");
+ return {"inode/directory"};
const MimeGlobMatchResult result = findByFileName(fileName);
QStringList matchingMimeTypes = result.m_matchingMimeTypes;
@@ -559,12 +562,9 @@ MimeDatabase::~MimeDatabase()
*/
MimeType MimeDatabase::mimeTypeForName(const QString &nameOrAlias) const
{
+ d->checkInitPhase(nameOrAlias);
QMutexLocker locker(&d->mutex);
- if (d->m_startupPhase <= int(MimeStartupPhase::PluginsInitializing))
- qWarning("Accessing MimeDatabase for %s before plugins are initialized",
- qPrintable(nameOrAlias));
-
return d->mimeTypeForName(nameOrAlias);
}
@@ -598,12 +598,9 @@ MimeType MimeDatabase::mimeTypeForName(const QString &nameOrAlias) const
*/
MimeType MimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode) const
{
+ d->checkInitPhase(fileInfo.filePath());
QMutexLocker locker(&d->mutex);
- if (d->m_startupPhase <= int(MimeStartupPhase::PluginsInitializing))
- qWarning("Accessing MimeDatabase for %s before plugins are initialized",
- qPrintable(fileInfo.filePath()));
-
if (fileInfo.isDir())
return d->mimeTypeForName(QLatin1String("inode/directory"));
@@ -656,12 +653,9 @@ MimeType MimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode
MimeType MimeDatabase::mimeTypeForFile(const QString &fileName, MatchMode mode) const
{
if (mode == MatchExtension) {
+ d->checkInitPhase(fileName);
QMutexLocker locker(&d->mutex);
- if (d->m_startupPhase <= int(MimeStartupPhase::PluginsInitializing))
- qWarning("Accessing MimeDatabase for %s before plugins are initialized",
- qPrintable(fileName));
-
const QStringList matches = d->mimeTypeForFileName(fileName);
const int matchCount = matches.count();
if (matchCount == 0) {
@@ -693,12 +687,9 @@ MimeType MimeDatabase::mimeTypeForFile(const QString &fileName, MatchMode mode)
*/
QList<MimeType> MimeDatabase::mimeTypesForFileName(const QString &fileName) const
{
+ d->checkInitPhase(fileName);
QMutexLocker locker(&d->mutex);
- if (d->m_startupPhase <= int(MimeStartupPhase::PluginsInitializing))
- qWarning("Accessing MimeDatabase for %s before plugins are initialized",
- qPrintable(fileName));
-
const QStringList matches = d->mimeTypeForFileName(fileName);
QList<MimeType> mimes;
mimes.reserve(matches.count());
@@ -728,11 +719,9 @@ QString MimeDatabase::suffixForFileName(const QString &fileName) const
*/
MimeType MimeDatabase::mimeTypeForData(const QByteArray &data) const
{
+ d->checkInitPhase("data");
QMutexLocker locker(&d->mutex);
- if (d->m_startupPhase <= int(MimeStartupPhase::PluginsInitializing))
- qWarning("Accessing MimeDatabase for data before plugins are initialized");
-
int accuracy = 0;
return d->findByData(data, &accuracy);
}
@@ -860,11 +849,9 @@ MimeType MimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, const
*/
QList<MimeType> MimeDatabase::allMimeTypes() const
{
+ d->checkInitPhase("all mime types");
QMutexLocker locker(&d->mutex);
- if (d->m_startupPhase <= int(MimeStartupPhase::PluginsInitializing))
- qWarning("Accessing MimeDatabase for all mime types before plugins are initialized");
-
return d->allMimeTypes();
}
@@ -921,4 +908,27 @@ void MimeDatabasePrivate::setGlobPatternsForMimeType(const MimeType &mimeType,
}
}
+void MimeDatabasePrivate::checkInitPhase(const QString &info)
+{
+ QReadLocker locker(&m_initMutex);
+ if (m_startupPhase <= int(MimeStartupPhase::PluginsInitializing)) {
+ qWarning("Accessing MimeDatabase for %s before plugins are initialized", qPrintable(info));
+ return;
+ }
+ // run initialization functions and ensure providers are loaded
+ // the initializers will call other MIME database functions which "checkInitPhase" again,
+ // so make sure not to recurse
+ if (!m_initialized.exchange(true)) {
+ for (const std::function<void()> &f : m_initializers)
+ f();
+ QMutexLocker locker(&mutex);
+ providers();
+ }
+}
+
+void MimeDatabasePrivate::addInitializer(const std::function<void()> &init)
+{
+ m_initializers.append(init);
+}
+
} // namespace Utils
diff --git a/src/libs/utils/mimetypes2/mimedatabase_p.h b/src/libs/utils/mimetypes2/mimedatabase_p.h
index 8709b2918eb..c816a5c0e5b 100644
--- a/src/libs/utils/mimetypes2/mimedatabase_p.h
+++ b/src/libs/utils/mimetypes2/mimedatabase_p.h
@@ -25,8 +25,11 @@
#include <QtCore/qlist.h>
#include <QtCore/qmutex.h>
-#include <vector>
+#include <QReadWriteLock>
+
+#include <atomic>
#include <memory>
+#include <vector>
QT_BEGIN_NAMESPACE
class QIODevice;
@@ -75,6 +78,8 @@ public:
void setMagicRulesForMimeType(const MimeType &mimeType,
const QMap<int, QList<MimeMagicRule>> &rules);
void setGlobPatternsForMimeType(const MimeType &mimeType, const QStringList &patterns);
+ void checkInitPhase(const QString &info);
+ void addInitializer(const std::function<void()> &init);
private:
using Providers = std::vector<std::unique_ptr<MimeProviderBase>>;
@@ -86,6 +91,7 @@ private:
QElapsedTimer m_lastCheck;
// added for Qt Creator
+ QList<std::function<void()>> m_initializers;
QHash<QString, QByteArray> m_additionalData; // id -> data
bool m_forceLoad = true;
@@ -94,6 +100,8 @@ public:
QMutex mutex;
// added for Qt Creator
+ QReadWriteLock m_initMutex;
+ std::atomic_bool m_initialized = false;
int m_startupPhase = 0;
};
diff --git a/src/libs/utils/mimetypes2/mimemagicrule_p.h b/src/libs/utils/mimetypes2/mimemagicrule_p.h
index fe2e0ff3e42..293f61ca914 100644
--- a/src/libs/utils/mimetypes2/mimemagicrule_p.h
+++ b/src/libs/utils/mimetypes2/mimemagicrule_p.h
@@ -14,7 +14,7 @@
// We mean it.
//
-#include <utils/utils_global.h>
+#include "../utils_global.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qlist.h>
diff --git a/src/libs/utils/mimetypes2/mimeprovider.cpp b/src/libs/utils/mimetypes2/mimeprovider.cpp
index c20e367517f..682cbb7e8a5 100644
--- a/src/libs/utils/mimetypes2/mimeprovider.cpp
+++ b/src/libs/utils/mimetypes2/mimeprovider.cpp
@@ -505,7 +505,7 @@ bool MimeBinaryProvider::loadMimeTypePrivate(MimeTypePrivate &data)
// shared-mime-info since 1.3 lowercases the xml files
QString mimeFile = m_directory + QLatin1Char('/') + data.name.toLower() + QLatin1String(".xml");
- if (!QFile::exists(mimeFile))
+ if (!QFileInfo::exists(mimeFile))
mimeFile = m_directory + QLatin1Char('/') + data.name + QLatin1String(".xml"); // pre-1.3
QFile qfile(mimeFile);
diff --git a/src/libs/utils/mimetypes2/mimetype.h b/src/libs/utils/mimetypes2/mimetype.h
index ec28140d6ae..b512aaae723 100644
--- a/src/libs/utils/mimetypes2/mimetype.h
+++ b/src/libs/utils/mimetypes2/mimetype.h
@@ -4,7 +4,7 @@
#pragma once
-#include <utils/utils_global.h>
+#include "../utils_global.h"
#include <QtCore/qobjectdefs.h>
#include <QtCore/qshareddata.h>
diff --git a/src/libs/utils/mimetypes2/mimeutils.cpp b/src/libs/utils/mimetypes2/mimeutils.cpp
index 92aeed56f0c..711dc97187a 100644
--- a/src/libs/utils/mimetypes2/mimeutils.cpp
+++ b/src/libs/utils/mimetypes2/mimeutils.cpp
@@ -57,7 +57,7 @@ QList<MimeType> allMimeTypes()
void setMimeStartupPhase(MimeStartupPhase phase)
{
auto d = MimeDatabasePrivate::instance();
- QMutexLocker locker(&d->mutex);
+ QWriteLocker locker(&d->m_initMutex);
if (int(phase) != d->m_startupPhase + 1) {
qWarning("Unexpected jump in MimedDatabase lifetime from %d to %d",
d->m_startupPhase,
@@ -69,12 +69,14 @@ void setMimeStartupPhase(MimeStartupPhase phase)
void addMimeTypes(const QString &id, const QByteArray &data)
{
auto d = MimeDatabasePrivate::instance();
- QMutexLocker locker(&d->mutex);
-
- if (d->m_startupPhase >= int(MimeStartupPhase::PluginsDelayedInitializing)) {
- qWarning("Adding items for ID \"%s\" to MimeDatabase after initialization time",
- qPrintable(id));
+ {
+ QReadLocker locker(&d->m_initMutex);
+ if (d->m_startupPhase >= int(MimeStartupPhase::PluginsDelayedInitializing)) {
+ qWarning("Adding items for ID \"%s\" to MimeDatabase after initialization time",
+ qPrintable(id));
+ }
}
+ QMutexLocker locker(&d->mutex);
d->addMimeData(id, data);
}
@@ -130,4 +132,14 @@ void visitMimeParents(const MimeType &mimeType,
}
}
+/*!
+ The \a init function will be executed once after the MIME database is first initialized.
+ It must be thread safe.
+*/
+void addMimeInitializer(const std::function<void()> &init)
+{
+ auto d = MimeDatabasePrivate::instance();
+ d->addInitializer(init);
+}
+
} // namespace Utils
diff --git a/src/libs/utils/mimeutils.h b/src/libs/utils/mimeutils.h
index 3fa0fc4ebb9..c5f8b819456 100644
--- a/src/libs/utils/mimeutils.h
+++ b/src/libs/utils/mimeutils.h
@@ -43,6 +43,7 @@ enum class MimeStartupPhase {
};
QTCREATOR_UTILS_EXPORT void setMimeStartupPhase(MimeStartupPhase);
+QTCREATOR_UTILS_EXPORT void addMimeInitializer(const std::function<void()> &init);
QTCREATOR_UTILS_EXPORT void addMimeTypes(const QString &id, const QByteArray &data);
QTCREATOR_UTILS_EXPORT QMap<int, QList<MimeMagicRule>> magicRulesForMimeType(
const MimeType &mimeType); // priority -> rules
diff --git a/src/libs/utils/minimizableinfobars.cpp b/src/libs/utils/minimizableinfobars.cpp
index a4fcd478118..d2ff3fe96f7 100644
--- a/src/libs/utils/minimizableinfobars.cpp
+++ b/src/libs/utils/minimizableinfobars.cpp
@@ -33,7 +33,7 @@ void MinimizableInfoBars::setPossibleInfoBarEntries(const QList<Utils::InfoBarEn
createActions();
}
-void MinimizableInfoBars::setSettingsGroup(const QString &settingsGroup)
+void MinimizableInfoBars::setSettingsGroup(const Key &settingsGroup)
{
m_settingsGroup = settingsGroup;
}
@@ -55,10 +55,10 @@ void MinimizableInfoBars::createActions()
}
}
-QString MinimizableInfoBars::settingsKey(const Id &id) const
+Key MinimizableInfoBars::settingsKey(const Id &id) const
{
QTC_CHECK(!m_settingsGroup.isEmpty());
- return m_settingsGroup + '/' + SETTINGS_PREFIX + id.toString();
+ return m_settingsGroup + '/' + SETTINGS_PREFIX + id.name();
}
void MinimizableInfoBars::createShowInfoBarActions(const ActionCreator &actionCreator) const
@@ -127,10 +127,7 @@ bool MinimizableInfoBars::showInInfoBar(const Id &id) const
void MinimizableInfoBars::setShowInInfoBar(const Id &id, bool show)
{
- QtcSettings::setValueWithDefault(InfoBar::settings(),
- settingsKey(id),
- show,
- kShowInInfoBarDefault);
+ InfoBar::settings()->setValueWithDefault(settingsKey(id), show, kShowInInfoBarDefault);
}
} // namespace Utils
diff --git a/src/libs/utils/minimizableinfobars.h b/src/libs/utils/minimizableinfobars.h
index a5818ac2cb6..03430f513d1 100644
--- a/src/libs/utils/minimizableinfobars.h
+++ b/src/libs/utils/minimizableinfobars.h
@@ -7,6 +7,7 @@
#include "id.h"
#include "infobar.h"
+#include "store.h"
#include <QHash>
#include <QObject>
@@ -21,15 +22,13 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT MinimizableInfoBars : public QObject
{
- Q_OBJECT
-
public:
using ActionCreator = std::function<QAction *(QWidget *widget)>;
public:
explicit MinimizableInfoBars(InfoBar &infoBar);
- void setSettingsGroup(const QString &settingsGroup);
+ void setSettingsGroup(const Key &settingsGroup);
void setPossibleInfoBarEntries(const QList<InfoBarEntry> &entries);
void createShowInfoBarActions(const ActionCreator &actionCreator) const;
@@ -39,7 +38,7 @@ public:
private:
void createActions();
- QString settingsKey(const Id &id) const;
+ Key settingsKey(const Id &id) const;
bool showInInfoBar(const Id &id) const;
void setShowInInfoBar(const Id &id, bool show);
@@ -47,9 +46,8 @@ private:
void showInfoBar(const Id &id);
-private:
InfoBar &m_infoBar;
- QString m_settingsGroup;
+ Key m_settingsGroup;
QHash<Id, QAction *> m_actions;
QHash<Id, bool> m_isInfoVisible;
QHash<Id, InfoBarEntry> m_infoEntries;
diff --git a/src/libs/utils/namevaluedictionary.h b/src/libs/utils/namevaluedictionary.h
index 4c8b5466816..722558f8912 100644
--- a/src/libs/utils/namevaluedictionary.h
+++ b/src/libs/utils/namevaluedictionary.h
@@ -30,7 +30,7 @@ inline bool operator<(const DictKey &k1, const DictKey &k2)
inline bool operator>(const DictKey &k1, const DictKey &k2) { return k2 < k1; }
using NameValuePair = std::pair<QString, QString>;
-using NameValuePairs = QVector<NameValuePair>;
+using NameValuePairs = QList<NameValuePair>;
using NameValueMap = QMap<DictKey, QPair<QString, bool>>;
class QTCREATOR_UTILS_EXPORT NameValueDictionary
diff --git a/src/libs/utils/namevalueitem.h b/src/libs/utils/namevalueitem.h
index b1f2bc22f84..62ba9d25baf 100644
--- a/src/libs/utils/namevalueitem.h
+++ b/src/libs/utils/namevalueitem.h
@@ -10,7 +10,6 @@
#include <QStringList>
#include <QVariantList>
-#include <QVector>
namespace Utils {
diff --git a/src/libs/utils/namevaluesdialog.cpp b/src/libs/utils/namevaluesdialog.cpp
index 892702566f4..51403f534eb 100644
--- a/src/libs/utils/namevaluesdialog.cpp
+++ b/src/libs/utils/namevaluesdialog.cpp
@@ -3,7 +3,7 @@
#include "namevaluesdialog.h"
-#include "environment.h"
+#include "algorithm.h"
#include "hostosinfo.h"
#include "utilstr.h"
@@ -15,7 +15,6 @@
#include <QVBoxLayout>
namespace Utils {
-
namespace Internal {
static EnvironmentItems cleanUp(const EnvironmentItems &items)
@@ -29,14 +28,26 @@ static EnvironmentItems cleanUp(const EnvironmentItems &items)
const QString &itemName = item.name;
QString emptyName = itemName;
emptyName.remove(QLatin1Char(' '));
- if (!emptyName.isEmpty() && !uniqueSet.contains(itemName)) {
+ if (!emptyName.isEmpty() && Utils::insert(uniqueSet, itemName))
uniqueItems.prepend(item);
- uniqueSet.insert(itemName);
- }
}
return uniqueItems;
}
+class NameValueItemsWidget : public QWidget
+{
+public:
+ explicit NameValueItemsWidget(QWidget *parent = nullptr);
+
+ void setEnvironmentItems(const EnvironmentItems &items);
+ EnvironmentItems environmentItems() const;
+
+ void setPlaceholderText(const QString &text);
+
+private:
+ QPlainTextEdit *m_editor;
+};
+
NameValueItemsWidget::NameValueItemsWidget(QWidget *parent)
: QWidget(parent)
{
@@ -65,6 +76,7 @@ void NameValueItemsWidget::setPlaceholderText(const QString &text)
{
m_editor->setPlaceholderText(text);
}
+
} // namespace Internal
NameValuesDialog::NameValuesDialog(const QString &windowTitle, const QString &helpText, QWidget *parent)
diff --git a/src/libs/utils/namevaluesdialog.h b/src/libs/utils/namevaluesdialog.h
index ad1795d503e..ada71d61fcf 100644
--- a/src/libs/utils/namevaluesdialog.h
+++ b/src/libs/utils/namevaluesdialog.h
@@ -13,32 +13,12 @@
#include <memory>
#include <optional>
-QT_BEGIN_NAMESPACE
-class QPlainTextEdit;
-QT_END_NAMESPACE
-
namespace Utils {
-namespace Internal {
-class NameValueItemsWidget : public QWidget
-{
- Q_OBJECT
-public:
- explicit NameValueItemsWidget(QWidget *parent = nullptr);
-
- void setEnvironmentItems(const EnvironmentItems &items);
- EnvironmentItems environmentItems() const;
-
- void setPlaceholderText(const QString &text);
-
-private:
- QPlainTextEdit *m_editor;
-};
-} // namespace Internal
+namespace Internal { class NameValueItemsWidget; }
class QTCREATOR_UTILS_EXPORT NameValuesDialog : public QDialog
{
- Q_OBJECT
public:
void setNameValueItems(const NameValueItems &items);
NameValueItems nameValueItems() const;
@@ -52,7 +32,6 @@ public:
Polisher polish = {},
const QString &windowTitle = {},
const QString &helpText = {});
-
protected:
explicit NameValuesDialog(const QString &windowTitle,
const QString &helpText,
diff --git a/src/libs/utils/namevaluevalidator.h b/src/libs/utils/namevaluevalidator.h
index c5c3aa23a69..2f11196eb6a 100644
--- a/src/libs/utils/namevaluevalidator.h
+++ b/src/libs/utils/namevaluevalidator.h
@@ -21,7 +21,6 @@ class NameValueModel;
class QTCREATOR_UTILS_EXPORT NameValueValidator : public QValidator
{
- Q_OBJECT
public:
NameValueValidator(QWidget *parent,
NameValueModel *model,
@@ -40,4 +39,5 @@ private:
QPersistentModelIndex m_index;
mutable QTimer m_hideTipTimer;
};
+
} // namespace Utils
diff --git a/src/libs/utils/navigationtreeview.cpp b/src/libs/utils/navigationtreeview.cpp
index 7a6bd4be234..61ef04d8167 100644
--- a/src/libs/utils/navigationtreeview.cpp
+++ b/src/libs/utils/navigationtreeview.cpp
@@ -24,8 +24,7 @@ NavigationTreeView::NavigationTreeView(QWidget *parent)
: TreeView(parent)
{
setFrameStyle(QFrame::NoFrame);
- setIndentation(indentation() * 9/10);
- setUniformRowHeights(true);
+ setIndentation(indentation() * 7/10);
setTextElideMode(Qt::ElideNone);
setAttribute(Qt::WA_MacShowFocusRect, false);
diff --git a/src/libs/utils/navigationtreeview.h b/src/libs/utils/navigationtreeview.h
index ab1b1b7b4a7..a3a0e2b07de 100644
--- a/src/libs/utils/navigationtreeview.h
+++ b/src/libs/utils/navigationtreeview.h
@@ -11,7 +11,6 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT NavigationTreeView : public TreeView
{
- Q_OBJECT
public:
explicit NavigationTreeView(QWidget *parent = nullptr);
void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override;
diff --git a/src/libs/utils/networkaccessmanager.h b/src/libs/utils/networkaccessmanager.h
index 725757c2fe6..33a479946b2 100644
--- a/src/libs/utils/networkaccessmanager.h
+++ b/src/libs/utils/networkaccessmanager.h
@@ -11,7 +11,6 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT NetworkAccessManager : public QNetworkAccessManager
{
- Q_OBJECT
public:
NetworkAccessManager(QObject *parent = nullptr);
diff --git a/src/libs/utils/optionpushbutton.cpp b/src/libs/utils/optionpushbutton.cpp
index c3993fef4b0..c20b2e74706 100644
--- a/src/libs/utils/optionpushbutton.cpp
+++ b/src/libs/utils/optionpushbutton.cpp
@@ -45,13 +45,16 @@ OptionPushButton::OptionPushButton(const QString &text, QWidget *parent)
This menu is shown if the user clicks on the menu indicator that is shown.
If the user clicks anywhere else on the button, QAbstractButton::clicked() is sent instead.
+ \note Calling this method removes all connections to the QAbstractButton::pressed() signal.
+
Ownership of the menu is not transferred to the push button.
*/
void OptionPushButton::setOptionalMenu(QMenu *menu)
{
setMenu(menu);
- // hack away that QPushButton opens the menu on "pressed"
- disconnect(this, SIGNAL(pressed()), this, SLOT(_q_popupPressed()));
+ // Hack away that QPushButton opens the menu on "pressed".
+ // Also removes all other connections to "pressed".
+ disconnect(this, &QPushButton::pressed, 0, 0);
}
/*!
diff --git a/src/libs/utils/optionpushbutton.h b/src/libs/utils/optionpushbutton.h
index e0b5800fd39..143ec2477ea 100644
--- a/src/libs/utils/optionpushbutton.h
+++ b/src/libs/utils/optionpushbutton.h
@@ -16,8 +16,6 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT OptionPushButton : public QPushButton
{
- Q_OBJECT
-
public:
OptionPushButton(QWidget *parent = nullptr);
OptionPushButton(const QString &text, QWidget *parent = nullptr);
diff --git a/src/libs/utils/overlaywidget.h b/src/libs/utils/overlaywidget.h
index 82e635c7ab6..8bc5b7d1eb5 100644
--- a/src/libs/utils/overlaywidget.h
+++ b/src/libs/utils/overlaywidget.h
@@ -13,7 +13,6 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT OverlayWidget : public QWidget
{
- Q_OBJECT
public:
using PaintFunction = std::function<void(QWidget *, QPainter &, QPaintEvent *)>;
diff --git a/src/libs/utils/passworddialog.cpp b/src/libs/utils/passworddialog.cpp
new file mode 100644
index 00000000000..7958f7d6bd9
--- /dev/null
+++ b/src/libs/utils/passworddialog.cpp
@@ -0,0 +1,204 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "passworddialog.h"
+
+#include "layoutbuilder.h"
+#include "stylehelper.h"
+#include "utilsicons.h"
+#include "utilstr.h"
+
+#include <QAbstractButton>
+#include <QCheckBox>
+#include <QDialogButtonBox>
+#include <QEnterEvent>
+#include <QLineEdit>
+#include <QPainter>
+
+namespace Utils {
+
+ShowPasswordButton::ShowPasswordButton(QWidget *parent)
+ : QAbstractButton(parent)
+{
+ setAttribute(Qt::WA_Hover);
+ setCheckable(true);
+ setToolTip(Tr::tr("Show/Hide Password"));
+}
+
+void ShowPasswordButton::paintEvent(QPaintEvent *e)
+{
+ Q_UNUSED(e);
+ QIcon icon = isChecked() ? Utils::Icons::EYE_OPEN_TOOLBAR.icon()
+ : Utils::Icons::EYE_CLOSED_TOOLBAR.icon();
+ QPainter p(this);
+ QRect r(QPoint(), size());
+
+ if (m_containsMouse && isEnabled())
+ StyleHelper::drawPanelBgRect(&p, r, creatorTheme()->color(Theme::FancyToolButtonHoverColor));
+
+ QWindow *window = this->window()->windowHandle();
+ QSize s = icon.actualSize(window, QSize(32, 16));
+
+ QPixmap px = icon.pixmap(s);
+ QRect iRect(QPoint(), s);
+ iRect.moveCenter(r.center());
+ p.drawPixmap(iRect, px);
+}
+
+void ShowPasswordButton::enterEvent(QEnterEvent *e)
+{
+ m_containsMouse = true;
+ e->accept();
+ update();
+}
+
+void ShowPasswordButton::leaveEvent(QEvent *e)
+{
+ m_containsMouse = false;
+ e->accept();
+ update();
+}
+
+QSize ShowPasswordButton::sizeHint() const
+{
+ QWindow *window = this->window()->windowHandle();
+ QSize s = Utils::Icons::EYE_OPEN_TOOLBAR.icon().actualSize(window, QSize(32, 16)) + QSize(8, 8);
+
+ if (StyleHelper::toolbarStyle() == StyleHelper::ToolbarStyleRelaxed)
+ s += QSize(5, 5);
+
+ return s;
+}
+
+class PasswordDialogPrivate
+{
+public:
+ QLineEdit *m_userNameLineEdit{nullptr};
+ QLineEdit *m_passwordLineEdit{nullptr};
+ QCheckBox *m_checkBox{nullptr};
+ QDialogButtonBox *m_buttonBox{nullptr};
+};
+
+PasswordDialog::PasswordDialog(const QString &title,
+ const QString &prompt,
+ const QString &doNotAskAgainLabel,
+ bool withUsername,
+ QWidget *parent)
+ : QDialog(parent)
+ , d(new PasswordDialogPrivate)
+{
+ setWindowTitle(title);
+
+ d->m_passwordLineEdit = new QLineEdit();
+ d->m_passwordLineEdit->setEchoMode(QLineEdit::Password);
+
+ if (withUsername)
+ d->m_userNameLineEdit = new QLineEdit();
+
+ d->m_checkBox = new QCheckBox();
+ d->m_checkBox->setText(doNotAskAgainLabel);
+
+ auto *showPasswordButton = new ShowPasswordButton;
+
+ connect(showPasswordButton, &QAbstractButton::toggled, this, [this, showPasswordButton] {
+ d->m_passwordLineEdit->setEchoMode(showPasswordButton->isChecked() ? QLineEdit::Normal
+ : QLineEdit::Password);
+ });
+
+ d->m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+
+ connect(d->m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(d->m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
+
+ using namespace Layouting;
+
+ // clang-format off
+ Column {
+ prompt,
+ If {
+ withUsername, {
+ Form {
+ Tr::tr("User:"), d->m_userNameLineEdit, br,
+ Tr::tr("Password:"), Row { d->m_passwordLineEdit, showPasswordButton }, br,
+ }
+ }, {
+ Row {
+ d->m_passwordLineEdit, showPasswordButton,
+ },
+ }
+ },
+ Row {
+ d->m_checkBox,
+ d->m_buttonBox,
+ }
+ }.attachTo(this);
+ // clang-format on
+
+ d->m_passwordLineEdit->setMinimumWidth(d->m_passwordLineEdit->width() / 2);
+ setFixedSize(sizeHint());
+}
+
+PasswordDialog::~PasswordDialog() = default;
+
+void PasswordDialog::setUser(const QString &user)
+{
+ QTC_ASSERT(d->m_userNameLineEdit, return);
+ d->m_userNameLineEdit->setText(user);
+}
+
+QString PasswordDialog::user() const
+{
+ QTC_ASSERT(d->m_userNameLineEdit, return {});
+ return d->m_userNameLineEdit->text();
+}
+
+QString PasswordDialog::password() const
+{
+ return d->m_passwordLineEdit->text();
+}
+
+std::optional<QPair<QString, QString>> PasswordDialog::getUserAndPassword(
+ const QString &title,
+ const QString &prompt,
+ const QString &doNotAskAgainLabel,
+ const QString &userName,
+ const CheckableDecider &decider,
+ QWidget *parent)
+{
+ if (!decider.shouldAskAgain())
+ return std::nullopt;
+
+ PasswordDialog dialog(title, prompt, doNotAskAgainLabel, true, parent);
+
+ dialog.setUser(userName);
+
+ if (dialog.exec() == QDialog::Accepted)
+ return qMakePair(dialog.user(), dialog.password());
+
+ if (dialog.d->m_checkBox->isChecked())
+ decider.doNotAskAgain();
+
+ return std::nullopt;
+}
+
+std::optional<QString> PasswordDialog::getPassword(const QString &title,
+ const QString &prompt,
+ const QString &doNotAskAgainLabel,
+ const CheckableDecider &decider,
+ QWidget *parent)
+{
+ if (!decider.shouldAskAgain())
+ return std::nullopt;
+
+ PasswordDialog dialog(title, prompt, doNotAskAgainLabel, false, parent);
+
+ if (dialog.exec() == QDialog::Accepted)
+ return dialog.password();
+
+ if (dialog.d->m_checkBox->isChecked())
+ decider.doNotAskAgain();
+
+ return std::nullopt;
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/passworddialog.h b/src/libs/utils/passworddialog.h
new file mode 100644
index 00000000000..a3cdb98b0f6
--- /dev/null
+++ b/src/libs/utils/passworddialog.h
@@ -0,0 +1,68 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "utils_global.h"
+
+#include "checkablemessagebox.h"
+
+#include <QAbstractButton>
+#include <QDialog>
+
+#include <memory>
+#include <optional>
+
+namespace Utils {
+
+class PasswordDialogPrivate;
+
+class QTCREATOR_UTILS_EXPORT ShowPasswordButton : public QAbstractButton
+{
+public:
+ ShowPasswordButton(QWidget *parent = nullptr);
+
+ void paintEvent(QPaintEvent *e) override;
+ void enterEvent(QEnterEvent *e) override;
+ void leaveEvent(QEvent *e) override;
+
+ QSize sizeHint() const override;
+
+private:
+ bool m_containsMouse{false};
+};
+
+class QTCREATOR_UTILS_EXPORT PasswordDialog : public QDialog
+{
+public:
+ PasswordDialog(const QString &title,
+ const QString &prompt,
+ const QString &doNotAskAgainLabel,
+ bool withUsername,
+ QWidget *parent = nullptr);
+ virtual ~PasswordDialog();
+
+ void setUser(const QString &user);
+ QString user() const;
+
+ QString password() const;
+
+ static std::optional<QPair<QString, QString>> getUserAndPassword(
+ const QString &title,
+ const QString &prompt,
+ const QString &doNotAskAgainLabel,
+ const QString &userName,
+ const CheckableDecider &decider,
+ QWidget *parent = nullptr);
+
+ static std::optional<QString> getPassword(const QString &title,
+ const QString &prompt,
+ const QString &doNotAskAgainLabel,
+ const CheckableDecider &decider,
+ QWidget *parent = nullptr);
+
+private:
+ std::unique_ptr<PasswordDialogPrivate> d;
+};
+
+} // namespace Utils
diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp
index 1fe1e962560..048fb57ddb7 100644
--- a/src/libs/utils/pathchooser.cpp
+++ b/src/libs/utils/pathchooser.cpp
@@ -3,6 +3,7 @@
#include "pathchooser.h"
+#include "async.h"
#include "commandline.h"
#include "environment.h"
#include "fileutils.h"
@@ -15,6 +16,7 @@
#include "utilstr.h"
#include <QFileDialog>
+#include <QFuture>
#include <QGuiApplication>
#include <QHBoxLayout>
#include <QMenu>
@@ -375,9 +377,10 @@ bool PathChooser::isReadOnly() const
void PathChooser::setReadOnly(bool b)
{
d->m_lineEdit->setReadOnly(b);
+ d->m_lineEdit->setFrame(!b);
const auto buttons = d->m_buttons;
for (QAbstractButton *button : buttons)
- button->setEnabled(!b);
+ button->setVisible(!b);
}
void PathChooser::slotBrowse(bool remote)
@@ -531,100 +534,73 @@ void PathChooser::setToolTip(const QString &toolTip)
d->m_lineEdit->setToolTip(toolTip);
}
-FancyLineEdit::ValidationFunction PathChooser::defaultValidationFunction() const
+static FancyLineEdit::AsyncValidationResult validatePath(FilePath filePath,
+ const QString &defaultValue,
+ PathChooser::Kind kind)
{
- return std::bind(&PathChooser::validatePath, this, std::placeholders::_1, std::placeholders::_2);
-}
-
-bool PathChooser::validatePath(FancyLineEdit *edit, QString *errorMessage) const
-{
- QString input = edit->text();
-
- if (input.isEmpty()) {
- if (!d->m_defaultValue.isEmpty()) {
- input = d->m_defaultValue;
+ if (filePath.isEmpty()) {
+ if (!defaultValue.isEmpty()) {
+ filePath = FilePath::fromUserInput(defaultValue);
} else {
- if (errorMessage)
- *errorMessage = Tr::tr("The path must not be empty.");
- return false;
+ return make_unexpected(Tr::tr("The path must not be empty."));
}
}
- const FilePath filePath = d->expandedPath(FilePath::fromUserInput(input));
- if (filePath.isEmpty()) {
- if (errorMessage)
- *errorMessage = Tr::tr("The path \"%1\" expanded to an empty string.").arg(input);
- return false;
- }
-
// Check if existing
- switch (d->m_acceptingKind) {
+ switch (kind) {
case PathChooser::ExistingDirectory:
if (!filePath.exists()) {
- if (errorMessage)
- *errorMessage = Tr::tr("The path \"%1\" does not exist.").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(
+ Tr::tr("The path \"%1\" does not exist.").arg(filePath.toUserOutput()));
}
if (!filePath.isDir()) {
- if (errorMessage)
- *errorMessage = Tr::tr("The path \"%1\" is not a directory.").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(
+ Tr::tr("The path \"%1\" is not a directory.").arg(filePath.toUserOutput()));
}
break;
case PathChooser::File:
if (!filePath.exists()) {
- if (errorMessage)
- *errorMessage = Tr::tr("The path \"%1\" does not exist.").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(
+ Tr::tr("The path \"%1\" does not exist.").arg(filePath.toUserOutput()));
}
if (!filePath.isFile()) {
- if (errorMessage)
- *errorMessage = Tr::tr("The path \"%1\" is not a file.").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(
+ Tr::tr("The path \"%1\" is not a file.").arg(filePath.toUserOutput()));
}
break;
case PathChooser::SaveFile:
if (!filePath.parentDir().exists()) {
- if (errorMessage)
- *errorMessage = Tr::tr("The directory \"%1\" does not exist.").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(
+ Tr::tr("The directory \"%1\" does not exist.").arg(filePath.toUserOutput()));
}
if (filePath.exists() && filePath.isDir()) {
- if (errorMessage)
- *errorMessage = Tr::tr("The path \"%1\" is not a file.").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(
+ Tr::tr("The path \"%1\" is not a file.").arg(filePath.toUserOutput()));
}
break;
case PathChooser::ExistingCommand:
if (!filePath.exists()) {
- if (errorMessage)
- *errorMessage = Tr::tr("The path \"%1\" does not exist.").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(
+ Tr::tr("The path \"%1\" does not exist.").arg(filePath.toUserOutput()));
}
if (!filePath.isExecutableFile()) {
- if (errorMessage)
- *errorMessage = Tr::tr("The path \"%1\" is not an executable file.").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(
+ Tr::tr("The path \"%1\" is not an executable file.").arg(filePath.toUserOutput()));
}
break;
case PathChooser::Directory:
if (filePath.exists() && !filePath.isDir()) {
- if (errorMessage)
- *errorMessage = Tr::tr("The path \"%1\" is not a directory.").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(
+ Tr::tr("The path \"%1\" is not a directory.").arg(filePath.toUserOutput()));
}
if (filePath.osType() == OsTypeWindows && !filePath.startsWithDriveLetter()
&& !filePath.startsWith("\\\\") && !filePath.startsWith("//")) {
- if (errorMessage)
- *errorMessage = Tr::tr("Invalid path \"%1\".").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(Tr::tr("Invalid path \"%1\".").arg(filePath.toUserOutput()));
}
break;
case PathChooser::Command:
if (filePath.exists() && !filePath.isExecutableFile()) {
- if (errorMessage)
- *errorMessage = Tr::tr("Cannot execute \"%1\".").arg(filePath.toUserOutput());
- return false;
+ return make_unexpected(Tr::tr("Cannot execute \"%1\".").arg(filePath.toUserOutput()));
}
break;
@@ -632,9 +608,32 @@ bool PathChooser::validatePath(FancyLineEdit *edit, QString *errorMessage) const
;
}
- if (errorMessage)
- *errorMessage = Tr::tr("Full path: \"%1\"").arg(filePath.toUserOutput());
- return true;
+ return filePath.toUserOutput();
+}
+
+FancyLineEdit::AsyncValidationFunction PathChooser::defaultValidationFunction() const
+{
+ return [this](const QString &text) -> FancyLineEdit::AsyncValidationFuture {
+ if (text.isEmpty()) {
+ return QtFuture::makeReadyFuture((Utils::expected_str<QString>(
+ make_unexpected(Tr::tr("The path must not be empty.")))));
+ }
+
+ const FilePath expanded = d->expandedPath(FilePath::fromUserInput(text));
+
+ if (expanded.isEmpty()) {
+ return QtFuture::makeReadyFuture((Utils::expected_str<QString>(
+ make_unexpected(Tr::tr("The path \"%1\" expanded to an empty string.")
+ .arg(expanded.toUserOutput())))));
+ }
+
+ return Utils::asyncRun(
+ [expanded,
+ defVal = d->m_defaultValue,
+ kind = d->m_acceptingKind]() -> FancyLineEdit::AsyncValidationResult {
+ return validatePath(expanded, defVal, kind);
+ });
+ };
}
void PathChooser::setValidationFunction(const FancyLineEdit::ValidationFunction &fn)
@@ -736,7 +735,7 @@ void PathChooser::installLineEditVersionToolTip(QLineEdit *le, const QStringList
ef->setArguments(arguments);
}
-void PathChooser::setHistoryCompleter(const QString &historyKey, bool restoreLastItemFromHistory)
+void PathChooser::setHistoryCompleter(const Key &historyKey, bool restoreLastItemFromHistory)
{
d->m_lineEdit->setHistoryCompleter(historyKey, restoreLastItemFromHistory);
}
diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h
index 62a370185da..b7b4a040f31 100644
--- a/src/libs/utils/pathchooser.h
+++ b/src/libs/utils/pathchooser.h
@@ -80,7 +80,7 @@ public:
/** Returns the suggested label title when used in a form layout. */
static QString label();
- FancyLineEdit::ValidationFunction defaultValidationFunction() const;
+ FancyLineEdit::AsyncValidationFunction defaultValidationFunction() const;
void setValidationFunction(const FancyLineEdit::ValidationFunction &fn);
/** Return the home directory, which needs some fixing under Windows. */
@@ -105,7 +105,7 @@ public:
static void installLineEditVersionToolTip(QLineEdit *le, const QStringList &arguments);
// Enable a history completer with a history of entries.
- void setHistoryCompleter(const QString &historyKey, bool restoreLastItemFromHistory = false);
+ void setHistoryCompleter(const Key &historyKey, bool restoreLastItemFromHistory = false);
// Sets a macro expander that is used when producing path and fileName.
// By default, the global expander is used.
@@ -153,7 +153,6 @@ private:
// Use filePath().toString() or better suitable conversions.
QString path() const { return filePath().toString(); }
- bool validatePath(FancyLineEdit *edit, QString *errorMessage) const;
// Returns overridden title or the one from <title>
QString makeDialogTitle(const QString &title);
void slotBrowse(bool remote);
diff --git a/src/libs/utils/pathlisteditor.cpp b/src/libs/utils/pathlisteditor.cpp
index f2349b275fd..383ca88b030 100644
--- a/src/libs/utils/pathlisteditor.cpp
+++ b/src/libs/utils/pathlisteditor.cpp
@@ -138,7 +138,7 @@ QStringList PathListEditor::pathList() const
{
const QString text = d->edit->toPlainText().trimmed();
if (text.isEmpty())
- return QStringList();
+ return {};
// trim each line
QStringList rc = text.split('\n', Qt::SkipEmptyParts);
const QStringList::iterator end = rc.end();
diff --git a/src/libs/utils/persistentcachestore.cpp b/src/libs/utils/persistentcachestore.cpp
new file mode 100644
index 00000000000..0cac5f83cde
--- /dev/null
+++ b/src/libs/utils/persistentcachestore.cpp
@@ -0,0 +1,115 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "persistentcachestore.h"
+
+#include "filepath.h"
+#include "fileutils.h"
+
+#include <QMap>
+#include <QMutex>
+#include <QStandardPaths>
+
+namespace Utils {
+
+class PrivateGlobal
+{
+public:
+ QMutex mutex;
+ QMap<Key, Store> caches;
+};
+
+static expected_str<FilePath> cacheFolder()
+{
+ static const FilePath folder = FilePath::fromUserInput(QStandardPaths::writableLocation(
+ QStandardPaths::CacheLocation))
+ / "CachedStores";
+ static expected_str<void> created = folder.ensureWritableDir();
+ static expected_str<FilePath> result = created ? folder
+ : expected_str<FilePath>(
+ make_unexpected(created.error()));
+
+ QTC_ASSERT_EXPECTED(result, return result);
+ return result;
+}
+
+static PrivateGlobal &globals()
+{
+ static PrivateGlobal global;
+ return global;
+}
+
+static expected_str<FilePath> filePathFromKey(const Key &cacheKey)
+{
+ static const expected_str<FilePath> folder = cacheFolder();
+ if (!folder)
+ return folder;
+
+ return (*folder / FileUtils::fileSystemFriendlyName(stringFromKey(cacheKey))).withSuffix(".json");
+}
+
+expected_str<Store> PersistentCacheStore::byKey(const Key &cacheKey)
+{
+ const expected_str<FilePath> path = filePathFromKey(cacheKey);
+ if (!path)
+ return make_unexpected(path.error());
+
+ QMutexLocker locker(&globals().mutex);
+
+ auto it = globals().caches.find(cacheKey);
+ if (it != globals().caches.end())
+ return it.value();
+
+ const expected_str<QByteArray> contents = path->fileContents();
+ if (!contents)
+ return make_unexpected(contents.error());
+
+ auto result = storeFromJson(*contents);
+ if (!result)
+ return result;
+
+ if (result->value("__cache_key__").toString() != stringFromKey(cacheKey)) {
+ return make_unexpected(QString("Cache key mismatch: \"%1\" to \"%2\" in \"%3\".")
+ .arg(stringFromKey(cacheKey))
+ .arg(result->value("__cache_key__").toString())
+ .arg(path->toUserOutput()));
+ }
+
+ return result;
+}
+
+expected_str<void> PersistentCacheStore::write(const Key &cacheKey, const Store &store)
+{
+ const expected_str<FilePath> path = filePathFromKey(cacheKey);
+ if (!path)
+ return make_unexpected(path.error());
+
+ QMutexLocker locker(&globals().mutex);
+ globals().caches.insert(cacheKey, store);
+
+ // TODO: The writing of the store data could be done in a separate thread in the future.
+ Store storeCopy = store;
+ storeCopy.insert("__cache_key__", stringFromKey(cacheKey));
+ storeCopy.insert("__last_modified__", QDateTime::currentDateTime().toString(Qt::ISODate));
+ QByteArray json = jsonFromStore(storeCopy);
+ const expected_str<qint64> result = path->writeFileContents(json);
+ if (!result)
+ return make_unexpected(result.error());
+ return {};
+}
+
+expected_str<void> PersistentCacheStore::clear(const Key &cacheKey)
+{
+ const expected_str<FilePath> path = filePathFromKey(cacheKey);
+ if (!path)
+ return make_unexpected(path.error());
+
+ QMutexLocker locker(&globals().mutex);
+ globals().caches.remove(cacheKey);
+
+ if (!path->removeFile())
+ return make_unexpected(QString("Failed to remove cache file."));
+ return {};
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/persistentcachestore.h b/src/libs/utils/persistentcachestore.h
new file mode 100644
index 00000000000..0c40061d619
--- /dev/null
+++ b/src/libs/utils/persistentcachestore.h
@@ -0,0 +1,22 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "utils_global.h"
+
+#include "expected.h"
+#include "store.h"
+#include "storekey.h"
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT PersistentCacheStore
+{
+public:
+ static expected_str<Store> byKey(const Key &cacheKey);
+ static expected_str<void> write(const Key &cacheKey, const Store &store);
+ static expected_str<void> clear(const Key &cacheKey);
+};
+
+} // namespace Utils
diff --git a/src/libs/utils/persistentsettings.cpp b/src/libs/utils/persistentsettings.cpp
index 2daf2934c51..54a829004b3 100644
--- a/src/libs/utils/persistentsettings.cpp
+++ b/src/libs/utils/persistentsettings.cpp
@@ -95,22 +95,18 @@ static QRect stringToRectangle(const QString &v)
namespace Utils {
-struct Context // Basic context containing element name string constants.
-{
- Context() {}
- const QString qtCreatorElement = QString("qtcreator");
- const QString dataElement = QString("data");
- const QString variableElement = QString("variable");
- const QString typeAttribute = QString("type");
- const QString valueElement = QString("value");
- const QString valueListElement = QString("valuelist");
- const QString valueMapElement = QString("valuemap");
- const QString keyAttribute = QString("key");
-};
+const QString qtCreatorElement("qtcreator");
+const QString dataElement("data");
+const QString variableElement("variable");
+const QString typeAttribute("type");
+const QString valueElement("value");
+const QString valueListElement("valuelist");
+const QString valueMapElement("valuemap");
+const QString keyAttribute("key");
struct ParseValueStackEntry
{
- explicit ParseValueStackEntry(QVariant::Type t = QVariant::Invalid, const QString &k = QString()) : type(t), key(k) {}
+ explicit ParseValueStackEntry(QVariant::Type t = QVariant::Invalid, const QString &k = {}) : type(t), key(k) {}
explicit ParseValueStackEntry(const QVariant &aSimpleValue, const QString &k);
QVariant value() const;
@@ -123,8 +119,8 @@ struct ParseValueStackEntry
QVariantMap mapValue;
};
-ParseValueStackEntry::ParseValueStackEntry(const QVariant &aSimpleValue, const QString &k) :
- type(aSimpleValue.type()), key(k), simpleValue(aSimpleValue)
+ParseValueStackEntry::ParseValueStackEntry(const QVariant &aSimpleValue, const QString &k)
+ : type(aSimpleValue.type()), key(k), simpleValue(aSimpleValue)
{
QTC_ASSERT(simpleValue.isValid(), return);
}
@@ -160,22 +156,16 @@ void ParseValueStackEntry::addChild(const QString &key, const QVariant &v)
}
}
-class ParseContext : public Context
+class ParseContext
{
public:
QVariantMap parse(const FilePath &file);
private:
- enum Element { QtCreatorElement, DataElement, VariableElement,
- SimpleValueElement, ListValueElement, MapValueElement, UnknownElement };
-
- Element element(const QStringView &r) const;
- static inline bool isValueElement(Element e)
- { return e == SimpleValueElement || e == ListValueElement || e == MapValueElement; }
QVariant readSimpleValue(QXmlStreamReader &r, const QXmlStreamAttributes &attributes) const;
bool handleStartElement(QXmlStreamReader &r);
- bool handleEndElement(const QStringView &name);
+ bool handleEndElement(const QStringView name);
static QString formatWarning(const QXmlStreamReader &r, const QString &message);
@@ -204,7 +194,7 @@ QVariantMap ParseContext::parse(const FilePath &file)
case QXmlStreamReader::Invalid:
qWarning("Error reading %s:%d: %s", qPrintable(file.fileName()),
int(r.lineNumber()), qPrintable(r.errorString()));
- return QVariantMap();
+ return {};
default:
break;
} // switch token
@@ -215,19 +205,14 @@ QVariantMap ParseContext::parse(const FilePath &file)
bool ParseContext::handleStartElement(QXmlStreamReader &r)
{
const QStringView name = r.name();
- const Element e = element(name);
- if (e == VariableElement) {
+ if (name == variableElement) {
m_currentVariableName = r.readElementText();
return false;
}
- if (!ParseContext::isValueElement(e))
- return false;
-
- const QXmlStreamAttributes attributes = r.attributes();
- const QString key = attributes.hasAttribute(keyAttribute) ?
- attributes.value(keyAttribute).toString() : QString();
- switch (e) {
- case SimpleValueElement: {
+ if (name == valueElement) {
+ const QXmlStreamAttributes attributes = r.attributes();
+ const QString key = attributes.hasAttribute(keyAttribute) ?
+ attributes.value(keyAttribute).toString() : QString();
// This reads away the end element, so, handle end element right here.
const QVariant v = readSimpleValue(r, attributes);
if (!v.isValid()) {
@@ -237,22 +222,26 @@ bool ParseContext::handleStartElement(QXmlStreamReader &r)
m_valueStack.push_back(ParseValueStackEntry(v, key));
return handleEndElement(name);
}
- case ListValueElement:
+ if (name == valueListElement) {
+ const QXmlStreamAttributes attributes = r.attributes();
+ const QString key = attributes.hasAttribute(keyAttribute) ?
+ attributes.value(keyAttribute).toString() : QString();
m_valueStack.push_back(ParseValueStackEntry(QVariant::List, key));
- break;
- case MapValueElement:
+ return false;
+ }
+ if (name == valueMapElement) {
+ const QXmlStreamAttributes attributes = r.attributes();
+ const QString key = attributes.hasAttribute(keyAttribute) ?
+ attributes.value(keyAttribute).toString() : QString();
m_valueStack.push_back(ParseValueStackEntry(QVariant::Map, key));
- break;
- default:
- break;
+ return false;
}
return false;
}
-bool ParseContext::handleEndElement(const QStringView &name)
+bool ParseContext::handleEndElement(const QStringView name)
{
- const Element e = element(name);
- if (ParseContext::isValueElement(e)) {
+ if (name == valueElement || name == valueListElement || name == valueMapElement) {
QTC_ASSERT(!m_valueStack.isEmpty(), return true);
const ParseValueStackEntry top = m_valueStack.pop();
if (m_valueStack.isEmpty()) { // Last element? -> Done with that variable.
@@ -262,8 +251,9 @@ bool ParseContext::handleEndElement(const QStringView &name)
return false;
}
m_valueStack.top().addChild(top.key, top.value());
+ return false;
}
- return e == QtCreatorElement;
+ return name == qtCreatorElement;
}
QString ParseContext::formatWarning(const QXmlStreamReader &r, const QString &message)
@@ -278,23 +268,6 @@ QString ParseContext::formatWarning(const QXmlStreamReader &r, const QString &me
return result;
}
-ParseContext::Element ParseContext::element(const QStringView &r) const
-{
- if (r == valueElement)
- return SimpleValueElement;
- if (r == valueListElement)
- return ListValueElement;
- if (r == valueMapElement)
- return MapValueElement;
- if (r == qtCreatorElement)
- return QtCreatorElement;
- if (r == dataElement)
- return DataElement;
- if (r == variableElement)
- return VariableElement;
- return UnknownElement;
-}
-
QVariant ParseContext::readSimpleValue(QXmlStreamReader &r, const QXmlStreamAttributes &attributes) const
{
// Simple value
@@ -318,16 +291,16 @@ QVariant ParseContext::readSimpleValue(QXmlStreamReader &r, const QXmlStreamAttr
PersistentSettingsReader::PersistentSettingsReader() = default;
-QVariant PersistentSettingsReader::restoreValue(const QString &variable, const QVariant &defaultValue) const
+QVariant PersistentSettingsReader::restoreValue(const Key &variable, const QVariant &defaultValue) const
{
- if (m_valueMap.contains(variable))
- return m_valueMap.value(variable);
+ if (m_valueMap.contains(stringFromKey(variable)))
+ return m_valueMap.value(stringFromKey(variable));
return defaultValue;
}
-QVariantMap PersistentSettingsReader::restoreValues() const
+Store PersistentSettingsReader::restoreValues() const
{
- return m_valueMap;
+ return storeFromMap(m_valueMap);
}
bool PersistentSettingsReader::load(const FilePath &fileName)
@@ -352,47 +325,50 @@ FilePath PersistentSettingsReader::filePath()
\class Utils::PersistentSettingsWriter
\inmodule QtCreator
- \brief The PersistentSettingsWriter class serializes a QVariantMap of
+ \brief The PersistentSettingsWriter class serializes a Store of
arbitrary, nested data structures to an XML file.
\sa Utils::PersistentSettingsReader
*/
-static void writeVariantValue(QXmlStreamWriter &w, const Context &ctx,
- const QVariant &variant, const QString &key = QString())
+#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
+static QString xmlAttrFromKey(const QString &key) { return key; }
+#else
+static QString xmlAttrFromKey(const QString &key) { return key; }
+#endif
+
+static void writeVariantValue(QXmlStreamWriter &w, const QVariant &variant, const QString &key = {})
{
- switch (static_cast<int>(variant.type())) {
- case static_cast<int>(QVariant::StringList):
- case static_cast<int>(QVariant::List): {
- w.writeStartElement(ctx.valueListElement);
- w.writeAttribute(ctx.typeAttribute, QLatin1String(QVariant::typeToName(QVariant::List)));
+ static const int storeId = qMetaTypeId<Store>();
+
+ const int variantType = variant.typeId();
+ if (variantType == QMetaType::QStringList || variantType == QMetaType::QVariantList) {
+ w.writeStartElement(valueListElement);
+ w.writeAttribute(typeAttribute, "QVariantList");
if (!key.isEmpty())
- w.writeAttribute(ctx.keyAttribute, key);
+ w.writeAttribute(keyAttribute, xmlAttrFromKey(key));
const QList<QVariant> list = variant.toList();
for (const QVariant &var : list)
- writeVariantValue(w, ctx, var);
+ writeVariantValue(w, var);
w.writeEndElement();
- break;
- }
- case static_cast<int>(QVariant::Map): {
- w.writeStartElement(ctx.valueMapElement);
- w.writeAttribute(ctx.typeAttribute, QLatin1String(QVariant::typeToName(QVariant::Map)));
+ } else if (variantType == storeId || variantType == QMetaType::QVariantMap) {
+ w.writeStartElement(valueMapElement);
+ w.writeAttribute(typeAttribute, "QVariantMap");
if (!key.isEmpty())
- w.writeAttribute(ctx.keyAttribute, key);
+ w.writeAttribute(keyAttribute, xmlAttrFromKey(key));
const QVariantMap varMap = variant.toMap();
- const QVariantMap::const_iterator cend = varMap.constEnd();
- for (QVariantMap::const_iterator i = varMap.constBegin(); i != cend; ++i)
- writeVariantValue(w, ctx, i.value(), i.key());
+ const auto cend = varMap.constEnd();
+ for (auto i = varMap.constBegin(); i != cend; ++i)
+ writeVariantValue(w, i.value(), i.key());
w.writeEndElement();
- }
- break;
- case static_cast<int>(QMetaType::QObjectStar): // ignore QObjects!
- case static_cast<int>(QMetaType::VoidStar): // ignore void pointers!
- break;
- default:
- w.writeStartElement(ctx.valueElement);
- w.writeAttribute(ctx.typeAttribute, QLatin1String(variant.typeName()));
+ } else if (variantType == QMetaType::QObjectStar) {
+ // ignore QObjects
+ } else if (variantType == QMetaType::VoidStar) {
+ // ignore void pointers
+ } else {
+ w.writeStartElement(valueElement);
+ w.writeAttribute(typeAttribute, QLatin1String(variant.typeName()));
if (!key.isEmpty())
- w.writeAttribute(ctx.keyAttribute, key);
+ w.writeAttribute(keyAttribute, xmlAttrFromKey(key));
switch (variant.type()) {
case QVariant::Rect:
w.writeCharacters(rectangleToString(variant.toRect()));
@@ -402,7 +378,6 @@ static void writeVariantValue(QXmlStreamWriter &w, const Context &ctx,
break;
}
w.writeEndElement();
- break;
}
}
@@ -410,7 +385,7 @@ PersistentSettingsWriter::PersistentSettingsWriter(const FilePath &fileName, con
m_fileName(fileName), m_docType(docType)
{ }
-bool PersistentSettingsWriter::save(const QVariantMap &data, QString *errorString) const
+bool PersistentSettingsWriter::save(const Store &data, QString *errorString) const
{
if (data == m_savedData)
return true;
@@ -418,7 +393,7 @@ bool PersistentSettingsWriter::save(const QVariantMap &data, QString *errorStrin
}
#ifdef QT_GUI_LIB
-bool PersistentSettingsWriter::save(const QVariantMap &data, QWidget *parent) const
+bool PersistentSettingsWriter::save(const Store &data, QWidget *parent) const
{
QString errorString;
const bool success = save(data, &errorString);
@@ -432,17 +407,16 @@ FilePath PersistentSettingsWriter::fileName() const
{ return m_fileName; }
//** * @brief Set contents of file (e.g. from data read from it). */
-void PersistentSettingsWriter::setContents(const QVariantMap &data)
+void PersistentSettingsWriter::setContents(const Store &data)
{
m_savedData = data;
}
-bool PersistentSettingsWriter::write(const QVariantMap &data, QString *errorString) const
+bool PersistentSettingsWriter::write(const Store &data, QString *errorString) const
{
m_fileName.parentDir().ensureWritableDir();
FileSaver saver(m_fileName, QIODevice::Text);
if (!saver.hasError()) {
- const Context ctx;
QXmlStreamWriter w(saver.file());
w.setAutoFormatting(true);
w.setAutoFormattingIndent(1); // Historical, used to be QDom.
@@ -452,12 +426,12 @@ bool PersistentSettingsWriter::write(const QVariantMap &data, QString *errorStri
arg(QCoreApplication::applicationName(),
QCoreApplication::applicationVersion(),
QDateTime::currentDateTime().toString(Qt::ISODate)));
- w.writeStartElement(ctx.qtCreatorElement);
- const QVariantMap::const_iterator cend = data.constEnd();
- for (QVariantMap::const_iterator it = data.constBegin(); it != cend; ++it) {
- w.writeStartElement(ctx.dataElement);
- w.writeTextElement(ctx.variableElement, it.key());
- writeVariantValue(w, ctx, it.value());
+ w.writeStartElement(qtCreatorElement);
+ const QVariantMap map = mapFromStore(data);
+ for (auto it = map.constBegin(), cend = map.constEnd(); it != cend; ++it) {
+ w.writeStartElement(dataElement);
+ w.writeTextElement(variableElement, it.key());
+ writeVariantValue(w, it.value());
w.writeEndElement();
}
w.writeEndDocument();
diff --git a/src/libs/utils/persistentsettings.h b/src/libs/utils/persistentsettings.h
index 7e07f0237c6..8092e8a0118 100644
--- a/src/libs/utils/persistentsettings.h
+++ b/src/libs/utils/persistentsettings.h
@@ -6,6 +6,7 @@
#include "utils_global.h"
#include "filepath.h"
+#include "store.h"
#include <QVariant>
@@ -19,13 +20,13 @@ class QTCREATOR_UTILS_EXPORT PersistentSettingsReader
{
public:
PersistentSettingsReader();
- QVariant restoreValue(const QString &variable, const QVariant &defaultValue = QVariant()) const;
- QVariantMap restoreValues() const;
+ QVariant restoreValue(const Key &variable, const QVariant &defaultValue = {}) const;
+ Store restoreValues() const;
bool load(const FilePath &fileName);
FilePath filePath();
private:
- QMap<QString, QVariant> m_valueMap;
+ QVariantMap m_valueMap;
FilePath m_filePath;
};
@@ -34,21 +35,21 @@ class QTCREATOR_UTILS_EXPORT PersistentSettingsWriter
public:
PersistentSettingsWriter(const FilePath &fileName, const QString &docType);
- bool save(const QVariantMap &data, QString *errorString) const;
+ bool save(const Store &data, QString *errorString) const;
#ifdef QT_GUI_LIB
- bool save(const QVariantMap &data, QWidget *parent) const;
+ bool save(const Store &data, QWidget *parent) const;
#endif
FilePath fileName() const;
- void setContents(const QVariantMap &data);
+ void setContents(const Store &data);
private:
- bool write(const QVariantMap &data, QString *errorString) const;
+ bool write(const Store &data, QString *errorString) const;
const FilePath m_fileName;
const QString m_docType;
- mutable QMap<QString, QVariant> m_savedData;
+ mutable Store m_savedData;
};
} // namespace Utils
diff --git a/src/libs/utils/port.h b/src/libs/utils/port.h
index c4b46631de2..2bf561f0b94 100644
--- a/src/libs/utils/port.h
+++ b/src/libs/utils/port.h
@@ -5,8 +5,8 @@
#include "utils_global.h"
-#include <QMetaType>
#include <QList>
+#include <QMetaType>
#include <QString>
namespace Utils {
diff --git a/src/libs/utils/process.cpp b/src/libs/utils/process.cpp
index 8721d6c4214..534dcff78f1 100644
--- a/src/libs/utils/process.cpp
+++ b/src/libs/utils/process.cpp
@@ -410,6 +410,13 @@ public:
}
connect(m_ptyProcess->notifier(), &QIODevice::readyRead, this, [this] {
+ if (m_setup.m_ptyData->ptyInputFlagsChangedHandler()
+ && m_inputFlags != m_ptyProcess->inputFlags()) {
+ m_inputFlags = m_ptyProcess->inputFlags();
+ m_setup.m_ptyData->ptyInputFlagsChangedHandler()(
+ static_cast<Pty::PtyInputFlag>(m_inputFlags.toInt()));
+ }
+
emit readyRead(m_ptyProcess->readAll(), {});
});
@@ -430,6 +437,7 @@ public:
private:
std::unique_ptr<IPtyProcess> m_ptyProcess;
+ IPtyProcess::PtyInputFlags m_inputFlags;
};
class QProcessImpl final : public DefaultImpl
@@ -1183,10 +1191,25 @@ const Environment &Process::controlEnvironment() const
return d->m_setup.m_controlEnvironment;
}
+void Process::setRunData(const ProcessRunData &data)
+{
+ if (data.workingDirectory.needsDevice() && data.command.executable().needsDevice()) {
+ QTC_CHECK(data.workingDirectory.isSameDevice(data.command.executable()));
+ }
+ d->m_setup.m_commandLine = data.command;
+ d->m_setup.m_workingDirectory = data.workingDirectory;
+ d->m_setup.m_environment = data.environment;
+}
+
+ProcessRunData Process::runData() const
+{
+ return {d->m_setup.m_commandLine, d->m_setup.m_workingDirectory, d->m_setup.m_environment};
+}
+
void Process::setCommand(const CommandLine &cmdLine)
{
if (d->m_setup.m_workingDirectory.needsDevice() && cmdLine.executable().needsDevice()) {
- QTC_CHECK(d->m_setup.m_workingDirectory.host() == cmdLine.executable().host());
+ QTC_CHECK(d->m_setup.m_workingDirectory.isSameDevice(cmdLine.executable()));
}
d->m_setup.m_commandLine = cmdLine;
}
@@ -1228,7 +1251,19 @@ void Process::start()
} else {
processImpl = d->createProcessInterface();
}
- QTC_ASSERT(processImpl, return);
+
+ if (!processImpl) {
+ // This happens if a device does not implement the createProcessInterface() function.
+ d->m_result = ProcessResult::StartFailed;
+ d->m_resultData.m_exitCode = 255;
+ d->m_resultData.m_exitStatus = QProcess::CrashExit;
+ d->m_resultData.m_errorString = Tr::tr("Failed to create process interface for \"%1\".")
+ .arg(d->m_setup.m_commandLine.toUserOutput());
+ d->m_resultData.m_error = QProcess::FailedToStart;
+ d->emitGuardedSignal(&Process::done);
+ return;
+ }
+
d->setProcessInterface(processImpl);
d->m_state = QProcess::Starting;
d->m_process->m_setup = d->m_setup;
@@ -1463,18 +1498,6 @@ QString Process::errorString() const
return resultData().m_errorString;
}
-// Path utilities
-
-Environment Process::systemEnvironmentForBinary(const FilePath &filePath)
-{
- if (filePath.needsDevice()) {
- QTC_ASSERT(s_deviceHooks.systemEnvironmentForBinary, return {});
- return s_deviceHooks.systemEnvironmentForBinary(filePath);
- }
-
- return Environment::systemEnvironment();
-}
-
qint64 Process::applicationMainThreadId() const
{
return d->m_applicationMainThreadId;
diff --git a/src/libs/utils/process.h b/src/libs/utils/process.h
index 83f1bb990b4..3134894b393 100644
--- a/src/libs/utils/process.h
+++ b/src/libs/utils/process.h
@@ -30,6 +30,7 @@ class Environment;
class DeviceProcessHooks;
class ProcessInterface;
class ProcessResultData;
+class ProcessRunData;
class QTCREATOR_UTILS_EXPORT Process final : public QObject
{
@@ -78,6 +79,21 @@ public:
// ProcessSetupData related
+ void setRunData(const ProcessRunData &data);
+ ProcessRunData runData() const;
+
+ void setCommand(const CommandLine &cmdLine);
+ const CommandLine &commandLine() const;
+
+ void setWorkingDirectory(const FilePath &dir);
+ FilePath workingDirectory() const;
+
+ void setEnvironment(const Environment &env); // Main process
+ const Environment &environment() const;
+
+ void setControlEnvironment(const Environment &env); // Possible helper process (ssh on host etc)
+ const Environment &controlEnvironment() const;
+
void setProcessImpl(ProcessImpl processImpl);
void setPtyData(const std::optional<Pty::Data> &data);
@@ -90,18 +106,6 @@ public:
void setProcessMode(ProcessMode processMode);
ProcessMode processMode() const;
- void setEnvironment(const Environment &env); // Main process
- const Environment &environment() const;
-
- void setControlEnvironment(const Environment &env); // Possible helper process (ssh on host etc)
- const Environment &controlEnvironment() const;
-
- void setCommand(const CommandLine &cmdLine);
- const CommandLine &commandLine() const;
-
- void setWorkingDirectory(const FilePath &dir);
- FilePath workingDirectory() const;
-
void setWriteData(const QByteArray &writeData);
void setUseCtrlCStub(bool enabled); // release only
@@ -111,8 +115,9 @@ public:
bool isRunAsRoot() const;
void setAbortOnMetaChars(bool abort);
- QProcess::ProcessChannelMode processChannelMode() const;
void setProcessChannelMode(QProcess::ProcessChannelMode mode);
+ QProcess::ProcessChannelMode processChannelMode() const;
+
void setStandardInputFile(const QString &inputFile);
void setExtraData(const QString &key, const QVariant &value);
@@ -134,9 +139,6 @@ public:
// These (or some of them) may be potentially moved outside of the class.
// Some of them could be aggregated in another public utils class.
- // TODO: Unused currently? Should it serve as a compartment for contrary of remoteEnvironment?
- static Environment systemEnvironmentForBinary(const FilePath &filePath);
-
static bool startDetached(const CommandLine &cmd, const FilePath &workingDirectory = {},
qint64 *pid = nullptr);
@@ -207,7 +209,6 @@ class DeviceProcessHooks
{
public:
std::function<ProcessInterface *(const FilePath &)> processImplHook;
- std::function<Environment(const FilePath &)> systemEnvironmentForBinary;
};
class QTCREATOR_UTILS_EXPORT ProcessTaskAdapter : public Tasking::TaskAdapter<Process>
@@ -217,8 +218,8 @@ public:
void start() final;
};
-} // namespace Utils
+using ProcessTask = Tasking::CustomTask<ProcessTaskAdapter>;
-TASKING_DECLARE_TASK(ProcessTask, Utils::ProcessTaskAdapter);
+} // namespace Utils
#endif // UTILS_PROCESS_H
diff --git a/src/libs/utils/processhandle.cpp b/src/libs/utils/processhandle.cpp
index 06850457d37..c27e8a70db6 100644
--- a/src/libs/utils/processhandle.cpp
+++ b/src/libs/utils/processhandle.cpp
@@ -47,7 +47,7 @@ bool ProcessHandle::equals(const ProcessHandle &rhs) const
return m_pid == rhs.m_pid;
}
-#ifndef Q_OS_OSX
+#ifndef Q_OS_MACOS
bool ProcessHandle::activate()
{
return false;
diff --git a/src/libs/utils/processinterface.h b/src/libs/utils/processinterface.h
index a0460c5af3a..796972d3093 100644
--- a/src/libs/utils/processinterface.h
+++ b/src/libs/utils/processinterface.h
@@ -18,12 +18,19 @@ namespace Internal { class ProcessPrivate; }
namespace Pty {
+enum PtyInputFlag {
+ None = 0x0,
+ InputModeHidden = 0x1,
+};
+
using ResizeHandler = std::function<void(const QSize &)>;
+using PtyInputFlagsChangeHandler = std::function<void(PtyInputFlag)>;
class QTCREATOR_UTILS_EXPORT SharedData
{
public:
ResizeHandler m_handler;
+ PtyInputFlagsChangeHandler m_inputFlagsChangedHandler;
};
class QTCREATOR_UTILS_EXPORT Data
@@ -32,6 +39,15 @@ public:
Data() : m_data(new SharedData) {}
void setResizeHandler(const ResizeHandler &handler) { m_data->m_handler = handler; }
+ void setPtyInputFlagsChangedHandler(const PtyInputFlagsChangeHandler &handler)
+ {
+ m_data->m_inputFlagsChangedHandler = handler;
+ }
+
+ PtyInputFlagsChangeHandler ptyInputFlagsChangedHandler() const
+ {
+ return m_data->m_inputFlagsChangedHandler;
+ }
QSize size() const { return m_size; }
void resize(const QSize &size);
@@ -43,6 +59,14 @@ private:
} // namespace Pty
+class QTCREATOR_UTILS_EXPORT ProcessRunData
+{
+public:
+ Utils::CommandLine command;
+ Utils::FilePath workingDirectory;
+ Utils::Environment environment;
+};
+
class QTCREATOR_UTILS_EXPORT ProcessSetupData
{
public:
diff --git a/src/libs/utils/processutils.cpp b/src/libs/utils/processutils.cpp
index 62ea514b658..1c4f988fc51 100644
--- a/src/libs/utils/processutils.cpp
+++ b/src/libs/utils/processutils.cpp
@@ -105,6 +105,32 @@ BOOL CALLBACK sendInterruptMessageToAllWindowsOfProcess_enumWnd(HWND hwnd, LPARA
ProcessHelper::ProcessHelper(QObject *parent)
: QProcess(parent), m_processStartHandler(this)
+{}
+
+void ProcessHelper::setLowPriority()
+{
+ m_lowPriority = true;
+ enableChildProcessModifier();
+}
+
+void ProcessHelper::setUnixTerminalDisabled()
+{
+#if defined(Q_OS_UNIX)
+# if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
+ m_unixTerminalDisabled = true;
+ enableChildProcessModifier();
+# else
+ setUnixProcessParameters(QProcess::UnixProcessFlag::CreateNewSession);
+# endif
+#endif
+}
+
+void ProcessHelper::setUseCtrlCStub(bool enabled)
+{
+ m_useCtrlCStub = enabled;
+}
+
+void ProcessHelper::enableChildProcessModifier()
{
#if defined(Q_OS_UNIX)
setChildProcessModifier([this] {
@@ -115,18 +141,15 @@ ProcessHelper::ProcessHelper(QObject *parent)
perror("Failed to set nice value");
}
+# if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
// Disable terminal by becoming a session leader.
if (m_unixTerminalDisabled)
setsid();
+# endif
});
#endif
}
-void ProcessHelper::setUseCtrlCStub(bool enabled)
-{
- m_useCtrlCStub = enabled;
-}
-
void ProcessHelper::terminateProcess()
{
#ifdef Q_OS_WIN
diff --git a/src/libs/utils/processutils.h b/src/libs/utils/processutils.h
index 89202c0daf2..c2a864db1fb 100644
--- a/src/libs/utils/processutils.h
+++ b/src/libs/utils/processutils.h
@@ -40,8 +40,8 @@ public:
using QProcess::setErrorString;
- void setLowPriority() { m_lowPriority = true; }
- void setUnixTerminalDisabled() { m_unixTerminalDisabled = true; }
+ void setLowPriority();
+ void setUnixTerminalDisabled();
void setUseCtrlCStub(bool enabled); // release only
static void terminateProcess(QProcess *process);
@@ -49,6 +49,7 @@ public:
static void interruptPid(qint64 pid);
private:
+ void enableChildProcessModifier();
void terminateProcess();
bool m_lowPriority = false;
diff --git a/src/libs/utils/progressindicator.h b/src/libs/utils/progressindicator.h
index df2e587a849..71732570e8a 100644
--- a/src/libs/utils/progressindicator.h
+++ b/src/libs/utils/progressindicator.h
@@ -55,7 +55,6 @@ private:
class QTCREATOR_UTILS_EXPORT ProgressIndicator : public OverlayWidget
{
- Q_OBJECT
public:
explicit ProgressIndicator(ProgressIndicatorSize size, QWidget *parent = nullptr);
diff --git a/src/libs/utils/projectintropage.cpp b/src/libs/utils/projectintropage.cpp
index 0b1a0a63557..b710e68723b 100644
--- a/src/libs/utils/projectintropage.cpp
+++ b/src/libs/utils/projectintropage.cpp
@@ -79,6 +79,7 @@ ProjectIntroPage::ProjectIntroPage(QWidget *parent) :
d->m_nameLineEdit = new Utils::FancyLineEdit(frame);
d->m_pathChooser = new Utils::PathChooser(frame);
+ d->m_pathChooser->setObjectName("baseFolder"); // used by Squish
d->m_pathChooser->setExpectedKind(PathChooser::Directory);
d->m_pathChooser->setDisabled(d->m_forceSubProject);
diff --git a/src/libs/utils/qtcsettings.cpp b/src/libs/utils/qtcsettings.cpp
index 65e73615e2d..2fb036422c1 100644
--- a/src/libs/utils/qtcsettings.cpp
+++ b/src/libs/utils/qtcsettings.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qtcsettings.h"
+#include "store.h"
namespace Utils {
@@ -10,7 +11,8 @@ namespace Utils {
\inheaderfile utils/qtcsettings.h
\inmodule QtCreator
- \brief The QtcSettings class is an extension of the QSettings class.
+ \brief The QtcSettings class is an extension of the QSettings class
+ the uses Utils::Key instead of QString for keys.
Use Utils::QtcSettings::setValueWithDefault() to write values with a
default.
@@ -29,4 +31,39 @@ namespace Utils {
\sa QSettings::setValue()
*/
+void QtcSettings::beginGroup(const Key &prefix)
+{
+ QSettings::beginGroup(stringFromKey(prefix));
+}
+
+QVariant QtcSettings::value(const Key &key) const
+{
+ return QSettings::value(stringFromKey(key));
+}
+
+QVariant QtcSettings::value(const Key &key, const QVariant &def) const
+{
+ return QSettings::value(stringFromKey(key), def);
+}
+
+void QtcSettings::setValue(const Key &key, const QVariant &value)
+{
+ QSettings::setValue(stringFromKey(key), mapEntryFromStoreEntry(value));
+}
+
+void QtcSettings::remove(const Key &key)
+{
+ QSettings::remove(stringFromKey(key));
+}
+
+bool QtcSettings::contains(const Key &key) const
+{
+ return QSettings::contains(stringFromKey(key));
+}
+
+KeyList QtcSettings::childKeys() const
+{
+ return keysFromStrings(QSettings::childKeys());
+}
+
} // namespace Utils
diff --git a/src/libs/utils/qtcsettings.h b/src/libs/utils/qtcsettings.h
index 13e5ef4c3cb..8a048b73482 100644
--- a/src/libs/utils/qtcsettings.h
+++ b/src/libs/utils/qtcsettings.h
@@ -5,59 +5,57 @@
#include "utils_global.h"
+#include "store.h"
+
#include <QSettings>
namespace Utils {
-class QTCREATOR_UTILS_EXPORT QtcSettings : public QSettings
+class QTCREATOR_UTILS_EXPORT QtcSettings : private QSettings
{
public:
using QSettings::QSettings;
+ using QSettings::group;
+ using QSettings::endGroup;
+ using QSettings::allKeys;
+ using QSettings::fileName;
+ using QSettings::setParent;
+ using QSettings::sync;
+ using QSettings::beginReadArray;
+ using QSettings::beginWriteArray;
+ using QSettings::endArray;
+ using QSettings::setArrayIndex;
+ using QSettings::childGroups;
+ using QSettings::status;
+ using QSettings::clear;
+
+ void beginGroup(const Key &prefix);
+
+ QVariant value(const Key &key) const;
+ QVariant value(const Key &key, const QVariant &def) const;
+ void setValue(const Key &key, const QVariant &value);
+ void remove(const Key &key);
+ bool contains(const Key &key) const;
+
+ KeyList childKeys() const;
template<typename T>
- void setValueWithDefault(const QString &key, const T &val, const T &defaultValue);
- template<typename T>
- void setValueWithDefault(const QString &key, const T &val);
+ void setValueWithDefault(const Key &key, const T &val, const T &defaultValue)
+ {
+ if (val == defaultValue)
+ remove(key);
+ else
+ setValue(key, val);
+ }
template<typename T>
- static void setValueWithDefault(QSettings *settings,
- const QString &key,
- const T &val,
- const T &defaultValue);
- template<typename T>
- static void setValueWithDefault(QSettings *settings, const QString &key, const T &val);
+ void setValueWithDefault(const Key &key, const T &val)
+ {
+ if (val == T())
+ remove(key);
+ else
+ setValue(key, val);
+ }
};
-template<typename T>
-void QtcSettings::setValueWithDefault(const QString &key, const T &val, const T &defaultValue)
-{
- setValueWithDefault(this, key, val, defaultValue);
-}
-
-template<typename T>
-void QtcSettings::setValueWithDefault(const QString &key, const T &val)
-{
- setValueWithDefault(this, key, val);
-}
-
-template<typename T>
-void QtcSettings::setValueWithDefault(QSettings *settings,
- const QString &key,
- const T &val,
- const T &defaultValue)
-{
- if (val == defaultValue)
- settings->remove(key);
- else
- settings->setValue(key, QVariant::fromValue(val));
-}
-
-template<typename T>
-void QtcSettings::setValueWithDefault(QSettings *settings, const QString &key, const T &val)
-{
- if (val == T())
- settings->remove(key);
- else
- settings->setValue(key, QVariant::fromValue(val));
-}
} // namespace Utils
diff --git a/src/libs/utils/removefiledialog.h b/src/libs/utils/removefiledialog.h
index 7fef70eb63f..a0a4299c253 100644
--- a/src/libs/utils/removefiledialog.h
+++ b/src/libs/utils/removefiledialog.h
@@ -17,8 +17,6 @@ class FilePath;
class QTCREATOR_UTILS_EXPORT RemoveFileDialog : public QDialog
{
- Q_OBJECT
-
public:
explicit RemoveFileDialog(const FilePath &filePath, QWidget *parent = nullptr);
~RemoveFileDialog() override;
diff --git a/src/libs/utils/runextensions.cpp b/src/libs/utils/runextensions.cpp
deleted file mode 100644
index efcd73a643e..00000000000
--- a/src/libs/utils/runextensions.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "runextensions.h"
-
-namespace Utils {
-namespace Internal {
-
-RunnableThread::RunnableThread(QRunnable *runnable, QObject *parent)
- : QThread(parent),
- m_runnable(runnable)
-{
-}
-
-void RunnableThread::run()
-{
- m_runnable->run();
- if (m_runnable->autoDelete())
- delete m_runnable;
-}
-
-} // Internal
-} // Utils
diff --git a/src/libs/utils/runextensions.h b/src/libs/utils/runextensions.h
deleted file mode 100644
index 6505b12a9cf..00000000000
--- a/src/libs/utils/runextensions.h
+++ /dev/null
@@ -1,479 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include "utils_global.h"
-
-#include "functiontraits.h"
-
-#include <QCoreApplication>
-#include <QFuture>
-#include <QFutureInterface>
-#include <QFutureWatcher>
-#include <QRunnable>
-#include <QThread>
-#include <QThreadPool>
-
-#include <functional>
-
-// hasCallOperator & Co must be outside of any namespace
-// because of internal compiler error with MSVC2015 Update 2
-
-using testCallOperatorYes = char;
-using testCallOperatorNo = struct { char foo[2]; };
-
-template<typename C>
-static testCallOperatorYes testCallOperator(decltype(&C::operator()));
-
-template<typename>
-static testCallOperatorNo testCallOperator(...);
-
-template<typename T>
-struct hasCallOperator
-{
- static const bool value = (sizeof(testCallOperator<T>(nullptr)) == sizeof(testCallOperatorYes));
-};
-
-namespace Utils {
-
-namespace Internal {
-
-/*
- resultType<F>::type
-
- Returns the type of results that would be reported by a callable of type F
- when called through the runAsync methods. I.e. the ResultType in
-
- void f(QFutureInterface<Result> &fi, ...)
- ResultType f(...)
-
- Returns void if F is not callable, and if F is a callable that does not take
- a QFutureInterface& as its first parameter and returns void.
-*/
-
-template <typename Function>
-struct resultType;
-
-template <typename Function, typename Arg>
-struct resultTypeWithArgument;
-
-template <typename Function, int index, bool>
-struct resultTypeTakesArguments;
-
-template <typename Function, bool>
-struct resultTypeIsMemberFunction;
-
-template <typename Function, bool>
-struct resultTypeIsFunctionLike;
-
-template <typename Function, bool>
-struct resultTypeHasCallOperator;
-
-template <typename Function, typename ResultType>
-struct resultTypeWithArgument<Function, QFutureInterface<ResultType>&>
-{
- using type = ResultType;
-};
-
-template <typename Function, typename Arg>
-struct resultTypeWithArgument
-{
- using type = functionResult_t<Function>;
-};
-
-template <typename Function, int index>
-struct resultTypeTakesArguments<Function, index, true>
- : public resultTypeWithArgument<Function, typename functionTraits<Function>::template argument<index>::type>
-{
-};
-
-template <typename Function, int index>
-struct resultTypeTakesArguments<Function, index, false>
-{
- using type = functionResult_t<Function>;
-};
-
-template <typename Function>
-struct resultTypeIsFunctionLike<Function, true>
- : public resultTypeTakesArguments<Function, 0, (functionTraits<Function>::arity > 0)>
-{
-};
-
-template <typename Function>
-struct resultTypeIsMemberFunction<Function, true>
- : public resultTypeTakesArguments<Function, 1, (functionTraits<Function>::arity > 1)>
-{
-};
-
-template <typename Function>
-struct resultTypeIsMemberFunction<Function, false>
-{
- using type = void;
-};
-
-template <typename Function>
-struct resultTypeIsFunctionLike<Function, false>
- : public resultTypeIsMemberFunction<Function, std::is_member_function_pointer<Function>::value>
-{
-};
-
-template <typename Function>
-struct resultTypeHasCallOperator<Function, false>
- : public resultTypeIsFunctionLike<Function, std::is_function<std::remove_pointer_t<std::decay_t<Function>>>::value>
-{
-};
-
-template <typename Callable>
-struct resultTypeHasCallOperator<Callable, true>
- : public resultTypeTakesArguments<Callable, 0, (functionTraits<Callable>::arity > 0)>
-{
-};
-
-template <typename Function>
-struct resultType
- : public resultTypeHasCallOperator<Function, hasCallOperator<Function>::value>
-{
-};
-
-template <typename Function>
-struct resultType<Function&> : public resultType<Function>
-{
-};
-
-template <typename Function>
-struct resultType<const Function&> : public resultType<Function>
-{
-};
-
-template <typename Function>
-struct resultType<Function &&> : public resultType<Function>
-{
-};
-
-template <typename Function>
-struct resultType<std::reference_wrapper<Function>> : public resultType<Function>
-{
-};
-template <typename Function>
-struct resultType<std::reference_wrapper<const Function>> : public resultType<Function>
-{
-};
-
-/*
- Callable object that wraps a member function pointer with the object it
- will be called on.
-*/
-
-template <typename Function>
-class MemberCallable;
-
-template <typename Result, typename Obj, typename... Args>
-class MemberCallable<Result(Obj::*)(Args...) const>
-{
-public:
- MemberCallable(Result(Obj::* function)(Args...) const, const Obj *obj)
- : m_function(function),
- m_obj(obj)
- {
- }
-
- Result operator()(Args&&... args) const
- {
- return ((*m_obj).*m_function)(std::forward<Args>(args)...);
- }
-
-private:
- Result(Obj::* m_function)(Args...) const;
- const Obj *m_obj;
-};
-
-template <typename Result, typename Obj, typename... Args>
-class MemberCallable<Result(Obj::*)(Args...)>
-{
-public:
- MemberCallable(Result(Obj::* function)(Args...), Obj *obj)
- : m_function(function),
- m_obj(obj)
- {
- }
-
- Result operator()(Args&&... args) const
- {
- return ((*m_obj).*m_function)(std::forward<Args>(args)...);
- }
-
-private:
- Result(Obj::* m_function)(Args...);
- Obj *m_obj;
-};
-
-/*
- Helper functions for runAsync that run in the started thread.
-*/
-
-// void function that does not take QFutureInterface
-template <typename ResultType, typename Function, typename... Args>
-void runAsyncReturnVoidDispatch(std::true_type, QFutureInterface<ResultType> &, Function &&function, Args&&... args)
-{
- function(std::forward<Args>(args)...);
-}
-
-// non-void function that does not take QFutureInterface
-template <typename ResultType, typename Function, typename... Args>
-void runAsyncReturnVoidDispatch(std::false_type, QFutureInterface<ResultType> &futureInterface, Function &&function, Args&&... args)
-{
- futureInterface.reportResult(function(std::forward<Args>(args)...));
-}
-
-// function that takes QFutureInterface
-template <typename ResultType, typename Function, typename... Args>
-void runAsyncQFutureInterfaceDispatch(std::true_type, QFutureInterface<ResultType> &futureInterface, Function &&function, Args&&... args)
-{
- function(futureInterface, std::forward<Args>(args)...);
-}
-
-// function that does not take QFutureInterface
-template <typename ResultType, typename Function, typename... Args>
-void runAsyncQFutureInterfaceDispatch(std::false_type, QFutureInterface<ResultType> &futureInterface, Function &&function, Args&&... args)
-{
- runAsyncReturnVoidDispatch(std::is_void<std::invoke_result_t<Function, Args...>>(),
- futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
-}
-
-// function, function pointer, or other callable object that is no member pointer
-template <typename ResultType, typename Function, typename... Args,
- typename = std::enable_if_t<!std::is_member_pointer<std::decay_t<Function>>::value>
- >
-void runAsyncMemberDispatch(QFutureInterface<ResultType> &futureInterface, Function &&function, Args&&... args)
-{
- runAsyncQFutureInterfaceDispatch(functionTakesArgument<Function, 0, QFutureInterface<ResultType>&>(),
- futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
-}
-
-// Function = member function
-template <typename ResultType, typename Function, typename Obj, typename... Args,
- typename = std::enable_if_t<std::is_member_pointer<std::decay_t<Function>>::value>
- >
-void runAsyncMemberDispatch(QFutureInterface<ResultType> &futureInterface, Function &&function, Obj &&obj, Args&&... args)
-{
- // Wrap member function with object into callable
- runAsyncImpl(futureInterface,
- MemberCallable<std::decay_t<Function>>(std::forward<Function>(function), std::forward<Obj>(obj)),
- std::forward<Args>(args)...);
-}
-
-// cref to function/callable
-template <typename ResultType, typename Function, typename... Args>
-void runAsyncImpl(QFutureInterface<ResultType> &futureInterface,
- std::reference_wrapper<Function> functionWrapper, Args&&... args)
-{
- runAsyncMemberDispatch(futureInterface, functionWrapper.get(), std::forward<Args>(args)...);
-}
-
-// function/callable, no cref
-template <typename ResultType, typename Function, typename... Args>
-void runAsyncImpl(QFutureInterface<ResultType> &futureInterface,
- Function &&function, Args&&... args)
-{
- runAsyncMemberDispatch(futureInterface, std::forward<Function>(function),
- std::forward<Args>(args)...);
-}
-/*
- AsyncJob is a QRunnable that wraps a function with the
- arguments that are passed to it when it is run in a thread.
-*/
-
-template <class T>
-std::decay_t<T>
-decayCopy(T&& v)
-{
- return std::forward<T>(v);
-}
-
-template <typename ResultType, typename Function, typename... Args>
-class AsyncJob : public QRunnable
-{
-public:
- AsyncJob(Function &&function, Args&&... args)
- // decay copy like std::thread
- : data(decayCopy(std::forward<Function>(function)), decayCopy(std::forward<Args>(args))...)
- {
- // we need to report it as started even though it isn't yet, because someone might
- // call waitForFinished on the future, which does _not_ block if the future is not started
- futureInterface.setRunnable(this);
- futureInterface.reportStarted();
- }
-
- ~AsyncJob() override
- {
- // QThreadPool can delete runnables even if they were never run (e.g. QThreadPool::clear).
- // Since we reported them as started, we make sure that we always report them as finished.
- // reportFinished only actually sends the signal if it wasn't already finished.
- futureInterface.reportFinished();
- }
-
- QFuture<ResultType> future() { return futureInterface.future(); }
-
- void run() override
- {
- if (priority != QThread::InheritPriority)
- if (QThread *thread = QThread::currentThread())
- if (thread != qApp->thread())
- thread->setPriority(priority);
- if (futureInterface.isCanceled()) {
- futureInterface.reportFinished();
- return;
- }
- runHelper(std::make_index_sequence<std::tuple_size<Data>::value>());
- }
-
- void setThreadPool(QThreadPool *pool)
- {
- futureInterface.setThreadPool(pool);
- }
-
- void setThreadPriority(QThread::Priority p)
- {
- priority = p;
- }
-
-private:
- using Data = std::tuple<std::decay_t<Function>, std::decay_t<Args>...>;
-
- template <std::size_t... index>
- void runHelper(std::index_sequence<index...>)
- {
- // invalidates data, which is moved into the call
- runAsyncImpl(futureInterface, std::move(std::get<index>(data))...);
- if (futureInterface.isPaused())
- futureInterface.waitForResume();
- futureInterface.reportFinished();
- }
-
- Data data;
- QFutureInterface<ResultType> futureInterface;
- QThread::Priority priority = QThread::InheritPriority;
-};
-
-class QTCREATOR_UTILS_EXPORT RunnableThread : public QThread
-{
-public:
- explicit RunnableThread(QRunnable *runnable, QObject *parent = nullptr);
-
-protected:
- void run() override;
-
-private:
- QRunnable *m_runnable;
-};
-
-template<typename Function,
- typename... Args,
- typename ResultType = typename Internal::resultType<Function>::type>
-QFuture<ResultType> runAsync_internal(QThreadPool *pool,
- QThread::Priority priority,
- Function &&function,
- Args &&... args)
-{
- auto job = new Internal::AsyncJob<ResultType,Function,Args...>
- (std::forward<Function>(function), std::forward<Args>(args)...);
- job->setThreadPriority(priority);
- QFuture<ResultType> future = job->future();
- if (pool) {
- job->setThreadPool(pool);
- pool->start(job);
- } else {
- auto thread = new Internal::RunnableThread(job);
- thread->moveToThread(qApp->thread()); // make sure thread gets deleteLater on main thread
- QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater);
- thread->start(priority);
- }
- return future;
-}
-
-} // Internal
-
-/*!
- The interface of \c {runAsync} is similar to the std::thread constructor and \c {std::invoke}.
-
- The \a function argument can be a member function,
- an object with \c {operator()} (with no overloads),
- a \c {std::function}, lambda, function pointer or function reference.
- The \a args are passed to the function call after they are copied/moved to the thread.
-
- The \a function can take a \c {QFutureInterface<ResultType>&} as its first argument, followed by
- other custom arguments which need to be passed to this function.
- If it does not take a \c {QFutureInterface<ResultType>&} as its first argument
- and its return type is not void, the function call's result is reported to the QFuture.
- If \a function is a (non-static) member function, the first argument in \a args is expected
- to be the object that the function is called on.
-
- If a thread \a pool is given, the function is run there. Otherwise a new, independent thread
- is started.
-
- \sa std::thread
- \sa std::invoke
- \sa QThreadPool
- \sa QThread::Priority
- */
-template <typename Function, typename... Args,
- typename ResultType = typename Internal::resultType<Function>::type>
-QFuture<ResultType>
-runAsync(QThreadPool *pool, QThread::Priority priority, Function &&function, Args&&... args)
-{
- return Internal::runAsync_internal(pool,
- priority,
- std::forward<Function>(function),
- std::forward<Args>(args)...);
-}
-
-/*!
- Runs \a function with \a args in a new thread with given thread \a priority.
- \sa runAsync(QThreadPool*,QThread::Priority,Function&&,Args&&...)
- \sa QThread::Priority
- */
-template <typename Function, typename... Args,
- typename ResultType = typename Internal::resultType<Function>::type>
-QFuture<ResultType>
-runAsync(QThread::Priority priority, Function &&function, Args&&... args)
-{
- return runAsync(static_cast<QThreadPool *>(nullptr), priority,
- std::forward<Function>(function), std::forward<Args>(args)...);
-}
-
-/*!
- Runs \a function with \a args in a new thread with thread priority QThread::InheritPriority.
- \sa runAsync(QThreadPool*,QThread::Priority,Function&&,Args&&...)
- \sa QThread::Priority
- */
-template <typename Function, typename... Args,
- typename = std::enable_if_t<
- !std::is_same<std::decay_t<Function>, QThreadPool>::value
- && !std::is_same<std::decay_t<Function>, QThread::Priority>::value
- >,
- typename ResultType = typename Internal::resultType<Function>::type>
-QFuture<ResultType>
-runAsync(Function &&function, Args&&... args)
-{
- return runAsync(static_cast<QThreadPool *>(nullptr),
- QThread::InheritPriority, std::forward<Function>(function),
- std::forward<Args>(args)...);
-}
-
-/*!
- Runs \a function with \a args in a thread \a pool with thread priority QThread::InheritPriority.
- \sa runAsync(QThreadPool*,QThread::Priority,Function&&,Args&&...)
- \sa QThread::Priority
- */
-template <typename Function, typename... Args,
- typename = std::enable_if_t<!std::is_same<std::decay_t<Function>, QThread::Priority>::value>,
- typename ResultType = typename Internal::resultType<Function>::type>
-QFuture<ResultType>
-runAsync(QThreadPool *pool, Function &&function, Args&&... args)
-{
- return runAsync(pool, QThread::InheritPriority, std::forward<Function>(function),
- std::forward<Args>(args)...);
-}
-
-} // namespace Utils
diff --git a/src/libs/utils/savefile.cpp b/src/libs/utils/savefile.cpp
index 4cf579ac0b9..a9d0cca3a40 100644
--- a/src/libs/utils/savefile.cpp
+++ b/src/libs/utils/savefile.cpp
@@ -111,7 +111,7 @@ bool SaveFile::commit()
if (!result) {
DWORD replaceErrorCode = GetLastError();
QString errorStr;
- if (!QFile::exists(finalFileName)) {
+ if (!QFileInfo::exists(finalFileName)) {
// Replace failed because finalFileName does not exist, try rename.
if (!(result = rename(finalFileName)))
errorStr = errorString();
@@ -148,7 +148,7 @@ bool SaveFile::commit()
// Back up current file.
// If it's opened by another application, the lock follows the move.
- if (QFile::exists(finalFileName)) {
+ if (QFileInfo::exists(finalFileName)) {
// Kill old backup. Might be useful if creator crashed before removing backup.
QFile::remove(backupName);
QFile finalFile(finalFileName);
diff --git a/src/libs/utils/searchresultitem.h b/src/libs/utils/searchresultitem.h
index ea9d0332d5a..766da19ffdc 100644
--- a/src/libs/utils/searchresultitem.h
+++ b/src/libs/utils/searchresultitem.h
@@ -5,9 +5,9 @@
#include "utils_global.h"
-#include <utils/filepath.h>
-#include <utils/hostosinfo.h>
-#include <utils/textutils.h>
+#include "filepath.h"
+#include "hostosinfo.h"
+#include "textutils.h"
#include <QColor>
#include <QHash>
@@ -96,6 +96,11 @@ private:
using SearchResultItems = QList<SearchResultItem>;
+inline size_t qHash(const SearchResultItem &item)
+{
+ return item.mainRange().begin.line << 16 | item.mainRange().begin.column;
+}
+
} // namespace Utils
Q_DECLARE_METATYPE(Utils::SearchResultItem)
diff --git a/src/libs/utils/settingsaccessor.cpp b/src/libs/utils/settingsaccessor.cpp
index 275290674fd..1c9f30ecba5 100644
--- a/src/libs/utils/settingsaccessor.cpp
+++ b/src/libs/utils/settingsaccessor.cpp
@@ -46,9 +46,9 @@ SettingsAccessor::~SettingsAccessor() = default;
/*!
* Restore settings from disk and report any issues in a message box centered on \a parent.
*/
-QVariantMap SettingsAccessor::restoreSettings(QWidget *parent) const
+Store SettingsAccessor::restoreSettings(QWidget *parent) const
{
- QTC_ASSERT(!m_baseFilePath.isEmpty(), return QVariantMap());
+ QTC_ASSERT(!m_baseFilePath.isEmpty(), return Store());
return restoreSettings(m_baseFilePath, parent);
}
@@ -56,7 +56,7 @@ QVariantMap SettingsAccessor::restoreSettings(QWidget *parent) const
/*!
* Save \a data to disk and report any issues in a message box centered on \a parent.
*/
-bool SettingsAccessor::saveSettings(const QVariantMap &data, QWidget *parent) const
+bool SettingsAccessor::saveSettings(const Store &data, QWidget *parent) const
{
QTC_CHECK(!m_docType.isEmpty());
QTC_CHECK(!m_applicationDisplayName.isEmpty());
@@ -83,14 +83,14 @@ SettingsAccessor::RestoreData SettingsAccessor::readData(const FilePath &path, Q
* Store the \a data in \a path on disk. Do all the necessary preprocessing of the data.
*/
std::optional<SettingsAccessor::Issue> SettingsAccessor::writeData(const FilePath &path,
- const QVariantMap &data,
+ const Store &data,
QWidget *parent) const
{
Q_UNUSED(parent)
return writeFile(path, prepareToWriteSettings(data));
}
-QVariantMap SettingsAccessor::restoreSettings(const FilePath &settingsPath, QWidget *parent) const
+Store SettingsAccessor::restoreSettings(const FilePath &settingsPath, QWidget *parent) const
{
QTC_CHECK(!m_docType.isEmpty());
QTC_CHECK(!m_applicationDisplayName.isEmpty());
@@ -99,7 +99,7 @@ QVariantMap SettingsAccessor::restoreSettings(const FilePath &settingsPath, QWid
const ProceedInfo pi = result.hasIssue() ? reportIssues(result.issue.value(), result.path, parent)
: ProceedInfo::Continue;
- return pi == ProceedInfo::DiscardAndContinue ? QVariantMap() : result.data;
+ return pi == ProceedInfo::DiscardAndContinue ? Store() : result.data;
}
/*!
@@ -116,7 +116,7 @@ SettingsAccessor::RestoreData SettingsAccessor::readFile(const FilePath &path) c
.arg(path.toUserOutput()), Issue::Type::ERROR));
}
- const QVariantMap data = reader.restoreValues();
+ const Store data = reader.restoreValues();
if (!m_readOnly && path == m_baseFilePath) {
if (!m_writer)
m_writer = std::make_unique<PersistentSettingsWriter>(m_baseFilePath, m_docType);
@@ -132,7 +132,7 @@ SettingsAccessor::RestoreData SettingsAccessor::readFile(const FilePath &path) c
* This method does not do *any* processing of the file contents.
*/
std::optional<SettingsAccessor::Issue> SettingsAccessor::writeFile(const FilePath &path,
- const QVariantMap &data) const
+ const Store &data) const
{
if (data.isEmpty()) {
return Issue(Tr::tr("Failed to Write File"),
@@ -175,7 +175,7 @@ SettingsAccessor::reportIssues(const Issue &issue, const FilePath &path, QWidget
/*!
* This method is called right after reading data from disk and modifies \a data.
*/
-QVariantMap SettingsAccessor::preprocessReadSettings(const QVariantMap &data) const
+Store SettingsAccessor::preprocessReadSettings(const Store &data) const
{
return data;
}
@@ -183,7 +183,7 @@ QVariantMap SettingsAccessor::preprocessReadSettings(const QVariantMap &data) co
/*!
* This method is called right before writing data to disk and modifies \a data.
*/
-QVariantMap SettingsAccessor::prepareToWriteSettings(const QVariantMap &data) const
+Store SettingsAccessor::prepareToWriteSettings(const Store &data) const
{
return data;
}
@@ -212,9 +212,9 @@ int BackUpStrategy::compare(const SettingsAccessor::RestoreData &data1,
return 0;
}
-std::optional<FilePath> BackUpStrategy::backupName(const QVariantMap &oldData,
+std::optional<FilePath> BackUpStrategy::backupName(const Store &oldData,
const FilePath &path,
- const QVariantMap &data) const
+ const Store &data) const
{
if (oldData == data)
return std::nullopt;
@@ -230,7 +230,7 @@ BackingUpSettingsAccessor::readData(const FilePath &path, QWidget *parent) const
{
const FilePaths fileList = readFileCandidates(path);
if (fileList.isEmpty()) // No settings found at all.
- return RestoreData(path, QVariantMap());
+ return RestoreData(path, Store());
RestoreData result = bestReadFileData(fileList, parent);
if (result.path.isEmpty())
@@ -253,7 +253,7 @@ BackingUpSettingsAccessor::readData(const FilePath &path, QWidget *parent) const
}
std::optional<SettingsAccessor::Issue> BackingUpSettingsAccessor::writeData(const FilePath &path,
- const QVariantMap &data,
+ const Store &data,
QWidget *parent) const
{
if (data.isEmpty())
@@ -290,7 +290,7 @@ BackingUpSettingsAccessor::bestReadFileData(const FilePaths &candidates, QWidget
return bestMatch;
}
-void BackingUpSettingsAccessor::backupFile(const FilePath &path, const QVariantMap &data,
+void BackingUpSettingsAccessor::backupFile(const FilePath &path, const Store &data,
QWidget *parent) const
{
RestoreData oldSettings = SettingsAccessor::readData(path, parent);
@@ -331,9 +331,9 @@ int VersionedBackUpStrategy::compare(const SettingsAccessor::RestoreData &data1,
return -1;
}
-std::optional<FilePath> VersionedBackUpStrategy::backupName(const QVariantMap &oldData,
+std::optional<FilePath> VersionedBackUpStrategy::backupName(const Store &oldData,
const FilePath &path,
- const QVariantMap &data) const
+ const Store &data) const
{
Q_UNUSED(data)
FilePath backupName = path;
@@ -374,7 +374,7 @@ QString VersionUpgrader::backupExtension() const
/*!
* Performs a simple renaming of the listed keys in \a changes recursively on \a map.
*/
-QVariantMap VersionUpgrader::renameKeys(const QList<Change> &changes, QVariantMap map) const
+Store VersionUpgrader::renameKeys(const QList<Change> &changes, Store map) const
{
for (const Change &change : changes) {
const auto oldSetting = map.constFind(change.first);
@@ -384,11 +384,11 @@ QVariantMap VersionUpgrader::renameKeys(const QList<Change> &changes, QVariantMa
}
}
- QVariantMap::iterator i = map.begin();
+ Store::iterator i = map.begin();
while (i != map.end()) {
QVariant v = i.value();
- if (v.type() == QVariant::Map)
- i.value() = renameKeys(changes, v.toMap());
+ if (Utils::isStore(v))
+ i.value() = variantFromStore(renameKeys(changes, storeFromVariant(v)));
++i;
}
@@ -433,9 +433,9 @@ SettingsAccessor::RestoreData UpgradingSettingsAccessor::readData(const FilePath
return upgradeSettings(BackingUpSettingsAccessor::readData(path, parent), currentVersion());
}
-QVariantMap UpgradingSettingsAccessor::prepareToWriteSettings(const QVariantMap &data) const
+Store UpgradingSettingsAccessor::prepareToWriteSettings(const Store &data) const
{
- QVariantMap tmp = BackingUpSettingsAccessor::prepareToWriteSettings(data);
+ Store tmp = BackingUpSettingsAccessor::prepareToWriteSettings(data);
setVersionInMap(tmp,currentVersion());
if (!m_id.isEmpty())
@@ -639,7 +639,7 @@ MergingSettingsAccessor::mergeSettings(const SettingsAccessor::RestoreData &main
= [this](const SettingsMergeData &global, const SettingsMergeData &local) {
return merge(global, local);
};
- const QVariantMap result = mergeQVariantMaps(main.data, secondary.data, mergeFunction).toMap();
+ const Store result = storeFromVariant(mergeQVariantMaps(main.data, secondary.data, mergeFunction));
// Update from the base version to Creator's version.
return RestoreData(main.path, postprocessMerge(main.data, secondary.data, result));
@@ -648,14 +648,14 @@ MergingSettingsAccessor::mergeSettings(const SettingsAccessor::RestoreData &main
/*!
* Returns true for housekeeping related keys.
*/
-bool MergingSettingsAccessor::isHouseKeepingKey(const QString &key)
+bool MergingSettingsAccessor::isHouseKeepingKey(const Key &key)
{
return key == VERSION_KEY || key == ORIGINAL_VERSION_KEY || key == SETTINGS_ID_KEY;
}
-QVariantMap MergingSettingsAccessor::postprocessMerge(const QVariantMap &main,
- const QVariantMap &secondary,
- const QVariantMap &result) const
+Store MergingSettingsAccessor::postprocessMerge(const Store &main,
+ const Store &secondary,
+ const Store &result) const
{
Q_UNUSED(main)
Q_UNUSED(secondary)
@@ -666,74 +666,75 @@ QVariantMap MergingSettingsAccessor::postprocessMerge(const QVariantMap &main,
// Helper functions:
// --------------------------------------------------------------------
-int versionFromMap(const QVariantMap &data)
+int versionFromMap(const Store &data)
{
return data.value(VERSION_KEY, -1).toInt();
}
-int originalVersionFromMap(const QVariantMap &data)
+int originalVersionFromMap(const Store &data)
{
return data.value(ORIGINAL_VERSION_KEY, versionFromMap(data)).toInt();
}
-QByteArray settingsIdFromMap(const QVariantMap &data)
+QByteArray settingsIdFromMap(const Store &data)
{
return data.value(SETTINGS_ID_KEY).toByteArray();
}
-void setOriginalVersionInMap(QVariantMap &data, int version)
+void setOriginalVersionInMap(Store &data, int version)
{
data.insert(ORIGINAL_VERSION_KEY, version);
}
-void setVersionInMap(QVariantMap &data, int version)
+void setVersionInMap(Store &data, int version)
{
data.insert(VERSION_KEY, version);
}
-void setSettingsIdInMap(QVariantMap &data, const QByteArray &id)
+void setSettingsIdInMap(Store &data, const QByteArray &id)
{
data.insert(SETTINGS_ID_KEY, id);
}
-static QVariant mergeQVariantMapsRecursion(const QVariantMap &mainTree, const QVariantMap &secondaryTree,
- const QString &keyPrefix,
- const QVariantMap &mainSubtree, const QVariantMap &secondarySubtree,
+static QVariant mergeQVariantMapsRecursion(const Store &mainTree, const Store &secondaryTree,
+ const Key &keyPrefix,
+ const Store &mainSubtree, const Store &secondarySubtree,
const SettingsMergeFunction &merge)
{
- QVariantMap result;
- const QList<QString> allKeys = filteredUnique(mainSubtree.keys() + secondarySubtree.keys());
+ Store result;
+ const QList<Key> allKeys = filteredUnique(mainSubtree.keys() + secondarySubtree.keys());
- MergingSettingsAccessor::SettingsMergeData global = {mainTree, secondaryTree, QString()};
- MergingSettingsAccessor::SettingsMergeData local = {mainSubtree, secondarySubtree, QString()};
+ MergingSettingsAccessor::SettingsMergeData global = {mainTree, secondaryTree, Key()};
+ MergingSettingsAccessor::SettingsMergeData local = {mainSubtree, secondarySubtree, Key()};
- for (const QString &key : allKeys) {
+ for (const Key &key : allKeys) {
global.key = keyPrefix + key;
local.key = key;
- std::optional<QPair<QString, QVariant>> mergeResult = merge(global, local);
+ std::optional<QPair<Key, QVariant>> mergeResult = merge(global, local);
if (!mergeResult)
continue;
- QPair<QString, QVariant> kv = mergeResult.value();
+ QPair<Key, QVariant> kv = mergeResult.value();
- if (kv.second.type() == QVariant::Map) {
- const QString newKeyPrefix = keyPrefix + kv.first + '/';
+ if (Utils::isStore(kv.second)) {
+ const Key newKeyPrefix = keyPrefix + kv.first + '/';
kv.second = mergeQVariantMapsRecursion(mainTree, secondaryTree, newKeyPrefix,
- kv.second.toMap(), secondarySubtree.value(kv.first)
- .toMap(), merge);
+ storeFromVariant(kv.second),
+ storeFromVariant(secondarySubtree.value(kv.first)),
+ merge);
}
if (!kv.second.isNull())
result.insert(kv.first, kv.second);
}
- return result;
+ return variantFromStore(result);
}
-QVariant mergeQVariantMaps(const QVariantMap &mainTree, const QVariantMap &secondaryTree,
+QVariant mergeQVariantMaps(const Store &mainTree, const Store &secondaryTree,
const SettingsMergeFunction &merge)
{
- return mergeQVariantMapsRecursion(mainTree, secondaryTree, QString(),
+ return mergeQVariantMapsRecursion(mainTree, secondaryTree, Key(),
mainTree, secondaryTree, merge);
}
diff --git a/src/libs/utils/settingsaccessor.h b/src/libs/utils/settingsaccessor.h
index 683743ac62f..b882fbaeb78 100644
--- a/src/libs/utils/settingsaccessor.h
+++ b/src/libs/utils/settingsaccessor.h
@@ -6,10 +6,10 @@
#include "utils_global.h"
#include "filepath.h"
+#include "store.h"
#include <QHash>
#include <QMessageBox>
-#include <QVariantMap>
#include <memory>
#include <optional>
@@ -20,28 +20,28 @@ namespace Utils {
// Helper:
// -----------------------------------------------------------------------------
-QTCREATOR_UTILS_EXPORT int versionFromMap(const QVariantMap &data);
-QTCREATOR_UTILS_EXPORT int originalVersionFromMap(const QVariantMap &data);
-QTCREATOR_UTILS_EXPORT QByteArray settingsIdFromMap(const QVariantMap &data);
+QTCREATOR_UTILS_EXPORT int versionFromMap(const Store &data);
+QTCREATOR_UTILS_EXPORT int originalVersionFromMap(const Store &data);
+QTCREATOR_UTILS_EXPORT QByteArray settingsIdFromMap(const Store &data);
-QTCREATOR_UTILS_EXPORT void setVersionInMap(QVariantMap &data, int version);
-QTCREATOR_UTILS_EXPORT void setOriginalVersionInMap(QVariantMap &data, int version);
-QTCREATOR_UTILS_EXPORT void setSettingsIdInMap(QVariantMap &data, const QByteArray &id);
+QTCREATOR_UTILS_EXPORT void setVersionInMap(Store &data, int version);
+QTCREATOR_UTILS_EXPORT void setOriginalVersionInMap(Store &data, int version);
+QTCREATOR_UTILS_EXPORT void setSettingsIdInMap(Store &data, const QByteArray &id);
// --------------------------------------------------------------------
// Helpers:
// --------------------------------------------------------------------
-QTCREATOR_UTILS_EXPORT int versionFromMap(const QVariantMap &data);
-QTCREATOR_UTILS_EXPORT int originalVersionFromMap(const QVariantMap &data);
-QTCREATOR_UTILS_EXPORT QByteArray settingsIdFromMap(const QVariantMap &data);
+QTCREATOR_UTILS_EXPORT int versionFromMap(const Store &data);
+QTCREATOR_UTILS_EXPORT int originalVersionFromMap(const Store &data);
+QTCREATOR_UTILS_EXPORT QByteArray settingsIdFromMap(const Store &data);
-QTCREATOR_UTILS_EXPORT void setVersionInMap(QVariantMap &data, int version);
-QTCREATOR_UTILS_EXPORT void setOriginalVersionInMap(QVariantMap &data, int version);
-QTCREATOR_UTILS_EXPORT void setSettingsIdInMap(QVariantMap &data, const QByteArray &id);
+QTCREATOR_UTILS_EXPORT void setVersionInMap(Store &data, int version);
+QTCREATOR_UTILS_EXPORT void setOriginalVersionInMap(Store &data, int version);
+QTCREATOR_UTILS_EXPORT void setSettingsIdInMap(Store &data, const QByteArray &id);
class PersistentSettingsWriter;
-using SettingsMergeResult = std::optional<QPair<QString, QVariant>>;
+using SettingsMergeResult = std::optional<QPair<Utils::Key, QVariant>>;
// --------------------------------------------------------------------
// SettingsAccessor:
@@ -76,7 +76,7 @@ public:
class RestoreData {
public:
RestoreData() = default;
- RestoreData(const FilePath &path, const QVariantMap &data) : path{path}, data{data} { }
+ RestoreData(const FilePath &path, const Store &data) : path{path}, data{data} { }
RestoreData(const QString &title, const QString &message, const Issue::Type type) :
RestoreData(Issue(title, message, type))
{ }
@@ -87,12 +87,12 @@ public:
bool hasWarning() const { return hasIssue() && issue.value().type == Issue::Type::WARNING; }
FilePath path;
- QVariantMap data;
+ Store data;
std::optional<Issue> issue;
};
- QVariantMap restoreSettings(QWidget *parent) const;
- bool saveSettings(const QVariantMap &data, QWidget *parent) const;
+ Store restoreSettings(QWidget *parent) const;
+ bool saveSettings(const Store &data, QWidget *parent) const;
void setBaseFilePath(const FilePath &baseFilePath) { m_baseFilePath = baseFilePath; }
void setReadOnly() { m_readOnly = true; }
@@ -100,7 +100,7 @@ public:
virtual RestoreData readData(const FilePath &path, QWidget *parent) const;
virtual std::optional<Issue> writeData(const FilePath &path,
- const QVariantMap &data,
+ const Store &data,
QWidget *parent) const;
void setDocType(const QString &docType) { m_docType = docType; }
@@ -108,14 +108,14 @@ public:
protected:
// Report errors:
- QVariantMap restoreSettings(const FilePath &settingsPath, QWidget *parent) const;
+ Store restoreSettings(const FilePath &settingsPath, QWidget *parent) const;
static ProceedInfo reportIssues(const Issue &issue, const FilePath &path, QWidget *parent);
- virtual QVariantMap preprocessReadSettings(const QVariantMap &data) const;
- virtual QVariantMap prepareToWriteSettings(const QVariantMap &data) const;
+ virtual Store preprocessReadSettings(const Store &data) const;
+ virtual Store prepareToWriteSettings(const Store &data) const;
virtual RestoreData readFile(const FilePath &path) const;
- virtual std::optional<Issue> writeFile(const FilePath &path, const QVariantMap &data) const;
+ virtual std::optional<Issue> writeFile(const FilePath &path, const Store &data) const;
QString m_docType;
QString m_applicationDisplayName;
@@ -141,9 +141,9 @@ public:
virtual int compare(const SettingsAccessor::RestoreData &data1,
const SettingsAccessor::RestoreData &data2) const;
- virtual std::optional<FilePath> backupName(const QVariantMap &oldData,
+ virtual std::optional<FilePath> backupName(const Store &oldData,
const FilePath &path,
- const QVariantMap &data) const;
+ const Store &data) const;
};
class QTCREATOR_UTILS_EXPORT BackingUpSettingsAccessor : public SettingsAccessor
@@ -153,7 +153,7 @@ public:
RestoreData readData(const FilePath &path, QWidget *parent) const override;
std::optional<Issue> writeData(const FilePath &path,
- const QVariantMap &data,
+ const Store &data,
QWidget *parent) const override;
BackUpStrategy *strategy() const { return m_strategy.get(); }
@@ -162,7 +162,7 @@ public:
private:
FilePaths readFileCandidates(const FilePath &path) const;
RestoreData bestReadFileData(const FilePaths &candidates, QWidget *parent) const;
- void backupFile(const FilePath &path, const QVariantMap &data, QWidget *parent) const;
+ void backupFile(const FilePath &path, const Store &data, QWidget *parent) const;
std::unique_ptr<BackUpStrategy> m_strategy;
};
@@ -183,9 +183,9 @@ public:
int compare(const SettingsAccessor::RestoreData &data1,
const SettingsAccessor::RestoreData &data2) const override;
- std::optional<FilePath> backupName(const QVariantMap &oldData,
+ std::optional<FilePath> backupName(const Store &oldData,
const FilePath &path,
- const QVariantMap &data) const override;
+ const Store &data) const override;
const UpgradingSettingsAccessor *accessor() const { return m_accessor; }
@@ -193,7 +193,7 @@ protected:
const UpgradingSettingsAccessor *m_accessor = nullptr;
};
-// Handles updating a QVariantMap from version() to version() + 1
+// Handles updating a Store from version() to version() + 1
class QTCREATOR_UTILS_EXPORT VersionUpgrader
{
public:
@@ -203,11 +203,11 @@ public:
int version() const;
QString backupExtension() const;
- virtual QVariantMap upgrade(const QVariantMap &data) = 0;
+ virtual Store upgrade(const Store &data) = 0;
protected:
- using Change = QPair<QLatin1String, QLatin1String>;
- QVariantMap renameKeys(const QList<Change> &changes, QVariantMap map) const;
+ using Change = QPair<Key, Key>;
+ Store renameKeys(const QList<Change> &changes, Store map) const;
private:
const int m_version;
@@ -233,7 +233,7 @@ public:
RestoreData readData(const FilePath &path, QWidget *parent) const override;
protected:
- QVariantMap prepareToWriteSettings(const QVariantMap &data) const override;
+ Store prepareToWriteSettings(const Store &data) const override;
void setSettingsId(const QByteArray &id) { m_id = id; }
@@ -254,9 +254,9 @@ class QTCREATOR_UTILS_EXPORT MergingSettingsAccessor : public UpgradingSettingsA
{
public:
struct SettingsMergeData {
- QVariantMap main;
- QVariantMap secondary;
- QString key;
+ Store main;
+ Store secondary;
+ Key key;
};
MergingSettingsAccessor();
@@ -271,10 +271,10 @@ protected:
virtual SettingsMergeResult merge(const SettingsMergeData &global,
const SettingsMergeData &local) const = 0;
- static bool isHouseKeepingKey(const QString &key);
+ static bool isHouseKeepingKey(const Key &key);
- virtual QVariantMap postprocessMerge(const QVariantMap &main, const QVariantMap &secondary,
- const QVariantMap &result) const;
+ virtual Store postprocessMerge(const Store &main, const Store &secondary,
+ const Store &result) const;
private:
std::unique_ptr<SettingsAccessor> m_secondaryAccessor;
@@ -282,7 +282,7 @@ private:
using SettingsMergeFunction = std::function<SettingsMergeResult(const MergingSettingsAccessor::SettingsMergeData &,
const MergingSettingsAccessor::SettingsMergeData &)>;
-QTCREATOR_UTILS_EXPORT QVariant mergeQVariantMaps(const QVariantMap &mainTree, const QVariantMap &secondaryTree,
+QTCREATOR_UTILS_EXPORT QVariant mergeQVariantMaps(const Store &mainTree, const Store &secondaryTree,
const SettingsMergeFunction &merge);
} // namespace Utils
diff --git a/src/libs/utils/settingsutils.h b/src/libs/utils/settingsutils.h
deleted file mode 100644
index 2feb62380d1..00000000000
--- a/src/libs/utils/settingsutils.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include <QSettings>
-#include <QString>
-#include <QStringList>
-#include <QVariant>
-
-namespace Utils {
-
-template <class SettingsClassT>
-void fromSettings(const QString &postFix,
- const QString &category,
- QSettings *s,
- SettingsClassT *obj)
-{
- QVariantMap map;
- s->beginGroup(category + postFix);
- const QStringList keys = s->allKeys();
- for (const QString &key : keys)
- map.insert(key, s->value(key));
- s->endGroup();
- obj->fromMap(map);
-}
-
-template <class SettingsClassT>
-void toSettings(const QString &postFix,
- const QString &category,
- QSettings *s,
- const SettingsClassT *obj)
-{
- QString group = postFix;
- if (!category.isEmpty())
- group.insert(0, category);
- const QVariantMap map = obj->toMap();
-
- s->beginGroup(group);
- for (auto it = map.constBegin(), end = map.constEnd(); it != end; ++it)
- s->setValue(it.key(), it.value());
- s->endGroup();
-}
-
-} // Utils
diff --git a/src/libs/utils/statuslabel.h b/src/libs/utils/statuslabel.h
index 091c186bbf0..5fdf852a9e8 100644
--- a/src/libs/utils/statuslabel.h
+++ b/src/libs/utils/statuslabel.h
@@ -15,11 +15,9 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT StatusLabel : public QLabel
{
- Q_OBJECT
public:
explicit StatusLabel(QWidget *parent = nullptr);
-public slots:
void showStatusMessage(const QString &message, int timeoutMS = 5000);
void clearStatusMessage();
diff --git a/src/libs/utils/store.cpp b/src/libs/utils/store.cpp
new file mode 100644
index 00000000000..37f939f5a8c
--- /dev/null
+++ b/src/libs/utils/store.cpp
@@ -0,0 +1,193 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "store.h"
+
+#include "algorithm.h"
+#include "qtcassert.h"
+#include "qtcsettings.h"
+
+#include <QJsonDocument>
+#include <QJsonParseError>
+
+namespace Utils {
+
+KeyList keysFromStrings(const QStringList &list)
+{
+ return transform(list, &keyFromString);
+}
+
+QStringList stringsFromKeys(const KeyList &list)
+{
+ return transform(list, &stringFromKey);
+}
+
+QVariant variantFromStore(const Store &store)
+{
+ return QVariant::fromValue(store);
+}
+
+Store storeFromVariant(const QVariant &value)
+{
+ if (value.typeId() == qMetaTypeId<Store>())
+ return value.value<Store>();
+
+ if (value.typeId() == QMetaType::QVariantMap)
+ return storeFromMap(value.toMap());
+
+ if (value.typeId() == qMetaTypeId<OldStore>())
+ return storeFromMap(value.toMap());
+
+ if (!value.isValid())
+ return {};
+
+ QTC_CHECK(false);
+ return Store();
+}
+
+static QVariantList storeListFromMapList(const QVariantList &mapList);
+static QVariantList mapListFromStoreList(const QVariantList &storeList);
+
+QVariant storeEntryFromMapEntry(const QVariant &mapEntry)
+{
+ if (mapEntry.type() == QVariant::Map)
+ return QVariant::fromValue(storeFromMap(mapEntry.toMap()));
+
+ if (mapEntry.type() == QVariant::List)
+ return QVariant::fromValue(storeListFromMapList(mapEntry.toList()));
+
+ return mapEntry;
+}
+
+QVariant mapEntryFromStoreEntry(const QVariant &storeEntry)
+{
+ if (storeEntry.metaType() == QMetaType::fromType<Store>())
+ return QVariant::fromValue(mapFromStore(storeEntry.value<Store>()));
+
+ if (storeEntry.type() == QVariant::List)
+ return QVariant::fromValue(mapListFromStoreList(storeEntry.toList()));
+
+ return storeEntry;
+}
+
+static QVariantList storeListFromMapList(const QVariantList &mapList)
+{
+ QVariantList storeList;
+
+ for (const auto &mapEntry : mapList)
+ storeList.append(storeEntryFromMapEntry(mapEntry));
+
+ return storeList;
+}
+
+static QVariantList mapListFromStoreList(const QVariantList &storeList)
+{
+ QVariantList mapList;
+
+ for (const QVariant &storeEntry : storeList)
+ mapList.append(mapEntryFromStoreEntry(storeEntry));
+
+ return mapList;
+}
+
+Store storeFromMap(const QVariantMap &map)
+{
+ Store store;
+
+ for (auto it = map.begin(); it != map.end(); ++it)
+ store.insert(keyFromString(it.key()), storeEntryFromMapEntry(it.value()));
+
+ return store;
+}
+
+QVariantMap mapFromStore(const Store &store)
+{
+ QVariantMap map;
+
+ for (auto it = store.begin(); it != store.end(); ++it)
+ map.insert(stringFromKey(it.key()), mapEntryFromStoreEntry(it.value()));
+
+ return map;
+}
+
+bool isStore(const QVariant &value)
+{
+ const int typeId = value.typeId();
+ return typeId == QMetaType::QVariantMap || typeId == qMetaTypeId<Store>();
+}
+
+Key::Key(const char *key, size_t n)
+ : data(QByteArray::fromRawData(key, n))
+{}
+
+Key::Key(const Key &base, int number)
+ : data(base.data + QByteArray::number(number))
+{}
+
+Key::~Key()
+{}
+
+const QByteArrayView Key::view() const
+{
+ return data;
+}
+
+const QByteArray &Key::toByteArray() const
+{
+ return data;
+}
+
+Key numberedKey(const Key &key, int number)
+{
+ return Key(key, number);
+}
+
+Key keyFromString(const QString &str)
+{
+ return str.toUtf8();
+}
+
+QString stringFromKey(const Key &key)
+{
+ return QString::fromLatin1(key.view());
+}
+
+expected_str<Store> storeFromJson(const QByteArray &json)
+{
+ QJsonParseError error;
+ QJsonDocument doc = QJsonDocument::fromJson(json, &error);
+ if (error.error != QJsonParseError::NoError)
+ return make_unexpected(error.errorString());
+
+ if (!doc.isObject())
+ return make_unexpected(QString("Not a valid JSON object."));
+
+ return storeFromMap(doc.toVariant().toMap());
+}
+
+QByteArray jsonFromStore(const Store &store)
+{
+ QJsonDocument doc = QJsonDocument::fromVariant(mapFromStore(store));
+ return doc.toJson();
+}
+
+Store storeFromSettings(const Key &groupKey, QtcSettings *s)
+{
+ Store store;
+ s->beginGroup(groupKey);
+ const KeyList keys = keysFromStrings(s->allKeys());
+ for (const Key &key : keys)
+ store.insert(key, storeEntryFromMapEntry(s->value(key)));
+ s->endGroup();
+ return store;
+}
+
+void storeToSettings(const Key &groupKey, QtcSettings *s, const Store &store)
+{
+ s->beginGroup(groupKey);
+ for (auto it = store.constBegin(), end = store.constEnd(); it != end; ++it)
+ s->setValue(it.key(), mapEntryFromStoreEntry(it.value()));
+ s->endGroup();
+}
+
+} // Utils
diff --git a/src/libs/utils/store.h b/src/libs/utils/store.h
new file mode 100644
index 00000000000..df45cc8e9ce
--- /dev/null
+++ b/src/libs/utils/store.h
@@ -0,0 +1,48 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "expected.h"
+#include "storekey.h"
+
+#include <QMap>
+#include <QVariant>
+
+namespace Utils {
+
+class QtcSettings;
+
+using KeyList = QList<Key>;
+
+using Store = QMap<Key, QVariant>;
+using OldStore = QMap<QByteArray, QVariant>;
+
+QTCREATOR_UTILS_EXPORT KeyList keysFromStrings(const QStringList &list);
+QTCREATOR_UTILS_EXPORT QStringList stringsFromKeys(const KeyList &list);
+
+QTCREATOR_UTILS_EXPORT QVariant variantFromStore(const Store &store);
+QTCREATOR_UTILS_EXPORT Store storeFromVariant(const QVariant &value);
+
+QTCREATOR_UTILS_EXPORT Store storeFromMap(const QVariantMap &map);
+QTCREATOR_UTILS_EXPORT QVariantMap mapFromStore(const Store &store);
+
+QTCREATOR_UTILS_EXPORT bool isStore(const QVariant &value);
+
+QTCREATOR_UTILS_EXPORT Key numberedKey(const Key &key, int number);
+
+QTCREATOR_UTILS_EXPORT expected_str<Store> storeFromJson(const QByteArray &json);
+QTCREATOR_UTILS_EXPORT QByteArray jsonFromStore(const Store &store);
+
+// These recursively change type.
+QTCREATOR_UTILS_EXPORT QVariant storeEntryFromMapEntry(const QVariant &value);
+QTCREATOR_UTILS_EXPORT QVariant mapEntryFromStoreEntry(const QVariant &value);
+
+// Don't use in new code.
+QTCREATOR_UTILS_EXPORT Store storeFromSettings(const Key &groupKey, QtcSettings *s);
+QTCREATOR_UTILS_EXPORT void storeToSettings(const Key &groupKey, QtcSettings *s, const Store &store);
+
+} // Utils
+
+Q_DECLARE_METATYPE(Utils::Store)
+Q_DECLARE_METATYPE(Utils::OldStore)
diff --git a/src/libs/utils/storekey.h b/src/libs/utils/storekey.h
new file mode 100644
index 00000000000..68b433d05a6
--- /dev/null
+++ b/src/libs/utils/storekey.h
@@ -0,0 +1,69 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "utils_global.h"
+
+#include <QByteArrayView>
+#include <QString>
+#include <QHashFunctions>
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT Key
+{
+public:
+ Key() = default;
+ Key(const Key &) = default;
+ Key(Key &&) = default;
+
+ Key(const QByteArray &key) : data(key) {}
+
+ template <int N>
+ Key(const char (&key)[N]) : data(key) {}
+
+ // FIXME:
+ // The following is wanted, but not used yet due to unclear ASAN report.
+ // template <int N>
+ // Key(const char (&key)[N]) : Key(key, strlen(key)) {}
+
+ Key(const char *key, size_t n);
+
+ Key(const Key &base, int number);
+ ~Key();
+
+ Key &operator=(const Key &) = default;
+ Key &operator=(Key &&) = default;
+
+ const QByteArrayView view() const;
+ const QByteArray &toByteArray() const;
+ QByteArrayView operator()() const { return data; }
+
+ bool isEmpty() const { return data.isEmpty(); }
+ void clear() { data.clear(); }
+
+ friend bool operator<(const Key &a, const Key &b) { return a.data < b.data; }
+ friend bool operator==(const Key &a, const Key &b) { return a.data == b.data; }
+
+ friend Key operator+(const Key &a, const Key &b)
+ {
+ return Key(a.data + b.data);
+ }
+ friend Key operator+(const Key &a, char b)
+ {
+ return Key(a.data + b);
+ }
+ friend size_t qHash(const Key &key, size_t seed = 0)
+ {
+ return qHash(key.data, seed);
+ }
+
+private:
+ QByteArray data;
+};
+
+QTCREATOR_UTILS_EXPORT Key keyFromString(const QString &str);
+QTCREATOR_UTILS_EXPORT QString stringFromKey(const Key &key);
+
+} // Utils
diff --git a/src/libs/utils/stringtable.h b/src/libs/utils/stringtable.h
index 1394b1c853d..eedfe513552 100644
--- a/src/libs/utils/stringtable.h
+++ b/src/libs/utils/stringtable.h
@@ -3,7 +3,7 @@
#pragma once
-#include <utils/utils_global.h>
+#include "utils_global.h"
namespace Utils::StringTable {
diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp
index a33a08e3d99..c3b6c596905 100644
--- a/src/libs/utils/stringutils.cpp
+++ b/src/libs/utils/stringutils.cpp
@@ -5,6 +5,7 @@
#include "filepath.h"
#include "qtcassert.h"
+#include "stylehelper.h"
#include "theme/theme.h"
#include "utilstr.h"
@@ -13,11 +14,13 @@
#include <QClipboard>
#endif
+#include <QCollator>
#include <QDir>
#include <QFontMetrics>
#include <QJsonArray>
#include <QJsonValue>
#include <QLocale>
+#include <QPalette>
#include <QRegularExpression>
#include <QSet>
#include <QTextDocument>
@@ -323,10 +326,18 @@ QTCREATOR_UTILS_EXPORT int parseUsedPortFromNetstatOutput(const QByteArray &line
int caseFriendlyCompare(const QString &a, const QString &b)
{
- int result = a.compare(b, Qt::CaseInsensitive);
+ static const auto makeCollator = [](Qt::CaseSensitivity caseSensitivity) {
+ QCollator collator;
+ collator.setNumericMode(true);
+ collator.setCaseSensitivity(caseSensitivity);
+ return collator;
+ };
+ static const QCollator insensitiveCollator = makeCollator(Qt::CaseInsensitive);
+ const int result = insensitiveCollator.compare(a, b);
if (result != 0)
return result;
- return a.compare(b, Qt::CaseSensitive);
+ static const QCollator sensitiveCollator = makeCollator(Qt::CaseSensitive);
+ return sensitiveCollator.compare(a, b);
}
QString quoteAmpersands(const QString &text)
@@ -573,16 +584,28 @@ QTCREATOR_UTILS_EXPORT int endOfNextWord(const QString &string, int position)
MarkdownHighlighter::MarkdownHighlighter(QTextDocument *parent)
: QSyntaxHighlighter(parent)
, h2Brush(Qt::NoBrush)
+ , m_codeBgBrush(Qt::NoBrush)
{
parent->setIndentWidth(30); // default value is 40
}
+QBrush MarkdownHighlighter::codeBgBrush()
+{
+ if (m_codeBgBrush.style() == Qt::NoBrush) {
+ m_codeBgBrush = StyleHelper::mergedColors(QGuiApplication::palette().color(QPalette::Text),
+ QGuiApplication::palette().color(QPalette::Base),
+ 10);
+ }
+ return m_codeBgBrush;
+}
+
void MarkdownHighlighter::highlightBlock(const QString &text)
{
if (text.isEmpty())
return;
- QTextBlockFormat fmt = currentBlock().blockFormat();
+ const QTextBlock block = currentBlock();
+ QTextBlockFormat fmt = block.blockFormat();
QTextCursor cur(currentBlock());
if (fmt.hasProperty(QTextFormat::HeadingLevel)) {
fmt.setTopMargin(10);
@@ -610,7 +633,8 @@ void MarkdownHighlighter::highlightBlock(const QString &text)
}
cur.setBlockFormat(fmt);
} else if (fmt.hasProperty(QTextFormat::BlockCodeLanguage) && fmt.indent() == 0) {
- // set identation for code blocks
+ // set identation and background for code blocks
+ fmt.setBackground(codeBgBrush());
fmt.setIndent(1);
cur.setBlockFormat(fmt);
}
@@ -624,6 +648,16 @@ void MarkdownHighlighter::highlightBlock(const QString &text)
list->setFormat(listFmt);
}
}
+
+ // background color of code
+ for (auto it = block.begin(); it != block.end(); ++it) {
+ const QTextFragment fragment = it.fragment();
+ QTextCharFormat fmt = fragment.charFormat();
+ if (fmt.fontFixedPitch()) {
+ fmt.setBackground(codeBgBrush());
+ setFormat(fragment.position() - block.position(), fragment.length(), fmt);
+ }
+ }
}
} // namespace Utils
diff --git a/src/libs/utils/stringutils.h b/src/libs/utils/stringutils.h
index 3bab6110cf3..b27a2efc6f0 100644
--- a/src/libs/utils/stringutils.h
+++ b/src/libs/utils/stringutils.h
@@ -130,7 +130,10 @@ public:
void highlightBlock(const QString &text);
private:
+ QBrush codeBgBrush();
+
QBrush h2Brush;
+ QBrush m_codeBgBrush;
};
} // namespace Utils
diff --git a/src/libs/utils/styleanimator.h b/src/libs/utils/styleanimator.h
index 1cb0f67cc11..6745890d148 100644
--- a/src/libs/utils/styleanimator.h
+++ b/src/libs/utils/styleanimator.h
@@ -64,8 +64,6 @@ public :
class QTCREATOR_UTILS_EXPORT StyleAnimator : public QObject
{
- Q_OBJECT
-
public:
StyleAnimator(QObject *parent = nullptr) : QObject(parent) {}
diff --git a/src/libs/utils/styledbar.h b/src/libs/utils/styledbar.h
index c6c41575cfb..654a8f216e6 100644
--- a/src/libs/utils/styledbar.h
+++ b/src/libs/utils/styledbar.h
@@ -11,7 +11,6 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT StyledBar : public QWidget
{
- Q_OBJECT
public:
StyledBar(QWidget *parent = nullptr);
void setSingleRow(bool singleRow);
@@ -26,9 +25,9 @@ protected:
class QTCREATOR_UTILS_EXPORT StyledSeparator : public QWidget
{
- Q_OBJECT
public:
StyledSeparator(QWidget *parent = nullptr);
+
protected:
void paintEvent(QPaintEvent *event) override;
};
diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp
index cc860e715a9..b93481ef9d4 100644
--- a/src/libs/utils/stylehelper.cpp
+++ b/src/libs/utils/stylehelper.cpp
@@ -712,6 +712,12 @@ bool StyleHelper::isQDSTheme()
return creatorTheme() ? creatorTheme()->flag(Theme::QDSTheme) : false;
}
+Qt::HighDpiScaleFactorRoundingPolicy StyleHelper::defaultHighDpiScaleFactorRoundingPolicy()
+{
+ return HostOsInfo::isMacHost() ? Qt::HighDpiScaleFactorRoundingPolicy::Unset
+ : Qt::HighDpiScaleFactorRoundingPolicy::Round;
+}
+
QIcon StyleHelper::getIconFromIconFont(const QString &fontName, const QList<IconFontHelper> &parameters)
{
QFontDatabase a;
@@ -847,7 +853,7 @@ QString StyleHelper::dpiSpecificImageFile(const QString &fileName)
if (qApp->devicePixelRatio() > 1.0) {
const QString atDprfileName =
imageFileWithResolution(fileName, qRound(qApp->devicePixelRatio()));
- if (QFile::exists(atDprfileName))
+ if (QFileInfo::exists(atDprfileName))
return atDprfileName;
}
return fileName;
@@ -867,7 +873,7 @@ QList<int> StyleHelper::availableImageResolutions(const QString &fileName)
QList<int> result;
const int maxResolutions = qApp->devicePixelRatio();
for (int i = 1; i <= maxResolutions; ++i)
- if (QFile::exists(imageFileWithResolution(fileName, i)))
+ if (QFileInfo::exists(imageFileWithResolution(fileName, i)))
result.append(i);
return result;
}
diff --git a/src/libs/utils/stylehelper.h b/src/libs/utils/stylehelper.h
index ffc03c1a29c..ac5e53a4bd4 100644
--- a/src/libs/utils/stylehelper.h
+++ b/src/libs/utils/stylehelper.h
@@ -108,6 +108,9 @@ QTCREATOR_UTILS_EXPORT void setPanelWidgetSingleRow(QWidget *widget, bool value
QTCREATOR_UTILS_EXPORT bool isQDSTheme();
+QTCREATOR_UTILS_EXPORT
+ Qt::HighDpiScaleFactorRoundingPolicy defaultHighDpiScaleFactorRoundingPolicy();
+
class IconFontHelper
{
public:
diff --git a/src/libs/utils/terminalcommand.cpp b/src/libs/utils/terminalcommand.cpp
index bb1492515f3..0d6ab280ede 100644
--- a/src/libs/utils/terminalcommand.cpp
+++ b/src/libs/utils/terminalcommand.cpp
@@ -6,14 +6,11 @@
#include "algorithm.h"
#include "environment.h"
#include "hostosinfo.h"
-
-#include <QCoreApplication>
-#include <QFileInfo>
-#include <QSettings>
+#include "qtcsettings.h"
namespace Utils {
-static QSettings *s_settings = nullptr;
+static QtcSettings *s_settings = nullptr;
TerminalCommand::TerminalCommand(const FilePath &command, const QString &openArgs,
const QString &executeArgs, bool needsQuotes)
@@ -40,12 +37,12 @@ bool TerminalCommand::operator<(const TerminalCommand &other) const
return command < other.command;
}
-void TerminalCommand::setSettings(QSettings *settings)
+void TerminalCommand::setSettings(QtcSettings *settings)
{
s_settings = settings;
}
-Q_GLOBAL_STATIC_WITH_ARGS(const QVector<TerminalCommand>, knownTerminals, (
+Q_GLOBAL_STATIC_WITH_ARGS(const QList<TerminalCommand>, knownTerminals, (
{
{"x-terminal-emulator", "", "-e"},
{"xdg-terminal", "", "", true},
@@ -82,9 +79,9 @@ TerminalCommand TerminalCommand::defaultTerminalEmulator()
return defaultTerm;
}
-QVector<TerminalCommand> TerminalCommand::availableTerminalEmulators()
+QList<TerminalCommand> TerminalCommand::availableTerminalEmulators()
{
- QVector<TerminalCommand> result;
+ QList<TerminalCommand> result;
if (HostOsInfo::isAnyUnixHost()) {
const Environment env = Environment::systemEnvironment();
diff --git a/src/libs/utils/terminalcommand.h b/src/libs/utils/terminalcommand.h
index edb9ffcadde..5ef1eba1cf4 100644
--- a/src/libs/utils/terminalcommand.h
+++ b/src/libs/utils/terminalcommand.h
@@ -7,16 +7,13 @@
#include "filepath.h"
+#include <QList>
#include <QMetaType>
-#include <QVector>
-
-QT_BEGIN_NAMESPACE
-class QSettings;
-QT_END_NAMESPACE
namespace Utils {
class Environment;
+class QtcSettings;
class QTCREATOR_UTILS_EXPORT TerminalCommand
{
@@ -33,9 +30,9 @@ public:
QString executeArgs;
bool needsQuotes = false;
- static void setSettings(QSettings *settings);
+ static void setSettings(QtcSettings *settings);
static TerminalCommand defaultTerminalEmulator();
- static QVector<TerminalCommand> availableTerminalEmulators();
+ static QList<TerminalCommand> availableTerminalEmulators();
static TerminalCommand terminalEmulator();
static void setTerminalEmulator(const TerminalCommand &term);
};
diff --git a/src/libs/utils/terminalhooks.cpp b/src/libs/utils/terminalhooks.cpp
index 3bda25b109c..bb517cb9554 100644
--- a/src/libs/utils/terminalhooks.cpp
+++ b/src/libs/utils/terminalhooks.cpp
@@ -6,24 +6,28 @@
#include "externalterminalprocessimpl.h"
#include "filepath.h"
#include "process.h"
+#include "utilstr.h"
#include <QMutex>
namespace Utils::Terminal {
-FilePath defaultShellForDevice(const FilePath &deviceRoot)
+expected_str<FilePath> defaultShellForDevice(const FilePath &deviceRoot)
{
if (deviceRoot.osType() == OsTypeWindows)
return deviceRoot.withNewPath("cmd.exe").searchInPath();
- const Environment env = deviceRoot.deviceEnvironment();
- FilePath shell = FilePath::fromUserInput(env.value_or("SHELL", "/bin/sh"));
+ const expected_str<Environment> env = deviceRoot.deviceEnvironmentWithError();
+ if (!env)
+ return make_unexpected(env.error());
+
+ FilePath shell = FilePath::fromUserInput(env->value_or("SHELL", "/bin/sh"));
if (!shell.isAbsolutePath())
- shell = env.searchInPath(shell.nativePath());
+ shell = env->searchInPath(shell.nativePath());
if (shell.isEmpty())
- return shell;
+ return make_unexpected(Tr::tr("Could not find any shell."));
return deviceRoot.withNewMappedPath(shell);
}
@@ -32,7 +36,6 @@ class HooksPrivate
{
public:
HooksPrivate()
- : m_getTerminalCommandsForDevicesHook([] { return QList<NameAndCommandLine>{}; })
{
auto openTerminal = [](const OpenTerminalParameters &parameters) {
DeviceFileHooks::instance().openTerminal(parameters.workingDirectory.value_or(
@@ -79,8 +82,6 @@ public:
return m_openTerminal;
}
- Hooks::GetTerminalCommandsForDevicesHook m_getTerminalCommandsForDevicesHook;
-
private:
Hooks::OpenTerminal m_openTerminal;
Hooks::CreateTerminalProcessInterface m_createTerminalProcessInterface;
@@ -111,11 +112,6 @@ ProcessInterface *Hooks::createTerminalProcessInterface() const
return d->createTerminalProcessInterface()();
}
-Hooks::GetTerminalCommandsForDevicesHook &Hooks::getTerminalCommandsForDevicesHook()
-{
- return d->m_getTerminalCommandsForDevicesHook;
-}
-
void Hooks::addCallbackSet(const QString &name, const CallbackSet &callbackSet)
{
d->addCallbackSet(name, callbackSet);
diff --git a/src/libs/utils/terminalhooks.h b/src/libs/utils/terminalhooks.h
index b37c51517c0..449c23daa93 100644
--- a/src/libs/utils/terminalhooks.h
+++ b/src/libs/utils/terminalhooks.h
@@ -8,6 +8,8 @@
#include "filepath.h"
#include "id.h"
+#include <QIcon>
+
#include <functional>
#include <memory>
@@ -41,9 +43,24 @@ enum class ExitBehavior { Close, Restart, Keep };
struct OpenTerminalParameters
{
+ OpenTerminalParameters() = default;
+ OpenTerminalParameters(const CommandLine &commandLine) : shellCommand(commandLine) {}
+ OpenTerminalParameters(const FilePath &directory, std::optional<Environment> env) :
+ workingDirectory(directory),
+ environment(env)
+ {}
+ OpenTerminalParameters(const CommandLine &commandLine,
+ const FilePath &directory,
+ std::optional<Environment> env) :
+ shellCommand(commandLine),
+ workingDirectory(directory),
+ environment(env)
+ {}
+
std::optional<CommandLine> shellCommand;
std::optional<FilePath> workingDirectory;
std::optional<Environment> environment;
+ QIcon icon;
ExitBehavior m_exitBehavior{ExitBehavior::Close};
std::optional<Id> identifier{std::nullopt};
};
@@ -54,7 +71,7 @@ struct NameAndCommandLine
CommandLine commandLine;
};
-QTCREATOR_UTILS_EXPORT FilePath defaultShellForDevice(const FilePath &deviceRoot);
+QTCREATOR_UTILS_EXPORT expected_str<FilePath> defaultShellForDevice(const FilePath &deviceRoot);
class QTCREATOR_UTILS_EXPORT Hooks
{
@@ -68,14 +85,10 @@ public:
CreateTerminalProcessInterface createTerminalProcessInterface;
};
- using GetTerminalCommandsForDevicesHook = Hook<QList<NameAndCommandLine>>;
-
public:
static Hooks &instance();
~Hooks();
- GetTerminalCommandsForDevicesHook &getTerminalCommandsForDevicesHook();
-
void openTerminal(const OpenTerminalParameters &parameters) const;
ProcessInterface *createTerminalProcessInterface() const;
diff --git a/src/libs/utils/terminalinterface.cpp b/src/libs/utils/terminalinterface.cpp
index 204cd79d7a1..9fb226ece54 100644
--- a/src/libs/utils/terminalinterface.cpp
+++ b/src/libs/utils/terminalinterface.cpp
@@ -45,12 +45,12 @@ static QString msgUnexpectedOutput(const QByteArray &what)
static QString msgCannotChangeToWorkDir(const FilePath &dir, const QString &why)
{
- return Tr::tr("Cannot change to working directory \"%1\": %2").arg(dir.toString(), why);
+ return Tr::tr("Cannot change to working directory \"%1\": %2").arg(dir.toUserOutput(), why);
}
-static QString msgCannotExecute(const QString &p, const QString &why)
+static QString msgCannotExecute(const FilePath &p, const QString &why)
{
- return Tr::tr("Cannot execute \"%1\": %2").arg(p, why);
+ return Tr::tr("Cannot execute \"%1\": %2").arg(p.toUserOutput(), why);
}
static QString msgPromptToClose()
@@ -169,7 +169,7 @@ void TerminalInterface::onStubReadyRead()
errnoToString(out.mid(10).toInt())));
} else if (out.startsWith("err:exec ")) {
emitError(QProcess::FailedToStart,
- msgCannotExecute(m_setup.m_commandLine.executable().toString(),
+ msgCannotExecute(m_setup.m_commandLine.executable(),
errnoToString(out.mid(9).toInt())));
} else if (out.startsWith("spid ")) {
d->envListFile.reset();
diff --git a/src/libs/utils/textfileformat.cpp b/src/libs/utils/textfileformat.cpp
index 264c6c4351f..0fea53720f3 100644
--- a/src/libs/utils/textfileformat.cpp
+++ b/src/libs/utils/textfileformat.cpp
@@ -288,6 +288,19 @@ TextFileFormat::ReadResult TextFileFormat::readFileUTF8(const FilePath &filePath
return TextFileFormat::ReadSuccess;
}
+tl::expected<QString, std::pair<TextFileFormat::ReadResult, QString>>
+TextFileFormat::readFile(const FilePath &filePath, const QTextCodec *defaultCodec)
+{
+ QString plainText;
+ TextFileFormat format;
+ QString errorString;
+ const TextFileFormat::ReadResult result =
+ readTextFile(filePath, defaultCodec, &plainText, &format, &errorString, nullptr);
+ if (result != TextFileFormat::ReadSuccess)
+ return tl::unexpected(std::make_pair(result, errorString));
+ return plainText;
+}
+
/*!
Writes out a text file to \a filePath into a string, \a plainText.
diff --git a/src/libs/utils/textfileformat.h b/src/libs/utils/textfileformat.h
index f500fed50e6..4cd67abec8e 100644
--- a/src/libs/utils/textfileformat.h
+++ b/src/libs/utils/textfileformat.h
@@ -3,9 +3,11 @@
#pragma once
+#include "expected.h"
#include "utils_global.h"
#include <QStringList>
+#include <utility>
QT_BEGIN_NAMESPACE
class QTextCodec;
@@ -53,6 +55,8 @@ public:
QByteArray *decodingErrorSample = nullptr);
static ReadResult readFileUTF8(const FilePath &filePath, const QTextCodec *defaultCodec,
QByteArray *plainText, QString *errorString);
+ static tl::expected<QString, std::pair<ReadResult, QString>>
+ readFile(const FilePath &filePath, const QTextCodec *defaultCodec);
bool writeFile(const FilePath &filePath, QString plainText, QString *errorString) const;
diff --git a/src/libs/utils/textutils.cpp b/src/libs/utils/textutils.cpp
index 28a9e12e1bb..f8ada6cca68 100644
--- a/src/libs/utils/textutils.cpp
+++ b/src/libs/utils/textutils.cpp
@@ -64,6 +64,16 @@ Position Position::fromCursor(const QTextCursor &c)
return c.isNull() ? Position{} : Position{c.blockNumber() + 1, c.positionInBlock()};
}
+int Position::toPositionInDocument(const QTextDocument *document) const
+{
+ QTC_ASSERT(document, return -1);
+ const QTextBlock block = document->findBlockByNumber(line - 1);
+ if (block.isValid())
+ return block.position() + qMin(column, block.length() - 1);
+
+ return -1;
+}
+
int Range::length(const QString &text) const
{
if (end.line < begin.line)
@@ -124,11 +134,10 @@ QString textAt(QTextCursor tc, int pos, int length)
if (pos < 0)
pos = 0;
tc.movePosition(QTextCursor::End);
- if (pos + length > tc.position())
- length = tc.position() - pos;
+ const int end = std::min(pos + length, tc.position());
tc.setPosition(pos);
- tc.setPosition(pos + length, QTextCursor::KeepAnchor);
+ tc.setPosition(end, QTextCursor::KeepAnchor);
// selectedText() returns U+2029 (PARAGRAPH SEPARATOR) instead of newline
return tc.selectedText().replace(QChar::ParagraphSeparator, QLatin1Char('\n'));
@@ -139,10 +148,10 @@ QTextCursor selectAt(QTextCursor textCursor, int line, int column, uint length)
if (line < 1)
line = 1;
- if (column < 1)
- column = 1;
+ if (column < 0)
+ column = 0;
- const int anchorPosition = positionInText(textCursor.document(), line, column);
+ const int anchorPosition = positionInText(textCursor.document(), line, column + 1);
textCursor.setPosition(anchorPosition);
textCursor.setPosition(anchorPosition + int(length), QTextCursor::KeepAnchor);
@@ -252,26 +261,6 @@ bool utf8AdvanceCodePoint(const char *&current)
return true;
}
-void applyReplacements(QTextDocument *doc, const Replacements &replacements)
-{
- if (replacements.empty())
- return;
-
- int fullOffsetShift = 0;
- QTextCursor editCursor(doc);
- editCursor.beginEditBlock();
- for (const Text::Replacement &replacement : replacements) {
- editCursor.setPosition(replacement.offset + fullOffsetShift);
- editCursor.movePosition(QTextCursor::NextCharacter,
- QTextCursor::KeepAnchor,
- replacement.length);
- editCursor.removeSelectedText();
- editCursor.insertText(replacement.text);
- fullOffsetShift += replacement.text.length() - replacement.length;
- }
- editCursor.endEditBlock();
-}
-
QDebug &operator<<(QDebug &stream, const Position &pos)
{
stream << "line: " << pos.line << ", column: " << pos.column;
diff --git a/src/libs/utils/textutils.h b/src/libs/utils/textutils.h
index 80e4150c1d2..d21ca20d4d9 100644
--- a/src/libs/utils/textutils.h
+++ b/src/libs/utils/textutils.h
@@ -33,6 +33,8 @@ public:
static Position fromFileName(QStringView fileName, int &postfixPos);
static Position fromPositionInDocument(const QTextDocument *document, int pos);
static Position fromCursor(const QTextCursor &cursor);
+
+ int toPositionInDocument(const QTextDocument *document) const;
};
class QTCREATOR_UTILS_EXPORT Range
@@ -49,25 +51,6 @@ public:
bool operator!=(const Range &other) const { return !(operator==(other)); }
};
-struct Replacement
-{
- Replacement() = default;
- Replacement(int offset, int length, const QString &text)
- : offset(offset)
- , length(length)
- , text(text)
- {}
-
- int offset = -1;
- int length = -1;
- QString text;
-
- bool isValid() const { return offset >= 0 && length >= 0; }
-};
-using Replacements = std::vector<Replacement>;
-
-QTCREATOR_UTILS_EXPORT void applyReplacements(QTextDocument *doc, const Replacements &replacements);
-
// line is 1-based, column is 0-based
QTCREATOR_UTILS_EXPORT bool convertPosition(const QTextDocument *document,
int pos,
@@ -78,6 +61,7 @@ QTCREATOR_UTILS_EXPORT int positionInText(const QTextDocument *textDocument, int
QTCREATOR_UTILS_EXPORT QString textAt(QTextCursor tc, int pos, int length);
+// line is 1-based, column is 0-based
QTCREATOR_UTILS_EXPORT QTextCursor selectAt(QTextCursor textCursor, int line, int column, uint length);
QTCREATOR_UTILS_EXPORT QTextCursor flippedCursor(const QTextCursor &cursor);
diff --git a/src/libs/utils/theme/theme_p.h b/src/libs/utils/theme/theme_p.h
index 6aa5fb06a6c..14483f6d58c 100644
--- a/src/libs/utils/theme/theme_p.h
+++ b/src/libs/utils/theme/theme_p.h
@@ -23,9 +23,9 @@ public:
QStringList preferredStyles;
QString defaultTextEditorColorScheme;
QString enforceAccentColorOnMacOS;
- QVector<QPair<QColor, QString> > colors;
- QVector<QString> imageFiles;
- QVector<bool> flags;
+ QList<QPair<QColor, QString> > colors;
+ QList<QString> imageFiles;
+ QList<bool> flags;
QMap<QString, QColor> palette;
};
diff --git a/src/libs/utils/tooltip/tips.h b/src/libs/utils/tooltip/tips.h
index 1eef42e8dcf..447c5e63439 100644
--- a/src/libs/utils/tooltip/tips.h
+++ b/src/libs/utils/tooltip/tips.h
@@ -3,8 +3,6 @@
#pragma once
-#include "../utils_global.h"
-
#include <QLabel>
#include <QPixmap>
#include <QVariant>
@@ -41,7 +39,6 @@ using TextItem = std::pair<QString, Qt::TextFormat>;
class TextTip : public TipLabel
{
- Q_OBJECT
public:
TextTip(QWidget *parent);
@@ -61,7 +58,6 @@ private:
class ColorTip : public TipLabel
{
- Q_OBJECT
public:
ColorTip(QWidget *parent);
diff --git a/src/libs/utils/transientscroll.h b/src/libs/utils/transientscroll.h
index c63c89d2e1b..b10f77541d6 100644
--- a/src/libs/utils/transientscroll.h
+++ b/src/libs/utils/transientscroll.h
@@ -18,7 +18,6 @@ class ScrollBarPrivate;
class QTCREATOR_UTILS_EXPORT TransientScrollAreaSupport : public QObject
{
- Q_OBJECT
public:
static void support(QAbstractScrollArea *scrollArea);
static void supportWidget(QWidget *widget);
@@ -35,7 +34,6 @@ private:
class QTCREATOR_UTILS_EXPORT ScrollBar : public QScrollBar
{
- Q_OBJECT
friend class ScrollAreaPrivate;
diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp
index e5e5aa59b99..fe96b9c83e4 100644
--- a/src/libs/utils/treemodel.cpp
+++ b/src/libs/utils/treemodel.cpp
@@ -4,6 +4,7 @@
#include "treemodel.h"
#include "qtcassert.h"
+#include "stringutils.h"
#include <QStack>
#include <QSize>
@@ -717,7 +718,7 @@ void TreeItem::sortChildren(const std::function<bool(const TreeItem *, const Tre
{
if (m_model) {
if (const int n = childCount()) {
- QVector<TreeItem *> tmp = m_children;
+ QList<TreeItem *> tmp = m_children;
std::sort(tmp.begin(), tmp.end(), cmp);
if (tmp == m_children) {
// Nothing changed.
@@ -1199,4 +1200,12 @@ Qt::ItemFlags StaticTreeItem::flags(int column) const
return Qt::ItemIsEnabled;
}
+bool SortModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
+{
+ if (m_lessThan)
+ return m_lessThan(source_left, source_right);
+ return caseFriendlyCompare(sourceModel()->data(source_left).toString(),
+ sourceModel()->data(source_right).toString()) < 0;
+}
+
} // namespace Utils
diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h
index 2cff2f72414..a8cc073fcff 100644
--- a/src/libs/utils/treemodel.h
+++ b/src/libs/utils/treemodel.h
@@ -7,7 +7,7 @@
#include "indexedcontainerproxyconstiterator.h"
-#include <QAbstractItemModel>
+#include <QSortFilterProxyModel>
#include <functional>
@@ -49,7 +49,7 @@ public:
TreeItem *lastChild() const;
int level() const;
- using const_iterator = QVector<TreeItem *>::const_iterator;
+ using const_iterator = QList<TreeItem *>::const_iterator;
using value_type = TreeItem *;
int childCount() const { return m_children.size(); }
int indexInParent() const;
@@ -81,7 +81,7 @@ private:
TreeItem *m_parent = nullptr; // Not owned.
BaseTreeModel *m_model = nullptr; // Not owned.
- QVector<TreeItem *> m_children; // Owned.
+ QList<TreeItem *> m_children; // Owned.
friend class BaseTreeModel;
};
@@ -344,6 +344,21 @@ public:
}
};
+// By default, does natural sorting by display name. Call setLessThan() to customize.
+class QTCREATOR_UTILS_EXPORT SortModel : public QSortFilterProxyModel
+{
+public:
+ using QSortFilterProxyModel::QSortFilterProxyModel;
+ using LessThan = std::function<bool(const QModelIndex &, const QModelIndex &)>;
+ void setLessThan(const LessThan &lessThan) { m_lessThan = lessThan; }
+
+protected:
+ bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
+
+private:
+ LessThan m_lessThan;
+};
+
} // namespace Utils
Q_DECLARE_METATYPE(Utils::TreeItem *)
diff --git a/src/libs/utils/treeviewcombobox.h b/src/libs/utils/treeviewcombobox.h
index b8afc20bc88..32169f3db36 100644
--- a/src/libs/utils/treeviewcombobox.h
+++ b/src/libs/utils/treeviewcombobox.h
@@ -12,7 +12,6 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT TreeViewComboBoxView : public QTreeView
{
- Q_OBJECT
public:
TreeViewComboBoxView(QWidget *parent = nullptr);
void adjustWidth(int width);
@@ -20,7 +19,6 @@ public:
class QTCREATOR_UTILS_EXPORT TreeViewComboBox : public QComboBox
{
- Q_OBJECT
public:
TreeViewComboBox(QWidget *parent = nullptr);
diff --git a/src/libs/utils/archive.cpp b/src/libs/utils/unarchiver.cpp
index 5e62835a20f..9435bc77a51 100644
--- a/src/libs/utils/archive.cpp
+++ b/src/libs/utils/unarchiver.cpp
@@ -1,11 +1,10 @@
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include "archive.h"
+#include "unarchiver.h"
#include "algorithm.h"
#include "mimeutils.h"
-#include "process.h"
#include "qtcassert.h"
#include "utilstr.h"
@@ -38,9 +37,9 @@ static FilePaths additionalInstallDirs(const QString &registryKey, const QString
#endif
}
-static const QVector<Tool> &sTools()
+static const QList<Tool> &sTools()
{
- static QVector<Tool> tools;
+ static QList<Tool> tools;
if (tools.isEmpty()) {
if (HostOsInfo::isWindowsHost()) {
tools << Tool{{"powershell", "-command Expand-Archive -Force '%{src}' '%{dest}'", CommandLine::Raw},
@@ -77,7 +76,7 @@ static const QVector<Tool> &sTools()
return tools;
}
-static QVector<Tool> toolsForMimeType(const MimeType &mimeType)
+static QList<Tool> toolsForMimeType(const MimeType &mimeType)
{
return Utils::filtered(sTools(), [mimeType](const Tool &tool) {
return Utils::anyOf(tool.supportedMimeTypes,
@@ -85,7 +84,7 @@ static QVector<Tool> toolsForMimeType(const MimeType &mimeType)
});
}
-static QVector<Tool> toolsForFilePath(const FilePath &fp)
+static QList<Tool> toolsForFilePath(const FilePath &fp)
{
return toolsForMimeType(mimeTypeForFile(fp));
}
@@ -99,66 +98,52 @@ static std::optional<Tool> resolveTool(const Tool &tool)
return executable.isEmpty() ? std::nullopt : std::make_optional(resolvedTool);
}
-static std::optional<Tool> unzipTool(const FilePath &src, const FilePath &dest)
+expected_str<Unarchiver::SourceAndCommand> Unarchiver::sourceAndCommand(const FilePath &sourceFile)
{
- const QVector<Tool> tools = toolsForFilePath(src);
+ const QList<Tool> tools = toolsForFilePath(sourceFile);
+ if (tools.isEmpty())
+ return make_unexpected(Tr::tr("File format not supported."));
+
for (const Tool &tool : tools) {
const std::optional<Tool> resolvedTool = resolveTool(tool);
- if (resolvedTool) {
- Tool result = *resolvedTool;
- const QString srcStr = src.path();
- const QString destStr = dest.path();
- const QString args = result.command.arguments().replace("%{src}", srcStr).replace("%{dest}", destStr);
- result.command.setArguments(args);
- return result;
- }
+ if (resolvedTool)
+ return SourceAndCommand(sourceFile, resolvedTool->command);
}
- return {};
-}
-bool Archive::supportsFile(const FilePath &filePath, QString *reason)
-{
- const QVector<Tool> tools = toolsForFilePath(filePath);
- if (tools.isEmpty()) {
- if (reason)
- *reason = Tr::tr("File format not supported.");
- return false;
- }
- if (!anyOf(tools, [tools](const Tool &t) { return resolveTool(t); })) {
- if (reason) {
- const QStringList execs = transform<QStringList>(tools, [](const Tool &tool) {
- return tool.command.executable().toUserOutput();
- });
- *reason = Tr::tr("Could not find any unarchiving executable in PATH (%1).")
- .arg(execs.join(", "));
- }
- return false;
- }
- return true;
+ const QStringList execs = transform<QStringList>(tools, [](const Tool &tool) {
+ return tool.command.executable().toUserOutput();
+ });
+ return make_unexpected(Tr::tr("Could not find any unarchiving executable in PATH (%1).")
+ .arg(execs.join(", ")));
}
-Archive::Archive(const FilePath &src, const FilePath &dest)
+static CommandLine unarchiveCommand(const CommandLine &commandTemplate, const FilePath &sourceFile,
+ const FilePath &destDir)
{
- const std::optional<Tool> tool = unzipTool(src, dest);
- if (!tool)
- return;
- m_commandLine = tool->command;
- m_workingDirectory = dest.absoluteFilePath();
+ CommandLine command = commandTemplate;
+ command.setArguments(command.arguments().replace("%{src}", sourceFile.path())
+ .replace("%{dest}", destDir.path()));
+ return command;
}
-Archive::~Archive() = default;
-
-bool Archive::isValid() const
+void Unarchiver::start()
{
- return !m_commandLine.isEmpty();
-}
+ QTC_ASSERT(!m_process, emit done(false); return);
-void Archive::unarchive()
-{
- QTC_ASSERT(isValid(), return);
- QTC_ASSERT(!m_process, return);
+ if (!m_sourceAndCommand) {
+ emit outputReceived(Tr::tr("No source file set."));
+ emit done(false);
+ return;
+ }
+ if (m_destDir.isEmpty()) {
+ emit outputReceived(Tr::tr("No destination directory set."));
+ emit done(false);
+ return;
+ }
- m_workingDirectory.ensureWritableDir();
+ const CommandLine command = unarchiveCommand(m_sourceAndCommand->m_commandTemplate,
+ m_sourceAndCommand->m_sourceFile, m_destDir);
+ m_destDir.ensureWritableDir();
m_process.reset(new Process);
m_process->setProcessChannelMode(QProcess::MergedChannels);
@@ -166,18 +151,28 @@ void Archive::unarchive()
emit outputReceived(m_process->readAllStandardOutput());
});
QObject::connect(m_process.get(), &Process::done, this, [this] {
- const bool successfulFinish = m_process->result() == ProcessResult::FinishedWithSuccess;
- if (!successfulFinish)
+ const bool success = m_process->result() == ProcessResult::FinishedWithSuccess;
+ if (!success)
emit outputReceived(Tr::tr("Command failed."));
- emit finished(successfulFinish);
+ emit done(success);
});
emit outputReceived(Tr::tr("Running %1\nin \"%2\".\n\n", "Running <cmd> in <workingdirectory>")
- .arg(m_commandLine.toUserOutput(), m_workingDirectory.toUserOutput()));
+ .arg(command.toUserOutput(), m_destDir.toUserOutput()));
- m_process->setCommand(m_commandLine);
- m_process->setWorkingDirectory(m_workingDirectory);
+ m_process->setCommand(command);
+ m_process->setWorkingDirectory(m_destDir);
m_process->start();
}
+UnarchiverTaskAdapter::UnarchiverTaskAdapter()
+{
+ connect(task(), &Unarchiver::done, this, &Tasking::TaskInterface::done);
+}
+
+void UnarchiverTaskAdapter::start()
+{
+ task()->start();
+}
+
} // namespace Utils
diff --git a/src/libs/utils/unarchiver.h b/src/libs/utils/unarchiver.h
new file mode 100644
index 00000000000..3e2b2f89386
--- /dev/null
+++ b/src/libs/utils/unarchiver.h
@@ -0,0 +1,57 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "utils_global.h"
+
+#include "commandline.h"
+#include "process.h"
+
+#include <solutions/tasking/tasktree.h>
+
+#include <QObject>
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT Unarchiver : public QObject
+{
+ Q_OBJECT
+public:
+ class SourceAndCommand
+ {
+ private:
+ friend class Unarchiver;
+ SourceAndCommand(const FilePath &sourceFile, const CommandLine &commandTemplate)
+ : m_sourceFile(sourceFile), m_commandTemplate(commandTemplate) {}
+ FilePath m_sourceFile;
+ CommandLine m_commandTemplate;
+ };
+
+ static expected_str<SourceAndCommand> sourceAndCommand(const FilePath &sourceFile);
+
+ void setSourceAndCommand(const SourceAndCommand &data) { m_sourceAndCommand = data; }
+ void setDestDir(const FilePath &destDir) { m_destDir = destDir; }
+
+ void start();
+
+signals:
+ void outputReceived(const QString &output);
+ void done(bool success);
+
+private:
+ std::optional<SourceAndCommand> m_sourceAndCommand;
+ FilePath m_destDir;
+ std::unique_ptr<Process> m_process;
+};
+
+class QTCREATOR_UTILS_EXPORT UnarchiverTaskAdapter : public Tasking::TaskAdapter<Unarchiver>
+{
+public:
+ UnarchiverTaskAdapter();
+ void start() final;
+};
+
+using UnarchiverTask = Tasking::CustomTask<UnarchiverTaskAdapter>;
+
+} // namespace Utils
diff --git a/src/libs/utils/uncommentselection.cpp b/src/libs/utils/uncommentselection.cpp
index 5bba136cdf1..d2feb494e77 100644
--- a/src/libs/utils/uncommentselection.cpp
+++ b/src/libs/utils/uncommentselection.cpp
@@ -40,23 +40,11 @@ bool CommentDefinition::hasMultiLineStyle() const
return !multiLineStart.isEmpty() && !multiLineEnd.isEmpty();
}
-static bool isComment(const QString &text, int index,
- const QString &commentType)
+static bool isComment(const QString &text, int index, const QString &commentType)
{
- const int length = commentType.length();
-
- Q_ASSERT(text.length() - index >= length);
-
- int i = 0;
- while (i < length) {
- if (text.at(index + i) != commentType.at(i))
- return false;
- ++i;
- }
- return true;
+ return QStringView(text).mid(index).startsWith(commentType);
}
-
QTextCursor unCommentSelection(const QTextCursor &cursorIn,
const CommentDefinition &definition,
bool preferSingleLine)
@@ -176,12 +164,34 @@ QTextCursor unCommentSelection(const QTextCursor &cursorIn,
}
const int singleLineLength = definition.singleLine.length();
+ int minTab = INT_MAX;
+ if (definition.isAfterWhitespace && !doSingleLineStyleUncomment) {
+ for (QTextBlock block = startBlock; block != endBlock && minTab != 0; block = block.next()) {
+ QTextCursor c(block);
+ if (doc->characterAt(block.position()).isSpace()) {
+ c.movePosition(QTextCursor::NextWord);
+ if (c.block() != block) // ignore empty lines
+ continue;
+ }
+ const int pos = c.positionInBlock();
+ if (pos < minTab)
+ minTab = pos;
+ }
+ }
for (QTextBlock block = startBlock; block != endBlock; block = block.next()) {
if (doSingleLineStyleUncomment) {
QString text = block.text();
int i = 0;
while (i <= text.size() - singleLineLength) {
- if (isComment(text, i, definition.singleLine)) {
+ if (definition.isAfterWhitespace
+ && isComment(text, i, definition.singleLine + ' ')) {
+ cursor.setPosition(block.position() + i);
+ cursor.movePosition(QTextCursor::NextCharacter,
+ QTextCursor::KeepAnchor,
+ singleLineLength + 1);
+ cursor.removeSelectedText();
+ break;
+ } else if (isComment(text, i, definition.singleLine)) {
cursor.setPosition(block.position() + i);
cursor.movePosition(QTextCursor::NextCharacter,
QTextCursor::KeepAnchor,
@@ -197,11 +207,13 @@ QTextCursor unCommentSelection(const QTextCursor &cursorIn,
const QString text = block.text();
for (QChar c : text) {
if (!c.isSpace()) {
- if (definition.isAfterWhiteSpaces)
- cursor.setPosition(block.position() + text.indexOf(c));
- else
+ if (definition.isAfterWhitespace) {
+ cursor.setPosition(block.position() + minTab);
+ cursor.insertText(definition.singleLine + ' ');
+ } else {
cursor.setPosition(block.position());
- cursor.insertText(definition.singleLine);
+ cursor.insertText(definition.singleLine);
+ }
break;
}
}
diff --git a/src/libs/utils/uncommentselection.h b/src/libs/utils/uncommentselection.h
index a309b028aa4..b6836ec5101 100644
--- a/src/libs/utils/uncommentselection.h
+++ b/src/libs/utils/uncommentselection.h
@@ -31,7 +31,7 @@ public:
bool hasMultiLineStyle() const;
public:
- bool isAfterWhiteSpaces = false;
+ bool isAfterWhitespace = false;
QString singleLine;
QString multiLineStart;
QString multiLineEnd;
diff --git a/src/libs/utils/unixutils.cpp b/src/libs/utils/unixutils.cpp
index 5d626c74f24..f0a7bbf0a13 100644
--- a/src/libs/utils/unixutils.cpp
+++ b/src/libs/utils/unixutils.cpp
@@ -8,42 +8,39 @@
#include "utilstr.h"
#include <QFileInfo>
-#include <QSettings>
-using namespace Utils;
+namespace Utils::UnixUtils {
-QString UnixUtils::defaultFileBrowser()
+QString defaultFileBrowser()
{
return QLatin1String("xdg-open %d");
}
-QString UnixUtils::fileBrowser(const QSettings *settings)
+QString fileBrowser(const QtcSettings *settings)
{
const QString dflt = defaultFileBrowser();
if (!settings)
return dflt;
- return settings->value(QLatin1String("General/FileBrowser"), dflt).toString();
+ return settings->value("General/FileBrowser", dflt).toString();
}
-void UnixUtils::setFileBrowser(QSettings *settings, const QString &term)
+void setFileBrowser(QtcSettings *settings, const QString &term)
{
- QtcSettings::setValueWithDefault(settings, "General/FileBrowser", term, defaultFileBrowser());
+ settings->setValueWithDefault("General/FileBrowser", term, defaultFileBrowser());
}
-
-QString UnixUtils::fileBrowserHelpText()
+QString fileBrowserHelpText()
{
- QString help = Tr::tr("<table border=1 cellspacing=0 cellpadding=3>"
- "<tr><th>Variable</th><th>Expands to</th></tr>"
- "<tr><td>%d</td><td>directory of current file</td></tr>"
- "<tr><td>%f</td><td>file name (with full path)</td></tr>"
- "<tr><td>%n</td><td>file name (without path)</td></tr>"
- "<tr><td>%%</td><td>%</td></tr>"
- "</table>");
- return help;
+ return Tr::tr("<table border=1 cellspacing=0 cellpadding=3>"
+ "<tr><th>Variable</th><th>Expands to</th></tr>"
+ "<tr><td>%d</td><td>directory of current file</td></tr>"
+ "<tr><td>%f</td><td>file name (with full path)</td></tr>"
+ "<tr><td>%n</td><td>file name (without path)</td></tr>"
+ "<tr><td>%%</td><td>%</td></tr>"
+ "</table>");
}
-QString UnixUtils::substituteFileBrowserParameters(const QString &pre, const QString &file)
+QString substituteFileBrowserParameters(const QString &pre, const QString &file)
{
QString cmd;
for (int i = 0; i < pre.size(); ++i) {
@@ -72,3 +69,5 @@ QString UnixUtils::substituteFileBrowserParameters(const QString &pre, const QSt
return cmd;
}
+
+} // Utils::UnixUtils
diff --git a/src/libs/utils/unixutils.h b/src/libs/utils/unixutils.h
index f82517e9005..a2396d5cc2d 100644
--- a/src/libs/utils/unixutils.h
+++ b/src/libs/utils/unixutils.h
@@ -6,21 +6,18 @@
#include "utils_global.h"
QT_BEGIN_NAMESPACE
-class QSettings;
class QString;
QT_END_NAMESPACE
-namespace Utils {
+namespace Utils { class QtcSettings; }
-class QTCREATOR_UTILS_EXPORT UnixUtils
-{
-public:
- static QString defaultFileBrowser();
- static QString fileBrowser(const QSettings *settings);
- static void setFileBrowser(QSettings *settings, const QString &term);
- static QString fileBrowserHelpText();
- static QString substituteFileBrowserParameters(const QString &command,
- const QString &file);
-};
+namespace Utils::UnixUtils {
-}
+QTCREATOR_UTILS_EXPORT QString defaultFileBrowser();
+QTCREATOR_UTILS_EXPORT QString fileBrowser(const QtcSettings *settings);
+QTCREATOR_UTILS_EXPORT void setFileBrowser(QtcSettings *settings, const QString &term);
+QTCREATOR_UTILS_EXPORT QString fileBrowserHelpText();
+QTCREATOR_UTILS_EXPORT QString substituteFileBrowserParameters(const QString &command,
+ const QString &file);
+
+} // Utils::UnixUtils
diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs
index d117b7057cb..51d6857d122 100644
--- a/src/libs/utils/utils.qbs
+++ b/src/libs/utils/utils.qbs
@@ -1,480 +1,477 @@
-import qbs 1.0
import qbs.FileInfo
-Project {
+QtcLibrary {
name: "Utils"
-
- QtcLibrary {
- cpp.includePaths: base.concat("mimetypes2", ".")
- cpp.defines: base.concat([
- "UTILS_LIBRARY"
- ])
- cpp.dynamicLibraries: {
- var libs = [];
- if (qbs.targetOS.contains("windows")) {
- libs.push("user32", "iphlpapi", "ws2_32", "shell32", "ole32");
- if (qbs.toolchainType === "mingw")
- libs.push("uuid");
- else if (qbs.toolchainType === "msvc")
- libs.push("dbghelp");
- } else if (qbs.targetOS.contains("unix")) {
- if (!qbs.targetOS.contains("macos"))
- libs.push("X11");
- if (!qbs.targetOS.contains("openbsd"))
- libs.push("pthread");
- }
- return libs;
+ cpp.includePaths: base.concat("mimetypes2", ".")
+ cpp.defines: base.concat(["UTILS_LIBRARY"])
+ cpp.dynamicLibraries: {
+ var libs = [];
+ if (qbs.targetOS.contains("windows")) {
+ libs.push("user32", "iphlpapi", "ws2_32", "shell32", "ole32");
+ if (qbs.toolchain.contains("mingw"))
+ libs.push("uuid");
+ else if (qbs.toolchain.contains("msvc"))
+ libs.push("dbghelp");
+ } else if (qbs.targetOS.contains("unix")) {
+ if (!qbs.targetOS.contains("macos"))
+ libs.push("X11");
+ if (!qbs.targetOS.contains("openbsd"))
+ libs.push("pthread");
}
+ return libs;
+ }
- cpp.enableExceptions: true
+ cpp.enableExceptions: true
- Properties {
- condition: qbs.targetOS.contains("macos")
- cpp.frameworks: ["Foundation", "AppKit"]
- }
+ Properties {
+ condition: qbs.targetOS.contains("macos")
+ cpp.frameworks: ["Foundation", "AppKit"]
+ }
- Depends { name: "Qt"; submodules: ["concurrent", "core-private", "network", "qml", "widgets", "xml"] }
- Depends { name: "Qt.macextras"; condition: Qt.core.versionMajor < 6 && qbs.targetOS.contains("macos") }
- Depends { name: "Tasking" }
- Depends { name: "app_version_header" }
- Depends { name: "ptyqt" }
+ Depends { name: "Qt"; submodules: ["concurrent", "core-private", "network", "qml", "widgets", "xml"] }
+ Depends { name: "Qt.macextras"; condition: Qt.core.versionMajor < 6 && qbs.targetOS.contains("macos") }
+ Depends { name: "Spinner" }
+ Depends { name: "Tasking" }
+ Depends { name: "ptyqt" }
+ files: [
+ "algorithm.h",
+ "ansiescapecodehandler.cpp",
+ "ansiescapecodehandler.h",
+ "appinfo.cpp",
+ "appinfo.h",
+ "appmainwindow.cpp",
+ "appmainwindow.h",
+ "aspects.cpp",
+ "aspects.h",
+ "async.cpp",
+ "async.h",
+ "basetreeview.cpp",
+ "basetreeview.h",
+ "benchmarker.cpp",
+ "benchmarker.h",
+ "buildablehelperlibrary.cpp",
+ "buildablehelperlibrary.h",
+ "camelcasecursor.cpp",
+ "camelcasecursor.h",
+ "categorysortfiltermodel.cpp",
+ "categorysortfiltermodel.h",
+ "changeset.cpp",
+ "changeset.h",
+ "checkablemessagebox.cpp",
+ "checkablemessagebox.h",
+ "clangutils.cpp",
+ "clangutils.h",
+ "classnamevalidatinglineedit.cpp",
+ "classnamevalidatinglineedit.h",
+ "codegeneration.cpp",
+ "codegeneration.h",
+ "commandline.cpp",
+ "commandline.h",
+ "completinglineedit.cpp",
+ "completinglineedit.h",
+ "completingtextedit.cpp",
+ "completingtextedit.h",
+ "cpplanguage_details.h",
+ "crumblepath.cpp",
+ "crumblepath.h",
+ "delegates.cpp",
+ "delegates.h",
+ "detailsbutton.cpp",
+ "detailsbutton.h",
+ "detailswidget.cpp",
+ "detailswidget.h",
+ "devicefileaccess.cpp",
+ "devicefileaccess.h",
+ "deviceshell.cpp",
+ "deviceshell.h",
+ "differ.cpp",
+ "differ.h",
+ "displayname.cpp",
+ "displayname.h",
+ "dropsupport.cpp",
+ "dropsupport.h",
+ "elfreader.cpp",
+ "elfreader.h",
+ "elidinglabel.cpp",
+ "elidinglabel.h",
+ "environment.cpp",
+ "environment.h",
+ "environmentdialog.cpp",
+ "environmentdialog.h",
+ "environmentmodel.cpp",
+ "environmentmodel.h",
+ "execmenu.cpp",
+ "execmenu.h",
+ "externalterminalprocessimpl.cpp",
+ "externalterminalprocessimpl.h",
+ "fadingindicator.cpp",
+ "fadingindicator.h",
+ "faketooltip.cpp",
+ "faketooltip.h",
+ "fancylineedit.cpp",
+ "fancylineedit.h",
+ "fancymainwindow.cpp",
+ "fancymainwindow.h",
+ "filecrumblabel.cpp",
+ "filecrumblabel.h",
+ "fileinprojectfinder.cpp",
+ "fileinprojectfinder.h",
+ "filenamevalidatinglineedit.cpp",
+ "filenamevalidatinglineedit.h",
+ "filepath.cpp",
+ "filepath.h",
+ "filesearch.cpp",
+ "filesearch.h",
+ "filestreamer.cpp",
+ "filestreamer.h",
+ "filestreamermanager.cpp",
+ "filestreamermanager.h",
+ "filesystemmodel.cpp",
+ "filesystemmodel.h",
+ "filesystemwatcher.cpp",
+ "filesystemwatcher.h",
+ "fileutils.cpp",
+ "fileutils.h",
+ "filewizardpage.cpp",
+ "filewizardpage.h",
+ "flowlayout.cpp",
+ "flowlayout.h",
+ "futuresynchronizer.cpp",
+ "futuresynchronizer.h",
+ "fuzzymatcher.cpp",
+ "fuzzymatcher.h",
+ "globalfilechangeblocker.cpp",
+ "globalfilechangeblocker.h",
+ "guard.cpp",
+ "guard.h",
+ "highlightingitemdelegate.cpp",
+ "highlightingitemdelegate.h",
+ "historycompleter.cpp",
+ "historycompleter.h",
+ "hostosinfo.h",
+ "hostosinfo.cpp",
+ "htmldocextractor.cpp",
+ "htmldocextractor.h",
+ "icon.cpp",
+ "icon.h",
+ "iconbutton.cpp",
+ "iconbutton.h",
+ "id.cpp",
+ "id.h",
+ "indexedcontainerproxyconstiterator.h",
+ "infobar.cpp",
+ "infobar.h",
+ "infolabel.cpp",
+ "infolabel.h",
+ "itemviews.cpp",
+ "itemviews.h",
+ "jsontreeitem.cpp",
+ "jsontreeitem.h",
+ "launcherinterface.cpp",
+ "launcherinterface.h",
+ "launcherpackets.cpp",
+ "launcherpackets.h",
+ "launchersocket.cpp",
+ "launchersocket.h",
+ "layoutbuilder.cpp",
+ "layoutbuilder.h",
+ "link.cpp",
+ "link.h",
+ "listmodel.h",
+ "listutils.h",
+ "macroexpander.cpp",
+ "macroexpander.h",
+ "mathutils.cpp",
+ "mathutils.h",
+ "mimeutils.h",
+ "minimizableinfobars.cpp",
+ "minimizableinfobars.h",
+ "multitextcursor.cpp",
+ "multitextcursor.h",
+ "namevaluedictionary.cpp",
+ "namevaluedictionary.h",
+ "namevalueitem.cpp",
+ "namevalueitem.h",
+ "namevaluemodel.cpp",
+ "namevaluemodel.h",
+ "namevaluesdialog.cpp",
+ "namevaluesdialog.h",
+ "namevaluevalidator.cpp",
+ "namevaluevalidator.h",
+ "navigationtreeview.cpp",
+ "navigationtreeview.h",
+ "networkaccessmanager.cpp",
+ "networkaccessmanager.h",
+ "optionpushbutton.h",
+ "optionpushbutton.cpp",
+ "osspecificaspects.h",
+ "outputformat.h",
+ "outputformatter.cpp",
+ "outputformatter.h",
+ "overlaywidget.cpp",
+ "overlaywidget.h",
+ "overridecursor.cpp",
+ "overridecursor.h",
+ "parameteraction.cpp",
+ "parameteraction.h",
+ "passworddialog.cpp",
+ "passworddialog.h",
+ "pathchooser.cpp",
+ "pathchooser.h",
+ "pathlisteditor.cpp",
+ "pathlisteditor.h",
+ "persistentcachestore.cpp",
+ "persistentcachestore.h",
+ "persistentsettings.cpp",
+ "persistentsettings.h",
+ "pointeralgorithm.h",
+ "port.cpp",
+ "port.h",
+ "portlist.cpp",
+ "portlist.h",
+ "predicates.h",
+ "process.cpp",
+ "process.h",
+ "processenums.h",
+ "processhandle.cpp",
+ "processhandle.h",
+ "processinfo.cpp",
+ "processinfo.h",
+ "processinterface.cpp",
+ "processinterface.h",
+ "processreaper.cpp",
+ "processreaper.h",
+ "processutils.cpp",
+ "processutils.h",
+ "progressindicator.cpp",
+ "progressindicator.h",
+ "projectintropage.cpp",
+ "projectintropage.h",
+ "proxyaction.cpp",
+ "proxyaction.h",
+ "qrcparser.cpp",
+ "qrcparser.h",
+ "qtcassert.cpp",
+ "qtcassert.h",
+ "qtcolorbutton.cpp",
+ "qtcolorbutton.h",
+ "qtcsettings.cpp",
+ "qtcsettings.h",
+ "reloadpromptutils.cpp",
+ "reloadpromptutils.h",
+ "removefiledialog.cpp",
+ "removefiledialog.h",
+ "savefile.cpp",
+ "savefile.h",
+ "scopedswap.h",
+ "scopedtimer.cpp",
+ "scopedtimer.h",
+ "searchresultitem.cpp",
+ "searchresultitem.h",
+ "set_algorithm.h",
+ "settingsaccessor.cpp",
+ "settingsaccessor.h",
+ "settingsselector.cpp",
+ "settingsselector.h",
+ "singleton.cpp",
+ "singleton.h",
+ "sizedarray.h",
+ "smallstring.h",
+ "smallstringiterator.h",
+ "smallstringio.h",
+ "smallstringliteral.h",
+ "smallstringlayout.h",
+ "smallstringmemory.h",
+ "smallstringvector.h",
+ "sortfiltermodel.h",
+ "span.h",
+ "../3rdparty/span/span.hpp",
+ "statuslabel.cpp",
+ "statuslabel.h",
+ "store.cpp",
+ "store.h",
+ "storekey.h",
+ "stringtable.cpp",
+ "stringtable.h",
+ "stringutils.cpp",
+ "stringutils.h",
+ "styleanimator.cpp",
+ "styleanimator.h",
+ "styledbar.cpp",
+ "styledbar.h",
+ "stylehelper.cpp",
+ "stylehelper.h",
+ "templateengine.cpp",
+ "templateengine.h",
+ "temporarydirectory.cpp",
+ "temporarydirectory.h",
+ "temporaryfile.cpp",
+ "temporaryfile.h",
+ "terminalcommand.cpp",
+ "terminalcommand.h",
+ "terminalhooks.cpp",
+ "terminalhooks.h",
+ "terminalinterface.cpp",
+ "terminalinterface.h",
+ "textfieldcheckbox.cpp",
+ "textfieldcheckbox.h",
+ "textfieldcombobox.cpp",
+ "textfieldcombobox.h",
+ "textfileformat.cpp",
+ "textfileformat.h",
+ "textutils.cpp",
+ "textutils.h",
+ "threadutils.cpp",
+ "threadutils.h",
+ "transientscroll.cpp",
+ "transientscroll.h",
+ "treemodel.cpp",
+ "treemodel.h",
+ "treeviewcombobox.cpp",
+ "treeviewcombobox.h",
+ "headerviewstretcher.cpp",
+ "headerviewstretcher.h",
+ "unarchiver.cpp",
+ "unarchiver.h",
+ "uncommentselection.cpp",
+ "uncommentselection.h",
+ "uniqueobjectptr.h",
+ "unixutils.cpp",
+ "unixutils.h",
+ "url.cpp",
+ "url.h",
+ "utils.qrc",
+ "utils_global.h",
+ "utilsicons.h",
+ "utilsicons.cpp",
+ "utilstr.h",
+ "variablechooser.cpp",
+ "variablechooser.h",
+ "winutils.cpp",
+ "winutils.h",
+ "wizard.cpp",
+ "wizard.h",
+ "wizardpage.cpp",
+ "wizardpage.h",
+ "images/*.png",
+ ]
+
+ Group {
+ name: "FSEngine"
+ prefix: "fsengine/"
+ cpp.defines: outer.concat("QTC_UTILS_WITH_FSENGINE")
files: [
- "QtConcurrentTools",
- "algorithm.h",
- "ansiescapecodehandler.cpp",
- "ansiescapecodehandler.h",
- "appmainwindow.cpp",
- "appmainwindow.h",
- "archive.cpp",
- "archive.h",
- "aspects.cpp",
- "aspects.h",
- "async.cpp",
- "async.h",
- "basetreeview.cpp",
- "basetreeview.h",
- "benchmarker.cpp",
- "benchmarker.h",
- "buildablehelperlibrary.cpp",
- "buildablehelperlibrary.h",
- "camelcasecursor.cpp",
- "camelcasecursor.h",
- "categorysortfiltermodel.cpp",
- "categorysortfiltermodel.h",
- "changeset.cpp",
- "changeset.h",
- "checkablemessagebox.cpp",
- "checkablemessagebox.h",
- "clangutils.cpp",
- "clangutils.h",
- "classnamevalidatinglineedit.cpp",
- "classnamevalidatinglineedit.h",
- "codegeneration.cpp",
- "codegeneration.h",
- "commandline.cpp",
- "commandline.h",
- "completinglineedit.cpp",
- "completinglineedit.h",
- "completingtextedit.cpp",
- "completingtextedit.h",
- "cpplanguage_details.h",
- "crumblepath.cpp",
- "crumblepath.h",
- "delegates.cpp",
- "delegates.h",
- "detailsbutton.cpp",
- "detailsbutton.h",
- "detailswidget.cpp",
- "detailswidget.h",
- "devicefileaccess.cpp",
- "devicefileaccess.h",
- "deviceshell.cpp",
- "deviceshell.h",
- "differ.cpp",
- "differ.h",
- "displayname.cpp",
- "displayname.h",
- "dropsupport.cpp",
- "dropsupport.h",
- "elfreader.cpp",
- "elfreader.h",
- "elidinglabel.cpp",
- "elidinglabel.h",
- "environment.cpp",
- "environment.h",
- "environmentdialog.cpp",
- "environmentdialog.h",
- "environmentmodel.cpp",
- "environmentmodel.h",
- "execmenu.cpp",
- "execmenu.h",
- "externalterminalprocessimpl.cpp",
- "externalterminalprocessimpl.h",
- "fadingindicator.cpp",
- "fadingindicator.h",
- "faketooltip.cpp",
- "faketooltip.h",
- "fancylineedit.cpp",
- "fancylineedit.h",
- "fancymainwindow.cpp",
- "fancymainwindow.h",
- "filecrumblabel.cpp",
- "filecrumblabel.h",
- "fileinprojectfinder.cpp",
- "fileinprojectfinder.h",
- "filenamevalidatinglineedit.cpp",
- "filenamevalidatinglineedit.h",
- "filepath.cpp",
- "filepath.h",
- "filesearch.cpp",
- "filesearch.h",
- "filestreamer.cpp",
- "filestreamer.h",
- "filestreamermanager.cpp",
- "filestreamermanager.h",
- "filesystemmodel.cpp",
- "filesystemmodel.h",
- "filesystemwatcher.cpp",
- "filesystemwatcher.h",
- "fileutils.cpp",
- "fileutils.h",
- "filewizardpage.cpp",
- "filewizardpage.h",
- "fixedsizeclicklabel.cpp",
- "fixedsizeclicklabel.h",
- "flowlayout.cpp",
- "flowlayout.h",
- "functiontraits.h",
- "futuresynchronizer.cpp",
- "futuresynchronizer.h",
- "fuzzymatcher.cpp",
- "fuzzymatcher.h",
- "globalfilechangeblocker.cpp",
- "globalfilechangeblocker.h",
- "guard.cpp",
- "guard.h",
- "highlightingitemdelegate.cpp",
- "highlightingitemdelegate.h",
- "historycompleter.cpp",
- "historycompleter.h",
- "hostosinfo.h",
- "hostosinfo.cpp",
- "htmldocextractor.cpp",
- "htmldocextractor.h",
- "icon.cpp",
- "icon.h",
- "id.cpp",
- "id.h",
- "indexedcontainerproxyconstiterator.h",
- "infobar.cpp",
- "infobar.h",
- "infolabel.cpp",
- "infolabel.h",
- "itemviews.cpp",
- "itemviews.h",
- "json.cpp",
- "json.h",
- "jsontreeitem.cpp",
- "jsontreeitem.h",
- "launcherinterface.cpp",
- "launcherinterface.h",
- "launcherpackets.cpp",
- "launcherpackets.h",
- "launchersocket.cpp",
- "launchersocket.h",
- "layoutbuilder.cpp",
- "layoutbuilder.h",
- "link.cpp",
- "link.h",
- "listmodel.h",
- "listutils.h",
- "macroexpander.cpp",
- "macroexpander.h",
- "mapreduce.h",
- "mathutils.cpp",
- "mathutils.h",
- "mimeutils.h",
- "minimizableinfobars.cpp",
- "minimizableinfobars.h",
- "multitextcursor.cpp",
- "multitextcursor.h",
- "namevaluedictionary.cpp",
- "namevaluedictionary.h",
- "namevalueitem.cpp",
- "namevalueitem.h",
- "namevaluemodel.cpp",
- "namevaluemodel.h",
- "namevaluesdialog.cpp",
- "namevaluesdialog.h",
- "namevaluevalidator.cpp",
- "namevaluevalidator.h",
- "navigationtreeview.cpp",
- "navigationtreeview.h",
- "networkaccessmanager.cpp",
- "networkaccessmanager.h",
- "optionpushbutton.h",
- "optionpushbutton.cpp",
- "osspecificaspects.h",
- "outputformat.h",
- "outputformatter.cpp",
- "outputformatter.h",
- "overlaywidget.cpp",
- "overlaywidget.h",
- "overridecursor.cpp",
- "overridecursor.h",
- "parameteraction.cpp",
- "parameteraction.h",
- "pathchooser.cpp",
- "pathchooser.h",
- "pathlisteditor.cpp",
- "pathlisteditor.h",
- "persistentsettings.cpp",
- "persistentsettings.h",
- "predicates.h",
- "pointeralgorithm.h",
- "port.cpp",
- "port.h",
- "portlist.cpp",
- "portlist.h",
- "process.cpp",
- "process.h",
- "processenums.h",
- "processhandle.cpp",
- "processhandle.h",
- "processinfo.cpp",
- "processinfo.h",
- "processinterface.cpp",
- "processinterface.h",
- "processreaper.cpp",
- "processreaper.h",
- "processutils.cpp",
- "processutils.h",
- "progressindicator.cpp",
- "progressindicator.h",
- "projectintropage.cpp",
- "projectintropage.h",
- "proxyaction.cpp",
- "proxyaction.h",
- "qrcparser.cpp",
- "qrcparser.h",
- "qtcassert.cpp",
- "qtcassert.h",
- "qtcolorbutton.cpp",
- "qtcolorbutton.h",
- "qtcsettings.cpp",
- "qtcsettings.h",
- "reloadpromptutils.cpp",
- "reloadpromptutils.h",
- "removefiledialog.cpp",
- "removefiledialog.h",
- "runextensions.cpp",
- "runextensions.h",
- "savefile.cpp",
- "savefile.h",
- "scopedswap.h",
- "scopedtimer.cpp",
- "scopedtimer.h",
- "searchresultitem.cpp",
- "searchresultitem.h",
- "set_algorithm.h",
- "settingsaccessor.cpp",
- "settingsaccessor.h",
- "settingsselector.cpp",
- "settingsselector.h",
- "settingsutils.h",
- "singleton.cpp",
- "singleton.h",
- "sizedarray.h",
- "smallstring.h",
- "smallstringiterator.h",
- "smallstringio.h",
- "smallstringliteral.h",
- "smallstringlayout.h",
- "smallstringmemory.h",
- "smallstringvector.h",
- "sortfiltermodel.h",
- "span.h",
- "../3rdparty/span/span.hpp",
- "statuslabel.cpp",
- "statuslabel.h",
- "stringtable.cpp",
- "stringtable.h",
- "stringutils.cpp",
- "stringutils.h",
- "styleanimator.cpp",
- "styleanimator.h",
- "styledbar.cpp",
- "styledbar.h",
- "stylehelper.cpp",
- "stylehelper.h",
- "templateengine.cpp",
- "templateengine.h",
- "temporarydirectory.cpp",
- "temporarydirectory.h",
- "temporaryfile.cpp",
- "temporaryfile.h",
- "terminalcommand.cpp",
- "terminalcommand.h",
- "terminalhooks.cpp",
- "terminalhooks.h",
- "terminalinterface.cpp",
- "terminalinterface.h",
- "textfieldcheckbox.cpp",
- "textfieldcheckbox.h",
- "textfieldcombobox.cpp",
- "textfieldcombobox.h",
- "textfileformat.cpp",
- "textfileformat.h",
- "textutils.cpp",
- "textutils.h",
- "threadutils.cpp",
- "threadutils.h",
- "treemodel.cpp",
- "treemodel.h",
- "treeviewcombobox.cpp",
- "treeviewcombobox.h",
- "headerviewstretcher.cpp",
- "headerviewstretcher.h",
- "uncommentselection.cpp",
- "uncommentselection.h",
- "uniqueobjectptr.h",
- "unixutils.cpp",
- "unixutils.h",
- "url.cpp",
- "url.h",
- "utils.qrc",
- "utils_global.h",
- "utilsicons.h",
- "utilsicons.cpp",
- "utilstr.h",
- "variablechooser.cpp",
- "variablechooser.h",
- "winutils.cpp",
- "winutils.h",
- "wizard.cpp",
- "wizard.h",
- "wizardpage.cpp",
- "wizardpage.h",
- "images/*.png",
+ "diriterator.h",
+ "fileiconprovider.cpp",
+ "fileiconprovider.h",
+ "fileiteratordevicesappender.h",
+ "fixedlistfsengine.h",
+ "fsengine.cpp",
+ "fsengine.h",
+ "fsenginehandler.cpp",
+ "fsenginehandler.h",
+ "fsengine_impl.cpp",
+ "fsengine_impl.h",
+ "rootinjectfsengine.h",
]
+ }
- Group {
- name: "FSEngine"
- prefix: "fsengine/"
- cpp.defines: outer.concat("QTC_UTILS_WITH_FSENGINE")
- files: [
- "diriterator.h",
- "fileiconprovider.cpp",
- "fileiconprovider.h",
- "fileiteratordevicesappender.h",
- "fixedlistfsengine.h",
- "fsengine.cpp",
- "fsengine.h",
- "fsenginehandler.cpp",
- "fsenginehandler.h",
- "fsengine_impl.cpp",
- "fsengine_impl.h",
- "rootinjectfsengine.h",
- ]
- }
+ Group {
+ name: "Theme"
+ prefix: "theme/"
+ files: [
+ "theme.cpp",
+ "theme.h",
+ "theme_p.h",
+ ]
+ }
- Group {
- name: "Theme"
- prefix: "theme/"
- files: [
- "theme.cpp",
- "theme.h",
- "theme_p.h",
- ]
- }
+ Group {
+ name: "Tooltip"
+ prefix: "tooltip/"
+ files: [
+ "effects.h",
+ "tips.cpp",
+ "tips.h",
+ "tooltip.cpp",
+ "tooltip.h",
+ ]
+ }
- Group {
- name: "Tooltip"
- prefix: "tooltip/"
- files: [
- "effects.h",
- "tips.cpp",
- "tips.h",
- "tooltip.cpp",
- "tooltip.h",
- ]
- }
+ Group {
+ name: "FileUtils_macos"
+ condition: qbs.targetOS.contains("macos")
+ files: [
+ "fileutils_mac.h", "fileutils_mac.mm",
+ ]
+ }
- Group {
- name: "FileUtils_macos"
- condition: qbs.targetOS.contains("macos")
- files: [
- "fileutils_mac.h", "fileutils_mac.mm",
- ]
- }
+ Group {
+ name: "Theme_macos"
+ condition: qbs.targetOS.contains("macos")
+ prefix: "theme/"
+ files: [
+ "theme_mac.h", "theme_mac.mm",
+ ]
+ }
- Group {
- name: "Theme_macos"
- condition: qbs.targetOS.contains("macos")
- prefix: "theme/"
- files: [
- "theme_mac.h", "theme_mac.mm",
- ]
- }
+ Group {
+ name: "ProcessHandle_macos"
+ condition: qbs.targetOS.contains("macos")
+ files: [
+ "processhandle_mac.mm",
+ ]
+ }
- Group {
- name: "ProcessHandle_macos"
- condition: qbs.targetOS.contains("macos")
- files: [
- "processhandle_mac.mm",
- ]
- }
+ Group {
+ name: "MimeTypes"
+ prefix: "mimetypes2/"
+ files: [
+ "mimedatabase.cpp",
+ "mimedatabase.h",
+ "mimedatabase_p.h",
+ "mimeglobpattern.cpp",
+ "mimeglobpattern_p.h",
+ "mimemagicrule.cpp",
+ "mimemagicrule_p.h",
+ "mimemagicrulematcher.cpp",
+ "mimemagicrulematcher_p.h",
+ "mimeprovider.cpp",
+ "mimeprovider_p.h",
+ "mimetype.cpp",
+ "mimetype.h",
+ "mimetype_p.h",
+ "mimetypeparser.cpp",
+ "mimetypeparser_p.h",
+ "mimeutils.cpp"
+ ]
+ }
+ Group {
+ name: "TouchBar support"
+ prefix: "touchbar/"
+ files: "touchbar.h"
Group {
- name: "MimeTypes"
- prefix: "mimetypes2/"
+ name: "TouchBar implementation"
+ condition: qbs.targetOS.contains("macos")
files: [
- "mimedatabase.cpp",
- "mimedatabase.h",
- "mimedatabase_p.h",
- "mimeglobpattern.cpp",
- "mimeglobpattern_p.h",
- "mimemagicrule.cpp",
- "mimemagicrule_p.h",
- "mimemagicrulematcher.cpp",
- "mimemagicrulematcher_p.h",
- "mimeprovider.cpp",
- "mimeprovider_p.h",
- "mimetype.cpp",
- "mimetype.h",
- "mimetype_p.h",
- "mimetypeparser.cpp",
- "mimetypeparser_p.h",
- "mimeutils.cpp"
+ "touchbar_appdelegate_mac_p.h",
+ "touchbar_mac_p.h",
+ "touchbar_mac.mm",
+ "touchbar_appdelegate_mac.mm",
]
}
-
Group {
- name: "TouchBar support"
- prefix: "touchbar/"
- files: "touchbar.h"
- Group {
- name: "TouchBar implementation"
- condition: qbs.targetOS.contains("macos")
- files: [
- "touchbar_appdelegate_mac_p.h",
- "touchbar_mac_p.h",
- "touchbar_mac.mm",
- "touchbar_appdelegate_mac.mm",
- ]
- }
- Group {
- name: "TouchBar stub"
- condition: !qbs.targetOS.contains("macos")
- files: "touchbar.cpp"
- }
+ name: "TouchBar stub"
+ condition: !qbs.targetOS.contains("macos")
+ files: "touchbar.cpp"
}
+ }
- Export {
- Depends { name: "Qt"; submodules: ["concurrent", "widgets" ] }
- Depends { name: "Tasking" }
- cpp.includePaths: base.concat("mimetypes2")
- }
+ Export {
+ Depends { name: "Qt"; submodules: ["concurrent", "widgets" ] }
+ Depends { name: "Tasking" }
+ cpp.includePaths: "mimetypes2"
}
}
diff --git a/src/libs/utils/utils.qrc b/src/libs/utils/utils.qrc
index c0f2d2559a1..91070dc708b 100644
--- a/src/libs/utils/utils.qrc
+++ b/src/libs/utils/utils.qrc
@@ -48,6 +48,12 @@
<file>images/clean_pane_small@2x.png</file>
<file>images/compile_error_taskbar.png</file>
<file>images/compile_error_taskbar@2x.png</file>
+ <file>images/continue_1_small.png</file>
+ <file>images/continue_1_small@2x.png</file>
+ <file>images/continue_2_small.png</file>
+ <file>images/continue_2_small@2x.png</file>
+ <file>images/debugger_overlay_small.png</file>
+ <file>images/debugger_overlay_small@2x.png</file>
<file>images/editcopy.png</file>
<file>images/editcopy@2x.png</file>
<file>images/editcut.png</file>
diff --git a/src/libs/utils/utilsicons.cpp b/src/libs/utils/utilsicons.cpp
index 01b1f0c1dbc..3e379ef5b96 100644
--- a/src/libs/utils/utilsicons.cpp
+++ b/src/libs/utils/utilsicons.cpp
@@ -63,6 +63,8 @@ const Icon BOOKMARK_TOOLBAR({
{":/utils/images/bookmark.png", Theme::IconsBaseColor}});
const Icon BOOKMARK_TEXTEDITOR({
{":/utils/images/bookmark.png", Theme::Bookmarks_TextMarkColor}}, Icon::Tint);
+const Icon SNAPSHOT({
+ {":/utils/images/snapshot.png", Theme::PanelTextColorMid}}, Icon::Tint);
const Icon SNAPSHOT_TOOLBAR({
{":/utils/images/snapshot.png", Theme::IconsBaseColor}});
const Icon NEWSEARCH_TOOLBAR({
@@ -225,6 +227,12 @@ const Icon INTERRUPT_SMALL({
{":/utils/images/interrupt_small.png", Theme::IconsInterruptColor}}, Icon::MenuTintedStyle);
const Icon INTERRUPT_SMALL_TOOLBAR({
{":/utils/images/interrupt_small.png", Theme::IconsInterruptToolBarColor}});
+const Icon CONTINUE_SMALL({
+ {":/utils/images/continue_1_small.png", Theme::IconsInterruptColor},
+ {":/utils/images/continue_2_small.png", Theme::IconsRunColor}}, Icon::MenuTintedStyle);
+const Icon CONTINUE_SMALL_TOOLBAR({
+ {":/utils/images/continue_1_small.png", Theme::IconsInterruptToolBarColor},
+ {":/utils/images/continue_2_small.png", Theme::IconsRunToolBarColor}});
const Icon BOUNDING_RECT({
{":/utils/images/boundingrect.png", Theme::IconsBaseColor}});
const Icon EYE_OPEN({
@@ -288,6 +296,7 @@ const Icon MACOS_TOUCHBAR_BOOKMARK(
":/utils/images/macos_touchbar_bookmark.png");
const Icon MACOS_TOUCHBAR_CLEAR(
":/utils/images/macos_touchbar_clear.png");
+
} // namespace Icons
QIcon CodeModelIcon::iconForType(CodeModelIcon::Type type)
diff --git a/src/libs/utils/utilsicons.h b/src/libs/utils/utilsicons.h
index 5a75267a363..bef0ef517f2 100644
--- a/src/libs/utils/utilsicons.h
+++ b/src/libs/utils/utilsicons.h
@@ -36,6 +36,7 @@ QTCREATOR_UTILS_EXPORT extern const Icon BROKEN;
QTCREATOR_UTILS_EXPORT extern const Icon BOOKMARK;
QTCREATOR_UTILS_EXPORT extern const Icon BOOKMARK_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon BOOKMARK_TEXTEDITOR;
+QTCREATOR_UTILS_EXPORT extern const Icon SNAPSHOT;
QTCREATOR_UTILS_EXPORT extern const Icon SNAPSHOT_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon NEWSEARCH_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon SETTINGS;
@@ -120,6 +121,9 @@ QTCREATOR_UTILS_EXPORT extern const Icon STOP_SMALL;
QTCREATOR_UTILS_EXPORT extern const Icon STOP_SMALL_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon INTERRUPT_SMALL;
QTCREATOR_UTILS_EXPORT extern const Icon INTERRUPT_SMALL_TOOLBAR;
+QTCREATOR_UTILS_EXPORT extern const Icon CONTINUE_SMALL;
+QTCREATOR_UTILS_EXPORT extern const Icon CONTINUE_SMALL_TOOLBAR;
+
QTCREATOR_UTILS_EXPORT extern const Icon BOUNDING_RECT;
QTCREATOR_UTILS_EXPORT extern const Icon EYE_OPEN;
QTCREATOR_UTILS_EXPORT extern const Icon EYE_OPEN_TOOLBAR;
@@ -148,6 +152,7 @@ QTCREATOR_UTILS_EXPORT extern const Icon CODEMODEL_FIXIT;
QTCREATOR_UTILS_EXPORT extern const Icon MACOS_TOUCHBAR_BOOKMARK;
QTCREATOR_UTILS_EXPORT extern const Icon MACOS_TOUCHBAR_CLEAR;
+
} // namespace Icons
namespace CodeModelIcon {
diff --git a/src/libs/utils/variablechooser.cpp b/src/libs/utils/variablechooser.cpp
index 07348b64894..22513d4bb45 100644
--- a/src/libs/utils/variablechooser.cpp
+++ b/src/libs/utils/variablechooser.cpp
@@ -81,7 +81,7 @@ public:
void createIconButton()
{
- m_iconButton = new IconButton;
+ m_iconButton = new FancyIconButton;
m_iconButton->setIcon(Icons::REPLACE.icon());
m_iconButton->setToolTip(Tr::tr("Insert Variable"));
m_iconButton->hide();
@@ -108,7 +108,7 @@ public:
QPointer<QLineEdit> m_lineEdit;
QPointer<QTextEdit> m_textEdit;
QPointer<QPlainTextEdit> m_plainTextEdit;
- QPointer<IconButton> m_iconButton;
+ QPointer<FancyIconButton> m_iconButton;
FancyLineEdit *m_variableFilter;
VariableTreeView *m_variableTree;
diff --git a/src/libs/utils/variablechooser.h b/src/libs/utils/variablechooser.h
index 257dcea5e2c..2ad7aebfbf5 100644
--- a/src/libs/utils/variablechooser.h
+++ b/src/libs/utils/variablechooser.h
@@ -19,8 +19,6 @@ namespace Internal { class VariableChooserPrivate; }
class QTCREATOR_UTILS_EXPORT VariableChooser : public QWidget
{
- Q_OBJECT
-
public:
explicit VariableChooser(QWidget *parent = nullptr);
~VariableChooser() override;
diff --git a/src/libs/utils/wizard.cpp b/src/libs/utils/wizard.cpp
index ce37d80705e..bbf22730a4f 100644
--- a/src/libs/utils/wizard.cpp
+++ b/src/libs/utils/wizard.cpp
@@ -5,6 +5,7 @@
#include "algorithm.h"
#include "hostosinfo.h"
+#include "icon.h"
#include "qtcassert.h"
#include "theme/theme.h"
#include "utilstr.h"
@@ -110,7 +111,7 @@ LinearProgressWidget::LinearProgressWidget(WizardProgress *progress, QWidget *pa
m_dotsItemWidget(nullptr),
m_disableUpdatesCount(0)
{
- m_indicatorPixmap = QIcon::fromTheme(QLatin1String("go-next"), QIcon(QLatin1String(":/utils/images/arrow.png"))).pixmap(16);
+ m_indicatorPixmap = Icon::fromTheme("go-next").pixmap(16);
m_wizardProgress = progress;
m_mainLayout = new QVBoxLayout(this);
m_itemWidgetLayout = new QVBoxLayout();
@@ -630,7 +631,7 @@ QList<WizardProgressItem *> WizardProgressPrivate::singlePathBetween(WizardProgr
if (!item)
item = m_startItem;
if (!item)
- return QList<WizardProgressItem *>();
+ return {};
// Optimization. It is workaround for case A->B, B->C, A->C where "from" is A and "to" is C.
// When we had X->A in addition and "from" was X and "to" was C, this would not work
@@ -666,7 +667,7 @@ QList<WizardProgressItem *> WizardProgressPrivate::singlePathBetween(WizardProgr
while (itItem != itEnd) {
path.prepend(itItem.key());
if (itItem.value().count() != 1)
- return QList<WizardProgressItem *>();
+ return {};
it = itItem.value().constBegin().key();
if (it == item)
return path;