aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build_scripts/main.py49
-rw-r--r--build_scripts/options.py2
-rw-r--r--build_scripts/platforms/windows_desktop.py7
-rw-r--r--build_scripts/setup_runner.py6
-rw-r--r--build_scripts/utils.py2
-rw-r--r--coin/instructions/execute_license_check.yaml2
-rw-r--r--coin_build_instructions.py4
-rw-r--r--dist/changes-1.2.3 (renamed from CHANGES.rst)0
-rw-r--r--dist/changes-5.15.049
-rw-r--r--examples/charts/charts.pyproject4
-rw-r--r--examples/charts/linechart.py84
-rw-r--r--examples/charts/logvalueaxis.py94
-rw-r--r--examples/charts/piechart.py87
-rw-r--r--examples/charts/qmlpolarchart/View1.qml78
-rw-r--r--examples/charts/qmlpolarchart/View2.qml99
-rw-r--r--examples/charts/qmlpolarchart/View3.qml86
-rw-r--r--examples/charts/qmlpolarchart/main.qml89
-rw-r--r--examples/charts/qmlpolarchart/qmlpolarchart.py63
-rw-r--r--examples/charts/qmlpolarchart/qmlpolarchart.pyproject3
-rw-r--r--examples/charts/temperaturerecords.py95
-rw-r--r--examples/declarative/textproperties/main.py3
-rw-r--r--examples/scriptableapplication/mainwindow.cpp2
-rw-r--r--examples/widgets/gallery/gallery.pyproject3
-rw-r--r--examples/widgets/gallery/main.py56
-rw-r--r--examples/widgets/gallery/widgetgallery.py429
-rw-r--r--examples/widgets/systray/images/bad.pngbin0 -> 2496 bytes
-rw-r--r--examples/widgets/systray/images/heart.pngbin0 -> 25780 bytes
-rw-r--r--examples/widgets/systray/images/trash.pngbin0 -> 12128 bytes
-rw-r--r--examples/widgets/systray/main.py58
-rw-r--r--examples/widgets/systray/rc_systray.py2581
-rw-r--r--examples/widgets/systray/systray.pyproject3
-rw-r--r--examples/widgets/systray/systray.qrc7
-rw-r--r--examples/widgets/systray/window.py273
-rw-r--r--sources/cmake_helpers/helpers.cmake57
m---------sources/pyside2-tools0
-rw-r--r--sources/pyside2/CMakeLists.txt44
-rw-r--r--sources/pyside2/PySide2/CMakeLists.txt4
-rw-r--r--sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt12
-rw-r--r--sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt12
-rw-r--r--sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt15
-rw-r--r--sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt4
-rw-r--r--sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt6
-rw-r--r--sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt24
-rw-r--r--sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml4
-rw-r--r--sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt10
-rw-r--r--sources/pyside2/PySide2/QtCharts/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt6
-rw-r--r--sources/pyside2/PySide2/QtCore/CMakeLists.txt11
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_common.xml17
-rw-r--r--sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt12
-rw-r--r--sources/pyside2/PySide2/QtGui/CMakeLists.txt22
-rw-r--r--sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml1
-rw-r--r--sources/pyside2/PySide2/QtHelp/CMakeLists.txt27
-rw-r--r--sources/pyside2/PySide2/QtHelp/typesystem_help.xml2
-rw-r--r--sources/pyside2/PySide2/QtLocation/CMakeLists.txt9
-rw-r--r--sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt12
-rw-r--r--sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt19
-rw-r--r--sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt24
-rw-r--r--sources/pyside2/PySide2/QtNetwork/CMakeLists.txt27
-rw-r--r--sources/pyside2/PySide2/QtNetwork/typesystem_network.xml2
-rw-r--r--sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtPositioning/CMakeLists.txt9
-rw-r--r--sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtQml/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtQuick/CMakeLists.txt22
-rw-r--r--sources/pyside2/PySide2/QtQuickControls2/CMakeLists.txt41
-rw-r--r--sources/pyside2/PySide2/QtQuickControls2/typesystem_quickcontrols2.xml (renamed from sources/pyside2/libpyside/destroylistener.cpp)72
-rw-r--r--sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt28
-rw-r--r--sources/pyside2/PySide2/QtRemoteObjects/CMakeLists.txt4
-rw-r--r--sources/pyside2/PySide2/QtScript/CMakeLists.txt8
-rw-r--r--sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt20
-rw-r--r--sources/pyside2/PySide2/QtScxml/CMakeLists.txt9
-rw-r--r--sources/pyside2/PySide2/QtSensors/CMakeLists.txt6
-rw-r--r--sources/pyside2/PySide2/QtSerialPort/CMakeLists.txt31
-rw-r--r--sources/pyside2/PySide2/QtSerialPort/typesystem_serialport.xml56
-rw-r--r--sources/pyside2/PySide2/QtSql/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtSvg/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtTest/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt10
-rw-r--r--sources/pyside2/PySide2/QtUiTools/CMakeLists.txt20
-rw-r--r--sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml25
-rw-r--r--sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt8
-rw-r--r--sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt6
-rw-r--r--sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt9
-rw-r--r--sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt26
-rw-r--r--sources/pyside2/PySide2/QtWebKit/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt26
-rw-r--r--sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt12
-rw-r--r--sources/pyside2/PySide2/QtWidgets/CMakeLists.txt12
-rw-r--r--sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt12
-rw-r--r--sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt12
-rw-r--r--sources/pyside2/PySide2/QtXml/CMakeLists.txt6
-rw-r--r--sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt8
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp32
-rw-r--r--sources/pyside2/cmake/Macros/FindQt5Extra.cmake4
-rw-r--r--sources/pyside2/cmake/Macros/PySideModules.cmake5
-rw-r--r--sources/pyside2/doc/CMakeLists.txt55
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs_qthelp/domainindex.html57
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs_qthelp/static/fakebar.pngbin0 -> 101 bytes
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpgbin0 -> 2660 bytes
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_qt.pngbin0 -> 1936 bytes
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs_qthelp/static/minus.pngbin0 -> 199 bytes
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs_qthelp/static/plus.pngbin0 -> 199 bytes
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pyside.css1943
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.pngbin0 -> 4936 bytes
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.pngbin0 -> 130 bytes
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs_qthelp/theme.conf7
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.cpp)5
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qobject.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qobject.cpp)158
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.py74
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.cpp73
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.py71
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.cpp)40
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.h81
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.py65
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedlayout/main.py87
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.cpp)3
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlquery/bindingExample.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlquery/bindingExample.cpp)12
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.cpp)6
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/widgets-tutorial/template.py66
-rw-r--r--sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.py (renamed from sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.cpp)15
-rw-r--r--sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.py (renamed from sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.cpp)2
-rw-r--r--sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.h (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.cpp)71
-rw-r--r--sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.py (renamed from sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.cpp)82
-rw-r--r--sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.py (renamed from sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.cpp)10
-rw-r--r--sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.py (renamed from sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.cpp)43
-rw-r--r--sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.cpp381
-rw-r--r--sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.py360
-rw-r--r--sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.py (renamed from sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.cpp)43
-rw-r--r--sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.py (renamed from sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.cpp)10
-rw-r--r--sources/pyside2/doc/conf.py.in11
-rw-r--r--sources/pyside2/doc/extras/QtCore.QEnum.rst92
-rw-r--r--sources/pyside2/doc/extras/QtUiTools.loadUiType.rst36
-rw-r--r--sources/pyside2/doc/extras/QtUiTools.rst2
-rw-r--r--sources/pyside2/doc/gettingstarted.rst30
-rw-r--r--sources/pyside2/doc/index.rst99
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/icons.pngbin0 -> 3202 bytes
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/icons/forward.pngbin0 -> 1113 bytes
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/icons/pause.pngbin0 -> 1001 bytes
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/icons/play.pngbin0 -> 970 bytes
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/icons/previous.pngbin0 -> 1050 bytes
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/icons/stop.pngbin0 -> 1064 bytes
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/player-new.pngbin0 -> 7818 bytes
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/player.pngbin0 -> 5835 bytes
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/qrcfiles.rst169
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/uifiles.rst6
-rw-r--r--sources/pyside2/doc/tutorials/expenses/expenses.rst12
-rw-r--r--sources/pyside2/doc/tutorials/index.rst1
-rw-r--r--sources/pyside2/doc/videos.rst67
-rw-r--r--sources/pyside2/libpyside/CMakeLists.txt49
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject.cpp66
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject.h5
-rw-r--r--sources/pyside2/libpyside/pyside.cpp11
-rw-r--r--sources/pyside2/libpyside/pyside.h1
-rw-r--r--sources/pyside2/libpyside/pysideproperty.cpp5
-rw-r--r--sources/pyside2/libpyside/pysideproperty.h3
-rw-r--r--sources/pyside2/libpyside/pysideqenum.cpp258
-rw-r--r--sources/pyside2/libpyside/pysideqenum.h (renamed from sources/pyside2/libpyside/destroylistener.h)41
-rw-r--r--sources/pyside2/libpyside/pysideqflags.cpp14
-rw-r--r--sources/pyside2/libpyside/pysidesignal.cpp32
-rw-r--r--sources/pyside2/libpyside/pysidesignal.h15
-rw-r--r--sources/pyside2/plugins/CMakeLists.txt17
-rw-r--r--sources/pyside2/pyside_version.py8
-rw-r--r--sources/pyside2/tests/CMakeLists.txt2
-rw-r--r--sources/pyside2/tests/QtCore/CMakeLists.txt3
-rw-r--r--sources/pyside2/tests/QtCore/qenum_test.py119
-rw-r--r--sources/pyside2/tests/QtNetwork/CMakeLists.txt2
-rw-r--r--sources/pyside2/tests/QtQuickControls2/CMakeLists.txt1
-rw-r--r--sources/pyside2/tests/QtSerialPort/CMakeLists.txt1
-rw-r--r--sources/pyside2/tests/QtSerialPort/serial.py95
-rw-r--r--sources/pyside2/tests/pysidetest/CMakeLists.txt48
-rw-r--r--sources/pyside2/tests/registry/init_platform.py4
-rw-r--r--sources/shiboken2/ApiExtractor/CMakeLists.txt14
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp337
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.h4
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h7
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp309
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h81
-rw-r--r--sources/shiboken2/ApiExtractor/apiextractor.cpp55
-rw-r--r--sources/shiboken2/ApiExtractor/apiextractor.h9
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp140
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h2
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp8
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangutils.h5
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp8
-rw-r--r--sources/shiboken2/ApiExtractor/docparser.cpp6
-rw-r--r--sources/shiboken2/ApiExtractor/doxygenparser.cpp16
-rw-r--r--sources/shiboken2/ApiExtractor/graph.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/include.cpp4
-rw-r--r--sources/shiboken2/ApiExtractor/include.h6
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp40
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h7
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.cpp94
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.h35
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel_enums.h7
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h3
-rw-r--r--sources/shiboken2/ApiExtractor/qtcompat.h40
-rw-r--r--sources/shiboken2/ApiExtractor/qtdocparser.cpp16
-rw-r--r--sources/shiboken2/ApiExtractor/reporthandler.cpp17
-rw-r--r--sources/shiboken2/ApiExtractor/reporthandler.h2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/CMakeLists.txt2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp30
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h1
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcontainer.cpp6
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp4
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.cpp84
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.h2
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp147
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.h16
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase_typedefs.h1
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp183
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h147
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_enums.h7
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_typedefs.h2
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.cpp189
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.h9
-rw-r--r--sources/shiboken2/CMakeLists.txt26
-rw-r--r--sources/shiboken2/data/shiboken_helpers.cmake6
-rw-r--r--sources/shiboken2/doc/CMakeLists.txt42
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs_qthelp/domainindex.html57
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/fakebar.pngbin0 -> 101 bytes
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpgbin0 -> 2660 bytes
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_qt.pngbin0 -> 1936 bytes
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/minus.pngbin0 -> 199 bytes
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/plus.pngbin0 -> 199 bytes
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pyside.css1943
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.pngbin0 -> 4936 bytes
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.pngbin0 -> 130 bytes
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs_qthelp/theme.conf7
-rw-r--r--sources/shiboken2/doc/conf.py.in8
-rw-r--r--sources/shiboken2/doc/index.rst10
-rw-r--r--sources/shiboken2/doc/shibokengenerator.rst2
-rw-r--r--sources/shiboken2/doc/typesystem_specifying_types.rst66
-rw-r--r--sources/shiboken2/generator/CMakeLists.txt2
-rw-r--r--sources/shiboken2/generator/generator.cpp105
-rw-r--r--sources/shiboken2/generator/generator.h40
-rw-r--r--sources/shiboken2/generator/main.cpp268
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp156
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.h4
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp825
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.h81
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.cpp71
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.h4
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.cpp2
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp197
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h25
-rw-r--r--sources/shiboken2/libshiboken/CMakeLists.txt2
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp55
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.h11
-rw-r--r--sources/shiboken2/libshiboken/bindingmanager.cpp5
-rw-r--r--sources/shiboken2/libshiboken/bindingmanager.h6
-rw-r--r--sources/shiboken2/libshiboken/helper.cpp115
-rw-r--r--sources/shiboken2/libshiboken/helper.h20
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.cpp16
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.h12
-rw-r--r--sources/shiboken2/libshiboken/sbkenum.cpp29
-rw-r--r--sources/shiboken2/libshiboken/sbkpython.h1
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.cpp5
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.h5
-rw-r--r--sources/shiboken2/shiboken_version.py8
-rw-r--r--sources/shiboken2/tests/CMakeLists.txt36
-rw-r--r--sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt2
-rw-r--r--sources/shiboken2/tests/dumpcodemodel/main.cpp78
-rw-r--r--sources/shiboken2/tests/libother/CMakeLists.txt3
-rw-r--r--sources/shiboken2/tests/libother/otherobjecttype.cpp10
-rw-r--r--sources/shiboken2/tests/libother/otherobjecttype.h7
-rw-r--r--sources/shiboken2/tests/libother/smartptrtester.cpp55
-rw-r--r--sources/shiboken2/tests/libother/smartptrtester.h49
-rw-r--r--sources/shiboken2/tests/libsample/CMakeLists.txt1
-rw-r--r--sources/shiboken2/tests/libsample/modifications.cpp19
-rw-r--r--sources/shiboken2/tests/libsample/modifications.h8
-rw-r--r--sources/shiboken2/tests/libsample/renaming.cpp46
-rw-r--r--sources/shiboken2/tests/libsample/renaming.h50
-rw-r--r--sources/shiboken2/tests/libsample/samplenamespace.h9
-rw-r--r--sources/shiboken2/tests/libsmart/smart.cpp25
-rw-r--r--sources/shiboken2/tests/libsmart/smart_integer.h8
-rw-r--r--sources/shiboken2/tests/libsmart/smart_obj.h6
-rw-r--r--sources/shiboken2/tests/otherbinding/CMakeLists.txt9
-rw-r--r--sources/shiboken2/tests/otherbinding/global.h1
-rw-r--r--sources/shiboken2/tests/otherbinding/other-binding.txt.in2
-rw-r--r--sources/shiboken2/tests/otherbinding/signature_test.py54
-rw-r--r--sources/shiboken2/tests/otherbinding/smartptr_test.py61
-rw-r--r--sources/shiboken2/tests/otherbinding/typesystem_other.xml5
-rw-r--r--sources/shiboken2/tests/samplebinding/CMakeLists.txt3
-rw-r--r--sources/shiboken2/tests/samplebinding/global.h1
-rw-r--r--sources/shiboken2/tests/samplebinding/modifications_test.py8
-rw-r--r--sources/shiboken2/tests/samplebinding/namespace_test.py19
-rw-r--r--sources/shiboken2/tests/samplebinding/renaming_test.py63
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml16
-rw-r--r--sources/shiboken2/tests/shiboken_test_helper.py40
-rw-r--r--sources/shiboken2/tests/smartbinding/smart_pointer_test.py16
-rw-r--r--sources/shiboken2/tests/smartbinding/typesystem_smart.xml3
-rw-r--r--sources/shiboken2/tests/test_generator/CMakeLists.txt18
-rw-r--r--tools/dump_metaobject.py155
-rw-r--r--tools/metaobject_dump.py67
-rw-r--r--tools/metaobject_dump.pyproject3
-rw-r--r--tools/missing_bindings-requirements.txt7
-rw-r--r--tools/missing_bindings.py8
300 files changed, 14632 insertions, 3208 deletions
diff --git a/build_scripts/main.py b/build_scripts/main.py
index cf56850df..99cc02185 100644
--- a/build_scripts/main.py
+++ b/build_scripts/main.py
@@ -74,10 +74,12 @@ def get_package_version():
final_version = "{}.{}.{}".format(
d['major_version'], d['minor_version'], d['patch_version'])
- pre_release_version_type = d['pre_release_version_type']
+ release_version_type = d['release_version_type']
pre_release_version = d['pre_release_version']
- if pre_release_version and pre_release_version_type:
- final_version += pre_release_version_type + pre_release_version
+ if pre_release_version and release_version_type:
+ final_version += release_version_type + pre_release_version
+ if release_version_type.startswith("comm"):
+ final_version += "." + release_version_type
# Add the current timestamp to the version number, to suggest it
# is a development snapshot build.
@@ -354,7 +356,7 @@ class PysideInstall(_install):
def run(self):
_install.run(self)
- print('*** Install completed ({}s)'.format(elapsed()))
+ print('--- Install completed ({}s)'.format(elapsed()))
class PysideDevelop(_develop):
@@ -735,7 +737,7 @@ class PysideBuild(_build):
_build.run(self)
else:
log.info("Skipped preparing and building packages.")
- print('*** Build completed ({}s)'.format(elapsed()))
+ print('--- Build completed ({}s)'.format(elapsed()))
def log_pre_build_info(self):
if config.is_internal_shiboken_generator_build_and_part_of_top_level_all():
@@ -746,16 +748,16 @@ class PysideBuild(_build):
setuptools_install_prefix = OPTION["FINAL_INSTALL_PREFIX"]
log.info("=" * 30)
log.info("Package version: {}".format(get_package_version()))
- log.info("Build type: {}".format(self.build_type))
+ log.info("Build type: {}".format(self.build_type))
log.info("Build tests: {}".format(self.build_tests))
log.info("-" * 3)
- log.info("Make path: {}".format(self.make_path))
+ log.info("Make path: {}".format(self.make_path))
log.info("Make generator: {}".format(self.make_generator))
- log.info("Make jobs: {}".format(OPTION["JOBS"]))
+ log.info("Make jobs: {}".format(OPTION["JOBS"]))
log.info("-" * 3)
- log.info("setup.py directory: {}".format(self.script_dir))
+ log.info("setup.py directory: {}".format(self.script_dir))
log.info("Build scripts directory: {}".format(build_scripts_dir))
- log.info("Sources directory: {}".format(self.sources_dir))
+ log.info("Sources directory: {}".format(self.sources_dir))
log.info(dedent("""
Building {st_package_name} will create and touch directories
in the following order:
@@ -765,9 +767,9 @@ class PysideBuild(_build):
setuptools install directory
(usually path-installed-python/lib/python*/site-packages/*)
""").format(st_package_name=config.package_name()))
- log.info("make build directory: {}".format(self.build_dir))
+ log.info("make build directory: {}".format(self.build_dir))
log.info("make install directory: {}".format(self.install_dir))
- log.info("setuptools build directory: {}".format(self.st_build_dir))
+ log.info("setuptools build directory: {}".format(self.st_build_dir))
log.info("setuptools install directory: {}".format(setuptools_install_prefix))
log.info(dedent("""
make-installed site-packages directory: {}
@@ -777,15 +779,15 @@ class PysideBuild(_build):
self.site_packages_dir))
log.info("-" * 3)
log.info("Python executable: {}".format(self.py_executable))
- log.info("Python includes: {}".format(self.py_include_dir))
- log.info("Python library: {}".format(self.py_library))
- log.info("Python prefix: {}".format(self.py_prefix))
- log.info("Python scripts: {}".format(self.py_scripts_dir))
+ log.info("Python includes: {}".format(self.py_include_dir))
+ log.info("Python library: {}".format(self.py_library))
+ log.info("Python prefix: {}".format(self.py_prefix))
+ log.info("Python scripts: {}".format(self.py_scripts_dir))
log.info("-" * 3)
- log.info("Qt qmake: {}".format(self.qtinfo.qmake_command))
+ log.info("Qt qmake: {}".format(self.qtinfo.qmake_command))
log.info("Qt version: {}".format(self.qtinfo.version))
- log.info("Qt bins: {}".format(self.qtinfo.bins_dir))
- log.info("Qt docs: {}".format(self.qtinfo.docs_dir))
+ log.info("Qt bins: {}".format(self.qtinfo.bins_dir))
+ log.info("Qt docs: {}".format(self.qtinfo.docs_dir))
log.info("Qt plugins: {}".format(self.qtinfo.plugins_dir))
log.info("-" * 3)
if sys.platform == 'win32':
@@ -1057,6 +1059,13 @@ class PysideBuild(_build):
cmake_cmd.append("-DCMAKE_OSX_DEPLOYMENT_TARGET={}".format(deployment_target))
os.environ['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
+ if OPTION["DOC_BUILD_ONLINE"]:
+ log.info("Output format will be HTML")
+ cmake_cmd.append("-DDOC_OUTPUT_FORMAT=html")
+ else:
+ log.info("Output format will be qthelp")
+ cmake_cmd.append("-DDOC_OUTPUT_FORMAT=qthelp")
+
if not OPTION["SKIP_CMAKE"]:
log.info("Configuring module {} ({})...".format(extension, module_src_dir))
if run_process(cmake_cmd) != 0:
@@ -1065,7 +1074,7 @@ class PysideBuild(_build):
log.info("Reusing old configuration for module {} ({})...".format(
extension, module_src_dir))
- log.info("Compiling module {}...".format(extension))
+ log.info("-- Compiling module {}...".format(extension))
cmd_make = [self.make_path]
if OPTION["JOBS"]:
cmd_make.append(OPTION["JOBS"])
diff --git a/build_scripts/options.py b/build_scripts/options.py
index 4229a2c10..db2a7e367 100644
--- a/build_scripts/options.py
+++ b/build_scripts/options.py
@@ -182,6 +182,8 @@ OPTION = {
# This is used automatically by distutils.command.install object, to
# specify the final installation location.
"FINAL_INSTALL_PREFIX": option_value("prefix", remove=False),
+ # This is used to identify the template for doc builds
+ "DOC_BUILD_ONLINE": has_option("doc-build-online"),
}
_deprecated_option_jobs = option_value('jobs')
if _deprecated_option_jobs:
diff --git a/build_scripts/platforms/windows_desktop.py b/build_scripts/platforms/windows_desktop.py
index 750a064b4..49c384bc7 100644
--- a/build_scripts/platforms/windows_desktop.py
+++ b/build_scripts/platforms/windows_desktop.py
@@ -251,7 +251,8 @@ def copy_msvc_redist_files(vars, redist_target_path):
"vcamp140.dll",
"vccorlib140.dll",
"vcomp140.dll",
- "vcruntime140.dll"
+ "vcruntime140.dll",
+ "vcruntime140_1.dll"
]
# Make a directory where the files should be extracted.
@@ -262,9 +263,9 @@ def copy_msvc_redist_files(vars, redist_target_path):
in_coin = os.environ.get('COIN_LAUNCH_PARAMETERS', None)
if in_coin is not None:
redist_url = "http://download.qt.io/development_releases/prebuilt/vcredist/"
- zip_file = "pyside_qt_deps_64.7z"
+ zip_file = "pyside_qt_deps_64_2019.7z"
if "{target_arch}".format(**vars) == "32":
- zip_file = "pyside_qt_deps_32.7z"
+ zip_file = "pyside_qt_deps_32_2019.7z"
download_and_extract_7z(redist_url + zip_file, redist_target_path)
else:
print("Qt dependency DLLs (MSVC redist) will not be downloaded and extracted.")
diff --git a/build_scripts/setup_runner.py b/build_scripts/setup_runner.py
index 1a7317e4d..b5b55fa20 100644
--- a/build_scripts/setup_runner.py
+++ b/build_scripts/setup_runner.py
@@ -41,6 +41,8 @@ import sys
import os
import textwrap
+import distutils.log as log
+
from build_scripts.config import config
from build_scripts.main import get_package_version, get_setuptools_extension_modules
from build_scripts.main import cmd_class_dict
@@ -49,6 +51,8 @@ from build_scripts.utils import run_process
from setuptools import setup
+if OPTION["VERBOSE_BUILD"]:
+ log.set_verbosity(1)
class SetupRunner(object):
def __init__(self, orig_argv):
@@ -148,7 +152,7 @@ class SetupRunner(object):
for cmd in self.invocations_list:
cmd_as_string = " ".join(cmd)
- print("\nRunning process: {}\n".format(cmd_as_string))
+ log.info("\nRunning setup: {}\n".format(cmd_as_string))
exit_code = run_process(cmd)
if exit_code != 0:
msg = textwrap.dedent("""
diff --git a/build_scripts/utils.py b/build_scripts/utils.py
index d1bc780dc..9f6d472cc 100644
--- a/build_scripts/utils.py
+++ b/build_scripts/utils.py
@@ -388,7 +388,7 @@ def run_process(args, initial_env=None):
No output is captured.
"""
command = " ".join([(" " in x and '"{}"'.format(x) or x) for x in args])
- log.info("Running process in directory {}: command {}".format(os.getcwd(), command))
+ log.info("In directory {}:\n\tRunning command: {}".format(os.getcwd(), command))
if initial_env is None:
initial_env = os.environ
diff --git a/coin/instructions/execute_license_check.yaml b/coin/instructions/execute_license_check.yaml
index 3a78a0aab..51027ba7d 100644
--- a/coin/instructions/execute_license_check.yaml
+++ b/coin/instructions/execute_license_check.yaml
@@ -6,7 +6,7 @@ instructions:
maxTimeInSeconds: 600
maxTimeBetweenOutput: 600
project: qt/qtbase
- ref: 5.14
+ ref: 5.15
directory: qt/qtbase
userMessageOnFailure: >
Could not install source archive. Please investigate why.
diff --git a/coin_build_instructions.py b/coin_build_instructions.py
index 5c3033b04..bfb10410c 100644
--- a/coin_build_instructions.py
+++ b/coin_build_instructions.py
@@ -95,9 +95,9 @@ def is_snapshot_build():
setup_script_dir, "sources", "pyside2", "pyside_version.py")
d = get_python_dict(pyside_version_py)
- pre_release_version_type = d['pre_release_version_type']
+ release_version_type = d['release_version_type']
pre_release_version = d['pre_release_version']
- if pre_release_version or pre_release_version_type:
+ if pre_release_version and release_version_type:
return True
return False
diff --git a/CHANGES.rst b/dist/changes-1.2.3
index 7deaa8bdd..7deaa8bdd 100644
--- a/CHANGES.rst
+++ b/dist/changes-1.2.3
diff --git a/dist/changes-5.15.0 b/dist/changes-5.15.0
new file mode 100644
index 000000000..77c8e7d27
--- /dev/null
+++ b/dist/changes-5.15.0
@@ -0,0 +1,49 @@
+Qt for Python 5.15.0 is a minor release.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+https://doc.qt.io/qtforpython/
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* PySide2 *
+****************************************************************************
+
+
+ - [PYSIDE-487] Add API of Qt 5.15
+ - [PYSIDE-487] Add support for QSerialPort
+ - [PYSIDE-487] Add QtQuickControls2
+ - [PYSIDE-841] example: add systray example
+ - [PYSIDE-841] doc: add more videos from Qt events
+ - [PYSIDE-841] doc: add tutorial for using qrc files
+ - [PYSIDE-904] libpyside: Remove deprecated API
+ - [PYSIDE-904] Add support for template type aliases
+ - [PYSIDE-957] Add a tool to dump meta objects of QObject-derived classes
+ - [PYSIDE-1280] Enable injecting raw code for setattro/getattro
+ - [PYSIDE-1309] Rename and update some snippets
+
+****************************************************************************
+* Shiboken2 *
+****************************************************************************
+
+ - [PYSIDE-454] shiboken: Add a way of specifying system includes to be parsed
+ - [PYSIDE-454] shiboken: Handle smart pointers with const pointees
+ - [PYSIDE-904] libshiboken: Remove deprecated API
+ - [PYSIDE-957] shiboken: Fix refcounts of sbkenum
+ - [PYSIDE-990] shiboken: Handle inline namespaces
+ - [PYSIDE-1024] shiboken: Make it possible to specify smartpointer instantiations
+ - [PYSIDE-1074] shiboken: Fix classes in hidden namespaces
+ - [PYSIDE-1188] shiboken: Fix shared pointer return value in virtual function
+ - [PYSIDE-1265] shiboken: Introduce a separate logging category for documentation generation
+ - [PYSIDE-1265] shiboken: Change debug messages to use qCInfo and remove some messages
+ - [PYSIDE-1267] shiboken: Allow for parsing headers under system include paths
+ - [PYSIDE-1296] shiboken: Support non-type template parameters in functions
+
diff --git a/examples/charts/charts.pyproject b/examples/charts/charts.pyproject
index a4e6c01c1..15a48a3a1 100644
--- a/examples/charts/charts.pyproject
+++ b/examples/charts/charts.pyproject
@@ -1,3 +1,5 @@
{
- "files": ["percentbarchart.py", "donutbreakdown.py", "legend.py", "nesteddonuts.py", "modeldata.py", "lineandbar.py", "memoryusage.py", "callout.py", "audio.py"]
+ "files": ["percentbarchart.py", "donutbreakdown.py", "legend.py", "nesteddonuts.py",
+ "modeldata.py", "lineandbar.py", "memoryusage.py", "callout.py", "audio.py",
+ "linechart.py", "logvalueaxis.py", "piechart.py", "temperaturerecords.py"]
}
diff --git a/examples/charts/linechart.py b/examples/charts/linechart.py
new file mode 100644
index 000000000..98d17b35c
--- /dev/null
+++ b/examples/charts/linechart.py
@@ -0,0 +1,84 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""PySide2 port of the linechart example from Qt v5.x"""
+
+import sys
+from PySide2.QtCore import QPointF
+from PySide2.QtGui import QPainter
+from PySide2.QtWidgets import QMainWindow, QApplication
+from PySide2.QtCharts import QtCharts
+
+
+class TestChart(QMainWindow):
+ def __init__(self):
+ QMainWindow.__init__(self)
+
+ self.series = QtCharts.QLineSeries()
+ self.series.append(0, 6)
+ self.series.append(2, 4)
+ self.series.append(3, 8)
+ self.series.append(7, 4)
+ self.series.append(10, 5)
+ self.series.append(QPointF(11, 1))
+ self.series.append(QPointF(13, 3))
+ self.series.append(QPointF(17, 6))
+ self.series.append(QPointF(18, 3))
+ self.series.append(QPointF(20, 2))
+
+ self.chart = QtCharts.QChart()
+ self.chart.legend().hide()
+ self.chart.addSeries(self.series)
+ self.chart.createDefaultAxes()
+ self.chart.setTitle("Simple line chart example")
+
+ self.chartView = QtCharts.QChartView(self.chart)
+ self.chartView.setRenderHint(QPainter.Antialiasing)
+
+ self.setCentralWidget(self.chartView)
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ window = TestChart()
+ window.show()
+ window.resize(440, 300)
+ sys.exit(app.exec_())
diff --git a/examples/charts/logvalueaxis.py b/examples/charts/logvalueaxis.py
new file mode 100644
index 000000000..7fb5604cd
--- /dev/null
+++ b/examples/charts/logvalueaxis.py
@@ -0,0 +1,94 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""PySide2 port of the Logarithmic Axis Example from Qt v5.x"""
+
+
+
+import sys
+from PySide2.QtCore import Qt, QPointF
+from PySide2.QtGui import QPainter
+from PySide2.QtWidgets import QMainWindow, QApplication
+from PySide2.QtCharts import QtCharts
+
+
+class TestChart(QMainWindow):
+ def __init__(self):
+ QMainWindow.__init__(self)
+
+ self.series = QtCharts.QLineSeries()
+ self.series.append([
+ QPointF(1.0, 1.0), QPointF(2.0, 73.0), QPointF(3.0, 268.0),
+ QPointF(4.0, 17.0), QPointF(5.0, 4325.0), QPointF(6.0, 723.0)])
+
+ self.chart = QtCharts.QChart()
+ self.chart.addSeries(self.series)
+ self.chart.legend().hide()
+ self.chart.setTitle("Logarithmic axis example")
+
+ self.axisX = QtCharts.QValueAxis()
+ self.axisX.setTitleText("Data point")
+ self.axisX.setLabelFormat("%i")
+ self.axisX.setTickCount(self.series.count())
+ self.chart.addAxis(self.axisX, Qt.AlignBottom)
+ self.series.attachAxis(self.axisX)
+
+ self.axisY = QtCharts.QLogValueAxis()
+ self.axisY.setTitleText("Values")
+ self.axisY.setLabelFormat("%g")
+ self.axisY.setBase(8.0)
+ self.axisY.setMinorTickCount(-1)
+ self.chart.addAxis(self.axisY, Qt.AlignLeft)
+ self.series.attachAxis(self.axisY)
+
+ self.chartView = QtCharts.QChartView(self.chart)
+ self.chartView.setRenderHint(QPainter.Antialiasing)
+
+ self.setCentralWidget(self.chartView)
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ window = TestChart()
+ window.show()
+ window.resize(800, 600)
+
+ sys.exit(app.exec_())
diff --git a/examples/charts/piechart.py b/examples/charts/piechart.py
new file mode 100644
index 000000000..820da8b91
--- /dev/null
+++ b/examples/charts/piechart.py
@@ -0,0 +1,87 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""PySide2 port of the Pie Chart Example from Qt v5.x"""
+
+import sys
+from PySide2.QtCore import Qt
+from PySide2.QtGui import QPainter, QPen
+from PySide2.QtWidgets import QMainWindow, QApplication
+from PySide2.QtCharts import QtCharts
+
+
+class TestChart(QMainWindow):
+
+ def __init__(self):
+ QMainWindow.__init__(self)
+
+ self.series = QtCharts.QPieSeries()
+
+ self.series.append('Jane', 1)
+ self.series.append('Joe', 2)
+ self.series.append('Andy', 3)
+ self.series.append('Barbara', 4)
+ self.series.append('Axel', 5)
+
+ self.slice = self.series.slices()[1]
+ self.slice.setExploded()
+ self.slice.setLabelVisible()
+ self.slice.setPen(QPen(Qt.darkGreen, 2))
+ self.slice.setBrush(Qt.green)
+
+ self.chart = QtCharts.QChart()
+ self.chart.addSeries(self.series)
+ self.chart.setTitle('Simple piechart example')
+ self.chart.legend().hide()
+
+ self.chartView = QtCharts.QChartView(self.chart)
+ self.chartView.setRenderHint(QPainter.Antialiasing)
+
+ self.setCentralWidget(self.chartView)
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ window = TestChart()
+ window.show()
+ window.resize(440, 300)
+
+ sys.exit(app.exec_())
diff --git a/examples/charts/qmlpolarchart/View1.qml b/examples/charts/qmlpolarchart/View1.qml
new file mode 100644
index 000000000..ad17fec6b
--- /dev/null
+++ b/examples/charts/qmlpolarchart/View1.qml
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtCharts 2.0
+
+Item {
+ anchors.fill: parent
+ //![1]
+ PolarChartView {
+ title: "Two Series, Common Axes"
+ anchors.fill: parent
+ legend.visible: false
+ antialiasing: true
+
+ ValueAxis {
+ id: axisAngular
+ min: 0
+ max: 20
+ tickCount: 9
+ }
+
+ ValueAxis {
+ id: axisRadial
+ min: -0.5
+ max: 1.5
+ }
+
+ SplineSeries {
+ id: series1
+ axisAngular: axisAngular
+ axisRadial: axisRadial
+ pointsVisible: true
+ }
+
+ ScatterSeries {
+ id: series2
+ axisAngular: axisAngular
+ axisRadial: axisRadial
+ markerSize: 10
+ }
+ }
+
+ // Add data dynamically to the series
+ Component.onCompleted: {
+ for (var i = 0; i <= 20; i++) {
+ series1.append(i, Math.random());
+ series2.append(i, Math.random());
+ }
+ }
+ //![1]
+}
diff --git a/examples/charts/qmlpolarchart/View2.qml b/examples/charts/qmlpolarchart/View2.qml
new file mode 100644
index 000000000..7f241c3e7
--- /dev/null
+++ b/examples/charts/qmlpolarchart/View2.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtCharts 2.0
+
+Item {
+ anchors.fill: parent
+
+ //![1]
+ PolarChartView {
+ title: "Historical Area Series"
+ anchors.fill: parent
+ legend.visible: false
+ antialiasing: true
+
+ DateTimeAxis {
+ id: axis1
+ format: "yyyy MMM"
+ tickCount: 13
+ }
+ ValueAxis {
+ id: axis2
+ }
+ LineSeries {
+ id: lowerLine
+ axisAngular: axis1
+ axisRadial: axis2
+
+ // Please note that month in JavaScript months are zero based, so 2 means March
+ XYPoint { x: toMsecsSinceEpoch(new Date(1950, 0, 1)); y: 15 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1962, 4, 1)); y: 35 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1970, 0, 1)); y: 50 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1978, 2, 1)); y: 75 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1987, 11, 1)); y: 102 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1992, 1, 1)); y: 132 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1998, 7, 1)); y: 100 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(2002, 4, 1)); y: 120 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(2012, 8, 1)); y: 140 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(2013, 5, 1)); y: 150 }
+ }
+ LineSeries {
+ id: upperLine
+ axisAngular: axis1
+ axisRadial: axis2
+
+ // Please note that month in JavaScript months are zero based, so 2 means March
+ XYPoint { x: toMsecsSinceEpoch(new Date(1950, 0, 1)); y: 30 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1962, 4, 1)); y: 55 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1970, 0, 1)); y: 80 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1978, 2, 1)); y: 105 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1987, 11, 1)); y: 125 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1992, 1, 1)); y: 160 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(1998, 7, 1)); y: 140 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(2002, 4, 1)); y: 140 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(2012, 8, 1)); y: 170 }
+ XYPoint { x: toMsecsSinceEpoch(new Date(2013, 5, 1)); y: 200 }
+ }
+ AreaSeries {
+ axisAngular: axis1
+ axisRadial: axis2
+ lowerSeries: lowerLine
+ upperSeries: upperLine
+ }
+ }
+ // DateTimeAxis is based on QDateTimes so we must convert our JavaScript dates to
+ // milliseconds since epoch to make them match the DateTimeAxis values
+ function toMsecsSinceEpoch(date) {
+ var msecs = date.getTime();
+ return msecs;
+ }
+ //![1]
+}
diff --git a/examples/charts/qmlpolarchart/View3.qml b/examples/charts/qmlpolarchart/View3.qml
new file mode 100644
index 000000000..5695a891f
--- /dev/null
+++ b/examples/charts/qmlpolarchart/View3.qml
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtCharts 2.0
+
+Item {
+ anchors.fill: parent
+
+ //![1]
+ PolarChartView {
+ title: "Numerical Data for Dummies"
+ anchors.fill: parent
+ legend.visible: false
+ antialiasing: true
+
+ LineSeries {
+ axisRadial: CategoryAxis {
+ min: 0
+ max: 30
+ CategoryRange {
+ label: "critical"
+ endValue: 2
+ }
+ CategoryRange {
+ label: "low"
+ endValue: 7
+ }
+ CategoryRange {
+ label: "normal"
+ endValue: 12
+ }
+ CategoryRange {
+ label: "high"
+ endValue: 18
+ }
+ CategoryRange {
+ label: "extremely high"
+ endValue: 30
+ }
+ }
+
+ axisAngular: ValueAxis {
+ tickCount: 13
+ }
+
+ XYPoint { x: 0; y: 4.3 }
+ XYPoint { x: 1; y: 4.1 }
+ XYPoint { x: 2; y: 4.7 }
+ XYPoint { x: 3; y: 3.9 }
+ XYPoint { x: 4; y: 5.2 }
+ XYPoint { x: 5; y: 5.3 }
+ XYPoint { x: 6; y: 6.1 }
+ XYPoint { x: 7; y: 7.7 }
+ XYPoint { x: 8; y: 12.9 }
+ XYPoint { x: 9; y: 19.2 }
+ }
+ }
+ //![1]
+}
diff --git a/examples/charts/qmlpolarchart/main.qml b/examples/charts/qmlpolarchart/main.qml
new file mode 100644
index 000000000..ed7a810c6
--- /dev/null
+++ b/examples/charts/qmlpolarchart/main.qml
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ width: 800
+ height: 600
+ property bool sourceLoaded: false
+
+ ListView {
+ id: root
+ focus: true
+ anchors.fill: parent
+ snapMode: ListView.SnapOneItem
+ highlightRangeMode: ListView.StrictlyEnforceRange
+ highlightMoveDuration: 250
+ orientation: ListView.Horizontal
+ boundsBehavior: Flickable.StopAtBounds
+
+ onCurrentIndexChanged: {
+ if (infoText.opacity > 0.0) {
+ if (sourceLoaded)
+ infoText.opacity = 0.0;
+ else if (currentIndex != 0)
+ currentIndex = 0;
+ }
+ }
+
+ model: ListModel {
+ ListElement {component: "View1.qml"}
+ ListElement {component: "View2.qml"}
+ ListElement {component: "View3.qml"}
+ }
+
+ delegate: Loader {
+ width: root.width
+ height: root.height
+
+ source: component
+ asynchronous: true
+
+ onLoaded: sourceLoaded = true
+ }
+ }
+
+ Rectangle {
+ id: infoText
+ anchors.centerIn: parent
+ width: parent.width
+ height: 40
+ color: "black"
+ Text {
+ color: "white"
+ anchors.centerIn: parent
+ text: "You can navigate between views using swipe or arrow keys"
+ }
+
+ Behavior on opacity {
+ NumberAnimation { duration: 400 }
+ }
+ }
+}
diff --git a/examples/charts/qmlpolarchart/qmlpolarchart.py b/examples/charts/qmlpolarchart/qmlpolarchart.py
new file mode 100644
index 000000000..4398169b0
--- /dev/null
+++ b/examples/charts/qmlpolarchart/qmlpolarchart.py
@@ -0,0 +1,63 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""PySide2 port of the QML Polar Chart Example from Qt v5.x"""
+
+import sys
+import os
+from PySide2.QtQuick import QQuickView
+from PySide2.QtCore import Qt, QUrl
+from PySide2.QtWidgets import QApplication, QMainWindow
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ viewer = QQuickView()
+
+ viewer.engine().addImportPath(os.path.dirname(__file__))
+ viewer.engine().quit.connect(viewer.close)
+
+ viewer.setTitle = "QML Polar Chart"
+ qmlFile = os.path.join(os.path.dirname(__file__), 'main.qml')
+ viewer.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile)))
+ viewer.setResizeMode(QQuickView.SizeRootObjectToView)
+ viewer.show()
+
+ sys.exit(app.exec_())
diff --git a/examples/charts/qmlpolarchart/qmlpolarchart.pyproject b/examples/charts/qmlpolarchart/qmlpolarchart.pyproject
new file mode 100644
index 000000000..6c18b1f43
--- /dev/null
+++ b/examples/charts/qmlpolarchart/qmlpolarchart.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["View1.qml", "View1.qml", "View2.qml", "View3.qml", "main.qml", "qmlpolarchart.py"]
+}
diff --git a/examples/charts/temperaturerecords.py b/examples/charts/temperaturerecords.py
new file mode 100644
index 000000000..dfd4dd67c
--- /dev/null
+++ b/examples/charts/temperaturerecords.py
@@ -0,0 +1,95 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""PySide2 port of the Temperature Records example from Qt v5.x"""
+
+import sys
+from PySide2.QtCore import Qt
+from PySide2.QtGui import QPainter
+from PySide2.QtWidgets import QMainWindow, QApplication
+from PySide2.QtCharts import QtCharts
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ QMainWindow.__init__(self)
+ low = QtCharts.QBarSet("Min")
+ high = QtCharts.QBarSet("Max")
+ low.append([-52, -50, -45.3, -37.0, -25.6, -8.0,
+ -6.0, -11.8, -19.7, -32.8, -43.0, -48.0])
+ high.append([11.9, 12.8, 18.5, 26.5, 32.0, 34.8,
+ 38.2, 34.8, 29.8, 20.4, 15.1, 11.8])
+
+ series = QtCharts.QStackedBarSeries()
+ series.append(low)
+ series.append(high)
+
+ chart = QtCharts.QChart()
+ chart.addSeries(series)
+ chart.setTitle("Temperature records in celcius")
+ chart.setAnimationOptions(QtCharts.QChart.SeriesAnimations)
+
+ categories = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
+ "Aug", "Sep", "Oct", "Nov", "Dec"]
+ axisX = QtCharts.QBarCategoryAxis()
+ axisX.append(categories)
+ axisX.setTitleText("Month")
+ chart.addAxis(axisX, Qt.AlignBottom)
+ axisY = QtCharts.QValueAxis()
+ axisY.setRange(-52, 52)
+ axisY.setTitleText("Temperature [&deg;C]")
+ chart.addAxis(axisY, Qt.AlignLeft)
+ series.attachAxis(axisX)
+ series.attachAxis(axisY)
+
+ chart.legend().setVisible(True)
+ chart.legend().setAlignment(Qt.AlignBottom)
+
+ chart_view = QtCharts.QChartView(chart)
+ chart_view.setRenderHint(QPainter.Antialiasing)
+
+ self.setCentralWidget(chart_view)
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ w = MainWindow()
+ w.resize(600, 300)
+ w.show()
+ sys.exit(app.exec_())
diff --git a/examples/declarative/textproperties/main.py b/examples/declarative/textproperties/main.py
index 8da443edc..2f9b987d0 100644
--- a/examples/declarative/textproperties/main.py
+++ b/examples/declarative/textproperties/main.py
@@ -44,6 +44,7 @@ from os.path import abspath, dirname, join
from PySide2.QtCore import QObject, Slot
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
+from PySide2.QtQuickControls2 import QQuickStyle
class Bridge(QObject):
@@ -90,8 +91,8 @@ class Bridge(QObject):
if __name__ == '__main__':
- sys.argv += ['--style', 'material']
app = QGuiApplication(sys.argv)
+ QQuickStyle.setStyle("Material")
engine = QQmlApplicationEngine()
# Instance of the Python object
diff --git a/examples/scriptableapplication/mainwindow.cpp b/examples/scriptableapplication/mainwindow.cpp
index 15504cb6e..ef4a2f2e0 100644
--- a/examples/scriptableapplication/mainwindow.cpp
+++ b/examples/scriptableapplication/mainwindow.cpp
@@ -114,7 +114,7 @@ MainWindow::MainWindow()
void MainWindow::slotRunScript()
{
- const QStringList script = m_scriptEdit->toPlainText().trimmed().split(QLatin1Char('\n'), QString::SkipEmptyParts);
+ const QStringList script = m_scriptEdit->toPlainText().trimmed().split(QLatin1Char('\n'), Qt::SkipEmptyParts);
if (!script.isEmpty())
runScript(script);
}
diff --git a/examples/widgets/gallery/gallery.pyproject b/examples/widgets/gallery/gallery.pyproject
new file mode 100644
index 000000000..635e123b0
--- /dev/null
+++ b/examples/widgets/gallery/gallery.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "widgetgallery.py"]
+}
diff --git a/examples/widgets/gallery/main.py b/examples/widgets/gallery/main.py
new file mode 100644
index 000000000..11f19201b
--- /dev/null
+++ b/examples/widgets/gallery/main.py
@@ -0,0 +1,56 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""PySide2 port of the widgets/gallery example from Qt v5.15"""
+
+import sys
+
+from PySide2.QtCore import QCoreApplication, Qt
+from PySide2.QtWidgets import QApplication
+from widgetgallery import WidgetGallery
+
+
+if __name__ == '__main__':
+ QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
+ QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
+ app = QApplication()
+ gallery = WidgetGallery()
+ gallery.show()
+ sys.exit(app.exec_())
diff --git a/examples/widgets/gallery/widgetgallery.py b/examples/widgets/gallery/widgetgallery.py
new file mode 100644
index 000000000..a06ac2e20
--- /dev/null
+++ b/examples/widgets/gallery/widgetgallery.py
@@ -0,0 +1,429 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+
+from PySide2.QtWidgets import *
+from PySide2.QtGui import (QCursor, QDesktopServices, QGuiApplication, QIcon,
+ QKeySequence, QStandardItem, QStandardItemModel,
+ QScreen, QWindow)
+from PySide2.QtCore import (QDateTime, QDir, QLibraryInfo, QMetaObject,
+ QSysInfo, QTextStream, QTimer, Qt, qVersion)
+
+
+POEM = """Twinkle, twinkle, little star,
+How I wonder what you are.
+Up above the world so high,
+Like a diamond in the sky.
+Twinkle, twinkle, little star,
+How I wonder what you arenot"""
+
+DIR_OPEN_ICON = ":/qt-project.org/styles/commonstyle/images/diropen-128.png"
+
+COMPUTER_ICON = ":/qt-project.org/styles/commonstyle/images/computer-32.png"
+
+SYSTEMINFO = """<html><head/><body>
+<h3>Python</h3><p>{}</p>
+<h3>Qt Build</h3><p>{}</p>
+<h3>Operating System</h3><p>{}</p>
+<h3>Screens</h3>
+{}
+</body></html>"""
+
+
+def class_name(o):
+ return o.metaObject().className()
+
+
+def help_url(page):
+ """Build a Qt help URL from the page name"""
+ major_version = qVersion().split('.')[0]
+ return "https://doc.qt.io/qt-{}/{}.html".format(major_version, page)
+
+
+def launch_help(widget):
+ """Launch a widget's help page"""
+ url = help_url(class_name(widget).lower())
+ QDesktopServices.openUrl(url)
+
+
+def launch_module_help():
+ QDesktopServices.openUrl(help_url("qtwidgets-index"))
+
+
+def init_widget(w, name):
+ """Init a widget for the gallery, give it a tooltip showing the
+ class name"""
+ w.setObjectName(name)
+ w.setToolTip(class_name(w))
+
+
+def style_names():
+ """Return a list of styles, default platform style first"""
+ default_style_name = QApplication.style().objectName().lower()
+ result = []
+ for style in QStyleFactory.keys():
+ if style.lower() == default_style_name:
+ result.insert(0, style)
+ else:
+ result.append(style)
+ return result
+
+
+def embed_into_hbox_layout(w, margin=5):
+ """Embed a widget into a layout to give it a frame"""
+ result = QWidget()
+ layout = QHBoxLayout(result)
+ layout.setContentsMargins(margin, margin, margin, margin)
+ layout.addWidget(w)
+ return result
+
+
+def format_geometry(rect):
+ """Format a geometry as a X11 geometry specification"""
+ return "{}x{}{:+d}{:+d}".format(rect.width(), rect.height(),
+ rect.x(), rect.y())
+
+
+def screen_info(widget):
+ """Format information on the screens"""
+ policy = QGuiApplication.highDpiScaleFactorRoundingPolicy()
+ policy_string = str(policy).split('.')[-1]
+ result = "<p>High DPI scale factor rounding policy: {}</p><ol>".format(policy_string)
+ for screen in QGuiApplication.screens():
+ current = screen == widget.screen()
+ result += "<li>"
+ if current:
+ result += "<i>"
+ result += '"{}" {} {}DPI, DPR={}'.format(screen.name(),
+ format_geometry(screen.geometry()),
+ int(screen.logicalDotsPerInchX()),
+ screen.devicePixelRatio())
+ if current:
+ result += "</i>"
+ result += "</li>"
+ result += "</ol>"
+ return result
+
+
+class WidgetGallery(QDialog):
+ """Dialog displaying a gallery of Qt Widgets"""
+
+ def __init__(self):
+ super(WidgetGallery, self).__init__()
+
+ self._progress_bar = self.create_progress_bar()
+
+ self._style_combobox = QComboBox()
+ init_widget(self._style_combobox, "styleComboBox")
+ self._style_combobox.addItems(style_names())
+
+ style_label = QLabel("Style:")
+ init_widget(style_label, "style_label")
+ style_label.setBuddy(self._style_combobox)
+
+ help_label = QLabel("Press F1 over a widget to see Documentation")
+ init_widget(help_label, "help_label")
+
+ disable_widgets_checkbox = QCheckBox("Disable widgets")
+ init_widget(disable_widgets_checkbox, "disable_widgets_checkbox")
+
+ buttons_groupbox = self.create_buttons_groupbox()
+ itemview_tabwidget = self.create_itemview_tabwidget()
+ simple_input_widgets_groupbox = self.create_simple_inputwidgets_groupbox()
+ text_toolbox = self.create_text_toolbox()
+
+ self._style_combobox.textActivated.connect(self.change_style)
+ disable_widgets_checkbox.toggled.connect(buttons_groupbox.setDisabled)
+ disable_widgets_checkbox.toggled.connect(text_toolbox.setDisabled)
+ disable_widgets_checkbox.toggled.connect(itemview_tabwidget.setDisabled)
+ disable_widgets_checkbox.toggled.connect(simple_input_widgets_groupbox.setDisabled)
+
+ help_shortcut = QShortcut(self)
+ help_shortcut.setKey(QKeySequence.HelpContents)
+ help_shortcut.activated.connect(self.help_on_current_widget)
+
+ top_layout = QHBoxLayout()
+ top_layout.addWidget(style_label)
+ top_layout.addWidget(self._style_combobox)
+ top_layout.addStretch(1)
+ top_layout.addWidget(help_label)
+ top_layout.addStretch(1)
+ top_layout.addWidget(disable_widgets_checkbox)
+
+ dialog_buttonbox = QDialogButtonBox(QDialogButtonBox.Help |
+ QDialogButtonBox.Close)
+ init_widget(dialog_buttonbox, "dialogButtonBox")
+ dialog_buttonbox.helpRequested.connect(launch_module_help)
+ dialog_buttonbox.rejected.connect(self.reject)
+
+ main_layout = QGridLayout(self)
+ main_layout.addLayout(top_layout, 0, 0, 1, 2)
+ main_layout.addWidget(buttons_groupbox, 1, 0)
+ main_layout.addWidget(simple_input_widgets_groupbox, 1, 1)
+ main_layout.addWidget(itemview_tabwidget, 2, 0)
+ main_layout.addWidget(text_toolbox, 2, 1)
+ main_layout.addWidget(self._progress_bar, 3, 0, 1, 2)
+ main_layout.addWidget(dialog_buttonbox, 4, 0, 1, 2)
+
+ self.setWindowTitle("Widget Gallery Qt {}".format(qVersion()))
+
+ def setVisible(self, visible):
+ super(WidgetGallery, self).setVisible(visible)
+ if visible:
+ self.windowHandle().screenChanged.connect(self.update_systeminfo)
+ self.update_systeminfo()
+
+ def change_style(self, style_name):
+ QApplication.setStyle(QStyleFactory.create(style_name))
+
+ def advance_progressbar(self):
+ cur_val = self._progress_bar.value()
+ max_val = self._progress_bar.maximum()
+ self._progress_bar.setValue(cur_val + (max_val - cur_val) / 100)
+
+ def create_buttons_groupbox(self):
+ result = QGroupBox("Buttons")
+ init_widget(result, "buttons_groupbox")
+
+ default_pushbutton = QPushButton("Default Push Button")
+ init_widget(default_pushbutton, "default_pushbutton")
+ default_pushbutton.setDefault(True)
+
+ toggle_pushbutton = QPushButton("Toggle Push Button")
+ init_widget(toggle_pushbutton, "toggle_pushbutton")
+ toggle_pushbutton.setCheckable(True)
+ toggle_pushbutton.setChecked(True)
+
+ flat_pushbutton = QPushButton("Flat Push Button")
+ init_widget(flat_pushbutton, "flat_pushbutton")
+ flat_pushbutton.setFlat(True)
+
+ toolbutton = QToolButton()
+ init_widget(toolbutton, "toolButton")
+ toolbutton.setText("Tool Button")
+
+ menu_toolbutton = QToolButton()
+ init_widget(menu_toolbutton, "menuButton")
+ menu_toolbutton.setText("Menu Button")
+ tool_menu = QMenu(menu_toolbutton)
+ menu_toolbutton.setPopupMode(QToolButton.InstantPopup)
+ tool_menu.addAction("Option")
+ tool_menu.addSeparator()
+ action = tool_menu.addAction("Checkable Option")
+ action.setCheckable(True)
+ menu_toolbutton.setMenu(tool_menu)
+ tool_layout = QHBoxLayout()
+ tool_layout.addWidget(toolbutton)
+ tool_layout.addWidget(menu_toolbutton)
+
+ commandlinkbutton = QCommandLinkButton("Command Link Button")
+ init_widget(commandlinkbutton, "commandLinkButton")
+ commandlinkbutton.setDescription("Description")
+
+ button_layout = QVBoxLayout()
+ button_layout.addWidget(default_pushbutton)
+ button_layout.addWidget(toggle_pushbutton)
+ button_layout.addWidget(flat_pushbutton)
+ button_layout.addLayout(tool_layout)
+ button_layout.addWidget(commandlinkbutton)
+ button_layout.addStretch(1)
+
+ radiobutton_1 = QRadioButton("Radio button 1")
+ init_widget(radiobutton_1, "radioButton1")
+ radiobutton_2 = QRadioButton("Radio button 2")
+ init_widget(radiobutton_2, "radioButton2")
+ radiobutton_3 = QRadioButton("Radio button 3")
+ init_widget(radiobutton_3, "radioButton3")
+ radiobutton_1.setChecked(True)
+
+ checkbox = QCheckBox("Tri-state check box")
+ init_widget(checkbox, "checkBox")
+ checkbox.setTristate(True)
+ checkbox.setCheckState(Qt.PartiallyChecked)
+
+ checkableLayout = QVBoxLayout()
+ checkableLayout.addWidget(radiobutton_1)
+ checkableLayout.addWidget(radiobutton_2)
+ checkableLayout.addWidget(radiobutton_3)
+ checkableLayout.addWidget(checkbox)
+ checkableLayout.addStretch(1)
+
+ main_layout = QHBoxLayout(result)
+ main_layout.addLayout(button_layout)
+ main_layout.addLayout(checkableLayout)
+ main_layout.addStretch()
+ return result
+
+ def create_text_toolbox(self):
+ result = QToolBox()
+ init_widget(result, "toolBox")
+
+ # Create centered/italic HTML rich text
+ rich_text = "<html><head/><body><i>"
+ for line in POEM.split('\n'):
+ rich_text += "<center>" + line + "</center>"
+ rich_text += "</i></body></html>"
+
+ text_edit = QTextEdit(rich_text)
+ init_widget(text_edit, "textEdit")
+ plain_textedit = QPlainTextEdit(POEM)
+ init_widget(plain_textedit, "plainTextEdit")
+
+ self._systeminfo_textbrowser = QTextBrowser()
+ init_widget(self._systeminfo_textbrowser, "systemInfoTextBrowser")
+
+ result.addItem(embed_into_hbox_layout(text_edit), "Text Edit")
+ result.addItem(embed_into_hbox_layout(plain_textedit),
+ "Plain Text Edit")
+ result.addItem(embed_into_hbox_layout(self._systeminfo_textbrowser),
+ "Text Browser")
+ return result
+
+ def create_itemview_tabwidget(self):
+ result = QTabWidget()
+ init_widget(result, "bottomLeftTabWidget")
+ result.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Ignored)
+
+ tree_view = QTreeView()
+ init_widget(tree_view, "treeView")
+ filesystem_model = QFileSystemModel(tree_view)
+ filesystem_model.setRootPath(QDir.rootPath())
+ tree_view.setModel(filesystem_model)
+
+ table_widget = QTableWidget()
+ init_widget(table_widget, "tableWidget")
+ table_widget.setRowCount(10)
+ table_widget.setColumnCount(10)
+
+ list_model = QStandardItemModel(0, 1, result)
+
+ list_model.appendRow(QStandardItem(QIcon(DIR_OPEN_ICON), "Directory"))
+ list_model.appendRow(QStandardItem(QIcon(COMPUTER_ICON), "Computer"))
+
+ list_view = QListView()
+ init_widget(list_view, "listView")
+ list_view.setModel(list_model)
+
+ icon_mode_listview = QListView()
+ init_widget(icon_mode_listview, "iconModeListView")
+
+ icon_mode_listview.setViewMode(QListView.IconMode)
+ icon_mode_listview.setModel(list_model)
+
+ result.addTab(embed_into_hbox_layout(tree_view), "Tree View")
+ result.addTab(embed_into_hbox_layout(table_widget), "Table")
+ result.addTab(embed_into_hbox_layout(list_view), "List")
+ result.addTab(embed_into_hbox_layout(icon_mode_listview),
+ "Icon Mode List")
+ return result
+
+ def create_simple_inputwidgets_groupbox(self):
+ result = QGroupBox("Simple Input Widgets")
+ init_widget(result, "bottomRightGroupBox")
+ result.setCheckable(True)
+ result.setChecked(True)
+
+ lineedit = QLineEdit("s3cRe7")
+ init_widget(lineedit, "lineEdit")
+ lineedit.setClearButtonEnabled(True)
+ lineedit.setEchoMode(QLineEdit.Password)
+
+ spin_box = QSpinBox()
+ init_widget(spin_box, "spinBox")
+ spin_box.setValue(50)
+
+ date_timeedit = QDateTimeEdit()
+ init_widget(date_timeedit, "dateTimeEdit")
+ date_timeedit.setDateTime(QDateTime.currentDateTime())
+
+ slider = QSlider()
+ init_widget(slider, "slider")
+ slider.setOrientation(Qt.Horizontal)
+ slider.setValue(40)
+
+ scrollbar = QScrollBar()
+ init_widget(scrollbar, "scrollBar")
+ scrollbar.setOrientation(Qt.Horizontal)
+ scrollbar.setValue(60)
+
+ dial = QDial()
+ init_widget(dial, "dial")
+ dial.setValue(30)
+ dial.setNotchesVisible(True)
+
+ layout = QGridLayout(result)
+ layout.addWidget(lineedit, 0, 0, 1, 2)
+ layout.addWidget(spin_box, 1, 0, 1, 2)
+ layout.addWidget(date_timeedit, 2, 0, 1, 2)
+ layout.addWidget(slider, 3, 0)
+ layout.addWidget(scrollbar, 4, 0)
+ layout.addWidget(dial, 3, 1, 2, 1)
+ layout.setRowStretch(5, 1)
+ return result
+
+ def create_progress_bar(self):
+ result = QProgressBar()
+ init_widget(result, "progressBar")
+ result.setRange(0, 10000)
+ result.setValue(0)
+
+ timer = QTimer(self)
+ timer.timeout.connect(self.advance_progressbar)
+ timer.start(1000)
+ return result
+
+ def update_systeminfo(self):
+ """Display system information"""
+ system_info = SYSTEMINFO.format(sys.version,
+ QLibraryInfo.build(),
+ QSysInfo.prettyProductName(),
+ screen_info(self))
+ self._systeminfo_textbrowser.setHtml(system_info)
+
+ def help_on_current_widget(self):
+ """Display help on widget under mouse"""
+ w = QApplication.widgetAt(QCursor.pos(self.screen()))
+ while w: # Skip over internal widgets
+ name = w.objectName()
+ if name and not name.startswith("qt_"):
+ launch_help(w)
+ break
+ w = w.parentWidget()
diff --git a/examples/widgets/systray/images/bad.png b/examples/widgets/systray/images/bad.png
new file mode 100644
index 000000000..c8701a241
--- /dev/null
+++ b/examples/widgets/systray/images/bad.png
Binary files differ
diff --git a/examples/widgets/systray/images/heart.png b/examples/widgets/systray/images/heart.png
new file mode 100644
index 000000000..cee1302b7
--- /dev/null
+++ b/examples/widgets/systray/images/heart.png
Binary files differ
diff --git a/examples/widgets/systray/images/trash.png b/examples/widgets/systray/images/trash.png
new file mode 100644
index 000000000..4c24db926
--- /dev/null
+++ b/examples/widgets/systray/images/trash.png
Binary files differ
diff --git a/examples/widgets/systray/main.py b/examples/widgets/systray/main.py
new file mode 100644
index 000000000..4fad002a6
--- /dev/null
+++ b/examples/widgets/systray/main.py
@@ -0,0 +1,58 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+
+from PySide2.QtWidgets import QApplication, QMessageBox, QSystemTrayIcon
+
+from window import Window
+
+if __name__ == "__main__":
+ app = QApplication()
+
+ if not QSystemTrayIcon.isSystemTrayAvailable():
+ QMessageBox.critical(None, "Systray", "I couldn't detect any system tray on this system.")
+ sys.exit(1)
+
+ QApplication.setQuitOnLastWindowClosed(False)
+
+ window = Window()
+ window.show()
+ sys.exit(app.exec_())
diff --git a/examples/widgets/systray/rc_systray.py b/examples/widgets/systray/rc_systray.py
new file mode 100644
index 000000000..2d59adc74
--- /dev/null
+++ b/examples/widgets/systray/rc_systray.py
@@ -0,0 +1,2581 @@
+# Resource object code (Python 3)
+# Created by: object code
+# Created by: The Resource Compiler for Qt version 5.15.0
+# WARNING! All changes made in this file will be lost!
+
+from PySide2 import QtCore
+
+qt_resource_data = b"\
+\x00\x00d\xb4\
+\x89\
+PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
+\x00\x02\xe8\x00\x00\x02\xe8\x08\x06\x00\x00\x00*Z\x00\x90\
+\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
+\x09pHYs\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01B(\
+\x9bx\x00\x00\x00\x07tIME\x07\xdc\x03\x09\x08\x1e\
+4hf\xd9|\x00\x00\x00\x06bKGD\x00\xff\x00\
+\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00d4IDATx\
+\xda\xec\x9d\x07\xb8U\xc5\xb9\xbf\xf7i\x1c\x0e\xe7\xd0\xcb\
+\x01Tz\x95\xa6 \xbd\x8b\x14E@\x10Q\x14\xa4\x05\
+\x14\x14\x14AAD\xaaT\xe9\xe7h\xd4\xab&\xc6$\
+\xb6\xc4DM\xa2&\x1a{\x895\xb1w\x05\xd9k\xa7\
+\xdc\x14M\x8c\xc66\xf7\x1b\xf6J\x82W\x84\xb5\xf6\xd9\
+k\xd6\xac\xb5\xdf\xf7y\xde\xe7\xb9\xf7\x7f\xff\xf7F\xcf\
+\x9e\xf9\xe6\xb7g\xcf|\x93H\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00@.Q(\xd6um\x22\xb6\x12;\x8a=\xc4\
+>\xe2q\xe2(\xf1x\xf7\xbf\xd6\xf6u\xff\xe7\xda\xa3\
+\xdc\xff\x9dz\xee\xff-\x00\x80\xaaRM\xac\xef\xd6\x96\
+\xee\xfb\xd5\x9b~\xfb\xd5\xa1\xd1\xe2\x08\xf7\xbf\xee\xed\xfe\
+\xcf\xdb\xbb\xff;\x8d\xf7\xabk\xf9\xfc9\x01\x00\xc0\x06\
+j\x8a\xdd\xc4\x93\xc4\x05\xe2*\xb1B\xfc\x81x\x8f\xf8\
+\x94\xf8\x8e\xf8\x81\xa8\xb2\xec?\xc5\xdf\x8bo\x8a\x0f\x8a\
+7\x89;\xc5\xe5\xe2,q\x8c\xbb\x90\xd6\xe3c\x02\xc8\
+)\x1a\x89\xbd\xc4\xb1\xe2\x1cq\x85[\x97n\x13\x1f\x16\
+\xdf\x12\xff(~\x1c@]\xfa\x8b[\x93~#\xfeB\
+\xfc\xbe[\x97V\x8a\xe7\xbau\xa9\x93X\x83\x8f\x09\x00\
+\x00\xaaB\xb3Dz\xf7h\xb6\xb8^\xbc\xd9]|\xfe\
+\x14\xc0\xe2\x16\x94\x1f\x8a/\x88w\x8a\xbb\xc4\x0b\xc4\x13\
+\xc4\xe6|\xbc\x00\x91C\xefT\xb7\x16\xc7\x89\x17\x8aW\
+\x88?\x17_\x16?\x8aP]J\x89\x8f\xbb\x1b\x1ak\
+\xc5\x99\xe2\xb1\x89\xf4/\x8c\x00\x00\x00\xfb\xa8\x9eH\xef\
+8\xebEB\xef\xf8<\x90H\xef\x06\xa9\x98\xfb\x81\xbb\
+H^\x93H\xff\x0a\xa0\x7f\xc6\xae\xc3p\x00\xb0\x82\x86\
+\x89\xf4\xd1\xb7E\xe2\xf5\x89\xf4\xafr\xff\xc8\x81\xba\xa4\
+w\xf8\x7f%^.N\x15\xbb\x8aE\x0c\x07\x00\x80x\
+\x93\x97H\xff\xcc\xaaw\xc5\xbf#\xbe$~\x96\x03\x8b\
+\x9eW\xbf\x14_\x17otC\xbb>\x0b_\xca\xb0\x01\
+\x08\x94Z\xe2 q\xb1x\x8b\xf8.\xb5\xe8+\xfeK\
+|\xde\xddL\x98&\xb6e\xc8\x00\x00D\x1b}\x09J\
+\x9f}\xdc(>\x9a#;PA\xf8\xb6x\xb5x\xa6\
+x\x04\xc3\x0a\xa0J\xb4H\xa4\xcf\x88\x7f\xcf\x9d[\xd4\
+\x18\xff\xfe\xdd\xad\xe9\x1b\xdd\x1a\xcf\xaf\x7f\x00\x00\x16\xa3\
+;\x13\xe8\xb3\x8c\x9b\xc5\xa7\x13\xec\x8e\x07\xe1\xe7\xe2\xb3\
+\x89\xf4O\xd0\xfaXLu\x86\x1d\xc0A)sC\xa4\
+\xbe\xb0\xa9\x7f\xb5\xfb\x92:\x92u?\x11\x1fK\xa4\xcf\
+\xb4\xeb_\xfe\x0a\x18v\x00\x00\xe1\xa2\xcf\x8f/I\xa4\
+\xcf-\x06\xd1\x9d\x00\x0f\x1d\xd8\x9fqw\xb2t`\xa7\
+\x15$\xb0Q\x90\x9e\x0b\x1b\xdd\xb9\xf1\x05u\xc2\xb8\x1f\
+\xb9k\xc2y\x09.\xc5\x03\x00\x18A\x9f#\xd7\xad\xc4\
+6\x89/\xb2\x10Y\xe7\x1eq\x878 A\x7fd\xc8\
+\x1d\x0a\xddP~U\x22\xdd\x06\x95Z`\x8f_\xb8_\
+\x94V\x8b]\x18\xaa\x00\x00\xd9\xe5\x98D\xfa\xe8\x0a\x17\
+\xa8\xa2\xa3#V\x8aC\x13\xfc\xe4\x0c\xf1C\xef\x94\xeb\
+\x07\xc6\xae\x15\xff\x97\xf9\x1e\x19_u\xc3z'\x860\
+\x00@f\xe8\x17\xee\xf4\xcf\xc4\x5c\xa4\x8aG\xfb4\x1d\
+\xd6\xf5\xf9\xd0<\x866D\x14\xfd\xab\xd0\xb0D\xba\xf5\
+\xe1\xdf\x98\xd7\x91W\xf7\x90\xd7\x8f)udh\x03\x00\
+\x1c\x9c\x96\x89\xf4E\x9f7Y<b\xab~\xd1pM\
+\x22\xfdl8@\x148J\xdc\x22\xeee\xfe\xc6V}\
+d\xf2\xe2\x04\x0f&\x01\x00\xfc\x07\xfd\x10\xc5\xc9\xe2=\
+\x09.T\xe5\x9a\x0f\x89\x93\xc5b\xa6\x01X\x86~\x03\
+@?`\xf64\xf34\xa7\xd4\xdd\xbfnO\xa4\x8f/\
+q\x8f\x06\x00r\x12\xfdl\xf5\x86D\xfa\xe9g\x16\x86\
+\xdc\xf6O\x89t\xeb\xc6vL\x0b\x08\x99n\xe2\x15\x09\
+\x8e\xb0`\x22\xf1\x9ex\xa9x\x18\xd3\x02\x00\xe2\x8e>\
+\x7f<R\xfce\x82\xddr<\xf0k\xa6\xf7\x8b'\xb2\
+{\x05\x06\xd1]XN\x13\x9fd\x0eb\xe2\xc0\xbb\xea\
+?\x15\x072U\x00 n\xe8\x07m\xbe\x95H?\xd4\
+A\xc1G/\xea{\x08\x0b\xc4\x9aL\x1f\x08\x88\xda\xe2\
+bq7\xf3\x0d=\xaa\x8f<\xe9cyEL\x1f\x00\
+\x882\x8d\xc4U\xe2\x1f(\xec\x98\xa1\x1f$\xd2\xbd\xd5\
+[3\x9d K\xe8\xcb\xe8\xdb\xc5\x0f\x99_\x98\xa1\xfa\
+\xcd\x87\x0b\xc5:L'\x00\x88\x12\xba\xc7\xec\xff$x\
+\xdd\x13\xb3\xfb3\xf3\xf7\x12\x9cS\x87\xcc\xd1\xddX\xf4\
+\x05\xc0/\x99O\x98%\xf5\x97\xbc\x9db+\xa6\x17\x00\
+\xd8\x1e\xccoc\x01\xc4\x00\xfd\x5c\xfc~\x82\xde\xc5\xe0\
+\x9d\x1e\xe2\x1d\xd4%\x0cx\x03A\xf7\xc7o\xc1t\x03\
+\x00\x9bh\xeb\x86&.~\xa2\xc9'\xbco\x22\xa8\xc3\
+A\xe8%\xfe\x8c\xb9\x82\x06\xfd\x97\xf8m\xf1p\xa6\x1f\
+\x00\x84\x89\xde-\xb8\xce\xdd=\xa08cX;\xea\xdf\
+\x11\x9b1\x1d\xc1E\x7fi\xe3(\x0b\x86\xa9>\xde\xa9\
+\xef\xce\x943\x1d\x01\xc0$\xba\xe8\x5c\xe1\xee\x16P\x8c\
+\xd1\x06?I\xa4/\xfe5dz\xe6,\xfaK\xda\xf5\
+\xee\x976\xe6\x04\xda\xe0?\xc4\x8d\x89t\xc7 \x00\x80\
+\xc0\xa8\x96H\xb7%\xe3\x11\x0f\xb4\xf9\xd2\xd6j\xb1\x8c\
+\xe9\x9a3\xd4w\xbf\x9c}\xc2\xf8GK\xfd\xbd8[\
+,`\xba\x02@\xb6\x19\x9fH\xf7\xa6\xa6\xd8b\x14\xdc\
++NI\xa4\x1f\xc7\x82x\xa2\x1f\x18:G\xfc3\xe3\
+\x1d#\xe2\xef\xc4c\x99\xba\x00\x90\x0dtk\xb2_S\
+X1\xa2>&\x1e\xc34\x8e\x1dC\xc5\x17\x18\xdf\x18\
+Q\xf5\xcb\xa4m\x99\xc6\x00\x90\x09\xfa\x9c\xb9\xeeeN\
+g\x16\x8cC\xc7\x17}\x99\xb91\xd3:\xf2\xe8~\xd3\
+\xb71\xa61\x06\xea;\x5c[\x13<v\x04\x00\x1e\xd1\
+G\x02\xe6\x88\x7f\xa5\x80\x1e\xda\xeab;\xb1\xaf8F\
+\x9c.^ ^&^)\xde*\xde\xe3\xfa+\xf1\x09\
+\xd7\xe7\xc4W\x0f\xe2\xf3\xe2\xc3\xe2\xcf\xc5[\xc4k\xc4\
+m\xe2\x12q\x968\xce\xfd\xcf\xd4\xff\xd9\xf5\xf8\x1c\xbc\
+\xfa\x17qV\x82c/QD\x1fg\xd1/7~\xc4\
+8>\xb82\xb8U\x03\xb1\xbd8@\x9c \xce\x16\x97\
+\x89\xdb\xc5k\xdd\x9ar\xb7\xf8\xa8[k\x0eV\x8b\x9e\
+\xd9\xafn\xdd\xbb_=\xbbI\xbcB\x5c+.\x14\xcf\
+\x14O\x10\xfb\x88\xad\xc5b>\x0b\xaf:\xe2D\xa68\
+\x00\x1c\x0c\xa9\xe9\x89\x87(\x98_\xb5\x898D\x9c!\
+\xaep\xc3\xf2/\xc4\x17D\xc7\x12\xdf\x16\xef\x17\xaf\x17\
+W\xba_\x14\x06\x89\x87\xf1\xf9\x1d\xc8\x07\x12\xfc\xbc\x1c\
+%\xba\x8b\xcf1n\xffk\xbe\xd8L<V\x9c)\xae\
+\x11o\x10\xa5x\xabw-\xaaK:\xfc\xdf%~[\
+\xbcD\x9c&\x0e\x14\x1b\xf2\x19\x1eH\xfd\x98\x16\xfd\xd3\
+\x01\xe0+\x14\x89\xcb\x13\xe9\xde\xad9[ k\x89=\
+\xc5\xa9\xe2z\xf1vw\x07\xc9\x89\xb8o\xb8_(v\
+\x8as\xc5\xfe\xee\xbfk\x8e/\x86z\xac/\x13\x8b\x99\
+\xfe\xd6R*^\x9e\xc8\xf1w\x16\xf4/d\x83\xc5s\
+\xdd_\xe5~\xe9~!\x8fz]z\xd1\xfd\x85Q\x7f\
+\xb98]<Z,\xa5.}\x90H_|\xceg\xfa\
+\x03@\x1f\xf1\xc5\x5c,\x86\xfag\xd8\xc9\xe2\x0e\xf1\xf1\
+\x18,x~L\xba\xff\xceW\x89g\x89\xdd\xc4\x82\xdc\
+\x5c\x10_Np\x89\xd4F$\x93&\xde\xc9\xb5\xf1X\
+\xe4n\x12\xcc\x17\xaf\x13\x9f\xca\xc1\xba\xa4\x7f\x05\x90o\
+ej\xa2xDn_n\xefD\x19\x00\xc8MJ\xc4\
+\x9d\x89\x1c\xb9\x04\xaa\xc3\xe7Q\xeeY\xcck-;\x9e\
+b\x8b\xaf\x8b\xdf\x13\xe7\x89\xdd\xc5\xc2\xdcY\x0c\xf5\x0e\
+\xed*\xf7\x97$\x08\xbf.m\xcb\x95\xbaTM\xec\xed\
+\x9e\xe1\xbe%&;\xe3\xd9\xf6Y\xf7\x97\x83\xe9bG\
+\xf7\x8c}\x8e\xd4\xa5\x7fQ\x97\x00r\x8f\xfe\xe2\xbbq\
+/p\x87\xbb\x17*Y\xf82\xf3\x1d\xf7ow\x8e\xd8\
+57\x16\xc6\x97\xc4\x1e\x94\x87\xd0\x18\x12\xf7\xba\x94\xef\
+\xee\x90_\xe2^\xb4|\x9f:\xe3\xdb7\xdd\xf3\xf6S\
+\xdc\xfbA\x89\xdc\xa8K])\x0f\x00\xf1F\x9fk\xd3\
+/\x81\xc6\xf2\xc5=\xbd\xf8\x1d\xe3v:\xb9\xd7\xfd\xb9\
+\x94\x05-{\xea.\x0e\x17\xbb\xbfD\xc48\xac\xeb\xb3\
+\xe9\x92\x9fx\xf1\xcf \xfao\xbd2\x11\xd3\xb3\xe6\x05\
+ng\x93\x95n\xf7&jI\xf6\xd4_p\xee\x14\xcf\
+\x17\xbb\xc4;\xa4\xff=\x91\xee@\x05\x001\xe40\xf1\
+Wq,^G\xb9\x8b\xdf\xb3,XF\x7fv^\xe7\
+\xb6q\x8b\xe9Q\x98\x07\x13tT0\xc1\x11\xe2\xc3q\
+\x1b?\xfa\xe8\xcapq\xab{\x19\x92\x9aa\xc6\xc7\xdd\
+\x0d\x9a\x0e\xf1\x0d\xea\xfa\x0d\x80z\x94\x0d\x80\xf80A\
+\xfc\xdf8\x15\xaa\x0en!~\x9cE)t\x7f\xe7\xf6\
+B>:~\x8b\xa1\x9e3\xe3(\x1f\x811^\xfcs\
+\x9c~\xc1\xeb\xeb^p|\x95\xba\x10\xba\xbf\x16\xcf\x13\
+[\xc4\xaf.\xbd\x9fH\xbf\xa4\x0b\x00\x11\xa6\x9axe\
+\x5c\x0aSC\xf7<\xf4\x83,>\xd6\xfa\x98\xb8(^\
+gC\xbf\x14+\x13\x5c\xd4\xca&\xa5q\xaaK-\xdd\
+3\xe5O3\xff\xad\xf5\x1e\xb7_|\xedx\xbd\x8e\xbc\
+:A;F\x80H\xa2\x7f\x9e\x7f\x22\x0e\xbbR\x83\xdc\
+\xc7\x81v\xb3\xd0D\xeal\xa8\xbe\xc8u\x5c|\xda7\
+\xea\xc7\x8d\xca)+U\xa6\x83\xf8j\xd4\xc7\x83n\x87\
+8\xd6\xed\xe3\xcd]\x97h]|\xd7\xefA\xf4\x8aO\
+P\xff\x99X\x97\xb2\x02\x10\x1d\x86\x88\x7f\x88r\xe1)\
+w{\x01?\xc1\xa2\x12y\xf5\xce\xe2\x05\xf1\xd8U\xdf\
++\xf6\xa3\xbcd\x8c>\xd2\xf2a\xd4w\xcb\x97\xd3\xa6\
+5\x16>\xe8\xb6\xdd\xad\x1b\xfd\xba\xf4\x96\xd8\x8d\xf2\x02\
+`7\xfa\xe7\xae\x8d\x89\xf4\xcf\xf2\x91,6\xc7\xb8;\
+\xaf{\xa3\xfc\xd8Fa\xa1J\xd5\xae\xadRM\x9b*\
+\xa7m[\xe5t\xeb\xa6\x92\xfd\xfa)g\xc4\x08\xe5\x8c\
+\x1b\x97v\xd2$\xe5L\x9e\xac\x9c)S\x943k\xd6\
+\xd7L\x9dqF\xfa\x7f\xae=\xe9$\xe5\x8c\x1c\xa9\x9c\
+\xc1\x83\x95\xd3\xab\x97r\xbavM\xff\xdfm\xdcX9\
+\xc5\xc5\x91\xf9\xbb\xecu?\xdb\x81\xd1^\x0c?O\xa4\
+{\x13\xf3\xd3\xb2w\xf4\xf1\xa0\xab\xa3\xfa\x99\xe7\xb9\x17\
+>\x7fJ\xa8\x8d\xa5\xbb\xdd]\xf5\x88_,\xd5\x9d\xd9\
+\xce\xa3\xd4\x00\xd8IM\xf1\xd6\xa8\x16\x18}\x8c\xe5\xe6\
+\x08\x05p\xa7\xbc\x5c9G\x1e\xa9\x9cA\x83\x943~\
+\xbcrf\xcfV\xce\xd2\xa5\xca\xd9\xb2E9W\x5ca\
+\xd4\xe4\xd6\xad\xcaY\xbe\x5c9\xf3\xe7+g\xeaT\xe5\
+\x8c\x1a\xa5\x9c\x1e=\x94\xd3\xac\x99rJJ\xac\xfc\x1b\
+\xea\xb0s\xbc{\x84)\xa2c\xf6\x87b\x0d\xca\xce!\
+\xd1\x1d'\xee\x8e\xe2g\xac\x8f\xb1\x9c,\xfe\x92\x10\x9b\
+\x13\xea\x0d\x84\xeb\xdcM\xa2\x08\x07\xf5+\x12\xe9\xbbg\
+\x00`\x09m\xc4W\xa2VLt{>\xfd\x9c\xf3}\
+6\x17\xee:u\x94\xd3\xa9\xd3\xbe\xdd\xef\xd4\xcc\x99\xfb\
+\x82p\xaa\xa2\xc2x\x08\xaf\x92\x1b7*\xe7\xfc\xf3\xd3\
+\xbb\xf6\xfd\xfb+\xa7E\x0b\x95\xaaV\xcd\x8a\xbf\xef\xc3\
+n\x08\x8a\xe89\xf5g\x13\xb4b<\x18\xfa\xbc\xf9\x9b\
+Q\xfb\x5c\xab\xb9\xafVr\xe93w\xd5\xbd\xd5GE\
+\xf7\xbd\x87\xc7\xc5\xc6\x94\x1f\x80\xf0\xd1\xaf\x82\xfe)J\
+\x05D\xef\x9a\x8e\x17\x1f\xb5\xad0\x97\x95)\xa7sg\
+\xe5\x8c\x19\xa3\x9c\x05\x0b\x94\xb3ys\xb4\x82\xb8\x1f+\
++\x95\xb3b\xc5\xbe\x1d\xf7}\xc7o\xf4q\x99\xbc\xbc\
+P\xbb\xbfL\x8afOu\xf9\xc7O\xf4\xa2\x0c}\x8d\
+\x91\xe2_\xa3\xf4Y\x16\xbb\x9d>xL\x08\xff\xed/\
+\xdd\xe3M\x11\x0c\xe9\xef\x89\x9d)C\x00\xe1qZ\x22\
+\xfd\xf2ad\xcer\x9e\xe0\xf6\xa7\xb5\xa1\xf8\xa6\x9a4\
+Q\xa9\x81\x03URBjj\xe5\xca\xf8\x86q\xaf\xea\
+/$g\x9f\xad\x9ca\xc3\x94s\xc4\x11\xa1\x04v\xdd\
+\xd7\xfe\xa4\xe8\x1d}\xd1s\xf0t\xca\xd1\x7f\xd0ga\
+?\x8f\xd2Q\x96\xa9\xe2\xf3\x04R\xfc\x06\x7f\xe6\x1e\xc3\
+\x8cXH\xff\x9b8\x9cr\x04`\x1e\xfd\x1cyd.\
+\x83\xeav{\xf7\x86]h\xf5\xb1\x8e\xae]UJ_\
+\xbc\x5c\xbb\x96@\xee%\xb0\x7f\xeb[\xca\x91/1N\
+\xc3\x86F?+}\xeciX\xf4\xfa\xa5_\x9a\xe35\
+I_\x9c\xad\x88\xd2\x86\xc18\xf7\xd7\x1bB(z\xf1\
+v\xb1w\xb4\xea\xd2\xa7\xe2l\xe2\x12\x80\x19tG\x84\
+\xeb\xa3R \x8et{\x05\x87VT\x1b4H\xef\x08\
+\xcf\x9f\xafR;w\x12\xba\xab\xa2\xbe\x88:f\x8cJ\
+\xea\xcb\xa7\x86v\xd7\x7f\x12\xbd\x17J\xf5\xa3F\x059\
+X\x97\x8a\xc5\x9b\xa3\xf29\x0d\xe0\xf2'V\xc1\xeb\xa2\
+\xf7B\xa9\xee\xee\x96G|\x02\x08\x8e:\xe2\xfdQ(\
+\x08\xfa\xd5\xcf\xcb\xdd\x07kB\xb9\xd8y\xec\xb1\xca\xb9\
+\xf0BBuP^v\x99rN9E9-[\x06\
+\x1e\xd6\xf5C0\x15\xd1\xea\xa3~\xbbX\x92cu\xe9\
+\x81(|6\xba\x8f\xf9w\x09\x98\x98\xa5\xf6\x8c\x97\x8a\
+\xb5\xa2S\x97n\xcd\xb1\xba\x04`\x8c\xfa\x89t\xd7\x08\
+\xeb; \x9c#\xben\xba\xf5\xa1\xbe\xe0\xa9[\x1e.\
+\x5c\x98\xbe\x00I\x886fj\xf5j\xe5\x8c\x1e\xad\x9c\
+F\x8d\x02\xfd\x8c\xdf\x16\x17\x89%\xd1X\x0c\x1fM\xa4\
+[\x0c\xc6\x1d\xdd\xc5\xe6\x05\xdb?\x0f\x1d\xa2V\xf1\x1a\
+1\x06\xe0\x8b\xe2\x99\xd1\xe9D\xa5\xebRm\xe2\x14@\
+\xf6h\x22\xbeh\xfb\xe4\x1f->i\xb28\xe6\xe7\xa7\
+[ \xce\x99\xa3\x9c]\xbb\x08\xcb6\x84\xf5\x0b/\xdc\
+w\xf16\xc8\xfe\xebOG\xa7\xb3\xc2+\xee\xdc\x8d+\
+\xed\xc5\xf7m\xff\x1c\xc6\xf3\xf2'\x1a\xf0~\xf7\xe8T\
+\x04\xea\xd23b\x03b\x15@\xd5i+\xee\xb6\xfdg\
+\xe3\x1f\x9b\xec\xbe\xa2_\xe8<\xe5\x14\x95\xd2\xfd\xbd\x09\
+\xc5v\xaa\xcf\xfb\xebWQ\xbbtI\x7f\x91\x0a`\x1c\
+\xdc&\xb6\x8aF\xbb\xb3\xd61\xacK=\xc5\xbf\xd8\xfc\
+\xb7o\xcf\xeb\x9f\x18\x82\xfa\xb5\xe4\xc6\xf6\xd7\xa5\xd7\xc4\
+#\x88W\x00U\xdb\xa1\xdac\xeb$\xd7]\x10\xce\x10\
+_3Q\xf8\xf49\xe7\xce\x9dU\xea\x9cs8\xc2\x12\
+\xb5]\xf5K/U\xa9\xc1\x83\xd3]t\xb2<.\xde\
+\x10g\xd9\xdf\x96\xf1\x1d\xb1e\x8c\xea\xd2Q\xe2\x1fm\
+\xfd{\xeb\xb6\x89\xe7\x89\xef\x10\x161$\x7f'\x8e\xb5\
+?\xa4\xbfAH\x07\xc8\x8cn\xe2\x1fl\x9d\xdc-\xdc\
+\x1dL#\xad\x11\x87\x0eU\xce\x9a5\x84\xdd\x88\x9b\xdc\
+\xba5\xfd\xcbG\xbdzY\x1f'\xfa\x17\x9c\xe6v/\
+\x86\xfa\x8bv;v\xce\x83\xef\x1aEw\x16\xb4\xc5\xef\
+\x88\xe5\xfc\xc2\x07\x10+\xfa\xd8\xba\x08\xea\x9d\xca\xb3\xdc\
+\x0b{\x81\x16\xb7\x1a5Tj\xe4H\x95\xda\xb0\x81p\
+\x1b\xb7\x1d\xf5\x9d;U\xea\x8c3T2\xcb\x97J\xdf\
+\x12g\xd8\xfd<\xb7~u4\xca\xaf\xfb\x0d\x10?\xb0\
+u\xd7\xfc\x02.\x81\xa2\x85\xea_\x98O\xb5;\xa4'\
+\xc5\x0e\xc4.\x80C\xd3[\xfc\xd0\xc6\x89\xdc\xd8DO\
+\xf3\x9a5\x953a\x82r\xb6m#\xcc\xc6\xdd\x8a\x0a\
+\x95\x9c>]9M\x9adu\x0c\xfd\xc8\xee\xdd\xf4?\
+\x89]\x22X\x97\x06\x89\x1f\xb1k\x8e\x98\x99\xd7\x88u\
+\xec\xadK\xef\xc7\xec\x18\x1e@ \xc7Z\xac\xdc9\xd7\
+\x1dZ^\x09\xb2\x80\xd5\xae\xad\x1c\xfd\xc2'\x8f\x09\xe5\
+\xa6\xfa!)\xddS=K\xe3\xe9M\xbbw\xad~\x9f\
+H\xdf/a\xd3\xa0\x8aw`\xcef\xd7\x1c#\xe4\xb3\
+b\x7f\xbb\xef\xca\x1cN\x0c\x03\xf8:G\x8b\x7f\xb5m\
+\xd2\xd6\x16\xaf\x0e\xb2h\xe9v|'\x9e\x98>\x9fL\
+P\xcdm++UJw~i\xd80\xabg@\xeb\
+\xda\xb9\x18\xea\xfb%GF\xe4X\xcb?l\xfc5\xef\
+G\x04>\x8c\xa0\xfa\xe1\xb5\xcd\xf6\xbe\xe7\xa0;\xc65\
+'\x8e\x01\xfc\x97\x16\x09\x0b\xfb\x09\xeb'\xd6\x1f\x0b\xaa\
+P\x15\x15)g\xe4H\xe5l\xd9B0\xc5\xaf\xaa{\
+\xdaO\x9a\x94>\xee\x94\x85\xb1\xa6{\xf3w\xb7\xf7\x82\
+V3\x8b\xebRg\xf7H\x8eU\x7f\xb7\xc1\xe2o\x09\
+z\x18q\xef\x16[\xdbY\x97\xf4\xc3c\xf5\x89e\x00\
+\x89DS\xf1-\xdb&\xe9\xb7\x82\xfa\xe9X\xb7K\xec\
+\xd1C9k\xd7\x12D\xf1\xd0]_\x8e?>\xfde\
+.\x0b\xcfr\xcf\xb0\xb7\x1f\xb1\x8d\x8f\x86\xb4J\xa4/\
+\xb5ZuA}\xb1\xbb\x03I\xc0\xc38\xa8\x9b-L\
+\xb0\xb3.=\x9d\xe0\xc5Q\xc8q\xf4\xc2\xfc\xb2M\x13\
+\xb3\x86xeP\x05\xa9M\x1b\xe5,]J\xf8D\x7f\
+]_\xd6\xafWN\xef\xde\xe9/wU\x1c\x83;\xc5\
+b\xfb\x16\xc3\xdf\x88\xa5\x16\xd5\xa5\x86\x89t\x8fdk\
+\xfeF\xb5\xc4\xef\x11\xe80\xa6^\xe6v\x22\xb2\xac.\
+=jY]\x020F\x89\xf8\x84M\x13\xb2\xa5\xfb\x5c\
+q\x10\x17@\x93S\xa7\xf2\xc0\x10V\xcdy\xf3\xb2r\
+>\xfd^\xf1p\xfb\x16\xc3_\x88E\x16\xd4\xa52\xf1\
+)\x9b\xfe6\x1d\xc4\xc7\x09q\x18s\xef\xb0\xb3g\xfa\
+\x9db\x01q\x0dr\x89|\xf1v\x9b&\xe2\x88 ^\
+\x04\xd5;\x9e\x83\x06)\x87\x0b\xa0\x98\xc5\x1e\xea\xce\xe8\
+\xd1*YXX\xa5\xb1\xf9\x92x\xac}\x8b\xe1\x0db\
+^\x88uI\x7fA\xb8\xc7\xa6\xbf\xc9x\xb7#\x0f\x01\
+\x0esA}\xb7\xa2\x8f}u\xa9\x92\xc8\x06\xb9\xc4v\
+\x9b&\xe0\x1cqo\xb6\x8bM\xf3\xe6\xcaY\xb6\x8cP\
+\x89\xc1\xb8f\x8dJv\xe8P\xa51\xfa\xbe8\xcb\xbe\
+\xc5pc\x88u\xe9\x06[\xfe\x0e\xba\x85\xe2E\x9c7\
+\xc7\x1c\xf4=\xf1d\xfb\xea\xd2\x22b\x1b\xe4\x02\x17\xda\
+2\xe9\xf4\x99\xb7\xed\xd9.0\xc5\xc5\xe9\xe7\xdc+*\
+\x08\x91\x18\xbc\xba-cYY\x95\xc6\xecv\xfb\xce\x7f\
+\x9e\x13B]Ze\xcb\xbf\x7fM\xf1\xfb\x045\xccq\
+\xd7\xb8\x17\xa3-\x99\x97_\x8aS\x89o\x10g\xc6\x89\
+\x9f\xdb0\xe1\xca\xc4\x1b\xb3\x5cP\xf4C3\xa9K/\
+%4\xa2Y/\xbb\xac\xca\xbb\xe9?\x10K\xedY\x0c\
+\xff%\x0e1X\x97&\x88_\xd8\xf0\xef^_\xbc\x8b\
+p\x86\xb8\xcf]vm\x1e\xfcS\xecG\x8c\x838\xd2\
+_\xfc\xd8\x86\x89v\x84\xf8`6\x0b\x89>\x0f|\xca\
+)\x5c\x02\xc5p\x9d6-\xfd\x0bN\x86\xe3\xf8\x01\xb1\
+\xa9=\x8b\xe1\x07\x89t\x1f\xf2\xa0\xe9kK]\xd2=\
+\xa1\x7fC(C\xfc\x8a?\x13\x1b\xdaS\x97\xfe&v\
+!\xceA\x9c\xd0\xcf\xe7\xa6l\x98`\x9d\xc4\xe7\xb2Y\
+@\x1a5R\xceE\x17\x11\x0e\xd1\x9a\xb3\xe9N\xabV\
+\x19\x8f\xe7'\xdcnF\x96,\x86\xaf\x8au\x02\xacK\
+\xfa\x0d\x86\xbd6\xfc\xbbv\x14\x9f'\x8c!\x1e\xd0G\
+\xc4\x16\xf6\xd4\xa5\xd7\x03\xaeK\x00\xc6(NX\xd2N\
+\xf1\x98lwj\xe9\xde]9\x97_N(\xc4\xc0^\
+\x14Mm\xd8\xa0\x9c\xe5\xcbUr\xe1B\xe5\xcc\x99\xa3\
+\x9c3\xceP\xa9\xf1\xe3\x953n\xdc\xben.\xa9\x11\
+#\x943|\xb8r\x06\x0c\xf8\xaf\x03\x07\xaaT\xf5\xea\
+\x19\x8f\xeb\x17\xedzy\xf4\xdeD0m\xcet\x9b\xd7\
+gl\xf8w\xec\x1bD\x07)\xc4\x98\xa9\xbf\xc0\xb6\xb3\
+\xa7.\xdd\x95Hw\xa3\x03\x884\xdf\xb6aB\xf5\xcf\
+f\xbb2\xfd\xb2\xe3\x94)\x04H\xac\x9a[\xb6\xec{\
+\xb8*5{\xb6rt\xe8\x96`\xed\x1cy\xa4J6\
+jT\xa5\x80\x9d\x0d\xdf\xb0\xab\xdd\xd9\xfa\x00\xea\x92\x15\
+\x1d[F\x89\xef\x12\xbe\x10=\xb7\x87\xedlO]Z\
+A\xbc\x83(s\xb6\x0d\x13\xe9\x04\xf7\xa9\xf3\xac\x14\x89\
+\x06\x0d\x94s\xf1\xc5\x84K\xf4\xd7\xbb\x5c\xbf \xab\x1f\
+\xab\x1a6L9\xed\xdbW\xb9\xf3\x8a\xa9vg#\xed\
+Y\x0c'e\xb1.\x9do\xc3\xbf\xd3\xa9n\xabK\x82\
+\x17\xa2w\xdf\x12\x07\xd8\xd3\xd9\xe5db\x1eD\x11\x99\
+C\x89O\xc3\x9eD\xa7ds\x11\xec\xd4\x89#-x\
+\xf00\xae\xdbk\xea0~\xea\xa9\xca\xe9\xd5K9M\
+\x9a\xa8d~~d\x17\xc3\xdd\xee\x17\x5c\x0b\x16\xc3\xbf\
+\x8b\x9d\xb2P\x97\x06\x89\x9f\x85\xfd\xef3\x83\x1e\xe7\x88\
+\x19\xfb\xb68\xc4\x8e\xba\xf4\xa1\xd8\x91\xb8\x07Q\xa2\xbe\
+\xf8^\xd8\x93G\xbf\xc2\xb7'[/\x82\x8e\x1eM\x97\
+\x16\xfc\xba\xfa\x0b\xdb\xd9g+g\xe4H\xe5\xb4m[\
+\xa5.*6\x87\xf4\xe3\xedX\x0c_\x14K\xabP\x97\
+\x1a\x89\xef\x87\xfd\xef1%\x88\x87\xd1\x10s\xccw\xec\
+y\x0d\xf9y\xb1\x06\xb1\x0f\xa2\x80\xbe\xd0uo\xd8\x93\
+fL\xb6v\xcek\xd4P\xce\xbcy\x04QL\xab\xbf\
+\xa4\xe9\x1d\xf2\xb1c\x95\xd3\xba\xb5r\x22\xbc;\xee7\
+\xa4\x8f\xb2c1\xfca\x86uI_\xe8\xba/\xec\x7f\
+\xfe\xa9\xec\x9c#f\xb5.\x1dgG]\xfa\x1e\xd1\x0f\
+\xa2\xc0\xea\xb0'\xcb\xf0l\x9d9\xaf_\x9f\x87\x87P\
+9\xdb\xb6)\xe7[\xdfRN\xdf\xbe*U\xbbvN\
+/\x86\x96\xecX\xcd\xcc\xa0.-\x0f\xfb\x9f{\x12;\
+\xe7\x88\x81\xec\xa4\xf7\xb7\xa3.\xcd&\xfe\x81\xcd\xf4\x0b\
+\xfb|\xe7`\xf7r[\x95'~\x9b6\xca\xd9\xbc\x99\
+p\x9a\xa3&\xb7nM?\xfc\xa3_\xe8\xcc\x91]r\
+\xaf\x8b\xa1\x05\x17\xb4\xfe!\xb6\xf7Q\x97\x06\x86]\x97\
+\xc6r!\x141\xd0\xaeS\xdd\xed\xa8K\xed\x88\x81`\
+#\xb5\xc4\xb7\xc3\x9c }\xdc\xcb#U\x9e\xf0={\
+\xa6;o\x10Ts\xcb\xed\xdb\xd3\xa1\xbcK\x97t+\
+M\x16\xbeo\xec\xa2\xd0+\xfc\xc5\xf0\xb9D\xfa\x8d\x05\
+/\xf7a\xf6\x84\xf9\xcf:\x22\x9b]\xa4\x10\xf1\x80\xbe\
+*\x1e\x19~]zZ,\x22\x0e\x82m|7\xcc\x89\
+\xd1\xc3\xfd\x16]\xe5\x89>t(\x97As\xad\xf3\xca\
+\x8a\x15\xfb\xda\x1f&#\xd0\xfa\xd0\xa6\xc5\xb0C\xf8\x8b\
+\xe1\xb6C\xd4\xa4<\xf1\xce0\xff\x19{\xb9\xbf:0\
+f\x10\x83\xf7\x05\xb1u\xf8ui\x1dq\x10l\xe2\x94\
+0'D[70T\xb9S\xcb\x84\x09\x04\xd6\x5c\x09\
+\xe5;v(\xe7\xcc3UJ\x1feba\xcb\xc8\xe7\
+\xc4\xc3\xc2\xefC<\xea uiv\x98u\xa9}6\
+\xea\x12\x22\xfa\xf2\x19\xb1<\xdc\xba\xf4\xb9{\xac\x0e \
+tZ\x88\x7f\x0bk24I\xa4\x9f\x00\xaej8O\
+\x9dv\x1a\xc15\x17\x82\xb9\xbe\xf4;h\x90rJJ\
+X\xcc\xb2\xe0\xe3b\xa3p\x17\xc3?\x8a\xe5\x07\xa8K\
+m\xc4\x8f\xc2\xfa\xe7j)\xbe\xc8\xf8@\x0c\xc5\x07\xc5\
+Z\xe1\xd6\xa5\xbd\xee\xf1:\x80\xd0\xd0\xad\xcb\xee\x0fk\
+\x12T\x17\xef\xaa\xead.(P\xce\xcc\x99\x84\xd78\
+\xab\x1f\x0f\x9a5+\xdd\x16\x91\xc5+\xeb\xea9Xl\
+W\xebE}\xb4%\xb4\x96\x8ae\xe2\xfd\x8c\x0b\xc4P\
+\xbdA,\x08\xb7.\xddHD\x840Y\x10\xd6\xe0\x97\
+o\x06\xea\xea\xaaNb}\x11p\xee\x5c\x02l\x9c/\
+}\x9er\x8aJ6h\xc0\x82\x15\xb0W\x8ay\xe1.\
+\x86\xa7\xecW\x97\xe6\x86\xf5\xcf\xa1\x03\xc1\xf7\x18\x0f\x88\
+V\xb8.\xfc\xf3\xe8'\x12\x13!\x0c\x9a%\xd2\xcfo\
+\x872\xf0/\xa9\xe2\xc4M\x16\x16*\xe7\xac\xb3\x08\xb1\
+q\x0d\xe6'\x9d\xa4\x9cZ\xb5X\xa4\x0c\xba0\xdc\x85\
+\xf0Obc\xb1e\x98u\xe92\xc6\x01\xa2U~+\
+\xdc\xba\xa4;H\xd5\x22.\x82i~\x1e\xd6\xa0\x9f\x9c\
+\x8d\x9d\xf3\xf9\xf3\x09\xb2q\xbc\xf89n\x9crJK\
+Y\x98BP\xbf\x909&\xdc\xc5\xf0\x16\xf1\xd7a\xfd\
+\xe7\xcf`\x0c Z\xa7~\x7f`x\xb8u\xe9\x0a\xe2\
+\x22\x98\xe4\xf4\xb0\x06{\xf7\xaa>D\xa4\xcf\x9c\xb3s\
+\x1e\xaf`\xae{\xd6\xeb`^\xb3&\x0b\x92\x05\x0f\x19\
+u\x0e\xffge\xe3\x0e\xe4!\x22Dk}Ml\x11\
+^}\xf8\x22AW\x170\x84\xbe\x99\xfc\x870\x06z\
+\x03\xb7\x85R\x95Z)N\x99B\xa8\x8d\x93s\xe6(\
+\xa7qc\x16!\x8b|R\xac\x93C\xe1\x5c\xb7\x9a|\
+\x89\xcf\x1d\xd1j\xf5\xc5\xed\x1a\xe1\xd5\x09\xf9\x8e\x90\xa8\
+N|\x84\xa0\xf9a\x18\x03\xbc\xa8\xaa\x1d[t8\x9f\
+:\x95@\x1b\x17\x17-R\xc9f\xcdXx,\xf56\
+\xb10\x07\xc2y\x09\x1d[\x10#\xe3w\xc2\xbd\xcc~\
+9\xf1\x11\x82dxX\x0b\xe1\xa5U\x9d\x9c\xfa\x08\x04\
+\xc16\xfa\xc7Y6nTN\xff\xfe\xca\xc9\xcfg\xc1\
+\xb1\xdc\xc59\x10\xd07\xf39#ri\xd4\x9b\x9f\x8a\
+\xdd\x88\x91\x10\x04\xd5\xc4\xd7\xc3\x18\xd8c\xdc\x0bh\x19\
+O\xca\xa1C\x09\xb7q8g\xae;\xb3T\xaf\xce\x22\
+\x13\x11\xf7\x8aCb\x1c\xce'\xf1\x19#F\xce\xddb\
+\xef\xf0\xea\xc6#\x89\xf4;\x0d\x00YeQ\x18\x03\xba\
+\x8d\xf8fU&d\xaf^\xca\xa9\xac$\xe4F9\x9c\
+\x9f{\xaer\xea\xd7gq\x89\xa0\xbfK\x84\xfe\xd2h\
+`u\xe9->_\xc4H\xfa[\xb1<\xbc\xfaq\x1a\
+q\x12\xb2\x89\xac\xb1\x89\xbf\x85q\xee\xfc\xde\xaaL\xc4\
+v\xed\x94\xa3w^\x09\xb9\xd1\x0c\xe6\x9b6)\xa7{\
+w\x16\x94\x88{K\x22\xfd\xb0X\x5c\xc2y1\xe7\xce\
+\x11#\xef\x0f\xc3;\x8f\xbe[,!VB\xb6\xb8>\
+\x8c\x85peU&`y\xb9r6o&\xe8FQ\
+\xfd\x8b\xc7\xe4\xc9\xca\xa9Q\x83\x85$&.\x8aQ@\
+\xdf\xca\xe7\x89\x18\x0b\xe7\x86WG\xd6\x12+!\x1b\xe8\
+K\x0d\x9f\x9b\x1e\xc0}\xdd3\xac\x19M<\xfdP\xcd\
+\x8a\x15\x04\xdd(\xba~\xbdr\xbave\xf1\x88\x99{\
+\xc4\x1e1\x08\xe7#\xf8,\x11c\xe3\xbbb\x87pj\
+\xc9G\xe2\xe1\xc4K\xa8*\x0f\x98\x1e\xbc\xb5\xc4\xa73\
+\x9dt\xba\xbb\xc7\x82\x05\x04\xdd(:w\xaeJ\x96\x95\
+\xb1p\xc4\xd4G\xdd\xb6\x84Q\x0d\xe7\xf5\xdc\xb3\xab|\
+\x96\x88\xf1\xea\x8f^-\x9c\x9a\xf2\x03\xe2%T\x85\x93\
+\xc3X\x08\xaf\xac\xca\x84\x9b8\x91\xa0\x1b5\xb7mS\
+N\xef\xde,\x169\xe0\xba\x08\x07\xf4\xab\xf8\xfc\x10c\
+\xe9\xaapj\xca\x97b?b&dB\x91\xf8\x96\xe9\
+A{RU&Z\x9f>\x84\xdd\xa8]\x04]\xbc\x98\
+\x0e-9\xa4n\x97: \x82\xe1|\x1c\x9f\x1db\xac\
+\xebR\xffpj\xcb\x13DM\xc8\x849a\xfc\x84\xfc\
+b\xa6\x93\xacI\x93\xf4N,\xa17:N\x9a\xa4\x9c\
+\xa2\x22\x16\x88\x1cS\x1f_\xab\x19\xa1p\xae\xdb\xb1\xbd\
+\xcc\xe7\x86\x18k\x1f\x13\xab\x87Sc\xc6\x107\xc1\x0f\
+\xc5\xe2\x1e\xd3\x03uW\xa6\x93K\x9f[^\xbb\x96\xc0\
+\x1b\x15\xb7lQN\x97.,\x0a\x1cu\x89\x84\xd7\xf0\
+y!\xe6\x84\xcb\xc2\xa91\xcf%x\xbc\x08|0\xdf\
+\xf4 \x1dR\x95\x895g\x0e\xa17*\xae\x5c\xa9\x9c\
+\xa6MY\x0cr\x5c\xdd\xa1\xa9{\x04\xc2\xf9p>+\
+\xc4\x9c\xea6\xd5)\x9cZs2\xb1\x13\xbc\xa0\x1b\xe8\
+;&\x07g\x0d\xf17\x99N\xaa\xc1\x83\x09\xbdQq\
+\xe6L\xe5\x14\x17\xb3\x10\xe0\x7f\xba'\x14Y\x1c\xceK\
+\xab\xd2M\x0a\x11#\xe9\xddb\x81\xf9z\xf3\xa2\x98O\
+\xfc\x84C\xb1\xc8\xf4B\xb8*\xd3\xc9\xa4\x1f#\xda\xbe\
+\x9d\xe0\x1b\x85\x87\x87F\x8dRN^\x1e\x0b\x00~\xc5\
+s,\x0e\xe8\xab\xf9|\x10s\xd2\xb3\xc2\xa99\x93\x89\
+\x9fp0\xca\xc4?\x9a\x1c\x94G\x8a\xefg2\x89\x8a\
+\x8aT\xf2\x92K\x08\xbf\xb6\xbbu\xabr:v\xa4\xe8\
+\xe3\x01}Glna8\xef\x9ai]B\xc4\xc8\xfb\
+\x96\xd8\xc4|\xddyM, \x86\xc27\xb1\xd4\xf4B\
+\xf8\xa3L'\xd1\xf8\xf1\x84_\xdb\xbd\xec2\xce\x9b\xe3\
+!\xbd\xde\xb2p\x9e'\xde\xc5\xe7\x82\x98\xd3V\x86S\
+\x7f\xa6\x11C\xe1\x9b:\xb7\x18={>:\xc3\x89\x93\
+j\xd3F9\x15\x15\x04`\x9b\xfb\x9b\xafX\xa1\x9c\x06\
+\x0d(\xf4\xe8\xc9\x81\x16\x05\xf4\x09|\x1e\x88\xf4F\x17\
+{\x84\xb3\x8b\xceYt\xf8\x1a\xb3L\x0eD\xf96\xa0\
+\x9e\xcc$\x9cW\xaf\xae\x92\xb4T\xb4\xdb\xb9s\xb9\x0c\
+\x8a\xbe|@,\xb4 \x9c\xeb\x0b\xeb\xcf\xf1y \xa2\
+\xf8s1\xdf|\x1d\x1aK\x1c\x85\xfd\xd1=8_6\
+9\x08\xe7g:i&L \x00\xdb\xec\xacY*Y\
+XHqG\xdf\xce\xb0 \xa0/\xe1s@\xc4\xfd\x9c\
+d\xbe\x0e=L$\x85\xfd9\xd1\xe4\x00\xd4/\xf3\xbd\
+\x91\xc9di\xdd:\xdd\x11\x84 l\xef\xcb\xa0tj\
+\xc1\x0c\xd5\xafu\xd6\x0a1\x9c\xebKa\xef\xf29 \
+\xe2~>\xef\xb6\x5c5\x5c\x8fz\x11K\xe1\xdf<h\
+r\xf0m\xc9\xb0k\x8b\xa3\xcf5\x13\x84\xed\xf4\xe4\x93\
+\x09\xe7Xe/\x0a1\xa0o\xe1\xef\x8f\x88\x07\xf0B\
+\xf3\xf5\xe8Vb)hz\x9a\x1cx-\x12\xe9\xd7\xba\
+|O\x92\xd1\xa3\x09\xc1\xb6\xaa?\x1b\x8a8f\xc17\
+\xc5\x86!\x84\xf3\xd6\x99\xd6%D\x8c\xbd\xfa\x17\xffz\
+fk\xd2\xe7bK\xe2)\xdcjr!\xac\xc8d\x82\
+\x94\x97\xab\xd4\xce\x9d\x04a\x1b\x1d;\x96\x02\x8eYu\
+]\x08\x01\xfd\x1a\xfe\xee\x88x\x10\x97\x9b\xafK;\x89\
+\xa7\xb9M3\xf7\x9b\x9a\x91\x01\xd76\x91\xe1\xe3\x1f\xf3\
+\xe6\x11\x84\x09\xe7\x98#\xee\x16\x9b%\xcc>J\x94\xe4\
+\xef\x8e\x88\x89\x83?^d\xf8\xd7\xbd\xbf\x8b\xb5\x89\xa9\
+\xb9\xcbZ\x93\xdf\x08\xaf\xcd\xa4\xadb\xd7\xae\x04a\x1b\
+\xfb\x9c\x8f\x1bG\xd1\xc6\xc0\xdcn\xb0.}\x8f\xbf7\
+\x22\xda\xf9\xeb\xde\xb9\xc4\xd4\xdc\xa4HL\x99\x1ahG\
+e\xb0K\xa5\xdb\xf5\xa5V\xaf&\x10\xdb\xa6nuI\
+\xb1\xc6\x00\xd5\xbf\xb4\xb54P\x97\xba\xf1\xb7FDK\
+\x7f\xdd\x13_ \xaa\xe6&F[+^\x97\xc9\x848\
+\xf6X\xc2\xb0m\x9e~:\xddZ\xd0\x88\x1b\x0d\xd4\xa5\
+\xab\xf9;#\xa2\x0f\xd7\x9b\xdfE?\x86\xb8\x9a{\xdc\
+a\xb2C\xc2^\xbf\x13\xa1F\x0d\xe5l\xdeL \xb6\
+\xc99sT2?\x9f\x22\x8dF|\xcf\xedM\x1eT\
+]j\x97I]B\xc4\x9c\xf6\x1d\xb1\xbe\xd9\x80~5\
+q5\xb78L\xfc\xcc\xd4\x00\xdb\x94\xc9D\x988\x91\
+@l\x91\xc9\x85\x0b\xd3\xbd\xe8)\xd0h\xd0\xcb\x02\xac\
+KW\xf0\xf7E\xc4\x0c\x5cd6\xa0\x7f(\x96\x11[\
+s\x87U\xa6\x06W\xb9\xbb\x13\xe6k\x024h\xa0\x9c\
+]\xbb\x08\xc6\xb6\xb8l\x99r\xaaW\xa70c(\xbb\
+\xe8\xe5\x01\xd4\xa5V\xec\x9e#b\x86\xbe\x920\xfe\xba\
+\xe8\xd9\xc4\xd6\xdc\xa0@|\xdf\xd4\xc0\xba(\x93\x090\
+e\x0a\xa1\xd8\x16\xd7\xadS\xa9:u(\xca\x18\x9a\x17\
+'x5\x14\x11\xedr\x86\xd9\x80\xfe,\xd157\x18\
+ajPU\x17_\xf4;\xf0\xcb\xcb\x95SQA0\
+\xb6\xc1m\xdb\x94s\xc4\x11\x14c\x0c}\xb7\xaa,\x8b\
+u\xa9\x91\xf8.\x7fWD\xac\x82\x8f\x8a\xf9fCz\
+g\xe2k\xfc\xb9\xd1\xd4\x80\x9a\x91\xc9\xc0\x9f6\x8d`\
+lC\x9fs\xf9\x92\x94\xea\xd4\x89B\x8cVxN\x16\
+\xeb\xd2\xa5\xfc=\x111\x0b\x9eh6\xa0o$\xbe\xc6\
+\x9bb\xf1\xaf&\x06S\x9e\xf8\x88\xcf\xc1\x9el\xd4h\
+_0$ [\x10\xd0G\x8e\xa4\x00\xa35>'\x16\
+e\xa1.\xd5\x12_\xe3\xef\x89\x88Y\xf0'f\x03\xfa\
+\x9bD\xd8xs\x92\xa9\xc14$\x83\xc1\x9e\x9c>\x9d\
+plI;Ez\x9d\xa3mN\xcdB]:\x9f\xbf\
+#\x22f\xd1NfCzObl|\xf9\xbe\xa9\x81\
+tU&g\xcf++\x09\xc7a\xbbt)\xed\x14\xd1\
+J\x1f\xa9\xe2\x99\xcfb\xf1\xb7\xfc\x1d\x111\x8b\xae6\
+\x1b\xd07\x11c\xe3I\xa9\xf8\x91\x89A\xd4 \x91~\
+\x12\xd7\xcf O\x9dv\x1a\xe18l\xf5\xc3P\xf5\xeb\
+St\xd1Z\xc7\x9a\xbe\x13\x83\x88x\x10\xf5\x91\xb9\x12\
+s\x01}\x8f\x98G\x9c\x8d\x1f\x13M}\xcb\x9b\xe7\xf7\
+hKY\x99J\xed\xd8A@\x0e\xd3\x8a\x0a\x95\xec\xd0\
+\x81\x82\x8bV{\x9f{\xbf\xc5oM\xd2\xe7\xd7\x9f\xe1\
+\xef\x87\x88\x018\xc1\xec.z?\xe2l\xfc\xb8\xcd\xd4\
+\xe5\xd0G\xfd\x0ep}!\x91\x90\x1c\xae\xe3\xc6Qh\
+1\x12\x0e\xcd\xa0.M\xe4\xef\x86\x88\x01\xf9#\xb3\x01\
+}'q6^\x94\x88\xff01xz\xf9\x1d\xdcE\
+E*\xb5i\x13\x019\xcc\x8e-\x8b\x17\xabd~>\
+\x85\x16#\xe1-\x19l\x1a\xdc\xc7\xdf\x0d\x11\x032)\
+6\xe7\x98\x0bd\xc8\xf1\xa6\xbe\xddm\xf5;\xb8\x07\x0c\
+ $\x87\xe9\xd6\xad\xcai\xd0\x80\x22\x8b\x91\xb2\x9b\x8f\
+\x9at,\x7f/D\x0c\xd8\x0b\xcd\xee\xa2\x1fE\xac\x8d\
+\x0f\x15&\x06M\xb5Lz\x0c/[FH\x0eS\xfd\
+\x05\x89\xe2\x8a\x11\xf3z\x1fu\xe9g\xfc\xbd\x101`\
+\x9f\xc8\xf0~L\x86^B\xac\x8d\x0f\xef\x98\x184\xc3\
+\xfd\x0e\xea\x96-\x09\xc8a:s&\x85\x15#\xfb\x93\
+r{\x0f5\xa97\x7f+D\xb4\xf0\x97\xbd*\xfa\x08\
+\xb16\x1e\xb46\xf5\xb3\xcb\x0e\xbf\x03z\xca\x14Br\
+H&\xd7\xaeUNI\x09E\x15#\xeb\x16\x0f5\xe9\
+;\xfc\x9d\x10\xd1\x90\x97\x98\x0b\xe8\x9f\x8a\xb5\x88\xb7\xd1\
+g\x81\x89\x01S]|\xc3\xcf`..VI}\xfe\
+\x99\xb0\x1c\x8e]\xbbRP1\xd2\xea\xb7\x16\x0e?H\
+M\xea\xcc\xdf\x08\x11\x0d\xfa\x8c\xd9c.\x13\x89\xb7\xd1\
+\xe7\x17&\x06\xcb\xf1>\x07rj\xe0@BrXN\
+\x9fN1\xc5X\xb8\xe6 5\xe9\x0a\xfe>\x88h\xd8\
+\x1e\xe6\x02\xfa\xb5\xc4\xdbhSl\xaa\xbdb\xa5\xdf\x81\
+\xac\x9f\x94',\x9bw\xe3F\xe5\x94\x96RH1\x16\
+\xea_\xed\xea\x1c\xa0\x1e\x1d\x9e\xf0\xff\x9a1\x22bU\
+]a.\xa0\xef&\xe2F\x9b\xe1&\x06\x8a~\xa5\xef\
+u?\x83\xb8iS\x82rX\xf6\xe9C\x11\xc5X\xb9\
+\xf0\x005i-\x7f\x17D\x0c\xc1'\xcd\xb6[\xecD\
+\xcc\x8d.\x1bL\x0c\x92~~\x07\xf1I'\x11\x94\xc3\
+\xb8\x18z\xd6Y\x14P\x8c\x9d/\x8a%\xfb\xd5\xa3z\
+\xe2\xdb\xfc]\x101$[\x9b\x0b\xe8\xf3\x89\xb9\xd1\xe5\
+1\x13\x83\xe4R\xbf\xe7\xcfW\xaf&0\x9bv\xfbv\
+\xe5\xd4\xafO\xf1\xc4X:g\xbfz\xb4\x94\xbf\x07\x22\
+\x86\xe8Y\xe6\x02\xfa\xad\xc4\xdchR]\xfc\xc4\xc4 \
+\xf9\xb5\x9f\xc1\xdb\xa2\x05a9\x0cG\x8e\xa4pbl\
+}\xd6=jW\xcb\xefq;D\xc4,{\xb3\xb9\x80\
+\x9e$\xeaF\x93\xbe&\x06H\xe3D\xfa\xd1\x10\xcf\x83\
+w\xc2\x04\xc2\xb2i\xd7\xacQNQ\x11\x85\x13c\xed\
+Dw\xe7\x8a\xbf\x05\x22\x86\xe9;\x89t\xebiC!\
+\xbd9q7z,218N\xf33p\xf3\xf2\x94\
+\xb3n\x1d\x81\xd9\xf4\xd9\xf3\xee\xdd)\x9a\x18{\x1fp\
+w\xd2\xf9[ b\xd8\x1ek.\xa0O&\xeeF\x8f\
+\xdbM\x0c\x8ek\xfc\x0c\xdaV\xad\x08\xcc\xa6]\xb8\x90\
+b\x89\x88\x88h\xd0\xb5\xe6\x02z%q7z\xfc>\
+\xe8\x81Q \xbeF\xf7\x16{\xad\xacT\xa9\x96-)\
+\x96\x88\x88\x88\x06}\xc4\x5c@\x7f\x9e\xb8\x1b-\xda\x99\
+\x18\x18\x9d\xfc\x0e\xdaK.!4\x9b<\xda\xc2\x8b\xa1\
+\x88\x88\x88\xa1Xn&\xa0\x7f!\xd6!\xf6F\x87\xa9\
+&\x02\xfa4?\x83\xb5^=B\xb3AS;w\xaa\
+\x94\xfe\x9bS$\x11\x11\x11\x8d{\xbc\xb9]\xf4\xe1\xc4\
+\xde\xe8\xb0\xcd\xc4\xa0\xb8\xd2\xcf`\x1d0\x80\xe0lr\
+\xf7|\xd2$\x0a$\x22\x22bH\xae2\x17\xd0/\x22\
+\xf6F\x87_\x99\x18\x14O\xfb\x19\xacs\xe6\x10\x9c\x0d\
+>J\x94\xaa]\x9b\x02\x89\x88\x88\x18\x92?7\x17\xd0\
+o$\xf6rA\xf4?\x96\xfb\x19\xa8\x85\x85*\xb9u\
++\xc1\xd9\x94\xe3\xc7S\x1c\x11\x11\x11Ctw\xc2X\
+?t.\x8aF\x84\xc6&\xbe\xb1\x8d\xf53P\xdb\xb6\
+%4\x1b\xdc=O\xd6\xacIqDDD\x0c\xd9\xbe\
+f\x02\xfa\xa7b5\xe2\xaf\xfd\x1cg\x22\xa0\xaf\xf23\
+HO8\x81\xe0l\xca\xb1c)\x8a\x88\x88\x88\x168\
+\xcf\xdc1\x97N\xc4_\xfb1\xf2\x82\xe8m~\x06\xe9\
+\x82\x05\x04gC\xbb\xe7Ni)E\x11\x11\x11\xd1\x02\
+\xaf4\x17\xd0O'\xfe\xda\xcfwM\x0c\x86W<\x0e\
+\xced~~:8\x12\xa0\x83\xf7\xb4\xd3(\x88\x88\x88\
+\x88\x96\xf8\x80\xb9\x80\xbe\x81\xf8k?\xcfXuA\xf4\
+\x88#\x08\xce\x86^\x0du\x1a5\xa2 \x22\x22\x22Z\
+tQ\xb4\xc8L@\xbf\x8b\xf8k?\x7f\x0fz \x0c\
+\xf63@\x87\x0c!<\x9b\xe8{~\xd6Y\x14CD\
+DD\xcb\xech&\xa0\xbfE\xfc\xb5\x9b\x86&~J\
+\x99\xebgp\xce\x9cI\x806\xa1\xee\x94C!DD\
+D\xb4\xca\x93\xcdur) \x06\xdbKo\x13\x01\xbd\
+\xc2\xc7\xc0L\xae]Kx\x0e\xda\x8b/\xa6\x08\x22\x22\
+\x22Z\xe8rs\xe7\xd0\x9b\x13\x83\xed\xe5T\x13\x83\xe0\
+W^\x07\xa6\xee(B\x80\x0e\xde\xbe})\x82\x88\x88\
+\x88\x16\xfa}s\x01}\x101\xd8^\x96\x04=\x00\xf2\
+\xc4\xb7\xbd\x0e\xcc\xf6\xed\x09\xcfA{\xf9\xe5\xca)*\
+\xa2\x08\x22\x22\x22Z\xe8\x93\xe6\x02\xfa4b\xb0\xbd\x5c\
+\x1d\xf4\x00h\xe4g`\x0e\x1dJ\x80\x0e\xfar\xe8\xa4\
+I\x14@DDDK\xddc\xae\x93\xcb*b\xb0\xbd\
+\xdc\x1b\xf4\x00\xe8\xe1g`N\x99B\x88\x0e\xda\xc3\x0e\
+\xa3\x00\x22\x22\x22Zl33\x01\xfd\x06b\xb0\xbd\xbc\
+\x11\xf4\x008\xc9\xc7\x80L-YB\x80\x0e\xd2\x8b.\
+\xa2\xf0!\x22\x22Zn\x7f3\x01\xfd!b\xb0\x9d\xe4\
+\x89\x1f\x07=\x00\xce\xf5: \xf3\xf3Uj\xc7\x0eB\
+t\x90\xf6\xefO\xe1CDD\xb4\xdcS\xcd\x04\xf4\xf7\
+\x88\xc2vR\xd7\xc4%\x84M^\x07\xa4~\xd5\x92\x10\
+\x1d\x9c\xdb\xb7+\xa7\xa4\x84\xc2\x87\x88\x88h\xb9\x8b\xcd\
+\x04\xf4O\x88\xc2v\xd2\xc6D@\xbf\xc9\xeb\x80\xec\xd4\
+\x89\x10\x1d\xa4\xfa\x01(\x8a\x1e\x22\x22\xa2\xf5\xee2\xd7\
+\xc9\xa5\x8c8l\x1f}L|\xf8\x0f{=\x7f>x\
+0!:H\x8f:\x8a\xa2\x87\x88\x88\x18\x01\x7fd.\
+\xa0\xb7 \x0e\xdb\xc7\x89&>\xfc\x97\xbd\x0e\xc8\xf1\xe3\
+\x09\xd1A\xb9u+\xbd\xcf\x11\x11\x11#\xe2\x03\xe6\x02\
+\xfa1\xc4a\xfb\x98\x16\xf4\x07_ \xee\xf5\xba\x83>\
+{6A:(\xa7O\xa7\xe0!\x22\x22F\xc4\xdf\x9a\
+\x0b\xe8#\x89\xc3\xf6\xb1(\xe8\x0f\xbe\x9e\x9f\x01\xb9t\
+)A: S]\xbbR\xf0\x10\x11\x11#\xe2\xeeD\
+\xfa%v\x03\x01\xfd\x0c\xe2\xb0}\xac\x0f\xfa\x83o\xed\
+g@n\xdeL\x98\x0e\xc2-[T\xb2\xb0\x90\x82\x87\
+\x88\x88\x18!k\x99\x09\xe8\x0b\x88\xc3\xf6qu\xd0\x1f\
+|O\xaf\xc7[\xaaW'H\x07\xb5{N\xf7\x16D\
+D\xc4\xc8\xd9\xc2L@_M\x1c\xb6\x8f\xdb\x82\xfe\xe0\
+Gx\x1c\x84Iz\xa0\x07g\xcf\x9e\x14:DD\xc4\
+\x88y\xb4\x99\x80^A\x1c\xb6\x8f_\x04\xfd\xc1\x9f\xea\
+u \xb6lI\x90\x0e\xc2\xcaJ\xe5\x94\x95Q\xe8\x10\
+\x11\x11#\xe603\x01\xfdz\xe2\xb0}\xdc\x17\xf4\x07\
+?\xcb\xeb@\xec\xd2\x850\x1d\x84\x17^H\x91CD\
+D\x8c\xa0c\xcd\x04\xf4\x1f\x10\x87\xed\xe3\xe1\xa0?\xf8\
+y^\x07b\x9f>\x84\xe9 \x1c=\x9a\x22\x87\x88\x88\
+\x18A'\x9a\x09\xe8\xb7\x11\x87\xed\xe37A\x7f\xf0\xe7\
+y\x1d\x88\xc3\x86\x11\xa6\x83\xb8 \xaa\x8f\x0eQ\xe4\x10\
+\x11\x11#\xe7\xe9f\x02\xfa\x9d\xc4a\xfbx>\xe8\x0f\
+~\xb1\xd7\x818v,\x81:\xdb\xea\xb6\x95\xf9\xf9\x14\
+9DD\xc4\x08:\xc3L@\xbf\x978l\x1f/\x07\
+\xfd\xc1/\xf3:\x10O?\x9d@\x9dm\xe7\xcc\xa1\xc0\
+!\x22\x22F\xd49f\x02\xfa\x03\xc4a\xfbx+\xe8\
+\x0f~\x95\xc7A\xb8\xafW7\xa1:\xab&\x8f;\x8e\
+\x02\x87\x88\x88\x18Q\xcf5\x13\xd0\x1f'\x0e\xdb\xc7\x9e\
+\xa0?\xf8u^\x07\xa2\xde\xed%Ts\xfe\x1c\x11\x11\
+\x11\xf7y\x81\x99\x80\xfe\x0cq\xd8>RA\x7f\xf0\x97\
+{\x1d\x88s\xe7\x12\xaa\xb3\xe9\xf6\xed\xca)(\xa0\xc0\
+!\x22\x22F\xd4%f\x02\xfa\x0b\xc4a\xfbp\x82\xfe\
+\xe07{=\xe22\x7f>\xa1:\x9b\xc7[\x16.\xa4\
+\xb8!\x22\x22F\xd8\x0b\xcd\x04\xf4\xdf\x12\x87s\xf0\x88\
+\xcbz\xaf\x03Q\x07J\x82u\xf6\x8e\xb7\x8c\x1bGq\
+CDD\xe4\x88\x0bG\x5c\x22\xc8;A\x7f\xf0k\xbd\
+\x0e\xc4\xc5\x8b\x09\xd6\xd9\x0c\xe8]\xbbR\xdc\x10\x11\x11\
+#\xec\x023\x01\xfd\x09\xe2\xb0}\xbc\x11\xf4\x07\xbf\xd2\
+\xeb@\x5c\xba\x94`\x9dMk\xd7\xa6\xb8!\x22\x22F\
+\xd8yf\x02\xfa#\xc4a\xfbx%\xe8\x0f~\xb9\xd7\
+\x81\xb8l\x19\xa1:\x9b\x0f\x14Q\xd8\x10\x11\x11\xe9\x83\
+\x9e\xa0\x0fz\x14y1\xe8\x0f~);\xe8\xe6=\xef\
+<\x0a\x1b\x22\x22b\xc4\x9di&\xa0\xff\x928l\x1f\
+\xcf\x07\xfd\xc1/\xf6:\x10/\xba\x88`\x9d-O9\
+\x85\xc2\x86\x88\x88\x18q\xcf4\x13\xd0\x7fA\x1c\xb6\x8f\
+\xa7\x83\xfe\xe0/\xf0\xdaf\x91K\xa2\xd9k\xb1\xd8\xaf\
+\x1f\x85\x0d\x11\x111\xe2N6\x13\xd0\xef \x0e\xdb\xc7\
+\xe3A\x7f\xf0s=\x0e\xc2$m\x16\xb3g\x8b\x16\x14\
+6DD\xc4\x88;\xd6L@\xbf\x8d8l\x1f\xbf\x0a\
+\xfa\x83\x9f\xeau \x9e\x7f>\xc1:\x1bVV*\xa7\
+\xb8\x98\xc2\x86\x88\x88\x18q\x8f5\x13\xd0\xaf'\x0e\xdb\
+\xc7O\x82\xfe\xe0'x=\xe2\xc2K\xa2\xd9q\xdd:\
+\x8a\x1a\x22\x22b\x0c\xeci&\xa0\xef$\x0e\xdb\xc7\x8d\
+A\x7f\xf0#\xbc\x06\xf4s\xce!\x5cg\xc3\x0b.\xa0\
+\xa8!\x22\x22\xc6\xc0\x8ef\x02\xfae\xc4a\xfb\xb82\
+\xe8\x0f~\x80\xd7\x80>{6\xe1:\x1bN\x9bFQ\
+CDD\x8c\x81\xcd\xcc\x04\xf4%\xc4a\xfb\xd8\x1c\xf4\
+\x07\x7f\xb4\xd7K\xa2S\xa7\x12\xae\xb3\xe1\xe8\xd1\x145\
+DD\xc4\x18X\xcfL@\x9fK\x1c\xb6\x8f\x15A\x7f\
+\xf0\xed\xbc\x0e\xc4I\x93\x08\xd7\xd9\xb0o_\x8a\x1a\x22\
+\x22b\x0c\xacf&\xa0O%\x0e\xdb\xc7\x05A\x7f\xf0\
+M\xbd\x1eq\x197\x8ep\x9d\x0d\xdb\xb6\xa5\xa8!\x22\
+\x22F\xdcw\xcc\x84s\xed8\xe2\xb0}\xcc\x09\xfa\x83\
+/\xf1:\x18G\x8d\x22\x5cg\xc3\xfa\xf5)l\x88\x88\
+\x88\x11\xf77\xe6\x02\xfa\xb1\xc4a\xfb\x98d\xe2\xc3\x7f\
+\xdb\xcb`\x1c:\x94p\x9d\x8dWD\x0b\x0b)l\x88\
+\x88\x88\x11\xf7\xe7\xe6\x02z7\xe2\xb0}\x0c5\xf1\xe1\
+?\xe5e0\xea\xe7\xe9\x09\xd8Us\xdb6\x8a\x1a\x22\
+\x22b\x0c\xbc\xc1\x5c@oL\x1c\xb6\x8f.&>\xfc\
+\xbb\xbd\x0c\xc6n\xdd\x08\xd8Uu\xcd\x1a\x8a\x1a\x22\x22\
+b\x0c\xdcb&\x9c\x7f!\x16\x10\x87\xed\xa3\xb1\x89\x80\
+\xfe}/\x97D\xdb\xb4!`W\xd5%K(j\x88\
+\x88\x881p\xa9\x99\x80\xfeG\xa2\xb0\x9d\x14\x89_\x06\
+=\x00vy\x19\x8c\xe5\xe5\x04\xec*\x9a:\xf7\x5c\x8a\
+\x1a\x22\x22b\x0c\xfc\x96\x99\x80\xfe\x12Q\xd8^\xfe\x1a\
+\xf4\x00X\xe5e0\x96\x96\x12\xb2\xab\xea\xf4\xe9\x145\
+DD\xc4\x188\xceL@\xff51\xd8^\xde\x08z\
+\x00\xcc\xf32\x18\xf3\xf2\x94SQA\xc8\xae\x8a\xa7\x9c\
+BQCDD\x8c\x81=\xcd\x04\xf4\x9b\x89\xc1\xf6\xf2\
+X\xd0\x03\xe0$\x8f\x831\xb5i\x13!\xbb*\x8e\x19\
+CQCDD\x8c\x81\x8d\xcd\x04\xf4\x9d\xc4`{\xf9\
+i\xd0\x03\xa0\x97\xd7\x01\xb9|9!\xbb*\x1e\x7f<\
+E\x0d\x11\x111\xe2\xee\x16\xf3\xcd\x04\xf4\xa5\xc4`{\
+\xb9\x22\xe8\x01\xd0\xd4\xeb\xa0\x5c\xb0\x80\x90]\x95K\xa2\
+#FP\xd8\x10\x11\x11#\xee\xe3\x09c=\xd0O#\
+\x06\xdb\xcb\xd2\xa0\x07@\x81\xb8\xc7\xcb\xa0\x9c:\x95\xa0\
+]\x15\x8f=\x96\xc2\x86\x88\x88\x18qo5\x17\xd0\xfb\
+\x10\x83\xed\xe5t\x13\x83\xe0\x19/\x83r\xf4hBv\
+Uv\xd0\x07\x0f\xa6\xb0!\x22\x22F\xdcm\xe6\x02z\
+\x13b\xb0\xbd\x0c21\x08\xee\xf20 \x93\xfd\xfa\x11\
+\xb4\xab\xe0\xbe\xbf\x1f\x85\x0d\x11\x111\xd2^`&\x9c\
+\x7f\x22\xe6\x13\x83\xed\xa5\x85\x89\x80~\x95\x97A\xd9\xb1\
+#A\xbb*\xf6\xeeMaCDD\x8c\xb8c\xcd\x04\
+\xf47\x89\xc0v\xa3_\x13\xfd\x22\xe8\x81p\x91\x97A\
+\xd9\xa4\x09!\xbb*G\x5cz\xf6\xa4\xb0!\x22\x22F\
+\xdc\x8ef\x02\xfa}D`\xfb\xd9\x1b\xf4@\x98\xe8a\
+@\xa6\xaaW'h\xb3\x83\x8e\x88\x88\x98\xb3\xbe/\x16\
+\x9b\x09\xe8\xd7\x11\x7f\xed\xe7\xf1\xa0\x07Bw\xaf\x83s\
+\xe3F\x826g\xd0\x11\x11\x11i\xb1\x18\xac\x97\x10\x7f\
+\xed\xe7\x07A\x0f\x84\xda^\x07\xe7\x05\x17\x10\xb63u\
+\xd0 \x8a\x1b\x22\x22b\x84\xbd\xc1\x5c@?\x99\xf8k\
+?+L\x0c\x86\x17\xbc\x0c\xce3\xce hg\xea\xd0\
+\xa1\x147DD\xc4\x08\xbb\xdc\x5c@\xefH\xfc\xb5\x9f\
+\xc9&\x06\xc3\x1d^\xce\xa1\xeb\xd70\x09\xdb\x99\x1dq\
+9\xee8\x8a\x1b\x22\x22b\x84=\xcdL8\xffL\xac\
+F\xfc\xb5\x9f\x1e&\x02\xfav/\x83\xb3[7\xc2v\
+\xa6\x8e\x1cIqCDD\x8c\xb0\x9d\xcd\x04\xf4\xd7\x88\
+\xbe\xd1\xa0\xa6\xf8e\xd0\x03\xe2,/;\xe8\xb4Z\xcc\
+\xdcq\xe3(n\x88\x88\x88\x11u\xb7Xd&\xa0\xff\
+\x84\xe8K\xab\xc5\xff8\xc0\xcb\x00-*RNE\x05\
+a;\x93>\xe8\x93'S\xe0\x10\x11\x11#\xea\xdd\xe6\
+\xce\x9f\xaf#\xf6F\x87\x07\x83\x1e\x10\xf5\xbc\x0e\xd2\xe5\
+\xcb\x09\xdc\x998k\x16\x05\x0e\x11\x111\xa2n1\x17\
+\xd0\xcf$\xf6F\x87kL\x0c\x8a\xe7\xbc\x0c\xd2\x193\
+\x08\xdb\x998\x7f>\x05\x0e\x11\x111\xa2N3\x17\xd0\
+\x8f&\xf6F\x87\x85&\x06\xc5\x8dtr\x09\xce%K\
+(p\x88\x88\x88\x11\xb5\xbb\x99p\xfe\x09\x1d\x5c\xa2\xc5\
+\xb1&\x02\xfa\xc5^\x06i\xc7\x8e\x84\xedL\x5c\xbd\x9a\
+\x02\x87\x88\x88\x18\xd1\x0b\xa2\xd5\xcd\x04\xf4g\x88\xbc\xd1\
+\xa2\xbe\x89\x80>\xd6\xcb@\xad]\x9b\xb0\x9d\x89[\xb6\
+P\xe4\x10\x11\x11#\xe8\xcf\xcd\x1do\xb9\x86\xc8\x1b=\
+\xf6\x04=0Zy\x1c\xa8\xa9\x8d\x1b\x09\xdc\x99tr\
+\xa9^\x9dB\x87\x88\x88\x181W\x99\x0b\xe8s\x89\xbb\
+\xd1\xe3\xae\xa0\x07F\x9e\xf8\xb2\x97\x80~\xee\xb9\x04\xee\
+L,/\xa7\xd0!\x22\x22F\xcc\xd1\xe6\x02zo\xe2\
+n\xf4\xb8\xcc\xc4\xe0\xf8\x9e\x97\xc1z\xc2\x09\x84\xedL\
+l\xdf\x9eB\x87\x88\x88\x181\x1b\x99\x09\xe7\x9f\x89%\
+\xc4\xdd\xe81\xd1D@?\x8f\x8b\xa2\xc1\xd9\xbb7\x85\
+\x0e\x11\x111B>nn\xf7\xfc\x05\xa2n4ik\
+b\x80xzQ\xb4\xa4D9\x95\x95\x04n\xbfg\xd0\
+G\x8e\xa4\xd8!\x22\x22F\xc8\x1d\xe6\x02\xfauD\xdd\
+h\x92'\xfe%\xe8\x01R&\xbe\xefe\xd0\xaeXA\
+\xe8\xf6\xeb\xa4I\x14;DD\xc4\x08y\x9a\xb9\x80>\
+\x93\xa8\x1b]\xee11H\xee\xf32h\xa7L!p\
+\xfb\xddA?\xe7\x1c\x8a\x1d\x22\x22b\x84<\xcc\x5c@\
+oG\xcc\x8d.\xabL\x0c\x92\xf5^\x06\xed\xc0\x81\x84\
+n\xbf\xaeZE\xb1CDD\x8c\x88\x8f\x98\x0b\xe7\x7f\
+pOJ@D\x19eb\xa0\x9c\xe8e\xe0\xea\x96\x81\
+\x84n\x7fVT\xa8da!E\x0f\x11\x111\x02\xae\
+3\x17\xd0\x7fL\xc4\x8d6u\xc5/\x83\x1e(\xf2\x1f\
+\xa2\xf6z\x19\xbc\xeb\xd6\x11\xba\xe9\x85\x8e\x88\x88\x18K\
+G\x9a\x0b\xe8\x17\x10q\xa3\xcf\xcb&\x06\xcb=^\x06\
+\xef\xb4i\x04n\xbf\xe7\xd0\xbbv\xa5\xe8!\x22\x22Z\
+\xeen\xb7q\x86\xa1\x80~\x0c\xf16\xfa\x5cob\xb0\
+\xac\xf02\x80\xfb\xf6%t\xfbu\xd80\x0a\x1f\x22\x22\
+\xa2\xe5\xdea.\x9c\xffC,\x22\xdeF\x9f9&\x06\
+\xcc0/\x03\xb8A\x03\x02\xb7_O?\x9d\xc2\x87\x88\
+\x88h\xb9\xe7\x99\x0b\xe8w\x13m\xe3\xc1\x91&\x06L\
+\xa9\xfb\xf3\xce\xa1\x06pj\xf5jB\xb7\x1f/\xba\x88\
+\xc2\x87\x88\x88h\xb9\x1d8\x7f\x0e>\xd1mxR&\
+\x06\xcd\x8f\xbd\x0c\xe2\xc9\x93\x09\xdd~\xdc\xbe]9y\
+y\x14?DDDK}\xdc\x5c8\xd7v&\xda\xc6\
+\x87\x1f\x98\x184\xf3\xbc\x0c\xe4\xce\x9d\x09\xddtrA\
+DD\x8c\x8d\xab\xcc\x85\xf3$\xfd\xcf\xe3\xc5\x0c\x13\x03\
+\xa7\x8d\x97\x81\x5cT\x94\xde\x15&x{6\xd9\xbd;\
+\x05\x10\x11\x11\xd1R{\x99\x0b\xe8\xd7\x13i\xe3EK\
+S?\xbd\xfc\xc6\xcb`\x9e7\x8f\xe0\xed\xc7\xb1c)\
+\x80\x88\x88\x88\x16\xfa\xb2X`.\xa0\x9fA\xa4\x8d\x1f\
+o\x9b\x18<\xeb\xbc\x0c\xe8!C\x08\xdd~<\xfbl\
+\x8a \x22\x22\xa2\x85n7\x17\xce\xf5\xc3\x93\xe5\xc4\xd9\
+\xf8\xf1?\xb6\xb4[L\xd5\xabG\xe8\xf6\xe3\xc6\x8d\x14\
+ADDD\x0b\x1dd.\xa0?G\x94\x8d'\x93M\
+\x0c\xa0\xea\xe2\x9b^\x06\xf5\xf2\xe5\x04o?\xd6\xafO\
+!DDD\xb4\xc8\xdf\x89\x85\xe6\x02\xfaJ\xa2l<\
+\xa9'~nb\x10Uz\x19\xd8\xc7\x1fO\xe8\xf6a\
+\xaagO\x8a!\x22\x22\xa2E\xae5\xdb^\xb1\x0bQ\
+6\xbe<ab\x10\x8d\xf60\xa8\x93\x8d\x1a\x11\xbc\xfd\
+8i\x12\xc5\x10\x11\x11\xd1\x22{\x9a\x0b\xe7\xef\x12a\
+\xe3\xcd\xc5&\x06R\xb1\xf8\xba\x97\xc1}\xc9%\x04o\
+\xaf;\xe8K\x96P\x0c\x11\x11\x11-\xf1I1\xcf\x5c\
+@\xdfJ\x84\x8d7G\x99\xfa)\xe6j\x8e\xb9d\xd7\
+]\xbbT\xaaZ5\x8a\x22\x22\x22\xa2\x05.7{\xbc\
+e\x08\x116\xde\xe8\xd7\xa7\xde71\x98\xc6z\x19\xe0\
+M\x9a\x10\xbc\xfd\xd8\xba5E\x11\x11\x11\xd1\x02;\x9a\
+\x0b\xe7\xff+\x16\x12a\xe3\xcf\xd5&\x06T\x0d\xf1m\
+/g\xd19\xe6\xe2\xddQ\xa3(\x8a\x88\x88\x88!\xfb\
+\x0b\xb3\xbb\xe7\xdf!\xba\xe6\x06cM\x0d\xaa\xab\xbc\x0c\
+\xf4a\xc3\x08\xde^]\xb0\x80\xc2\x88\x88\x88\x18\xb2g\
+\x9a\x0d\xe8#\x89\xae\xb9A\x89\xf8w\x13\x83\xea8/\
+\x03\xbdf\xcd}\xe7\xab\x09\xe0\x1e\xdc\xb1C9EE\
+\x14GDD\xc4\x90\xd4\xa7\x03j\x99\x0b\xe7\x7f\xe4x\
+Knq\xb3\x89\x81\xa5\x9b\xf7\xff\xd6\xcb\x80\x9f;\x97\
+\xf0\xed\xd56m(\x90\x88\x88\x88!\xb9\xcb\xec\xee\xf9\
+\x15D\xd6\xdc\xe2$S\x83k\xb9\x97\x01\xdf\xbd;\xc1\
+\xdb\xab'\x9c@\x81DDD\x0c\xc9^f\x03z_\
+\x22knQC\xfc\x87\x89\xc1\xd5\xd1\xcb\x80\xd7\xc76\
+.\xbf\x9c\xf0\xed\xc5\xf3\xce\xa3@\x22\x22\x22\x86\xe0#\
+\x09\xa3\xbd\xcf\xf7\x88\xf9D\xd6\xdc\xe3\x87\xa6\xbe\x01\xde\
+\xe3e\xe0O\x9eL\xf8\xf6\xf2`\x11\xe7\xd0\x11\x11\x11\
+Cq\x9a\xd9\xdd\xf3\x8dD\xd5\xdcd\xa2\xa9A\xf6-\
+/\x03\xff\xb0\xc3\x08\xe0^\xed\xd4\x89B\x89\x88\x88h\
+\xd07\xc4\x9af\x03zw\xa2*\xc7\x5c\x02\xb5\xb6\xf8\
+\x8e\x97\x09\xb0h\x11\xe1\xdb\x8b\x93&Q,\x11\x11\x11\
+\x0d\xba\xcel8\xff\x1d15\xb7\xb9\xc9\xd4`\xdb\xee\
+e\x02\xf4\xeaE\xf8\xf6\xe2\x9a5\x14KDDDC\
+&\xc5\xd6f\x03\xfa\x02\x22jns\x82\xa9\xc1v\xb4\
+\x97\x09PX\xa8R\x9b6\x11\xc0\xbd\xd8\xa8\x11E\x13\
+\x11\x11\xd1\x80?4\x1b\xce?\x11\xeb\x13Qs\x1b\xdd\
+\xfc>e\xd5e\xd1\xf1\xe3\x09\xdf^\x1c2\x84\xa2\x89\
+\x88\x88h\xc0af\x03\xfa\xcd\xc4S\xd0l15\xe8\
+N\xf72\x11\xf4\xcepe%\x01\xfcP\xce\x9bG\xd1\
+DDD\x0c\xd8\xfb\xcd\xb6V\xd4\x0e'\x9a\x82\xa6\xab\
+\xa9AWC|\xcd\xcb\x84\x98=\x9b\x00~\xa8v\x8b\
+;w*\xa7zu\x8a'\x22\x22b\x80\x9el6\x9c\
+\xbf\x97\xa0\xf79\xec\xc7s\xa6\x06\xdfj/\x13\xa2U\
++B\xb8\x07\x93\xfa\x05V\x8a'\x22\x22b \xfeF\
+,4\x1b\xd0W\x12Ia\x7f\xce75\xf8\x8e\x10\xf7\
+x\x99\x18\x8b\x17\x13\xc2\x0f\xe5\x8c\x19\x14PDD\xc4\
+\x80\x9ci6\x9c\xffKlL$\x85\xfdi$~f\
+j\x10^\xe5\xa5\xa3\x8b\xde\x1d&\x84\x1f\xdc-[\x94\
+SXH\x11EDD\xcc\xb2/\x8a%f\x03\xfa\xf7\
+\x89\xa3p ~jj\x10v\xf729\x0a\x0a\x94s\
+\xd9e\x84\xf0C\x1ds\xe9\xd0\x81B\x8a\x88\x88\x98e\
+\x17\x9a\x0d\xe7\xda>DQ8\x10\xa3L\x0e\xc4;\xbc\
+L\x90\xc1\x83\x09\xe1\x87r\xf2d\x0a)\x22\x22b\x16\
+\xd5\x0d-j\x99\x0d\xe7O\x11C\xe1\x9b\xd0\xb7\x86\xdf\
+25\x18\x8f\xf70AR\xd5\xaa\xf1p\xd1\xa1\xba\xb9\
+\xac_\xaf\x9c\xbc<\x0a*\x22\x22btw\xcf\xa7\x12\
+C\xe1`\x5cdj0\x16\x88\x8fy9\x8b~\xdcq\
+\x04\xf1C\xd9\xae\x1d\x05\x15\x11\x111\x0b\xbe,\xd64\
+\x1b\xce\xff \x16\x13A\xe1`4H\xa4\x9f\x9852\
+(O\xf52Y\xd8E?\xf4.:\xc7\x5c\x10\x11\x11\
+\xb3\xe2|\xf3\xbb\xe7k\x89\x9f\xe0\x85\x1bM\x0d\xca\x22\
+\xf1I/\x13\xe6\xf8\xe3\x09\xe2\x07S\x7f\x81\xd1\x97j\
+)\xac\x88\x88\x88U\xea\xdcRj6\x9c\xebM\xd1&\
+DO\xf0B?\x93\xdf\x1c\xa7z\x994\xa5\xa5*\xb9\
+u+A\xfc`v\xecHqEDD\xac\x82s\xcd\
+\xef\x9e_M\xec\x04?<j\xdd.\xfa\xa8Q\x84\xf0\
+\x83\xb5[\x9c:\x95\xe2\x8a\x88\x88\x98\xa1O\xb8\x99\xc4\
+`8\xd7\xef\xcf\xb4$r\x82\x1fN5\xf9\x0dr\x86\
+\xd7\xb3\xe8\x1b7\x12\xc6\xbfI\xfd\x0bCQ\x11E\x16\
+\x11\x111\x03O5\xbf{~+q\x13\xfcR(\xee\
+65H\x8b\xc5\xe7\xbcL :\xba\x1c\xdc\xae])\
+\xb2\x88\x88\x88>\xbd\xdf\xed.g8\xa0\xf7 nB\
+&\x9cor\xa0N\xf62\x89\xf4\xb3\xf6k\xd6\x10\xc4\
+\xbf\xc9\xb3\xce\xa2\xd0\x22\x22\x22\xfa\xb4\xbf\xf9p\xfe\x0b\
+b&dJm\xf1C\x93g\xd1\x1f\xf72\x91\xfa\xf6\
+%\x88\x7fS\xbb\xc5\x8a\x0a\x95\xacY\x93b\x8b\x88\x88\
+\xe8\xd1[\xcd\x87s\xedq\xc4L\xa8\x0a;L\x0e\xd8\
+\x09^&\x93n'\xb8b\x05\x81\xfc\x9b\x1c<\x98\x82\
+\x8b\x88\x88\xe8\xc1\xa4\xd8\xd5|8\x7f\x8ax\x09U\xa5\
+\x95{\xcb\xd8\xc8\xa0\xcdw\xcf\x81\x1djB\xa5:u\
+\x22\x88\x7f\x93\x17_L\xd1EDD\xf4\xe0\x15\xe1\xec\
+\x9e\x9f@\xbc\x84lp\x83\xc9\x81;\xd2\xe3\xa4J\x9d\
+{.a\xfc\x9b<\xec0\x0a/\x22\x22\xe2A|K\
+lb>\x9c?I\xac\x84l\xd1A\xfc\xc2\xe4\x00\xbe\
+\xc3\xcb\xe4j\xdcx\xdf\x99k\x02\xf9\x01<\xf9d\x8a\
+/\x22\x22\xe2A<?\x9c\xdd\xf3Q\xc4J\xc8&\xdf\
+79\x80;\x89{\xbdL\xb0)S\x08\xe3\x07\xba,\
+\xbaaC\xfa\xac>\x05\x18\x11\x11\xf1k>\x9a0\xfe\
+(\x91\xf6A\xe2$d\x9b\x8e\xa6w\xd1\xb7{9\xe6\
+R\xbb\xb6r\xb6m#\x94\x1f\xe8e\xd1\xa3\x8e\xa2\x08\
+#\x22\x22\x1e\xc0\x11\xe1\xec\x9e\x0f%NB\x10\xdca\
+r \xebsao{\x99hC\x87\x12\xc8\x0f\xe4\x82\
+\x05\x14aDDD;\xda*>L\x8c\x84\xa08J\
+\xfc\xd2\xe4\x80>\xdf\xcbd\xcb\xcfOw.!\x94\x7f\
+\xd5\xcaJ\x95l\xd4\x88b\x8c\x88\x88\xb8\xdf\xc5\xd0\xc3\
+\xcd\x87\xf3/\xdc\x0c\x05\x10\x18w\x9b\x1c\xd45\xc4\xe7\
+\xbcL\xbaV\xad\xf6\x05R\x82\xf9\xff;\x8b>~<\
+\x05\x19\x11\x11\xd1\xf5\x82pv\xcfo#>B\xd0\xf4\
+0\xbd\x8b>\xc9\xeb\xc4\x9b:\x95P\xfe\xff\xdd\xb4I\
+%\x0b\x0b)\xca\x88\x88\x98\xf3>,V3\x1f\xce?\
+\x15\xdb\x12\x1f\xc1\x047\x99\xfe\xf6y\x9b\x97\xc9W\xab\
+\x96r\xb6l!\x94\xff\x7f\xbbw\xa70#\x22bN\
+\xab;\xc3u\x0fg\xf7|;\xb1\x11L\xd1\xd6\xfdF\
+hl\x80\xb7\x13w{\x99\x84\x83\x06\x11\xc8\xff\xbf\xe7\
+\x9dGqFD\xc4\x9cvc8\xe1\xfc\xcfb]b\
+#\x98\xe4;\xa6\x07\xfae^&a^\x9er\xe6\xcf\
+'\x94\xf3\xb2(\x22\x22\xe2>_\x10\xeb\x86\x13\xd0\x97\
+\x13\x17\xc14-\xc4\x7f\x99\x1c\xe8\xb5\xc4\xdfy\x99\x8c\
+\x8d\x1a\xa9\xd4\x8e\x1d\x84\xf2\xfd=\xe3\x0c\x8a4\x22\x22\
+\xe6\xa4'\x86\x13\xce\xf7\x8a\xa5\xc4E\x08\x83]\xa6\x07\
+\xfc)^'\xe4\x88\x11\x84\xf2\xfd\xbb\xb9\xe8/,\xa5\
+\xa5\x14jDD\xcc)\xaf\x0e'\x9ckO'&B\
+X4\x12?0=\xe8o\xf60!\x93\xba7\xfa\x92\
+%\x84\xf3\xfdC\xba\xfe\xd2B\xb1FD\xc4\x1c\xf1%\
+\xb1A8\xe1\xfc\x111\x8f\x98\x08a\xb2\xd8\xf4\xc0?\
+L|\xc3\xcb\xe4l\xde\x5c\xa5**\x08\xe7\xffv\xf5\
+\xea\xf4\x19}\x8a6\x22\x22\xe6\x80#\xc2\x09\xe7\xba\x89\
+\xc6\x91\xc4C\x08\x9b\xea\xe2{\xa6'\xc0\x5c\xaf\x13t\
+\xcc\x18\x82\xf9\xfe\xbb\xe8]\xbbR\xb4\x11\x111\xf6^\
+\x1f\xde\xd1\x96+\x89\x86`\x0b\x93MO\x80B\xf1^\
+\xafG].\xba\x88p\xee\x9a\x5c\xb8\x90\xc2\x8d\x88\x88\
+\xb1\xf6E\xb1Qxm\x15\xeb\x13\x0b\xc1\x16\xf49\xab\
+'MO\x84.\xe2\x1e/\x93\xb5qc\xe5\xd0\xd5\xe5\
+\xbf\xb6hA\x01GD\xc4\xd8:*\xbc\xdd\xf3yD\
+B\xb0\x8d\xfe\xe2\x97\xa6'\xc3R\xaf\x13v\xf8p\x82\
+\xf9\xbf\x8f\xb9\xcc\x9cI\x01GD\xc4X\xba-\xbcp\
+\xfe\x94X@\x1c\x04\x1b\xb9\xd9\xf4\x84(\x12\x7f\xe5\xf1\
+\xa8K\xea\xc2\x0b\x09\xe8\xda]\xbb\x94S\xa7\x0e\x85\x1c\
+\x11\x11c\xe5\x13bY8\xe1\xfcs\xb1;1\x10l\
+\xa5\x5c\xfc\xab\xe9\x89\xd1F|\xc7\xcb\xe4\xad[W9\
+\x9b7\x13\xd0\xb5\x13&P\xcc\x11\x1116\xee\x16\xbb\
+\x86\xb7{\xbe\x99\x08\x08\xb6\xb38\x8c\xc91\xdf\xeb$\
+>\xfah\xc2\xb9\xbe,\xbau\xabrJJ(\xea\x88\
+\x88\x18\x0b/\x0e/\x9c\xeb\x17Ck\x12\xff\xc0v\xf4\
+\xf9\xab\xdf\x9a\x9e \xf9\xe2\x8f=N\xe2}g\xb0\x09\
+\xe9\xca\x19:\x94\xa2\x8e\x88\x88\x91\xf7.\xb7\xbb[H\
+\x01\xfdx\xa2\x1fD\x85\xa1aL\x92\xd6\xe2\xdb^&\
+sq\xb1J\xad\x5c\xc9e\xd1\x0d\x1b\x94STDq\
+GD\xc4\xc8\xaa\x1f.l\x19^8\xff\x19\x91\x0f\xa2\
+\xc6\x0f\xc3\x98,g{\x9d\xd4\xadZ\xf1\xca\xa8>\xea\
+\xd2\xaf\x1f\x05\x1e\x11\x11#\xeb\xc4\xf0\xc2\xf9\x07b3\
+\xe2\x1eD\x8d\xa6\xe2\x87a\x1cu\xb9\xcd\xeb\xc4\x1e2\
+\x84\x80\xbev\xadr\x0a\x0b)\xf2\x88\x88\x189w\x86\
+\x17\xce\xb5g\x11\xf5 \xaa,\x0ac\xd24\x11_\xf1\
+:\xc1\xa7M\xe3,z\xdf\xbe\x14zDD\x8c\x94\x8f\
+\x8a\xa5\xe1\x85\xf3\xfb\x12\xe9G\x1a\x01\x22I\xa1\xf8L\
+\x18\x93g\xb4\xd7I^\x5c\xac\x9c\xe5\xcbs\xfb,\xfa\
+\xea\xd5\xfb\xfa\xc4S\xf0\x11\x111\x0a\xea\xfbfG\x86\
+\x17\xce\xff.\xb6$\xe2A\xd4\xe9 ~\x12\xc6$Z\
+\xefu\xb2\x97\x97+G\xb7\x1d\xcc\xe5]\xf4c\x8e\xa1\
+\xe8#\x22b$\x1c\x1b\xee\xd1\x96\xd9D;\x88\x0b\xeb\
+\xc2\x98D5\xc4\x87\xbdN\xf8\x1e=r;\xa0\xeb_\
+\x11\xf2\xf2(\xfc\x88\x88h\xb5\x97\x87\x1b\xce\x1f\x14\xf3\
+\x89u\x10\x17\xaa\x8b\xaf\x851\x99:xm\xbd\xa8\x9d\
+4)\xb7Cz\xb7n\x14\x7fDD\xb4\xd6{\xc5\xe2\
+p\x8f\xb6\xb4&\xd2A\xdc\x18(~\x11\xc6\xa4:\xd5\
+\xeb\xe4/(P\xce\xa2E\xb9\x1b\xd0\x97.e\x17\x1d\
+\x11\x11\xad\xf4U\xb1Y\xb8\xbb\xe7\xb3\x88r\x10W\xae\
+\x08kb\xed\xf4Z\x04\xea\xd6U\xa9M\x9br\xf7\xc2\
+h\xa7N,\x04\x88\x88h\x95Iqx\xb8\xe1\xfc\xa7\
+D8\x883e\xe2\xdba\x9dG\x7f\xd0k1h\xdf\
+^9\xb9\xfa\x88\xd1\xe2\xc5,\x06\x88\x88h\x95\x8b\xc3\
+\x0d\xe7\xbf\x17\x1b\x12\xe1 \xee\x0c\x0e\xeb\xa8K{?\
+\xe7\xd1\xc7\x8c\xc9\xdd]\xf46mX\x10\x10\x11\xd1\x0a\
+\xbf\x9bH?B\x18b@?\x91\xe8\x06\xb9\xc2\xce\xb0\
+&\xda\x04\xafE!/O%\xa7O\xcf\xcd\x90\xbe`\
+\x01\x8b\x02\x22\x22\x86\xeeCb\xcdp\xc3\xf9\xd5D6\
+\xc8%j\x88o\x845\xe1\xd6x-\x0e\xd5\xaa)\xe7\
+\xe2\x8bss\x17\xbdeK\x16\x07DD\x0c\xcd\xd7\xc4\
+\xd6\xe1\x86\xf3\xb7\xc4R\x22\x1b\xe4\x1a\xfd\xc3:\xeaR\
+$\xfe\xc4k\x91\xa8UK9\x97]\x96{!\xfd\x82\
+\x0bX \x10\x111\x14\xf7\x8a\xc7\x85\x1b\xce\xff%\xf6\
+$\xaaA\xae\xb2)\xac\xc9\xd7H|\xdek\xb18\xfc\
+p\xe5l\xdfNG\x17DDD\x03.\x087\x9ck\
+\x17\x13\xd1 \x97\xd1\xafq=\x10\xd6\x04\xec$\xbe\xe3\
+\xb5`\xe8G|*+s+\xa4/[F_tD\
+D4\xea\xc6\xf0\xc3\xf9O\xc4<\x22\x1a\xe4:\xfaU\
+\xae\x0f\xc3\x9a\x883|\x14\x8d\xd4\xc8\x91\xb9w\xd4\xa5\
+G\x0f\x16\x0cDD4\xa2>~Z-\xdcp.\xff\
+\x18\x89FD3\x804g\x86\xf9my\x87\x9f\x90~\
+\xc6\x19\xb9\x15\xd0W\xaeL\xbf\xb0\xca\xc2\x81\x88\x88\x01\
+\xfa\xb8X/\xdcp\xae\xef\xc5\x0d#\x92\x01|\x95\x9b\
+\xc2\x9a\x94\xfa\xdb\xfaO\xbd\x16\x11\x1dV\xcf??\xb7\
+B\xfa\x80\x01,\x1e\x88\x88\x18\x98\xaf\x84\xdf\xb1E\xbb\
+\x9e(\x06\xf0u\xea\x88\xef\x8551\xeb\x8bOz-\
+&\xa5\xa5*\xb5zu\xee\x5c\x16]\xbf^\xa5t\xcb\
+I\x16\x11DD\xcc\xb2\xbb\xc5\xfe\xe1\x87\xf3\x87\xc4B\
+\xa2\x18\xc0\x81\x19 ~\x1e\xd6\x04\xd5/\x8d\xbe\xee\xa3\
+\xb3Kr\xeb\xd6\xdc\xd9E\x1f:\x94\x85\x04\x11\x11\xb3\
+\xee\xa9\xe1\x87\xf3\x94\xd8\x84\x08\x06pp\x96\x879Q\
+\xfb\xb8\xdf\xe6=\x15\x966m\x94\xb3cGn\x04\xf4\
+\xcb/WN\x8d\x1a,&\x88\x88\x985\x17\x85\x1f\xce\
+u\xbf\xf3\xdeD/\x80CS \xfe:\xcc\x09;\xcb\
+\xcf\xa5\xd1\xae]U\xaa\xa2\x227B\xfa\x981,(\
+\x88\x88\x98\x15\xaf\x11\xf3\xc3\x0f\xe8\x17\x11\xbb\x00\xbc\xd3\
+P\xdc\x1b\xe6\xa4]\xe3\xa7\xd0\xe8K\x94\xb9\x10\xd0\xb7\
+oW\xc9\x9a5YX\x10\x11\xb1J\xde\x96H\xbf\xea\
+\x1dr8\xbf\x91\xb8\x05\xe0\x9f\xe3\x12\xe9\x96G\xa1L\
+\x5c]8n\xf1SpN8!7B\xfa)\xa7\xb0\
+\xb8 \x22b\xc6>\x95H\xbf\xe6\x1dr8\x7fS\xac\
+M\xd4\x02\xc8\x8c\xd5aN`\x99\xb9\xea\x11?\x85G\
+\x87\xd7\xb8\x07\xf4\x9d;\x95\xd3\xa0\x01\x8b\x0c\x22\x22\xfa\
+\xf65\xb1C\xf8\xe1\x5c?\x8e\xd8\x89\x88\x05P\xb5\xf3\
+\xe8\xf7\x879\x91[\xba\xfdY\xbd\x14\x9ed~\xber\
+\xe6\xce\x8d\x7fH\x9f:\x95\x85\x06\x11\x11}\xf9\x8e\xd8\
+;\xfcp\xfe\xa58\x9ex\x05Pu\x1a$B\xec\x8f\
+\xae\xed'\xbe\xeb\xb5\x08\x15\x16*g\xfe\xfcx\x07\xf4\
+\xcaJ\xe5\xb4j\xc5\x82\x83\x88\x88\x9e\xdc#\x0e\x0f?\
+\x9c+\xf7\x97y\x00\xc8\x12=\xc4\x8f\xc3\x9c\xd4'\x88\
+\xef{-F\xd5\xab+\xe7\xe2\x8b\xe3\x1d\xd2\x17/V\
+N^\x1e\x0b\x0f\x22\x22\x1e\xfc\xd7eq\x92\x1d\xe1\xfc\
+\x0e1\x9fH\x05\x90]&\x87=\xb9Ov\x0b\x8d\xa7\
+\xa2T\xbb\xb6r\xd6\xac\x89uHOv\xef\xce\xe2\x83\
+\x88\x88\x07u\x9a\x1d\xe1\xfc\x05\xb1\x8c(\x05\x10\x0cW\
+\x85=\xc9\x17\xf9\xe9\x91\xde\xa4\x89Jm\xda\x14\xdf\x90\
+\xbejU\xfaH\x0f\x0b\x10\x22\x22\x1e\xc0\xe5v\x84\xf3\
+\xbf\x88\xed\x89P\x00\xc1Q(>\x14\xf6d_\xe5\xa7\
+@\x95\x97\xab\xd4\xc6\x8d\xf1\x0d\xe9#F\xb0\x08!\x22\
+\xe2\xd7\x5ccG8\xd7\xc7c\xfb\x13\x9f\x00\x82\xe7p\
+\xf1\x0faN\xf8\x02\xf1:?\x85\xea\xb0\xc3\x94\xb3y\
+s<\x8f\xb9l\xdd\xaa\x9cZ\xb5X\x8c\x10\x11\xf1?\
+^/\x16\xda\x11\xd0g\x10\x9b\x00\xcc1D\xfcW\x98\
+\x93\xbeX\xfc\x89\x9f\x82u\xc4\x11\xca\xb9\xfc\xf2x\xee\
+\xa2O\x9e\xcc\x82\x84\x88\x88\xfb\xfc\xb1\xbbFZ\x10\xce\
+7\x10\x97\x00\xcc3)\x91\xeeg\x1a\xda\xe4/\x13\xef\
+\xf5S\xb8Z\xb6T\xce\xb6m\xf1\x0b\xe8\x15\x15\xcai\
+\xda\x94\x85\x09\x111\xc7\xbdS,\xb1#\x9c\x7fO\xcc\
+#*\x01\x84\xc3\xba\xb0\x8b@}\xf1Q?\x05\xac}\
+{\x95\xda\xb1#~!}\xc1\x02\x16'D\xc4\x1c\xf6\
+!\xb1\xae\x1d\xe1\xfc\xd7b5\x22\x12@x\xe8\x97F\
+\xef\x0c\xbb\x18\xb4\x11_\xf6S\xc8:vT\xa9\x9d;\
+\xe3\x17\xd2;wf\x91BD\xccA\x9f\x15\x9b\xd9\x11\
+\xce\xdf\x13\x1b\x13\x8f\x00\xc2\xa7D\xfcM\xd8E\xa1\xab\
+\xf8\x86\x9f\x82\xd6\xad\x9brv\xed\x8aU@O\xadX\
+\xa1\x9c\x82\x02\x16+D\xc4\x1cR\x16`u\x18\xed\x14\
+\x01\xe0\x004\x17\x7f\x1fvq8.\x91~\xce\xd8s\
+a;\xfah\x95\xd2\xe7\xb7\xe3\xb4\x8b>x0\x0b\x16\
+\x22b\x8e\xf8\x82\xd8\xd6\x8ep\xfe\x998\x8a8\x04`\
+\x1fG\x8b\xff\x08\xbbH\x8c\xf2\x19\xd2S\x03\x07*\xa7\
+\xb22>\x01]\xf7|/)a\xe1BD\x8c\xb9\xcf\
+\x8b\xad\xec\x08\xe7\xb4S\x04\xb0\x9c\x09\xe2\x17a\x17\x8a\
+\x13\xc5\xf7\xfd\x14\xbac\x8eIwB\x89\xcbQ\x97\xd3\
+Nc\xf1BD\x8c\xb1/\x89\x1d\xed\x09\xe7\xb4S\x04\
+\x88\x00\xcbm(\x18\xa7\x8a{\xfd\x14\xbc\x1e=\xe2s\
+\xdcE\xff\x22\xd0\xa2\x05\x8b\x18\x22b\x0c}E<\xd2\
+\x9ep\xfe\xc3\x04\xed\x14\x01\x22\x81\x9e\xa8\xb7\xdaP8\
+\xe6\xf9-|q\x0a\xe9K\x96('/\x8f\xc5\x0c\x11\
+1F\xbe)\xf6\xb4'\x9c?%\x96\x11{\x00\xa2C\
+u\xf1q\x1b\x0a\xc8\x1c\x9f\xc5/\xd9\xbd{|B\xfa\
+\x80\x01,h\x88\x881Qw*\xebaO8\x7f^\
+\xacM\xdc\x01\x88\x1eM\xc5wm($\xcb\xfd\x16\xc2\
+\xa3\x8f\x8eG\x0b\xc6\xcd\x9bU\xb2\xac\x8c\x85\x0d\x111\
+\xe2\xcab\xaa\x06\xd9\x13\xce\xdf\x17\x9b\x11s\x00\xa2K\
++1eCA\xb9\xc4\xefN\xfaQG\xc5#\xa4\x9f\
+q\x06\x8b\x1b\x22b\x84}G\x1chO8\xd7kz\
+k\xe2\x0d@\xf4\xe9\x22\xfe5\xec\xa2\x92'\xae\xf7[\
+\x18;w\x8e\xfe\x8b\xa3\xfa\xc2h\xcb\x96,r\x88\x88\
+\x11\xdd9\x1flO8\xd7kyWb\x0d@|8\
+^\xfc4\xec\xe2R ^\xe1\xb7@v\xea\xa4\x9c\x1d\
+;\xa2\x1d\xd2\x97.UN~>\x8b\x1d\x22b\x84\xd4\
+oz\x8c\xb5'\x9c\xffK\x1cA\x9c\x01\x88\x1f\xa7&\
+,\xe8\x91\x9e\x9fAHO\xc5!\xa4\xf3\xc2(\x22b\
+\xa4v\xce\x8f\xb5'\x9c\xebWB\xc7\x12c\x00\xe2\xcb\
+E6\x14\x9b\x22\xf1\x1a\xbf!\xbdk\xd7h\x1fw\xd9\
+\xbcY9\x5c\x18ED\xb4\xde\xdd\x89\xf4\xab\xd8\x09{\
+<\x87\xf8\x02\x10\x7f6\xd8Pp\xf4q\x97\xed~C\
+z\x9b6\xca\xd9\xb2%\xba!\xfd\xcc3Y\xfc\x10\x11\
+-\xefs\xde\xd7\xaep\xbe\x94\xd8\x02\x90\x1b\xe8\x87\x8c\
+\xae\xb5\xa1\xf0\xe8\x8b\xa3\x1b\xfc\x16\xd0#\x8eP\xa9M\
+\x9b\xa2{a\xb4m[\x16ADDK\xc3y\x1f\xbb\
+\xc2\xf9\x16\x22\x0b@nQ \xdenKH\xf7\xdd\xdd\
+\xa5qc\xe5\xac[\x17\xcd\x90\xbe|\xb9r\x0a\x0aX\
+\x0c\x11\x11-{\x84\xa8\x97]\xe1\xfc:wC\x0d\x00\
+r\x8c\x9a\xe236\x14\xa2\xfc\x0c\x8e\xbb8\xe5\xe5\xd1\
+\x0d\xe9C\x87\xb2 \x22\x22Z\xe2[b\x7f\xbb\xc2\xf9\
+\xbdb5b\x0a@\xeeR_|\xc5\x96\x9d\xf4\xb5~\
+\xcf\xa4\xd7\xae\xad\x92\x97\x5c\x12\xb9\x80\x9e\xd2\x1di\x1a\
+6daDD\x0cYY\x00UW\xbb\xc2\xf9\xcf\x09\
+\xe7\x00\xa0\xd1\xaf\x8d:\xb6\x84\xf4M~\x0bli\xa9\
+r.\xbc0z\xbb\xe8\xe7\x9f\xaf\x9c\xbc<\x16HD\
+\xc4\x90|]\xeciW8\x7fL,#\x96\x00\xc0\xbf\
+i#&m)RK\xfd\x16\xda\x92\x12\xe5,Z\x14\
+\xbd\x9d\xf4>}X$\x11\x11C\xf0%\xb1\x93]\xe1\
+\xfc!\xb1\x06q\x04\x00\xfe?G\x89\x7f\x89\xecq\x97\
+j\xd5\x94s\xee\xb9\xd1\xeb\x8d^\xb3&\x8b%\x22\xa2\
+A_\x15\xbb\xd9\x15\xce\x9f\x17\xeb\x12C\x00\xe0\x9b\xe8\
+%~`KH_\x95IH\x9f7/R!=9\
+u*\x0b&\x22\xa2\xc1\x9ds\xcb\xce\x9c\xbf(6 \
+~\x00\xc0\xa1\x18(~dK\xf1Z\xee\xb7\x00\xe7\xe7\
++\xe7\xf4\xd3\xa3\xb5\x93\xde\xa5\x0b\x0b'\x22b\xc0>\
+/\xb6\xb3+\x9c\xbf*\x96\x13;\x00\xc0+\xfd\xc4\xbf\
+\xdbR\xc4f\x88I?\x85X_\xbe\x1c=::\xbb\
+\xe8k\xd7*\xa7\xb8\x98\x05\x14\x111 \x1f\x11\x0f\xb3\
++\x9c\xbf$6$n\x00\x80_\x8e\x13?\xb6\xa5\x98\
+M\x11\xf7\xfa-\xcaC\x86\xa4_\xef\x8cBP?\xf9\
+d\x16QD\xc4\x00\xfc\x95\xd8\xc0\xaep\xfe\x0a;\xe7\
+\x00P\x15F\x89\x9f\xd8R\xd4N\x12w\xfb-\xce\xbd\
+z)g\xd7.\xfb\x03\xba\xfe\x22\xd1\xb2%\x8b)\x22\
+b\x16\xbdS\xaceW8\x7f[<\x9cx\x01\x00U\
+e\x82\xf8\x99-\xc5m\xb8\xf8\xae\xdf\x22\xdd\xb9\xb3r\
+\xb6o\xb7?\xa4\xebG\x97\x0a\x0aXT\x11\x11\xb3\xe0\
+Mb\x0d\xbb\xc2\xb9,_\x89f\xc4\x0a\x00\xc8\x16s\
+\xc4/m)r#\xc4\xf7\xfc\x16\xeb\x16-\xd2m\x0d\
+m\x0f\xe9#F\xb0\xb0\x22\x22V\xd1\x1f\x88%v\x85\
+\xf3?\x88\x1d\x89\x13\x00\x90m\xce\xb3\xa8\xd0\xa9\x81\xe2\
+[~\x8bv\x93&\xcaY\xb7\xce\xee\xc7\x8bv\xeeT\
+Ny9\x0b,\x22b\x86^#\x16\xd9\x15\xce\xffW\
+\xecN\x8c\x00\x80\xa0\xb8\xd8\xa6\x90\xae\x9fh~\xcdg\
+\xe1N6j\xa4\x9c5k\xec\xdeE\xd7\x0f.\xe9N\
+4,\xb4\x88\x88\xbe\xdc.\x16\xd8\x15\xce\xff(v#\
+>\x00@\xd0\x5chSH\xef\xe2><\xe1\xebA\xa3\
+:uTR\x9f\xf7\xb6\xb9\xf5b\xbf~,\xb6\x88\x88\
+>\xd4/P\xe7\xd9\x15\xce\x7f/v&6\x00\x80)\
+\x16&,:\x93\xde\xce}\x80\xc2W1/.V\xa9\
+s\xce\xb17\xa4o\xdf\xae\x92\x0d\x1a\xb0\xe8\x22\x22z\
+\xf0B\xbb\x82\xb9V\xfe\xb18s\x0e\x00\xe6\x99%~\
+aK1\xd4\x0fP<\xe6\xb7\xa8\x17\x16\xaa\xe4\xf4\xe9\
+\xf6\x86\xf4\xf3\xce\xe3\xa8\x0b\x22\xe2A\xdc#\x9ej_\
+8\xd7\xad\x14\x9b\x13\x13\x00 ,\xe6\xd9\xb4\x93\xdeD\
+|\xd8o\x81\xd7\x01\xf8\xa4\x93\xec\xbd4:p \x8b\
+0\x22\xe2\x01\xd4\xefb\x9cl_8\x97\xef\x0c\x896\
+\xc4\x03\x00\x08\x9b\xc9\x09\x8b\xfa\xa4\xeb\x07)~\x92I\
+\xb1\x1f:\xd4\xceWGu\xffv\x8e\xba \x22~\xc5\
+\xd7\xc5\xfe\xf6\x85\xf37\xc5#\x88\x05\x00`\x0b\xa7\xda\
+\x14\xd2\xab\x89\xd7fR\xf4{\xf6T\x8ensh[\
+H_\xb0\x80\xa3.\x88\x88\xae/\x8a\xdd\xec\x0b\xe7/\
+\x8b\x8d\x89\x03\x00`\x1b\x93l\x0a\xe9\xba\xcd\xd6\xd6L\
+\x8a\x7f\xfb\xf6\xca\xd9\xba\xd5\xbe\x90\xde\xbf?\x0b3\x22\
+\xe6\xbcO\x8bm\xec\x0b\xe7\xf2\x9d!QN\x0c\x00\x00\
+[\x99(~jK\xd1\xd4\xed\xb6\x96g\xb2\x084m\
+j\xdf\x83F\xf2\xa5!U\xaf\x1e\x0b4\x22\xe6\xac\xf7\
+\x8b\xe5\xf6\x85\xf3\x17\xc4F,\xff\x00`;'\xdb\x14\
+\xd2\xb5\xb3\xf4\x03E~\x17\x83\xfa\xf5\x95\xb3b\x05G\
+]\x10\x11-\xf0.\xb1\x8e}\xe1\xfc\xb7bC\x96}\
+\x00\x88\x0aV\x9dI\xd7N\x17\xf7\xfa]\x14JK\x95\
+\xb3h\x91]!\x9d\x07\x8c\x101\xc7\xbc\xddm\x00`\
+Y8\x7fZl\xc0r\x0f\x00\x1cw\xa9\xa2c\xdd\xb6\
+\x5c\xbe\x16\x87\x92\x92\xf4\xce\xb5-\x01}\xf3f\x95\xaa\
+]\x9bE\x1b\x11s\xc2\x1b\xc4\xea\xf6\x85\xf3\x87\xc5Z\
+,\xf3\x00\x10UN\x12?\xb1\xa9\xb0\x0e\x12\xdf\xf4\xbb\
+H\xe4\xe7\xab\xd4i\xa7\xd9\x13\xd2\xe7\xcf\xe7\xa8\x0b\x22\
+\xc6\xde\x1db\xa1}\xe1\xfc\x1e\xb1\x06\xcb;\x00D\x9d\
+\xe1\xe2?l*\xb0G\x89/e\xf2\xa0\xd1\x981\xf6\
+\x84\xf4^\xbdX\xc0\x111\xb6\xaer/\xfa[\x16\xce\
+o\x17\x8bY\xd6\x01 .\xf4\x17\xffjS\xa1m\xe3\
+\xb6\xeb\xf2\xbdp\xe8`lC\xaft\xfd\x80Q\xc3\x86\
+,\xe4\x88\x18+\xf5\x85\xfey\xf6\x05s\xed\x8db!\
+\xcb9\x00\xc4\x8d\xa3\xc5?\xdaTp\x1b\x8a\xf7f\xda\
++}\xcb\x96\xf0C\xba\xbe\xc0\x9a\x9f\xcf\xa2\x8e\x88\xb1\
+P\xdf\x11\x9ahg8\xff\xb6\x98\xcf2\x0e\x00q\xa5\
+\xa5\xf8\x96M\x85\xb7\xc4\xbd\x84\xe4{1i\xd2D%\
+\xd7\xae\x0d?\xa4\x8f\x18\xc1\xc2\x8e\x88\x91\xf75\xb1\x9f\
+\x9d\xe1|\x09K7\x00\xe4\x02M\x12\xe9W\xd7\xac)\
+\xc0\xfa\xd5\xd1M\x19,(\xfb\xba\xa9,]\x1an@\
+\xdf\xb5K9\xcd\x9b\xb3\xc0#bd}Flo_\
+0\xffR<\x97%\x1b\x00r\x09\xfd\xea\xda\xf3\xb6\xed\
+\x94\x9c\x93\xc9\xe2R\x5c\xac\x9cy\xf3B\x0d\xe9\xa9K\
+/UNQ\x11\x0b=\x22F\xce\x87\xc5\xc3\xed\x0b\xe7\
+_\x88sX\xaa\x01 \x17\xa9#>j[H?U\
+\xdc\xe3\xf7R\x93>\x07>yr\xb8;\xe9\x13'\xb2\
+\xd8#b\xa4\xfc\xa9X\xdb\xbep\xae\xdf\xef\x98\xcc\x12\
+\x0d\x00\xb9\x8c\xee%{\xafm!}\x84\xf8v&m\
+\x18G\x8fVNee8\x01]\xff\xe7\x1ey$\x8b\
+>\x22F\xc2k\xc4j\xf6\x85\xf3\x8f\xc5\x13Y\x9a\x01\
+\x00\xd2!\xfdn\xdbBz\x7f\xf7\xd2\x92\xef\x85\xa7O\
+\x9f\xf4\xb9\xf00B\xfa\xbau\xca)-e\xf1GD\
+\xab\xdd%\x16\xd9\x17\xce?\x12G\xb3$\x03\x00\xfc\x97\
+j\xe2\x8fl\x0b\xe9\x1d\xc5\xe73Y\x80:tP\xce\
+\xd6\xad\xe1\x84\xf4\x193\x08\x00\x88h\xad\xcb\xed|\x80\
+\xe8/b?\x96b\x00\x80\x03\x87\xf4\x9bm\x0b\xe9\xfa\
+\xf2\xd2C\x99,DM\x9b\xa6w\xb4\xc3\x08\xe9\xc7\x1c\
+C\x10@D\xab\xdc+~\xcb\xce6\x8a\xf2\x8f\x96\xe8\
+\xcc\x12\x0c\x00\xf0\xcd\xe8\x87 \xae\xb0\xad\x80\xd7\x15\xef\
+\xcc\xa4\x0dc\x9d:\xcaY\xb6\xcc|@\xdf\xb2E\xa5\
+\xea\xd5#\x14 \xa2\x15\xbe+\x8e\xb13\x9c\xbf&6\
+g\xe9\x05\x00\xf0\xc6J\xdb\x0ayu\xf1\xbb\x99,N\
+%%\xca9\xff|\xf3!}\xc1\x82\xf4\xc5U\xc2\x01\
+\x22\x86\xe8\xabbo;\xc3\xf9\xd3bC\x96[\x00\x00\
+\x7fL\x15?\xb3\xa9\xa0\xebs\x93\x8b2Y\xa4t\x8f\
+\xf2\xd9\xb3\xcd\xf7G\x1f<\x98\x80\x80\x88\xa1\xf9\xa8\xd8\
+\xdc\xcep\xfe\xb3D\xbaA\x01\x00\x00d\xc0\x18\xf1\x9f\
+\xb6\x15\xf7Y\xeey\xca\x8c\xda0\x9a\x0c\xe8;w*\
+\xe7\x88#\x08\x0a\x88h\xdc;\xdd\xe3\x81\x16\x86\xf3k\
+\xc5\x02\x96W\x00\x80\xaa1H\xfc\x9bmE~T&\
+\xbd\xd2\xb5}\xfb\xaaTE\x85\xd1WFS\xd5\xaa\x11\
+\x18\x10\xd1\x987\x885\xec\x0c\xe7\x9b\xc4<\x96U\x00\
+\x80\xec\xd0)\x91\xbeioU\xb1\xef.\xbe\x90\xc9\x02\
+\xd6\xb1\xa3J\x1al\xc3\x98\xd2\xaf\x9c\x12\x1a\x10\xd1\x80\
+\x92\x80U\x81}\xc1\xfcK\xf1<\x96R\x00\x80\xec\xd3\
+R|\xc3\xb6\x90\xde\xdc=g\xe9{!k\xd5J9\
+\x9b7\x9b{e\xb4S'\xc2\x03\x22\x06\xea9v\xee\
+\x9a\xeb\xbbLg\xb2\x84\x02\x00\x04G\xb9\xf8\x9cm\x0b\
+\x80>gyG&\x0bZ\xfd\xfa\xcaY\xb1\xc2LH\
+\xbf\xfcrZ/\x22b \xee\x16O\xb53\x9c\xeb;\
+LcX:\x01\x00\x82\xa7\x9e\xf8\x84m\x0bA\x99\xf8\
+\x83L\x16\xb7\xd2R\xe5\x5cp\x81\x99\x90\xae\xdb=\xe6\
+\xe7\x13(\x101\xab=\xceO\xb07\x9c\x9f\xc8\x92\x09\
+\x00`\x8e\xd2D\xbaM\x96U\x0bB\xa1\xb85\x83\x05\
+.YX\xa8\x9cY\xb3\xcc\x84\xf4\xe1\xc3\x09\x15\x88\x98\
+\x15_\x11{\xd9\x19\xce\xff,\xf6c\xa9\x04\x000\x8f\
+n\x93u\xb5\x85\x0b\x83Z\xa8C\xb7\xdf\xc5.?_\
+%'M\x0a>\xa0\xef\xda\xa5\x9c\x16-\x08\x17\x88X\
+%\x9f\x12\xdb\xda\x19\xcew\x8b\x1dY\x22\x01\x00\xc2\xc5\
+\xbaWG\xb5\x93\xdcs\x99\xbe\x17\xbe\xa1C\xd3\x97:\
+\x83\xec\xea\xb2z\xb5JU\xafN\xc8@\xc4\x8c\xfc\x95\
+Xng8\x7fA<\x8ce\x11\x00\xc0\x0e\xa6\x88\x9f\
+\xda\xb6X\xf4\x10_\xcad\x01<\xfah\xe5\xec\xd8\x11\
+\xecN\xfa\x94)\x04\x0dD\x8cS\x8f\xf3_$\xd2\xc7\
+\x1f\x01\x00\xc0\x22\x86\x89\x1f\xd8\xb6h\xb4\x10\x1f\xcfd\
+!l\xdf^9[\xb6\x04\x1b\xd2{\xf4 p \xa2\
+g7\xda\xd9\xe3\xfc\xdf\xaf\x83\x16\xb2\x0c\x02\x00\xd8I\
+\x97\x84\x85\x0f\x1a5\x12\xef\xc9\xe4\xf2h\xb3f*\xb5\
+qcp\x01}\xd3&\xe5\xd4\xaeM\xf0@\xc4\x83\xd7\
+\x22{{\x9ckW%x\x1d\x14\x00\xc0z\xf4\x83F\
+\xaf\xd9\xb6\x88\xd4p\x7f\x1a\xf6\xbd8\xea\x00\xbdlY\
+p\xe7\xd1/\xbcP9\x05\x05\x84\x10D\x8cZ\x8f\xf3\
+/\xc4\x05,y\x00\x00\xd1A\xf7J\x7f\xcc\xb6\x05E\
+\xff4\xbc!\x93E\xb2\xa4$\xdd\xc3<\xa8\x9d\xf4\xb1\
+c\x09\x22\x88\xf85\xdf\x10\x07\xd9\x19\xce?\x16'\xb0\
+\xd4\x01\x00D\x0f+{\xa5kg\x89{\xfd.\x96\x85\
+\x85*9}z0\x01]w\x8d\xe9\xd8\x91@\x82\x88\
+\xff\xf1wb7;\xc3\xf9\xdf\xc4\xa1,q\x00\x00\xd1\
+E\xf7J\xbf\xc6\xc6\x90>\xc6}\x81\xcf\xd7\xa2\x99\x97\
+\xa7\x9c\xd1\xa3\x83\x09\xe9\xfa\xac;\xe7\xd1\x11Q|D\
+lfg8\x7f_\xec\xcc\xd2\x06\x00\x10}\xf2\xc5m\
+6\x86\xf4c\xc573Y@\x87\x0c\x09\xa6W\xba>\
+F\x93\x9fO@A\xcca\x7fio\x8f\xf3w\xc4\xf6\
+,i\x00\x00\xf1bQ\x22}\xa9\xc8\xaaE\xa7\x8b\xf8\
+|&\x0bi\xb7n*\x15D\xaf\xf4\xe3\x8f'\xa4 \
+\xe6\xa87\x8bev\x86\xf3g\xc5\xc6,c\x00\x00\xf1\
+d\xac\xf8\x91m\x8bO\xb9\xbbk\xe5w1M\xb5l\
+\x99n\x95\x98\xed\xf3\xe8\xba\x07;a\x05\x91\x1e\xe7v\
+x\xa7X\x83\xe5\x0b\x00 \xde\x0c\x14\xffl\xdb\x22T\
+[\xbc=\x93\x85\xb5aC\xe5\xacZ\x95\xdd\x90\xben\
+\x9dr\xca\xca\x08-\x889\xe2r1\xcf\xcep\xfe]\
+\xb1\x88e\x0b\x00 7\xe8\x90H\x9fg\xb4j1\xaa\
+&^\x9b\xc9\x02[\xab\x96r\x96.\xcdnH\x9f7\
+/})\x95\xf0\x82\x18\xeb\x07\x88\xe6\xda\xfb\x00\xd1\xba\
+\x04\x0f\x10\x01\x00\xe4\x1c\xbaW\xfa\xc3\xb6-Jz\x17\
+\xeb\x92L\x16\xdb\xe2\xe2t\xa8\xcefH\x1f6\x8c\x10\
+\x83\x18S\xdf\x11G\xd9\x19\xcc?\x15\xcfd\x89\x02\x00\
+\xc8]\x8a\xc5\x9bl\xdc=\xca\xa4WzRw`9\
+\xfd\xf4\xec\x05\xf4]\xbb\x94\xa3\xcf\xb9\x13f\x10c\xe5\
+Kb\x0f;\xc3\xf9\x07\xe2q,M\x00\x00\xa0\x7fB\
+\xddhcH?\xde\xdd\xe5\xf2\xdd+}\xc2\x84\xec\x85\
+\xf4\x95+U\xaazuB\x0dbL|Zlgg\
+8\xdf+veI\x02\x00\x80\xfd9/aa\x1bF\
+\xbd\xcb\xf5b&\x0b\xf1q\xc7e\xafW\xfa\xcc\x99\x04\
+\x1b\xc4\x18x\x9f\xbd=\xce_\x15[\xb2\x0c\x01\x00\xc0\
+\x81\x18/\xfe\xd3\xb6\xc5\xab\x85\xf8X\x86\xbd\xd2\x9dl\
+\xf5J\xe7<:b\xa4\xd5]\xa2j\xd9\x19\xce\x1fI\
+\xa4\xef\x04\x01\x00\x00|#}\xc4?\xda\xb6\x885\x14\
+\xef\xcedan\xdbV9[\xb6T9\xa0\xa7**\
+\x94\xd3\xba5A\x071\x82^\xe5v\x89\xb20\x9c\xdf\
+\x9aH\xdf\x05\x02\x00\x008$\xad\xc5\xd7m[\xccj\
+\x887d\xf2\xa0Q\xd3\xa6\xe9\xde\xe6Y\xe8\x8f\x9e\xa4\
+?:b\xa4\x5cg\xef\x03DW\x88\x05,7\x00\x00\
+\xe0\x87\xfa\xe2\xa3\xb6-jz\xa1\xdd\x90\xc9B]\xbf\
+\xberV\xac\xa8zH_\xb0@9\xba[\x0c\xc1\x07\
+\xd1\xfa\x1e\xe7\xb3\xec\x0c\xe6_&\xd2w~\x00\x00\x00\
+2\xa2\xa6x\xafm\x0b\x9c\xee\x95\xbe$\x93E\xbb\xb4\
+T9\x8b\x16U=\xa4\x9fp\x02\x01\x08\xd1b\xdf\x17\
+\xcf\xb43\x9c\x7f.\x9e\xc5\xd2\x02\x00\x00UE?3\
+}\xbd\x85\x0b\x9d\x9a\x22\xee\xf1\xbbxW\xabV\xf5\x07\
+\x8dtw\x98\x8e\x1d\x09B\x88<@\xe4\xc7\x8f\xc4\xb1\
+,)\x00\x00\x90M\xacl\xc38@|-\x93\x07\x8d\
+\xce8\xa3j\x97F7mRN\x9d:\x04\x22D\x8b\
+|A\xecfo\x8f\xf3.,#\x00\x00\x10\x04'\x8b\
+\x1f\xdb\xb6\xf8u\x10\x9f\xc9\xe4A\xa3\xd1\xa3\xab\xb6\x93\
+\xbex\xb1r\x0a\x0b\x09F\x88\x16\xa8[\xb16\xb7\xb7\
+\xc7y\x0b\x96\x0f\x00\x00\x08\x92~\xe2\x9fl[\x04\xf5\
+\xe3#\xbf\xcada\x1f5\xaaj\x0f\x1a\x8d\x1dK8\
+B\x0c\xd9{\xdcV\xac\x16\x86sz\x9c\x03\x00\x801\
+\x8e\x14\xdf\xb3m1,\x13\x7f\x98\xc9\x02\xdf\xb3\xa7r\
+v\xed\xca\xfc<\xfaQG\x11\x92\x10C\xf2\xfbn\x0b\
+V\x0b\xc39=\xce\x01\x00\xc08\x8d\xc5gl[\x14\
+\x8b\xc4\x8aL\x16\xfa\xa3\x8fV\xa9\x9d;3\x0b\xe9\x9b\
+7+\xa7^=\xc2\x12\xa2a\xb7\x8a\x85v\x86\xf3\xca\
+\x04=\xce\x01\x00 $J\xc5\x9f\xd9\xb68\xea6\x8c\
+\x8b2y\xd0\xa8M\x9b\xcc_\x1d]\xb6L\xa5t\x87\
+\x18B\x13\xa2\x11\x17\xb9s\xdd\xb2\xfa\xa3/\xd2\xd3\xe3\
+\x1c\x00\x00BG\xef\x12}\xdb\xc2\x1d,59\x836\
+\x8c\xfa\xd5\xd1\xd4\xfa\xf5\x99\x85\xf4\xe9\xd3\x09N\x88\x01\
+\xbbW\x9ci\xe7\xae\xf9\xa7\xe2T\x96\x04\x00\x00\xb0\x85\
+<q\x9d\x8d!}\x8c\xf8n&\xaf\x8e\xaeZ\x95Y\
+H\x1f0\x80\x10\x85\x18\x90\xbb\xc5\x89v\x86\xf3\x0f\xc5\
+\x13X\x0a\x00\x00\xc0F\xceN\xa4_\xca\xb3j\xf1\xec\
+%\xbe\xe27\x0c\xd4\xaa\xb5\xef\xd8\x8a\xef\xfe\xe8\xfa\x1c\
+{\xf3\xe6\x84)\xc4,\xfb\xa68\xd8\xcep\xfe{\xb1\
+\x07\xe5\x1f\x00\x00l\xe68\xf1\x03\xdb\x16\xd1f\xe2#\
+~CAI\x89r.\xb8\xc0wHO\xae]\xab\x9c\
+\xb22B\x15b\x96\xd4\xef\x1c\xb4\xb73\x9c\xffNl\
+J\xd9\x07\x00\x80(\xa0_\xcc\xdbk\xdbbZG\xfc\
+\xa9\xdf3\xe9\xfa\xe2\xe7\xbcy\xfe\x8f\xba,X\xa0\x1c\
+\xfdb)\xe1\x0a\xb1J\xde\xef\xbes`a8\xd7=\
+\xce\xebR\xee\x01\x00 J\xb4\x15\xdf\xb2mQ-u\
+\xfb&\xfb\x09\x08I\x1d\xb4\xa7N\xf5\x1f\xd2\xf5K\xa5\
+\x04,\xc4\x8c\xbdWl`g8\xbfG,\xa3\xcc\x03\
+\x00@\x14i$>e\xdb\xe2\xaa\xfb&_\xe17,\
+\xe4\xe5)g\xc2\x04\xff\x8f\x18u\xeaD\xd0B\xcc\xc0\
+\x1f\x8b\xb5\xec\x0c\xe7\xdf\x13\x8b(\xef\x00\x00\x10e\xf4\
+Kz7\xd9\xb6\xc8f\xd4+]\x87\xf4\xf1\xe3\xfd]\
+\x1a\xdd\xb4I9u\xeb\x12\xb8\x10}\xf8m\xf7\xd11\
+\x0b\xc3\xf9\x12J:\x00\x00\xc4\x05\xdd\x86q\x93\x85\x8b\
+\xad\x9a\xe1\xf6U\xf6\x15 \x86\x0f\xe7\x11#\xc4\x80\x5c\
+i\xe7\x03D\x9f\x893(\xe5\x00\x00\x10G\xf4\x0b{\
+_\xd8\x16\xd2\x8f\xcf\xa0Wzj\xe0\xc0\xf4\x11\x16\xaf\
+!}\xda4\xc2\x17\xe2!<\xc7\xce]\xf3\x7f\x8ac\
+)\xdf\x00\x00\x10g&\xb8\x0b\x9eU\x8bp?\xf15\
+\xbf\x81b\xd0 \x7f!\xbdwoB\x18\xe27\xbc\x0e\
+:\xcd\xcep\xfe'\xb17e\x1b\x00\x00r\x81\xbe\xee\
+\xc2g\xd5b\xdcA|\xceo\xb8\xe8\xd1C9\xbbv\
+y\x0b\xe8\xf2\xff/\xd5\xa6\x0d\x81\x0cq?\xf5\xafW\
+\xa3\xec\x0c\xe7\xbb\xc5\x8e\x94k\x00\x00\xc8%\x8e\x14\xdf\
+\xb3mQ>B|\xd4o\xc8\xe8\xdcY9;vx\
+\xbb4\xbaa\x83J\xd5\xa9C0C\x14_\x17\xfb\xdb\
+\x19\xce\x9f\x17\x9bP\xa6\x01\x00 \x17\xd1\x0b\xe0\xb3\xb6\
+-\xceu\xc5\xbb\xfc\x86\x8dv\xed\x94\xb3m\x9b\xb7\x9d\
+\xf4\xc5\x8bU\xb2\xb0\x90\x80\x869\xed\x8bb7;\xc3\
+\xf9Cb\x1d\xca3\x00\x00\xe42\xfa\xb1\x8f_\xd8\xb6\
+H\xd7\xc8\xe0A\xa3}\xc7W\xb6n\xf5\x16\xd2'O\
+&\xa4a\xce\xfa\xb4\xd8\xc6\xcep~K\x22\xdd\x1a\x16\
+\x00\x00 \xe7\xd1\x0b\xe2\xcd\xb6-\xd6\xd5\xc4\xff\xf1\x1b\
+>\x9a5S\xce\xe6\xcd\xdeB\xfa\x80\x01\x845\xcc9\
+\x1f\x13\x9b\xd9\x19\xce\xaf\x13\x0b)\xc7\x00\x00\x00\xffE\
+\xf7J_e\xdb\xa2\xad\xfb1_\xe27\x844i\xa2\
+\x9c\xf5\xeb=]\x1au\xb84\x8a9\xe4\x1dbm\xfb\
+\x82\xf9\x97\x09\x1e \x02\x00\x008(V\xf6J_(\
+&\xfd\x84\x91\xf2r\xe5\xac[w\xe8K\xa3\x1b7*\
+\x87K\xa3\x98\x03\xfeX\xaci_8\xff\x5c\x9cG\xd9\
+\x05\x00\x0084'\x8b\x1f\xdb\x16\xd2'\x89{|\x86\
+\xf4\x94\x87\x9d\xf4\xe4\xc2\x85\xca)( \xc4al\xd5\
+\xf79J\xec\x0b\xe7\x1f\xbb\xb5\x06\x00\x00\x00<\xd2S\
+\xfc\xbdm!}\x80\xf8\x86\x9fpR\xaf\x9erV\xaf\
+>\xf4q\x973\xcf$\xc8a,\xdd.\x16\xd8\x17\xce\
+\xff\xe8\xd6\x18\x00\x00\x00\xf0IK\xf15\xdbB\xfaQ\
+\xe2K~\xba\xbbHHOy\x09\xe9\x03\x07\x12\xe80\
+V\xaev\xefqX6\x87\xdf\x14[S^\x01\x00\x00\
+2\xa7\x9e\xf8\x88m!\xbd\xad\xf8\xac\x9f\xb0R\xb7\xae\
+rV\xad:\xf4\xa5\xd1\xb6m\x09v\x18\x0b\xcf\xb1\xb3\
+S\xcbsbc\xca*\x00\x00@\xd5\xd1m\x18o\xb1\
+m\xb1?\xdc\xef\xab\xa3\xfa2\xe8!B:\x97F1\
+\xea&\xed\x0d\xe7\xf7&\xd2\xef.\x00\x00\x00@\x96(\
+\x10+m[\xf4\x1b\x8a\xbf\xf4\x13`j\xd5R\xce\xf2\
+\xe5\x07\xdfI_\xbaT9EE\x84=\x8c\x9c{\xc5\
+3\xed\x0c\xe77\x89\xd5(\xa3\x00\x00\x00\xc1\xb0\xca\xb6\
+\xc5\xbf\x8e\xf83?;\x8c5k\x1e:\xa4O\x9bF\
+\xe0\xc3H\xf9\xbe8\xd9\xcep~\xa5\xfb\x05\x1f\x00\x00\
+\x00\x02d\xaa\xf8/\x9bB@\xa9x\x93\x9f@#!\
+=y\xc9%\x07?\xee2x0\xc1\x0f#\xe1nq\
+\xac\x9d\xe1|%\xe5\x12\x00\x00\xc0\x1c#\xc4\xbf\xdb\x14\
+\x06\x8a\xc4\xab|\x86t\xe7`!\x9dK\xa3\x18\x01\xdf\
+\x11\x87\xd9\x17\xcc\xf5cg\xe7P&\x01\x00\x00\xccs\
+\x8c\xf8\x07\x9b\x82\x81\xee\xf7\xbc\xc9\xcfq\x97\xb22\xe5\
+,[v\xf0K\xa3\xba\x03\x0cA\x10-\xf4u\xb1\xaf\
+}\xe1\x5c\xff\xba6\x99\xf2\x08\x00\x00\x10\x1e\xcd\xc5W\
+-\x0b\x08\xfb\xbaXx\x0e:5j\xa8\xd4\x92%\x07\
+\xbd4\x9a\xaaV\x8d@\x88V\xf9\xbc\xd8\xce\xbep\xfe\
+\x818\x98\xb2\x08\x00\x00\x10>\xba\xaf\xf1s\xb6\x85\xf4\
+9n\xcb9\xcf\xc7]\x0evqt\xf2dB!Z\
+\x15\xce\xdb\xdb\x17\xce\xff,\xf6\xa5\x1c\x02\x00\x00\xd8C\
+-\xf1>\xdbB\xfa\xa9nw\x0bO\xc1\xa7\xac\xec\xe0\
+\x17G\x87\x0c!\x1cb\xe8>-\xb6\xb0/\x9c\xcbw\
+\xe1Dg\xca \x00\x00\x80}\xe8Vj\xffc[H\
+\x1f.\xbe\x9b\x85\x9d\xf4TE\x85r\xda\xb5#$b\
+h>(6\xb2/\x9c\xffNlB\xf9\x03\x00\x00\xb0\
+\x97\xbc\x84\x85\xbd\xd2\xfb\x89oz\x0dB\xf5\xea)g\
+\xed\xda\x03\xef\xa2\xaf_\xcfK\xa3\x18\x8a\xbfv\x1f\xe6\
+\xb2ln=&\xd6\xa5\xec\x01\x00\x00D\x83\xf9\x89t\
+\xab5k\xc2D/\xb7\xeb\x85\xa7@\xa4;\xb7\xacY\
+s\xe0\x90\xae\xbb\xbepi\x14\x0dz\xbf\xd8\xc0\xbep\
+~\xb7XJ\xa9\x03\x00\x00\x88\x16\x13\xc4\x8fm\x0a\x15\
+]\xc5\x97<\x86\xa2\xd4\xc1v\xd2\xe7\xccQN^\x1e\
+\xe1\x11\x03\xf7\xe7bm\xfb\xc2\xf9\xcdb5J\x1c\x00\
+\x00@4\x19\x9aH\xb7^\xb3&\x5c\xb4s\xbb`x\
+\x0aH\x8d\x1a\xa9\x94>\xd6r\xa0\x90>z4\x01\x12\
+\x03\xf5.\xb1\x96}\xe1\xfc\xdb\x89\xf4}\x13\x00\x00\x00\
+\x880}\xc4\xbf\xd8\x142:\x88\xbf\xf5\x1a\x94\xca\xcb\
+Uj\xc3\x86\xaf\x07\xf4\xcaJ\xe5\xf4\xe8A\x90\xc4@\
+\xbc\xdb\xce\x9d\xf3\xcb\x13\xe9{&\x00\x00\x00\x10\x03:\
+\x8a{l\x0a\x1b\x87\x8b\x8f{\x0dLM\x9b*g\xf3\
+\xe6\xafwv\xd9\xb1C9\xcd\x9a\x11(1\xab\xde*\
+\xd6\xb0+\x98\x7f)\x9eK\x19\x03\x00\x00\x88\x1f\xcd\xc4\
+\xd7l\x0a\xe9\x8d\xdc\xee\x18\x9e\x82\xd3\xe1\x87\x1f0\xa4\
+\xef;\xa7\xae\xdb3\x12,1\x0b\xde,\x96\xd8\x15\xce\
+?\x13\xa7R\xbe\x00\x00\x00\xe2KS\xf1\x05\x9bBz\
+\xb9\xdb_\xdaS\x80j\xd1B9[\xb7~=\xa4/\
+Z\xa4\x92\x85\x85\x04L\x8c\xdb\xce\xb9\x0e\xe7gR\xb6\
+\x00\x00\x00\xe2O\x99\xf8K\x9bBz-\xf7B\x9e\xa7\
+ \xd5\xaa\x95r\xb6m\xfbzH\x9f:\x95\x90\x89\x19\
+{\x9dXdW8\xff\xa7x\x02\xe5\x0a\x00\x00 w\
+(\x16\x7fdSH\xd7;\x97\xb7x\x0dT\x9d;+\
+g\xd7\xae\xaf\x87\xf4\xfe\xfd\x09\x9b\xe8\xdb\xff\xb1/\x9c\
+\xeb\xceK\x83(S\x00\x00\x00\xb9\x87\xee\xa3|\x93M\
+!\xbd\xd4=f\xe0)Xu\xeb\xa6R\x15\x15_\xbd\
+4\xaa\xff\xfb\xf6\xed\x09\x9d\xe8\xd9\xeb\xed\x0b\xe7\x7f\x15\
+\xfbS\x9e\x00\x00\x00r\x17\xdd\xb2m\xb3M!]\x87\
+\xa5k\xbd\x06\xac\x01\x03\xbe\xbe\x8b\xae/\x926lH\
+\xf8\xc4C\xfam\xb1\xc0\xaep\xbe7\x91\xee\xb8\x04\x00\
+\x00\x00\x90X\x92H\xb7r\xb3\x22\xa8\xe8\xd0t\xa5\xd7\
+\xa05j\xd4\xd7\xdb/\xaeX\xa1\x9c\x92\x12B(F\
+i\xe7\xfc-\xb1\x05\xa5\x08\x00\x00\x00\xf6gZ\x22\xdd\
+5\xc2\x9a\x90~\x85\xd7\xc05a\xc2\xd7w\xd2\xcf:\
+K9yy\x84Q\xfc\x9a\xdf\xb1/\x9c\xeb\xceJM\
+(A\x00\x00\x00p N\x12?\xb6)\xa4Wz\x09\
+]:\x88O\x99\xf2\xf5\x90>f\x0c\x81\x14\xbf\xe2w\
+\xed\x0b\xe7O\x8a\xf5(=\x00\x00\x00p0\x86\x8a\x1f\
+\xda\x14\xd2+\xbc\x84\xaf\xfc|\xe5\xcc\x9e\xfd\xd5\x80^\
+Y\xa9\x9cc\x8e!\x98\xe2>o\xb0/\x9c?\x22\xd6\
+\xa6\xe4\x00\x00\x00\x80\x17\x06\x8a\x7f\xb3%\xc8\x14\xb9\xad\
+\xf0\x0e\x19\xc2\x8a\x8a\x94\xb3p\xe1WC\xfa\x8e\x1d\xca\
+i\xde\x9c\x80\x9a\xe3\xfe\xc8\xbe\x17B\x1f\x12kRj\
+\x00\x00\x00\xc0\x0f\xba\x9bD2a\xd1N\xfaN/a\
+\xaczu\xe5,]\xfa\xd5K\xa3\xeb\xd7\xabT\x9d:\
+\x04\xd5\x1c\xf5F\xb1\x9a]\xe1\xfc\x8eD\xfa-\x02\x00\
+\x00\x00\x00\xdf\xb4\x13\xf7\xd8\x14\xd2wx\x08d\xc9\xb2\
+2\xe5\xe8N.\xfb\x87\xf4\xc5\x8bU\xb2\xb0\x90\xc0\x9a\
+c\xea\xbe\xfa\xd5\xed\x0a\xe7\xb7'\xd2o\x10\x00\x00\x00\
+\x00dL[q\xb7-\x01\xa7\xd0\xed_}\xc8pV\
+\xb7\xaer.\xbb\xec\xab\xc7]\xce<\x93\xd0\x9aC\xde\
+)\x96\xd9\x15\xce\xe5\x1f\x89\x9ds\x00\x00\x00\xc8\x0e\xcd\
+\xc47\x12\x89\x88\xb5`l\xd2$\xfdp\xd1\xfe!\xfd\
+\xd8c\x09\xaf9\xe0]bM\xbb\xc2\xf9\x8f\x13\xec\x9c\
+\x03\x00\x00@\x96\xd1\xad\xe0~cK\xe0\xc9\x13\xd7{\
+\x09k\xed\xda\xa9\xd4\xce\x9d\xff\x0d\xe8\xbbv\xed\xfb\x7f\
+#\xc4r!\xd4\xa0\xd7\x8b\x05\x94\x10\x00\x00\x00\x08\x82\
+:\xe2c\x91\x0b\xe9]\xba(\xa7\xa2\xe2\xbf!\xfd\xf2\
+\xcbU\xb2Q#\xc2l\x0c\xbd]\xacaW8\xaf\x14\
+\xf3(\x1d\x00\x00\x00\x10$\xb5m\x0a\xe9\xf9\x1e/\x8e\
+:\xc3\x86}\xf5\xa8\x8b\xbeDZRB\xa8\x8d\x91\xf7\
+\x8a\xb5\xed\x0a\xe7\xd7\x8a\xf9\x94\x0c\x00\x00\x000A\xa9\
+x\x9fM!\xdd\xd3\x8b\xa3\x13'~5\xa4\x9f{n\
+\xfa\x81#\xc2m\xe4}@\xackW8\xbf2\xc1\xce\
+9\x00\x00\x00\x18F_x\xbb\xcd\xa6\x90\xbe\xebPA\
+./\xef\xeb\xaf\x8d\x9et\x12\x017\xe2>(\xd6\xb7\
++\x9c\xaf\xa1<\x00\x00\x00@X\xe8\x8bo\xdf\xb1%\
+\x18\xe9\xee.Wzymt\xd1\xa2\xaf\x86\xf4\xbe}\
+\x09\xba\x11\xf5I\xb1\xb1]\xe1|\x09e\x01\x00\x00\x00\
+\xc2F\xff\x8c\xbf\xcb\xa6\x90~\xd5\xa1\x82]i\xa9J\
+\xad\x5c\xf9\xdf\x80\xbec\x87rZ\xb4 \xf0F\xcc\xe7\
+\xc5\x16\x84s\x00\x00\x00\x80\x03\xa2/\xc2]aKP\
+*\x16o9T\xc0k\xd0@9\x1b7\xfe\xf7\xa5\xd1\
+\x0d\x1b\x94S\xa7\x0e\xc17\x22\xbe&v\xb6+\x9c\xaf\
+\xa6\x0c\x00\x00\x00\x80m\xe8\x9d\xf4u\xb6\x04&\xdd\x07\
+\xfb\xc7\x87\x0az\xcd\x9b\xab\xffk\xef\xfec\xed\xae\xeb\
+;\x8e\x7fo\x7f\xd1\xd6\xda\x9f\x16\x1a\x1bhK\xaf\xa6\
+\x19\xb8D\xaa-m\x88s\xcd\xbaF\x94\x15\x9dT\xc6\
+\xa6\x80\xa3\xb9\x13\x7f\xc4\x94\x8b\xd8\xc9\xc0\x16*k\xb5\
++\xed\xed6\xdc2\xe6\xb6f,\xe0d\xd9\x961A\
+\x13\xc1X\x7f!n\xc8HQA\x84\xdes\x8d\x1a\xa3\
+\x9bf*\xb4_\xdf\xdf\x9d\xe3N[\xee\xbd\xed\xed\xfd\
+\xf1\xf9\x9cs\x1e\x8f\xe4\xf5o\xd3\x9c\xf3=\xc9\xb3\xa7\
+\xdf\xf3\xf9\xd6\xf6\xeci~\x93\xfe\xfe\xf7\x97\x03\xd3\xa6\
+\x09\xe0\xcc\xf7\xcd\xd8\xab\xf3\x8a\xf3\x9d>\xfe\x00@\xce\
+\xae\xcf%\x9c\xa6\xc7\xee\x19\xe9\x19\xe9W^)\x823\
+\x8f\xf3W\xf9A(\x00\xc0\x88\xf5\x16\xad\xf4M\xfa\xba\
+u\xc7\xffht\xfdz1\x9c\xe1\x9e\x8e\xbd&\xaf8\
+\xbf\xd5G\x1d\x00h%7\xe5\x12R\xd5\xc3k\xee\x1f\
+\xc9\x19\xe9\xfb\xf7\x97\xb5\xf3\xcf\x17\xc5\x19\xedp\xec\xcd\
+y\xc5y\xf5\xc3h\xe7\x9c\x03\x00-gK.A5\
+;v\xdf0\x01\xd8_=\xb0\xe8\x1d\xefhF\xfa\xae\
+]em\xe1Bq\x9cI\x9co\xca+\xceo\xf3\xd1\
+\x06\x00Z\xd9{cGs\x89\xf4O\x9e\xec\x8c\xf4\xf7\
+\xbd\xaf\x19\xe9\xdb\xb7\x97\xb5Y\xb3Dr\xe2]\x9dW\
+\x9c\xff\xb1\x8f4\x00\xd0\x0e\xfe \x97H_\xd0x,\
+\xfc\x90A8gNY\xdb\xb1\xa3\x19\xe9\xef~w\xfd\
+\xdbu\xa1\x9cd[\xdc\xd6\x02\x000nzr\x89\xf4\
+\x85\xb1\x07\x87\x89\xc2\x81\xee\xee\xb2\xb6wo3\xd27\
+n\x14\xcb\x09vc^q\xde'\xce\x01\x80vt]\
+.\xc1uN\xec\xcb\xc3\x05\xe2\xaaU\xc7\x9f\xec\xb2f\
+\x8dh\x9e\xc0\xed\x8fM\xca'\xce?V\xd4\x1f\xc6\x05\
+\x00\xd0\x966\xc7\x8e\xe4\x10^K\x1a\x8f\x8b\x1f2\x14\
+/\xbd\xb4\x19\xe8\xb7\xdf^\xd6\x96.\x15\xcf\x13\xb0;\
+c\x93\xf3\x89\xf3?+|s\x0e\x00t\x80kr\x89\
+\xf4\x15\xb1\xc7\x87\x8a\xc5\xae\xae\xb2\xbf\xa7\xa7\x19\xe9\x1f\
+\xfaP\xfd\x1eu\x11=n\xfb\xe7\xc6\x03\xa62\x89\xf3\
+;\xc49\x00\xd0I~?\x97H_\xd9xB\xe5\xa0\
+\xf7\xa3O\x9f^\xd6>\xf0\x81f\xa4_w]Y\x9b\
+2EL\x8f\xc3\x1e\x8a\xcds[\x0b\x00@R\xef,\
+2\xf9\xe1\xe8\xebb\xcf\x0e\x15\x8f\x0b\x16\x94\x03;w\
+6#}\xd3&A=\xc6{4\xb64\x9f8\xbf'\
+6\xc5\xc7\x13\x00\xe8To/2\xf9&\xfd\x8d\x8d\x87\
+\xe2\x0c\x1a\x91\xcb\x97\x1fw\xb2K\xff\xda\xb5\xc2z\x8c\
+v\xa8q\xabQ&q~wl\xb2\x8f%\x00\xd0\xe9\
+\xdeUd\xf2M\xfaU\xc3\xc5du\x92K#\xd0\x07\
+\xaaX\xf7\xa3\xd1Q\xef\xe9\xd8\xda|\xe2\xfc\xbe\xd84\
+\x1fG\x00\x80\xba\xf7f\x12ie\xef0A\xd9_\xdd\
+\xde\xe2G\xa3c\xb2\xea\x7f+~+\x9f8\x7f(6\
+\xd3\xc7\x10\x00\xe0x\xd9\x9c\x93\xbem\xa8@\xaf\x9e*\
+\xfa\x9e\xf74\xbfI\xef\xed\xf5\xa3\xd1\xd3\xdc\x95\xf9\xc4\
+\xf9\xc3\xb19>~\x00\x00\x83\xdb\x99C\xb4U\xe7p\
+\xff\xd5Pq9sfY\xbb\xf9\xe6f\xa4_~\xb9\
+\xe0\x1e\xe1\xb6\xe7\x13\xe7\xdf\x8c\xbd\xd4\xc7\x0e\x00`x\
+;r\x88\xb7\xa9\xb1\x03CE\xe6\xe2\xc5\xe5@\xf5\xf0\
+\xa2_\xde\xeeR=yTx\x9f\xd2\xf6\xc4\xba\xf2\x88\
+\xf3\xa7b\x8b}\xdc\x00\x00NM\x16\xdf\xa4\xcf\x88\xfd\
+\xd3P\xb1\xb9re3\xd0\xf7\xed+\x07\xba\xbb\x05\xf8\
+Iv\xa0\xf1\x0f\x9f\x0c\xde\xdb\xf8\xeb\x14\xcb}\xcc\x00\
+\x00N]\xf5\x04\xc7?\xcd!\xd2g\xc7\x1e\x18*:\
+/\xbb\xacy\xab\xcbm\xb7\x95\x03s\xe7\x0a\xf1!\xf6\
+/\x8d\x7f\xf0d\xf0\x9e~?v\xbe\x8f\x18\x00\xc0\xe9\
+E\xfa\x1d9D\xfaY\xb1/\x0c\x16\x9e\x93'\x97\xb5\
+-[\x9a\xdf\xa4\xf7\xf6\x96\xfd~4\xfa\x82}66\
+?\x8f8\xff\xef\xd8\xab}\xb4\x00\x00N_\xf5\xd0\x98\
+\xbbs\x88\xf4\x97\xc5\x1e\x1f,@\xe7\xcf/k\xbbv\
+5#\xbd\xfaV]\x94\xff\xff\x1e\x8b-\xcf#\xce\x7f\
+\x1a\xfbM\x1f)\x00\x80\xd1\x9b\x1a\xbb7\x87H_\x1d\
+\xfb\xd6`!\xfa\xf2\x97\x97\xb5\xbe\xbef\xa4_x\xa1\
+8o<\x88hU\x1eq\xfe\x5c\xec\x8d>J\x00\x00\
+c\xa7\xfa&\xfd\x1fr\x88\xf4\xf5\xb1g\x07\x0b\xd2\x0d\
+\x1b\x9a\x81^\x9d\xf0r\xf6\xd9\x1d\xff \xa27\xe4\x13\
+\xe7o\xf2\x11\x02\x00\x18{\xd3c\x0f\xe4\x10\xe9\xd7\x0e\
+\x16\xa5]]em\xf3\xe6f\xa4Wg\xa5\xcf\x98\xd1\
+\xb1\x81~C\x1eq~4v\xad\x8f\x0e\x00\xc0\xf8\x99\
+Q\xd4\x1f\xcb\x9e<\xfen\x1e,L#\xc8\x07\xb6m\
+kFzOO=\xdc;,\xce\xf7\xe5s\xd6\xf9u\
+>2\x00\x00\xe3\xafz,\xfb#\xa9\xe3oR\xec/\
+\x86x\x88Qm\xcf\x9ef\xa4\xaf[\xd7Qq\xfe\xf1\
+|\xce:\xdf\xed\xa3\x02\x000q\xce\x8c=\x91:\x02\
+\xcf\x18\xeaAF\x17]\xd4<\x1f}\xef\xde\xb2\xb6d\
+IG\xc4\xf9\xc1\xd8\xbc<\xe2\xfco\x8b\xfa1\x9d\x00\
+\x00L\xa0s\x8b\xfa\x13!\x93\xc6\xe0\xbc\xc69\xdf/\
+\x08\xd6+\xaeh~\x8b~\xeb\xade\xedE/j\xeb\
+8?\x14\xeb\xce#\xce\xef/\xea'\xff\x00\x00\x90\xc0\
++b?H\x1d\x85\xe7\xc4\xfe\xf3\x84`\xad\x1eX4\
+p\xc3\x0d\xcdo\xd2\xab\x1f\x90\xb6i\x9c?\x13{M\
+\x1eq\xfe\xd5\xd8l\x1f\x0b\x00\x80\xb4\xd6\x15\xf5\x87\xd0\
+$\x8d\xc3U\x83\x9d\x91\xbepaY\xfb\xc8G\x9a\xdf\
+\xa4\xaf^\xdd\x96\x81\xbe9\x8f8?\x1c;\xc7\xc7\x01\
+\x00 \x0f\xaf\x8f\xfd<u$\xfeF\xe3\xdb\xe4\xe3\x02\
+\xf6\xbc\xf3\xca\xda\xfe\xfd\xf5@\xaf~<\xbahQ[\
+\xc5\xf9\xf6<\xe2\xfc\xbb\xb1n\x1f\x03\x00\x80\xbc\x5c\x11\
+;\x92:\x16\x7f\xefd\xf7\xa3W\xb7\xbdL\x99\xd2\x16\
+q\xfe\xb1\xc6i6\x89_\xf3\x1f\xc7V\xb9\xfc\x01\x00\
+\xf2tm\x91\xc17\xba\x7f4\xc8\xfd\xe8\xb5\xad[\x9b\
+\x91\xbeqc\xcb\xc7\xf9\xa7b\xb3\xf2xJ\xe8\x1b\x5c\
+\xf6\x00\x00y\xdb\x9e:\xd0\xab\x87\xf4\xec?1j\xcf\
+<\xb3\xec\xdf\xbd\xbb\x1e\xe8}}em\xe9\xd2\x96\x8d\
+\xf3Gb\x8b\xf2\xb8\xb5e\xb3\xcb\x1d\x00\xa05\xdc^\
+dxFz\xff\xda\xb5\xcdS]n\xba\xa9\xacM\x9d\
+\xdarq\xfed\xecW\xf3\x88\xf3\xed.s\x00\x80\xd6\
+19\xf6\x89\xd4\x11\xb9 \xf6\xf9\x13#\xfd\xaa\xab\x9a\
+\xb7\xba\x5crI\xcb\x05\xfa[\xf2\x88\xf3\xbf+<\x88\
+\x08\x00\xa0\xe5T\x0f\xab\xf9\xb7\xd41\xb9$\xf6\xd8\xb1\
+\x91[=\xb0\xa8zpQ\x15\xe8\xd5SF\xcf:\xab\
+e\xe2\xfc\xe6<\xe2\xfc\xde\xc6?\xc0\x00\x00hA\xd5\
+Ck\x1eN\x1d\x95\xbf\x1e{\xf6\xd8\xd8\xed\xee\xae\xdf\
+\x87^EzOOK\xc4\xf9?\xc6\xa6\xa6\x8f\xf3G\
+b/vY\x03\x00\xb4\xb6\x05\xb1C\xa9#\xfd\xf2\x13\
+\xa3\xf7\xe2\x8b\x9b\xb7\xba\xacX\x91u\x9c\x1f\x8c\xcdI\
+\x1f\xe7O\xc7\x16\xb9\x9c\x01\x00\xda\xc3\xb2\xd8wRG\
+\xfa\xf6c\xc3w\xf2\xe4\xb2v\xfd\xf5\xf5@\xef\xed-\
+k]]Y\xc6\xf9\x13\xb1\x97\xa5\x8f\xf3\x1f\xc6~\xc5\
+e\x0c\x00\xd0^^U\xd4\x1fj\x93,4\xab\x87\xfa\
+\xfc\xcd\xb1\x01<o^Y\xfb\xf0\x87\xb3\xfd\x16\xfdp\
+lC\x1eg\x9dop\xf9\x02\x00\xb4\xa7\xd7\xc7\x9eO\
+\x19\x9c\xd5\xc3}>}l\x08\xafYS\x0f\xf4\xb7\xbd\
+-\xbb@\xef\xcd\xe3G\xa1\xefr\xd9\x02\x00\xb4\xb7\xde\
+\xd4\xd1\xb9,\xf6\xf8\xb11|\xcd5e\xff-\xb7d\
+\x15\xe7\x07b\x93\xd3\xc7\xf9G]\xae\x00\x00\x9d\xa1/\
+u\xa4_\x14{\xe6\x97A<sfY\xbb\xf1\xc6l\
+\xe2\xfc\xa1\xd8\xec\xf4q\xfe@Q?*\x13\x00\x80\x0e\
+P=\xe4\xe6@\xeaH\x7f\xeb\xb1a<gN\x16q\
+~(\xb64}\x9c\xffG\xe18E\x00\x80\x8e3=\
+\xf6\xd9\xd4\x91\xbe3\xa3\xdbZ\xfac\xeb\xd3\xc7\xf9\xe1\
+\xd8b\x97'\x00@g\x9a_$>#}j\xe3!\
+@9\x04\xfa\x1f\xa6\x8f\xf3\xea\x94\x9d\x95.K\x00\x80\
+\xce\x96\xfc\x8c\xf4\x85\xb1\x87\x13\xc7\xf9]\x8dc \x13\
+\xbe\x0eGb\xbf\xedr\x04\x00\xa0\x92\xfc\x8c\xf4\xf3b\
+O&\x8a\xf3\xaf\xc4^\x92\xfe\xdb\xf3\xad.C\x00\x00\
+\x8eU\x9d\x91\xfe\x5c\xcaH}S\x828\x7f:v\x81\
+\xe3\x14\x01\x00\xc8\xd4\x96\xc4\xa1Z\xde2\xc1\x81\xde\x93\
+>\xce?W\xd4\x7f\xb0\x0b\x00\x00\x83\xda\x972X\xa7\
+\xc4>>Aq~G\xac+m\x9c\x7f+\xb6\xd0%\
+\x07\x00\xc0p&\xc5\xeeM\x19\xe9sc_\x18\xe78\
+\xffLlf\xda8\xffQl\x85\xcb\x0d\x00\x80S1\
+#\xf6\xa5\x22\xf1\x8fF\x9f\x1a\xa78\xffzly\xfa\
+\x13[6\xba\xcc\x00\x00\x18\x89\x97\x16\xf5\x87\xe6$\x0b\
+\xd9\xdf\x1d\xa7@\xbf4\xfd}\xe7\xdb\x5c^\x00\x00\x9c\
+\x8e\xea\xa19?I\x19\xb3\xbb\xc78\xce\xff$}\x9c\
+\xdf\x13\xebri\x01\x00p\xba\xde\x1c;\x9a*h\xcf\
+\x88\xdd7Fq~\x7f\xe3\xcfK\x18\xe7_\x8b\xcdr\
+I\x01\x000Z\x1fL\x18\xb5\xe5\xe2\xd8c\xa3\x8c\xf3\
+'b\xcb\xd2\xc6\xf9\xf7\x8a\xfaS[\x01\x00`\xd4\xaa\
+\x93]>\x912\xd2\xd7\xc7\x0e\x8f\x22\xd07\xa5\xffQ\
+\xe8%.#\x00\x00\xc6Ruk\xc6\xa3)#\xbd\xf7\
+4\xe3\xbc/\xfd}\xe7;\x5c>\x00\x00\x8c\x87\xead\
+\x97\xfeT\xa1;)v`\x84q\xfe`\xfa\xf3\xce\xff\
+\xb5\xa8\xff\x0f\x04\x00\x00\x8c\x8b\xb5\xb1\x9f\x16\x09\x1fb\
+\xf4\xc5S\x8c\xf3\xea\x1c\xf5\x15i\xe3\xfc\x1b\xb1\xb9.\
+\x19\x00\x00\xc6\xdb\x95\x09\xa3\xb7|e\xec\xdb\xa7\x10\xe8\
+W\xa7\x8d\xf3\x1f\xc7^\xe1R\x01\x00`\xa2\xf4\xa5\x8c\
+\xf4\x9e\x93\xc4\xf9\x9d\xe9\xef;\xff\x1d\x97\x08\x00\x00\x13\
+iJ\xec\xd3\xa9\x02\xb8+\xf6\x97C\xc4\xf9\x97bs\
+\xd2\xc6\xf9>\x97\x07\x00\x00)\xcc/\xea\xf7Y'\x09\
+\xe1\xd9\xb1\x83'\xc4\xf9\xb3\xb1\xd5i\xe3\xfc\xc1\xd8T\
+\x97\x06\x00\x00\xa9\x5c\x10\xfb\xdfTA|\xc1\x09\xf7\xa3\
+oM\x1b\xe7\xdf\x8f\x9d\xed\x92\x00\x00 \xb5\xab\x13F\
+\xf1\xff\xfd\x18\xb4\x8a\xf3\x7f\x8fMI\xf7\xf78\x1a\xbb\
+\xd8\xa5\x00\x00@.nO\x19\xe9\xbbbK\xd2~{\
+\xbe\xcd%\x00\x00@N\xa6\xc5>_$\xfc\xd1h\xc2\
+8\x7f\xa8\xa8\xffh\x16\x00\x00\xb2rV\xecp\x91\xfe\
+\x88\xc3\x89\x5c\xf5d\xd53\xbd\xf5\x00\x00\xe4\xea\xc2\xd8\
+\xcf:$\xce\x9f\x8f\xfd\x9a\xb7\x1c\x00\x80\xdc\xbd\xb3C\
+\x02\xfdFo5\x00\x00\xad\xe2\xce6\x8f\xf3\xfbb\x93\
+\xbc\xcd\x00\x00\xb4\x8aY\xb1Cm\x1a\xe7\xdf\x89-\xf2\
+\x16\x03\x00\xd0j\xce\x8f\xfd\xa4\xcd\xe2\xbc:\xef|\x83\
+\xb7\x16\x00\x80V\xb5\xa9\xcd\x02}\x87\xb7\x14\x00\x80V\
+\xd7\xd7&q~\xb0p\xde9\x00\x00m`j\xecs\
+-\x1e\xe7?\x8c-\xf3V\x02\x00\xd0.\xce\x8e}\xaf\
+\x85\x03\xfd2o!\x00\x00\xed\xe6u\xb1#-\x18\xe7\
+\x7f\xed\xad\x03\x00\xa0]\xedj\xb18\x7f26\xc7\xdb\
+\x06\x00@\xbb\xaa\xeeG\xffb\x8b\xc4\xf9s\xb1U\xde\
+2\x00\x00\xda\xdd\xb9E\xfdG\x97\xb9\x07\xfaM\xde*\
+\x00\x00:E\xee\xe7\xa3;R\x11\x00\x80\x8e\xf3\xd1L\
+\xe3\xfc\x7fb\xcb\xbd=\x00\x00t\x9a3b_\xc90\
+\xd0\xdf\xea\xad\x01\x00\xa0Su\xc7~\x94Q\x9c\xdf\xe5\
+-\x01\x00\xa0\xd3\xbd%\x938\xffvl\xae\xb7\x03\x00\
+\x00\x8a\xe2\xef\x13\xc7\xf9\xd1\xa2\xfe %\x00\x00 \xcc\
+\x8b=\x930\xd0\xef\xf0\x16\x00\x00\xc0\xf1^\x1b;\x92\
+ \xce\x9f\x8a\xbd\xd8\xcb\x0f\x00\x00/\xb4m\x82\xe3\xfc\
+\xf9\xd8\x1a/;\x00\x00\x0c\xaez8\xd0\xc1\x09\x0c\xf4\
+]^r\x00\x00\x18\xde\xb9\xc5\xc4\x1c\xbd\xf8\xb5\xa2~\
+\x16;\x00\x00p\x12W\x8ds\x9c\xff<\xf6J/3\
+\x00\x00\x9c\xba\xbb\xc61\xd0\xb7{y\x01\x00`d^\
+\x12\xeb\x1f\x878\x7f\xacpk\x0b\x00\x00\x9c\x96\xea\xe1\
+AG\x8b\xb1=\xb5e\x95\x97\x15\x00\x00N\xdf\xde1\
+\x0c\xf4[\xbc\x9c\x00\x000:\xd5\xed(\x8f\x8eA\x9c\
+W\x7f\xc64/'\x00\x00\x8c^u\xe2\xca\xcf\x0a\xa7\
+\xb6\x00\x00@6\xb6\x8e\x22\xd0o\xf3\xf2\x01\x00\xc0\xd8\
+\x9a\x14\xfbL\xe1\xd4\x16\x00\x00\xc8\xc6\xb2bdO\x19\
+\xadNmY\xede\x03\x00\x80\xf1\xf3\xf6\x11\x04\xfa.\
+/\x17\x00\x00\x8c\xbf\xbbO!\xce\xff\xabpk\x0b\x00\
+\x00L\x88\xea)\xa3\x03\xc5\xf0\xb7\xb6\x5c\xe8e\x02\x00\
+\x80\x89\xb3\xa1\x18\xfa)\xa3\xbb\xbd<\x00\x000\xf1\xfe\
+|\x908\xffzl\x86\x97\x06\x00\x00&\xde\xcc\xd8\xa1\
+\xe2\xf8[[\xd6xY\x00\x00 \x9d\x95E\xfdI\xa1\
+U\xa0\xef\xf5r\x00\x00@z\x1f\x8c}\xa3\xa8\x7f\xa3\
+\x0e\x00\x00$6-v\x81\x97\x01\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x0e\xf2\x0b@\
+;\x84\xc7\x9dY\x0c\xd3\x00\x00\x00\x00IEND\xae\
+B`\x82\
+\x00\x00\x09\xc0\
+\x89\
+PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
+\x00\x00\x9c\x00\x00\x00\xb2\x08\x03\x00\x00\x00\x80\xc0V9\
+\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
+\x09pHYs\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01B(\
+\x9bx\x00\x00\x00\x07tIME\x07\xdc\x03\x09\x08\x1d\
+0D&N\xa6\x00\x00\x02\xd3PLTE\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x02\x01\x00\x03\x02\
+\x00\x04\x02\x00\x05\x03\x00\x06\x03\x00\x06\x04\x00\x07\x04\x00\
+\x08\x05\x00\x09\x05\x00\x0a\x06\x00\x0b\x07\x00\x0c\x07\x00\x0d\
+\x08\x00\x0e\x08\x00\x0f\x09\x00\x10\x0a\x00\x11\x0a\x00\x12\x0b\
+\x00\x13\x0b\x00\x14\x0c\x00\x15\x0d\x00\x16\x0d\x00\x17\x0e\x00\
+\x18\x0e\x00\x19\x0f\x00\x1a\x10\x00\x1b\x10\x00\x1c\x11\x00\x1d\
+\x11\x00\x1e\x12\x00\x1f\x13\x00 \x13\x00!\x14\x00\x22\x14\
+\x00#\x15\x00$\x16\x00%\x16\x00&\x17\x00'\x17\x00\
+(\x18\x00)\x19\x00*\x19\x00+\x1a\x00,\x1a\x00-\
+\x1b\x00.\x1c\x00/\x1c\x000\x1d\x001\x1d\x002\x1e\
+\x003\x1f\x004\x1f\x005 \x006 \x007!\x00\
+8\x22\x009\x22\x00:#\x00;#\x00<$\x00=\
+%\x00>%\x00?&\x00@&\x00A'\x00B(\
+\x00C(\x00D)\x00E)\x00F*\x00G+\x00\
+I,\x00J,\x00K-\x00L.\x00M.\x00N\
+/\x00O/\x00P0\x00Q1\x00R1\x00S2\
+\x00U3\x00W4\x00X5\x00Y5\x00Z6\x00\
+[7\x00\x5c7\x00]8\x00^8\x00_9\x00`\
+:\x00a:\x00c;\x00e=\x00g>\x00h>\
+\x00i?\x00j@\x00k@\x00lA\x00mA\x00\
+nB\x00oC\x00pC\x00qD\x00sE\x00t\
+F\x00uF\x00vG\x00wG\x00yI\x00zI\
+\x00{J\x00|J\x00|K\x00}K\x00~L\x00\
+\x7fL\x00\x80M\x00\x81M\x00\x82N\x00\x83O\x00\x84\
+O\x00\x86P\x00\x87Q\x00\x88R\x00\x8aS\x00\x8bS\
+\x00\x8eU\x00\x8fV\x00\x91W\x00\x93X\x00\x94Y\x00\
+\x95Y\x00\x96Z\x00\x98[\x00\x99\x5c\x00\x9c^\x00\x9d\
+^\x00\x9e_\x00\x9f_\x00\xa0`\x00\xa1a\x00\xa2a\
+\x00\xa3b\x00\xa4b\x00\xa5c\x00\xa6d\x00\xa7d\x00\
+\xaaf\x00\xacg\x00\xadh\x00\xafi\x00\xb0j\x00\xb1\
+j\x00\xb2k\x00\xb3k\x00\xb4l\x00\xb5m\x00\xb6m\
+\x00\xb8n\x00\xbap\x00\xbbp\x00\xbcq\x00\xbdq\x00\
+\xber\x00\xbfs\x00\xc0s\x00\xc1t\x00\xc2t\x00\xc3\
+u\x00\xc5v\x00\xc7w\x00\xc8x\x00\xc9y\x00\xcay\
+\x00\xcbz\x00\xccz\x00\xce|\x00\xcf|\x00\xd0}\x00\
+\xd1}\x00\xd2~\x00\xd3\x7f\x00\xd4\x7f\x00\xd5\x80\x00\xd6\
+\x80\x00\xd7\x81\x00\xd8\x82\x00\xd9\x82\x00\xda\x83\x00\xdb\x83\
+\x00\xdc\x84\x00\xdd\x85\x00\xde\x85\x00\xdf\x86\x00\xe0\x86\x00\
+\xe1\x87\x00\xe2\x88\x00\xe3\x88\x00\xe4\x89\x00\xe5\x89\x00\xe6\
+\x8a\x00\xe7\x8b\x00\xe8\x8b\x00\xe9\x8c\x00\xea\x8c\x00\xeb\x8d\
+\x00\xec\x8e\x00\xed\x8e\x00\xee\x8f\x00\xef\x8f\x00\xf0\x90\x00\
+\xf1\x91\x00\xf2\x91\x00\xf3\x92\x00\xf4\x92\x00\xf5\x93\x00\xf6\
+\x94\x00\xf7\x94\x00\xf8\x95\x00\xf9\x95\x00\xfa\x96\x00\xfb\x97\
+\x00\xfc\x97\x00\xfd\x98\x00\xfe\x98\x00\xff\x99\x00\xff\xff\xff\
+s\xb6\xc7\xfa\x00\x00\x00\x08tRNS\x00\x09\x0e\x1b\
+(=\x5cr\xeeu#\xcb\x00\x00\x00\x01bKGD\
+\xf05\xb8\xefT\x00\x00\x06RIDATx\xda\xed\
+\x9c\xf9_\x94U\x14\xc6\xad\xacf\x18mTP\xc0\x04\
+\xc4\x85E\x05\xc1\x0d\xc9P\xd1\xc8\x5cZ\x15\xb5\xc5$\
+\xca4\xcb4\xcbJ\xcd\xca\xd2\xd4RJ\xcd\xca4\xb2\
+\x12\xcd\xcaL\xb1 \x90\x08DS@\xf6M\xf6\x01F\
+\x99a\xe6\x9d\x7f!\xd6\x98\xe5]\xeer\xee0\x9f\xbc\
+\xcf\xcf\x9c\xf7~\x99y\xdf\xf7\x9e\xf3\x9cs\xa7_?\
+...........W\xd5\x1dw\xbb\
+\x88\xfa\x8b\xc0\xdd\xa9r\x11\xdd\xc5\xe1n)\xb8dc\
+\x9f\xaa@\x16.\xc5\xd2\xa7*\xe3p\x1c\x8e\xc3\xc1\xc1\
+\x99]\x18\xae0\xe4G\xe2\xa5u\x8c\xe1\xcaBT\xda\
+S\x84lY\xbe;\x98\xc2U\x84\xb6\xff\xcd\x903D\
+l\x17\x86\xabT\x9b\x19\xc2U\x85un~\xee\xbf\x11\
+\xb0\xa5{w\x84\xbe\xcd\x0c\xae6\xa2{kv?\x8b\
+\xcd\x96\xe6\xdd\x15\xbaI`\x03W\x17\xf9_\xe2\xe0~\
+\x0e\x93\xedO\xaf\x9e\xd0\x97\x05\x16pM\xd1Vi\x8d\
+\xc7y,\xb6T\xaf\xde\xd0\x97\xcc\xf0p\xcdsm\x92\
+.\xcfT\x0c\xb6d\x0f\xeb\xd0\xb86h\xb8\x96\x18\xbb\
+\x94\xd0+\x0d\x99\xed\x9c\x87m\xe8\xb3m\xb0p7\x1f\
+qHX\xbd\xd2\x11\xd9\xcez\xd8\x87>c\x84\x84k\
+}L$\x9d\xf6\xbe\x80\xc4v\xc6\xdd1tI+\x1c\
+\x9cq\xb9h\xb2\xef\x9d\x81\xc0\xf6\xab\xbbX\xe8\xe37\
+\xa1\xe0\xda\x9e\x96(E|\xb2\x15\xd9N\x0f\x11\x0f}\
+\xf4\x06\x0c\x9c\xf9y\xc9B\xc9\xf7\xa2\x02\xdb\xc9AR\
+\xa1\xf3\x9a \xe0\xcc/\xca\x94q~9\xb2l'\xb4\
+\xd2\xa11:z8a\x8dl\x91\xe9wI\x86-I\
++\x17\x1aUG\x0d\xf7\x9aB\x09<\xf2\xb2$\xdbq\
+\xad|\xe8\x8cZJ\xb87\x14\x0bt\xff\x7f$\xd8~\
+\x18\xa8\x14\x1aYM\x05\xf7\x1e\x82}06_\x94-\
+Q\xa3\x1c:\xa9\x9c\x02n'\x92\xb9\x11pM\x84\xed\
+\x1b\x0dJhX\x191\xdc.D\xeb%\xb0\xc0\x81\xed\
+\x88\x06-4\xb8\x80\x10\xeecdc(\xb0\xd0\x8e\xed\
+k\x0djhP>\x11\xdc~5\xbam\x15Td\xc3\
+vX\x83\x1e\x1a\x90G\x00w\x10\x83M\xa5\x0a\xb5\xbe\
+y\xbet\xc3\x09\xf5\xcf\xc1\x86;\x8a\xb5@;]9\
+\xd1G\xde\xf9\x22\xcf\xc6\x84K\xd4\xa805\xb1\xa2;\
+\xf435n\xa8\xef\xdfxp\xcb\xf0\xed\xd2\xc8:\x82\
+\xef\xb4{\x9f\xc5\x833.\xc5_\x22\xbc\xb2=0A\
+\x8d\x1f\x18Q\x8dy\xcf\x19b\x09\x16\xa9\xb1\xec#`\
+\x8b\xaa\xc7~Z\x0dK\xf0\x97\x99\xfe.\x81{>\xb3\
+\x9e\xe0=gX\xec\x14g\x7fV\x03\xd1\x0eqc\x91\
+\x13\xd8f7\x12\xee\xad\xfa\x85\xcc\xd9\xa2\x1b\x89\xb3\x12\
+\xfd\x02\xc6l\x0f\xb5P\xe4s\xfa\xf9L\xd9\xe6\xb7P\
+e\xc2-\xf3\x18\xb2-l\xa1\xac!t\xd1\xcc\xd8\x16\
+\xe9\xa9K\xc3\xc6Y\x8c\xd8\x1e\xd6\x03\x14\xd5\x8d3\x99\
+\xb0\x89\xf9%\x04vDC\x14\x03\xb6\xd8V #\xa7\
+\xe1~p\xb6\xa5\x060\x0b\xacf\x1a0\xdbr\x03\xa0\
+yX=\x15\x94\xedI\x03\xa8\xedz}\x0a \xdbS\
+\xa0\xcef\x07\xddd0\xb6\xe7L\xe0V\x7f\xd5$ \
+\xb6x\x13\x83&Ie8\x08\xdb\x0b&&\xed\xa5\xd2\
+\x09\x00l\xabL\x8c\x1as%\xe3\xa9\xd9V\x9b\x99\xb5\
+4\x8b\xc7Q\xb2\xad\x13\x186\x83\x8b\x83\xa9\xd8^\x15\
+\x98\xb6\xd1\xf3\xc6P\xb0m\x10\x18\x0f \xe4\x92\xd3m\
+Tb\xa3\x1f\xdd\xc8\x1dM\xc8\xf6\xba\x22\x1b\xc0\x5c\xc9\
+\xd5QDl[\x9d3\xf4\xf2\xd7=\x04l\xdb\x9c3\
+\x91\xd3\xfc \xc9\x07\xb7\xc9)pM1d\xb7\xdc\x9b\
+N\x80kz\x80\xf4a\xdd\xce\x1cN7\x97\xfc5\xf7\
+!c\xb8z\xaaZg'S\xb8:\xcaJ\xe7#\x86\
+p\xb53h\x93\x92]\xec\xc6\x85\xee\xa3O\xe7\xf60\
+\x82\xab\x89\x04\xc85\xd5\x09L\xe0\xaa\xa7\x83d\xe9\xea\
+O\x19\xc0U@\xd57\xea\xfd\xe0p\x15\xe1*(\xa9\
+\x0f\x00\xc3\x95\x87\x01\xd6\xd4\xea\x83\xa0pe\x13A\xdd\
+\x08\xb7\xc3\x80p\xa5\xa1\xc0>\x8e\xdb\x110\xb8\xc2`\
+\x15\xb44G\x81\xe0\x0a\x82\x18x\x87\x9aD\x10\xb8k\
+\x81L\x5cW\xcd\xb7\x00p\xf9l\xd8\xda\xe9\x8eQ\xc3\
+\xe5\x050s\xfa\x07&Q\xc2\xe5\x8ee\xd8#\xd1\x9e\
+\xa0\x82\xbb\xe4\xcf\xb4\xbb\xa4=I\x01\x973\x92q_\
+\xce~\x08\x1f\x03\xee\xa2\x1f\xf3\x8e\xe6\xa0\x9f\x08\xe1\xb2\
+\xd9\xb3\xd9\x1f\x11@\x86\xcb\xf2\xc5_j0\xfe\xf8\x81\
+\xcd\x10>*\x5c\xc7\xf1\x05\x5cy\xa6\x10\x0cnX\x0f\
+\xe1#\xc2\xa5{\xe3\xb3\x0d\xcf\xb0X\xf6\xe1\x87y$\
+c\xc2\xa5\x11\xb0\xdd\xdb9\xd3\xbc\x97\x80\xee<\x1e\xdc\
+\x1a\x92\xef\xb4+t;~\xe8\x846,8\xd3j\xdc\
+\x05Fd\xf6\xfc\xfb\x9f`\x87fa\xdes\xc2z\xbc\
+\x05|2{o\xeb\x0f0o\x87L\xec\xa7U\xd8\x88\
+\xb3\x80\xbf\xcd\xb4\xf0\xfb8\xa1\xc3RI^\xc2\xef\xa0\
+/0\xcanVx\x1bz\xe8\xd0\x14\xb2\xed\x0b\xf9\xd6\
+\x1e}\xc5>\xbd\xd8\x8a\xfc\xa4\xfeA\xba\xf1\xef!e\
+\xb3X\xb6 n)\xa7\xc9S&\xa4a\xdc1W\xc5\
+\xca\x81\xcdH\xfb\xfe/4\xc9\xe6\x01\xe5\xed(\xb8P\
+\xb4\x90\x126 \xe4\xc2\xc7\xe9\xd2\xf4\xcf\x95&0\xc7\
+\x15I\x14\xc8\xca/\xa3\x01\xdf\xd3\x168_\xc8\xd3\x8d\
+/\x964>\x84u\xd8\x955vixl\x80\xdc\xc6\
+S,ch\x09\xaf\xc8\xb2}\x05QT\x7f'}\xae\
+!\xa4D\xd6\xa8\x14\xd6\xca\xb89\x87`\xec\x88S\x83\
+%\x16\x08-U0\xa0\xcd\xab$\xe1\x12\xa0\x8c\x9c\x9f\
+\xc5\xcfGM\xaeTl,H\x9e|\xda\x0bg\x81%\
+\x0f\x15\xb9\xfe\x94*\x84\x86\x91)^\x94m\x07\xa4y\
+\xf8\xfb0\x87\xebO\xbd\x8et\x9a\xcf\x14\x87\xd1B$\
+\xb4]S<\xed\xae?\x0d\x8d\xad\x9dn\xa5\x03\xdb\x16\
+h\xc3:c\x84\xcd\xf5#\xaa\x91O\x90\x9aV\xd8\xb1\
+\xbd\x05o\xf5g\xfaX]\xdfjd[Y\xc6e\xa8\
+\xe3\x1b\xe4M\x92\xcb\xbd\xeds\xeb\x91m\x04\x19\xac\x8f\
+\x08\xac\x15\x98\xb4\x97\xae\xf4\x0cF\xcc\xc6c\xb39\x22\
+\x10of\xd4\x98+\xec\x1a\xc8\xb1\x1d\xd9F\xa3\xeb\x19\
+\xc2\x8f31ki\x16u\x8cZ\xcd\xd1Y\xf0\xd5\xfa\
+D'\xdb\x0a\x13\xc3fpI\xa8\xc3\xc86\xa2:\x8f\
+\x08\xc4\x1a\x99\xb6\xd1\x8bW6Z\xc8\xa4_\xa0Zl\
+`?WB(\xdd\xfaf\x8b\xcb\xc29g\x22\x87\xc3\
+q8\x0e\xe7\x02p\xbb\x93\xfaT\x87d\xe1\x5cA\x1c\
+\xee\x96\x81\xbb\xad\xbf\x8b\xe8v\xfe\x83\xac\x5c\x5c\x5c\x5c\
+\x5c\x5c\x5c\x5c\x5c\x5c\x5c\xffC\xfd\x0b\x99\xa5\x5c~G\
+q`B\x00\x00\x00\x00IEND\xaeB`\x82\
+\x00\x00/`\
+\x89\
+PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
+\x00\x01[\x00\x00\x01\x5c\x08\x06\x00\x00\x00f\xca\x1dU\
+\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
+\x09pHYs\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01B(\
+\x9bx\x00\x00\x00\x07tIME\x07\xdc\x03\x09\x08\x1f\
+%\x1b\xcd\xc8\xcf\x00\x00\x00\x06bKGD\x00\xff\x00\
+\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00.\xe0IDATx\
+\xda\xed\x9d\x09t\x15U\xb6\xfe\xaf\xb6C\xdb-\xdc\x9b\
+\x00b\xdb\xb4\xa2\xb6\xf6\xa0\xdd\xb6\xa2>q\xa0\xaa\x92\
+0*\x8a \xa2\x88\x8a8\xb7-\x88\xa08a\xa7E\
+Q[[\x14'\x22!u+\x84\x00\x81\x10H \x10\
+\xa6@\x98\xc7\x80!\xcc\x90\x90\x89\x84\x04\x12\x12\x12\x12\
+\x02\xa9W\xbb\x82\x1aHn\x86\x9b[u\xeb\xd4\xf9~\
+\xff\xf5\xad\xf7_\xbd^?\xaa\xce>\xe7\xcb\xb9\xa7\xf6\
+\xd9\xdb\xe1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x18@\x07Y\xbc2P\x11\xba\x06\xc8B_\x97,\
+\x0eu\xb9\xc5QNE\xfcX\xfb\x9f\xe1\x9a\xe24\xa5\
+\xb8\xdcB\xba\xa6\x03\xb5\x12\x0b5\x1d\xd3\xfe\xff\xc7\xb5\
+\xff\xa9\xd6\x97\xfe\x9f\x1f\xab\xfd\xdf\xfb\xe9\xbf\xa3\xff\xf7\
+Wj\xff\xd9\x1cM\x93\x9dni<\xfd;\xf4\xef\xd1\
+\xbf\x1b(\x8bw\xd1s \x1a\x00\x00v\x09\xebrq\
+\x80\x12\xfcw\xcd\xe0\x06\xe8\x06\xe7\x16\xbfq*\xc2\x82\
+Z\x03\x14+\x1a6L\xbf\xa9\xe2\xecs\xcd\xd7\xf4\xb5\
+K\x91^w\xc9R\xff\x00\xb9\xdb\xdf\xe8=\x10L\x00\
+\x80\xffQ\x1d\x17\x04\xba\xa5\x9b\x9c\xb20P\xdb1\x86\
+jf\x95\xa0)\xcfbf\xdaZ\xe5\xe9\xef\xa5\xbd\x1f\
+\xbd'\xbd/\xbd7\x82\x0f\x000\x8e\x89\xbd/\x0d\x8c\
+\x08\xba\xdb\xe9\x16Gk\xe63W\xdb\x11\xe6\xda\xccX\
+\x9b)\xfd\xbd\xe9\xb8c\x14\x1d\x878b\x06^\x82\xc9\
+\x01\x00\xf0\x9a6Jp;\x97[z0\xc0-|\xaa\
+\x19\xcb*\xcddO\xf2i\xae\x8d\xeb\xec\xb8\xa4\xd0\xb9\
+3\x9d\x07\xb7\x0d\xef\x19\x88\xd9\x03\x00ht\xe7Jf\
+\xa1\x99k\xd8\xd9\x0fS0S\xefw\xbf\xf4\x91\xee+\
+\xcd\x80Ch\x5c1\xb9\x00\xe0\x9c\xc0(\xb1\x93\xb63\
+{V3\x88Yg\xbf\xe8\xc3(}o\xbcG\xb5?\
+`3]\xb24\xac\x9d\x12\xf4{\xcc:\x00\xf89\x1e\
+\xb8\xb1\xf6\x83\x96\xfe\x15\x1efh\xbe\xf9\xa6\xd3\xf8\xb7\
+\x95\xbb\xdd\x80\xd9\x08\x80\xcdp\xba\x83\xae\x87\xc1Z\xd7\
+x\x9d\x11!\xd7a\x96\x02\xc0(\x9db\xba^\xe6r\
+KOi\x8bz\xa9\xa6\xd306K\x8b\xe2\xb38@\
+\x11\x87t\x96\xc5_c\xf6\x02\xc0\xc2.V\x11C\x02\
+\x14)\x06\xd9\x03\xcc\xaa\xd4\xa5H\x91\xfa\xc75\x00\x80\
+\xe5\xcea\xdbi\x8bs\x8cf\xb0;aV\xf6:f\
+\xa0\xb8\x22\x9d\x0c\x00?\xe3\x92\xc5\xce\x94b\xe4\xb9n\
+\x00d\x13\x95h\x9a\xe0\x0a\x0f\xba\x06\xb3\x1e\x00\x93\x8f\
+\x0aj\xaf\xc7\x0ag`D\x5c\xedt)\xde\x09\x01\x91\
+\xe2\xbdX\x05\x00\x18E\xb2xQ\xed\x07/a\x0bL\
+\x07\xd2\xb4\x99\xe6\x83#f\xe0\xaf\xb08\x00\xf0\x05\xa1\
+\xa1\x17\x06\xc8\xd2`\xa4mA\x1e\x94\xa6\xfd\xd2\x19D\
+\xf3\x04\x8b\x05\x00o\xd0v,N\xb7\xf4\x82\xb6\x982\
+`(P3j4\xec\xc2N\x17\x80\x96\xa0:.\xd0\
+\xcb\x16b'\x0by\xa7\x1d4\x7fP\x0a\x12\x80Fp\
+EJ\x82\xb6XV\xc30 \x1f|L[\x89\x0fi\
+\x00\x9c\x07u\x068{\xd3\x0b&\x01\xf9ZK4\xd3\
+\xbd\x19\xab\x0cp\xcd\xe5\x11\xf7u\xa8-i(V\xc3\
+\x14 \x03u\x8a\xe6Y\x9bh\xb1=V\x1d\xe0\xed\xe3\
+\xd7%t3\x08e\x0d!\xb3\xcb=\xba\x14q\x04\xa5\
+\x11b\x11\x02\xfb\x1f\x19\xb8\xa5{\xb4\x89\x9f\x8a\x85\x0f\
+\xf93G\x97:\x0cc5\x02[B\xf5\x0b\xa8@\x0c\
+\x16:d\x11\xd5P\xc1\x1b\xd4]\x00\xb6\xe2l\xa9\xc3\
+|,p\xc8\x82\xf9\xb9\x87\x9d\x8a\xf8\x08V)`\x1a\
+j;s\xb6\xc57\x166\xc3\xfaG\xec\xe3\xeaK\xab\
+\xc6\xab\x13\xd2\xa2\xd5y\x99+\xd5-\x85\xbb\xd4\xbd%\
+\x87\xd4\x8c\xd2<u\xdf\xf1l5\xb5h\x8f\x9a\x98\xb5\
+F\xfd&=F\x1d\xb1\xf6s\xf5\xff\xe6>\xad\x06\xb8\
+%\xd6\xde3\x01m{\x00\xa3g\xb3\xc2\xe3\xda\x04.\
+\x84Y\xb1\xa9\xee\x0b^Q\xbf\xdf9[\xcd9Q\xa0\
+zCQe\x89\xaa\xec\x9d\xaf>\xbcx\xb4\x1a\xa8\xb0\
+b\xbcB\x81\xd3-=\x8a\xd5\x0b\x989\x9b\xd5&\xee\
+\x1c\x18\x16{\x22S|v\xe58}\xa7\xeaKh\xf7\
+;r\xdd\x17\xea\x15\x91!l\x8c\x85\x22\xc4\xd2<\xc6\
+j\x06\xd6\xdd\xcd\xcaR\x1f\x9c\xcd\xb2\xa9\x9e\x89\xff\xf2\
+\xb9\xc9\x9e\xcf~\xcdt\x07-}\x9b\x99\xb3\xdc@Y\
+\xec\x85U\x0d\xac\xc5\xc4\xde\x97\xd6\x16\xf1\x16k`\x5c\
+l\xa9\xe3\xd4\xee\xea\xa4\x9d\xb1j\x8d\xf6\xff\xcc\x82\xce\
+};G\xf7e#cA\x9b\xd7\x94\x17\x8eE\x0e\xfc\
+\x0e\xb5\xa4\xd6&\xe4\x06\x18\x17{\xbaqf\x7fuC\
+\xc1\x0e\xd5\x1f\xd0\x07\xb6\xdb\xe7\x0cae\x97\xbb\x16\x1d\
+\x80\x81_q)\xe2\xd3h\xac\xc8\xa6\xba\xce}F\xcd\
+\xf6\xf2\xe3\x97\xaf(\xae*U\xfb.\x1a\xc9\xca\x98\x95\
+\xe9\xd5\xc4\x000\x95\xb0.\x17\x9f\xadi\x00\xe3bP\
+\xdd\xe2\x9fWK\xaa\xcaT+Pu\xa6Z\x1d\xb0\xe4\
+Mv.B\xd0\xb1\x02\xae\xfb\x023\xf8\xed\xe4\xe0\x8e\
+T\xbe\x0e\xa6\xc5\xea\xd1\xc1\xc3^\xa7s\x19E\xe9\xa9\
+r\xf5\xce\xb8\xa7Y\x1a\xc7\xe4\xcb#{\x5c\x017\x00\
+\xc6\x9d\xcf*Awj\x13-\x1b\xa6\xc5\xa6\xda+\xc1\
+\xea\xea\xfcm\xaa\x15\xa13\xdc?L\xeb\xc3\xd2xf\
+\xb5\x95\x85;\xe0\x0a\xc0\xe7P\xb2\xb76\xc1N\xc0\xb4\
+\xd8\xd5'\xdb\xdc\xaa\x95\x99\xb6o!kcZ\xe6\x92\
+\xa5\xfep\x07\xe0\x1bBC/<\x9b\xd6\x05\xc3bX\
+\xf4\xe5\xbf\xf2t\x95\xa5\xcd\x96\xd2\xcf\xee_8\x82\xbd\
+\x826\xb2\x18\x8a6<\xa0Ut\x8a\xe9z\x19*u\
+\xd9C\x0b\xb2V\xab,\x90~\xec\x00C\xd7{\xebH\
+\x16\xdd\xc8\xc7\x05^A]\x14(\xbf\x10F\xc5\xbe\xee\
+\x8b\x7f\xce\xd4K\x0b\xade\xc8\xf2\xb1\xac\x8e\xf5jt\
+\x83\x00-\xa2\xcd\x14\xe9O\xda\xc4\xd9\x0f\xa3\xb2\x87\xe8\
+,\x94%\xd6\xe4ogy\xbc\xf7\xd1E\x1f\xb8\x08h\
+\x12\x97\xd2\xedV\xba\x17\x0e\x93\xb2\x87~\x1f\xd5[-\
+;U\xce\x94\xd9\xd2.\xfc\x96\xd9\x8f\xb3\xdc~'7\
+@\x09\xfe;\xdc\x04x\xce8\x88\x08\x0aB\xc6\x81\xbd\
+D?\xc9Y\xe4\xbdM\xdf\xb1>\xf6%\x81\x11Aw\
+\xc3U@}\xa3\x95\x85\xee\xda_\xe4r\x18\x94\xbd4\
+yW\x1c\x93f\xbb$g\xbd\x1d\xc6\xff\x84S\x11C\
+\xe0.\xa0\xce\xd1\x81\xf4\x9061*aN\xf6\x93\xd1\
+e\x13\x8d\x82\xae\x13\xdb$\x06\xda\xba\x92\x1e\x84\xcb\x00\
+\xba\xac0@\xdb\xd1V\xc1\x98\xec'jMS^}\
+Re\x15\xbaZl\x93\x16\xeaU\xb8\xfc\xc0\xfd\x8eV\
+x\x18Fk_\xfdqF?\x95eB\xe6\xbfl\xa3\
+xh\xebL\xfb\x05\x09\xd7\xe1sGK\xd7oO\xc3\
+\x94\xec\xab[c\x073m\xb6\x03\x16\xbfa\xb7\x98\x9c\
+F\x99F\xce\xd0~^\xde\x8f\x1d\xad\xfdu\xf7\xbca\
+L\x9b-\xc3\x97\x1b\x1a\xdd\xe1R\xfb(\xb8\x10\x0fG\
+\x07\xb2(jA\xaf\x80\x19\xf1\xd1\x82\x9ce\xfa/\x1e\
+m\xd7\xd8T\xb8\x22%\x01nd\xe7\x1dm\xa4x/\
+\xf2hqf\x8b3[K\xecp\x8f\xa3D\xa3}\xcf\
+h\xbbP\xa25L\x88\xafl\x84R\xc6n\x8f\xd5\x85\
+\xfeX\xd8<F\xc5tc\x13\xeed#\x02\xa3\xc4N\
+Z`s`@\xfcis\xe1.&\x8d\xb6\xa8\xb2\x84\
+\x97\x18e\xb5\x9f\xd2\xfd*\xb8\x94\x1dv\xb4\xd3\xee\x0d\
+p\xba\xc5\x9d0\x1e\xdc \xc3\x0d2\xcb\x1e)\xa4\xbb\
+d\xd1\x05\xb7b\x99\x89\xbd/\xd5\x82\xb8\x02\xa6\xc3\xaf\
+\x1e[\xf6\x0e\x93f;f\xc3D\xdeb\x95\x8cz\xb8\
+,g\x1e\xb8E\x19\x86\x83\xaa_\xa8\xfa\xc5\x88\x14a\
+\x0a\x5c\x8bM\xa3}\x0ff\x03\x91\x22\xf6\xc43e\xb6\
+\xcbs7\xf1\xfbQS\x16\xdf\x82{\xb1\x95y@\xf5\
+\x0e\xce\xc0h tj`\xee\xfc\xf6\x0c\xae\xf52\x94\
+\xe2\xe5t\x8b'a2P]\xc5\x1e\x5c\xc6\x84\xd1n\
+<\xb2\x03\xf1r\x8b\x15\xce\x88\xa0\xdb\xe0f\x16\x86\xfa\
+\x1f\xb9\x141\x13\x93\x15Bw]\xe6\x95\xd1F\x09n\
+\x07W\xb3\x221\x03\x7f\xa5\x05h\x09&)\xe4I\xef\
+o\x9edi\xb3\x0d\xdf=\x17q:\xe7R\x8a\x90D\
+\xeb\x1a\xe6f\xbd\x0fb\xe30A\xa1\xc6\xd4^\x09V\
+W\xe7o\xb3\xa4\xd1\xee-9\xa4\xfeaZ\x1f\xc4\xa9\
+^\x86\x82\xf8o\xb8\x9b\xe5>\x88\x895\x98\x9cPS\
+\xa2\x82\xdc9'\x0a,e\xb4t\xa5\xf8\xce\xb8\xa7\x11\
+\x1f\x0f\x1f\xcc\xa8J\x1f\x5c\xce\x0aF\x1b\xd9\xedZ-\
+(\xc70)\xa1\x96\xd4\xb9=\x5c^d\x09\xa3\xa5\x1c\
+\xe0\xe0\xf9/!.\x8d\xab0 2\xe4j\xb8\x9d?\
+\x09\xebr\xb1\x16\x88\xcd\x98\x8cPK\xd5u\xee3j\
+\xb6\x9fw\xb8\xc5U\xa5j\xdfE#\x11\x8f\xe6]x\
+X\xe3H\x16/\x82\xe9\xe1\x9c\x16b\xf2H\xa1\xbf\xba\
+\xa1`\x87\xdf\xceh)C\x02qh\x89\xa4\xf7\xe1z\
+\xfe0\xdaHI\xc0\xc5\x05\xa8\xb5j\xa7\x04\xa9\xa1\x9b\
+\xc3\xd4Sg\xaaMK\xef\x9a\xb43V\xed8\xb5\x07\
+\xc6\xbf\xe5\xaa\x0eT\x84\xaep?\x13\x09\x8c\xea\xddV\
+\x1b\xf8\x83\x98|\x90\xaf\xd43\xf1_\x86\xb7=\xdf\x7f\
+<[\x1d\xb4\xf4m\x8cw\xeb>\x98\x1d\xa0\xf5\x0f\x17\
+4kW\xabH\x91\x98t\x90\xaf\x15\xa8H\xea\xb3+\
+\xc7\xf9\xdct\xf7i&;r\xdd\x17\xea\x15\x91!\x18\
+g\xdf\x1c'D\xc0\x05\xcd0ZY\xec\x87\xc9\x06\x19\
+\xad\xee\x0b^Q\xbf\xdf9\xdb\xeb41*\xfe\xad\xec\
+\x9d\xaf>\xbcx\xb4n\xe2\x18S_\x17\xac\x11\xfa\xc2\
+\x0d\x0d\xe4\xf2\xc8\x1eWh\x03]\x84\xc9\x06\x99)j\
+\x1c\xf9\xd2\xaa\xf1\xea7\xe91\xea\xb2\xdcM\xea\x81\xd2\
+\x1c5\xa34\xef\x1c\xa5\x1c\xde\xaa\x17*\x1f\xb1\xf6s\
+\xf5\xff\xe6>\xad\xb7\xe4\xc1\xd8\x19\xaa\xfc\xb6\xe1=\x03\
+\xe1\x8a8>\x80 \x08\xf5o\xd9\xa4m\xa4\xd4\x13\x13\
+\x0c\x82\xa0:\xaaq*b\x08\xdc\xd1\x87t\x88\x11/\
+G5/\xa8\xb5\xea\x1c\xdd\xb7IQ\xee-\x1d\x1b4\
+%\xaa\x91+&\xbc\xd0\xa8\xa8\x15y\xbf\xa4QMj\
+\xf0\xb2w\xd5\xa1+B\x1b\xd5\x93\xc9c\x11\xc3\x86\xb5\
+\xafSL\xd7\xcb\xe0\x92>\xfb(&\xfc\x0f\x93\xea\x5c\
+\xfd%\xe6\x11u\xd4\xba\x09\xea\x84\xb4h\x8f\xfa*m\
+\xba*\xefIhR3\xf6'\xa9q\x19\xc9M\x8a:\
+\x08$\xe7mnTk\xf2\xb7\xeb_\xf3\x9b\x12}\xa1\
+?\xff\xdc\xf3|e\x95\xe5\xeb\xb7\xac\x9aR\xe5\xe9S\
+*\x0f\xfcm\xf6 \xcc\xfd\x06\xa4\xedn?\x86K\xfa\
+\x22\xa7V\x11\xba\xe2\xf2B\xe3\x1fo\xde\xda\xf0\xb5\xba\
+\xbe \x8d\xa9n\x04\xa0\xe5|\xf1c\x14\xe6\xbc\x87\xcb\
+\x0e(6\xdeZT\xc7\x05N\xb7\xb8\x0e\x93\xa9y\xa2\
+\xcaQ\x1fl\x99lxr>\xf0\x0f\x85'\x8b\xd5\xdf\
+E\xf5\xc4\x5co\xf8\xb2\xc3J\x18f\xebrj\x87b\
+\x12y\xa7\xeb\xa6?\xa8\xa7+-\xca^\xabV\x99t\
+\x15\x15\x18O\xe8\x96\x1f0\xbf=\xe6\xdeJ\x83\xe1\x9a\
+\xde_\xc9\xcd\xc7$j\xbd\xae\x8a\xea\xa5>\xb6\xec\x1d\
+\xfdl\x96\xb5\xb6\xde\xe0\x5cJ\xaa\xca\xd4k\xa2\x1f\xc0\
+\xbcnX9\x1d#{\xfc\x16\xee\xd9B\x9c\xb2\xf0\x11\
+&\x8f\xefE\x05P\xc8x\xe9\xc3\xd8\x11\xedg)`\
+\x8fO\xb6\xb91\x97=I\x16C\xe1\x9e-1\xda\xc8\
+n\xd7\xa2C\xae9\x15\xafz%\xbe\xaaW\xa1\xca+\
+/\x84\x8b1\x02uv\xb8vz_\xcc\xe1\x86U\xe1\
+\x0a\x0f\xba\x06.\xda\xdc\xb3Z\xb78\x0b\x93\xc6|\xdd\
+5w\xa8\xbek\xa2Z\xab\x00\x99\x09\xec\xa6\x82\x09\xd3\
+\xe0\xa2\xcdN\xf5B?1+\x18/\xd5yEJ\x99\
+5)\xaf>\xa9\xf7S\xc3\x5cm\xb8o\x993R\xbc\
+\x1dn\xda\xf4\xaev5&\x8b\xf5\x8c\xf7\xc3\xadS\xd4\
+mE{\xe1r\x16\xe2\xeb\x1d31?=k)\xdc\
+\xb4\xb1\xb3ZE\x0c\xc1$\xb1\xb6\xae\x9f\xfe\x10R\xca\
+,\x02\x8d?5\xaf\xc4\xbc\xf4\xf8\xb1L\x84\xabz\xb8\
+\xc0\xa0\x0d\xd0FL\x12\xb6j\x0d\xd0\xbd}\xa4\x94\xf9\
+\x8f\x99\x07\x16c.z\xd6j\x18k\x03\x04\xc8R\x1f\
+L\x0evu\xe5\xd4\x9eH)\xf3\x03gjj\xd4n\
+\xf1\xcfc\x0ez\xae\x9b\x80\xaa`\xf5w\xb5\xc2\x16L\
+\x0e\xfb\xa5\x94\x1d./\x82#\x1a\xcc\xe2\xec\xf5\x98w\
+\x9e\xcc\xd6-\xae\x85\xc1\xd6\xfd(\xa6H\x0fab\xd8\
+\xb7\xaf\x17\x95\x1b\xacM)\xcb\x823\x1a\xc4\x83I#\
+1\xdf<]\xe3U\x84\xdep\xd9_2\x10pV\xcb\
+aJ\x19\xf0\x1d\x9b\x0bw\xa1\x15\x0f\xcen\x9b\xc8@\
+\x88\x08\x0a\xc2d\xe0S\x7f\x9f\xfd\xd8\xcf\xe5!\xe9\xec\
+\x11\xb4\x8e!\xcbQ`\xbc\x91\x06\x91\xf7\xc1l\x15a\
+\x01&\x03\xf4\xc7\x19\xfd\x90R\xd6J\xe8\x98\xa6\xbd\x12\
+\x8c\xf9\xd4p\x1a\xd8\x5c\xbeo\x8bE\x04\xff\x15\xb7\xc5\
+\xa0\xc6R\xcaNTW\xc0E[\xc0\xf05\x9fa\x0e\
+y\xe8W\xd6N\x16\xff\xcco\xba\x97\x22\xfd\x80I\x00\
+5'\xa5\x8c\x8c\x97\xca\x0b\x82\xc6\xa1\xec\x0f\x14\x18\xf7\
+\x94\x99 }\xc7\xa5\xd1v\x90\xc5+\xb5\x01\xa8\xc4$\
+\x80\xbcI)\xcb\xaf@J\x99'\xe8\x03$\xe6K\x83\
+5\x13\xca\xdbD\x8b\xed\xf9\xcb@\x90\xc5P\x04\x1f\xf2\
+EJ\x195\x8f\x04\xbf@\xbf\x00P\x82\xd1\xd3\xd9\xad\
+0\x96/\xa7\x0d\xebr\xb1\xf6\xe2y\x08>\xe4\xeb\xf2\
+\x90\xe8\xbfV\xcb\x97i\xd31/<tsp$\x8b\
+\x17\xf1\x93\x81 \x0b\x03\x11t\xc8(\xdd2\x1b\x1d\x87\
++OW\xa97\xcdz\x14\xf3\xa1!)\xc2\xc3<]\
+bX\x8c\xa0Cf\xa7\x94\x9d\xe2,\xa5L\xd9;\x1f\
+s\xa0\xe1+\xbc\x89|\xecj\xddA\xd7#\xdd\xcbG\
+\x89\xdanI\xbd/\xfe9\x8cE3\xf5\xe7\x98\x01\xea\
+\xeb\xeb&\xa89'\x0a\xb80[\xfa\xe3\xd2e\xce\x10\
+\xc4\xbe\x81\xe2\xe2\x5c\xb4\xce\xd1\xfe\xaa|\x88`\xfbF\
+\x03\x16\xbf\xf1s2;}\x81\xa6\xf6\xe5\x18\x97\xa6\xf5\
+T\xf2\xfb\xdc\xecn\x13\x0e\xa5 \xe6\x5c6\x86\x0c\xeb\
+r\xb1f\xb6\x87\x11l\xdf(6c\xf99\x0b\x8bj\
+\xcaF\xec\x9e\xa7\x06\xcd\x7f\x09\xe3\xd3\xc4/\x02^>\
+\xa4\xd1\x99\xb5\x94\xf0\x22\xe2^_\xd9\x8e\x98\x81\xbf\xb2\
+\xf1Y\xad\xf4 \x82\xec\x1b\xdd0\xa3_\xa3\xd7Z3\
+\xcb\xf2\xd4\xaf\xd2\xa6\xab\xc1\x9a\xf1\xa2@I}\xf5^\
+8\x9c\x9b\xdd\xed\xb2\xdcM\x889o\xd5\xc0\xb4\x17\x9c\
+\x8d \xfbF\xe3\xb6\x867{\xb1e\x9f(P\xbfM\
+\x8f\xd1/\x04\xe0\xee\xfc/J\xca^\xc7\x8d\xe1\xd2\x1f\
+\x17\xc4\xbc\xde\x87\xb2\xe9\xf6\xbc\x9a\x1b\x16\xe2\xc4\x8d1\
+\xdf\xe8\x8a\xc8\x10\xafoPU\xd7\x9c\xd6\x7fBOH\
+\x8bV\xfb%\x8d\xd2\xffo\xf1:\x8eB\xc2\xf3\xdc\xa4\
+\x86-\xc9A\x81\xf1\x86n\x94u\x88\x11/\xb7\xe1\x8d\
+1\xe1I\x04\xd77\x1a\xb6\xe2?>[\x84\x85'\x8b\
+\xf5\xb3\xdf77L\xd4w\xbe\x9d\xa6\xf5\xe1j,\xe3\
+3S\xb8\xd9\xdd\xf6\xc1\xee\xb6\x81\xd2\x8b\xe2cv<\
+B\x88Gp}\xf3qgk\xd1nC?\xa8\x1c(\
+\xcdQ\xe32\x92\xd5\xffl\x99\xac>\xb2d\x8cz\xf3\
+\xacG\xf5\xba\x04f\x5c\xc1\xbd-\xf6\x09S\xc7\xf3\xde\
+\xf8g\xb9\xd9\xdd\xae\xc8\xdb\x825T_sle\xb4\
+m\xc3{\x06j[\xf6*\x04\xb6\xf5\xa2\x0aX\xfe\x80\
+>\xc6\x91\x09/\xcf\xdd\xa47u\x0c\xdd\xf2\x83\xbe\xc3\
+\x0eY\xf0O\xf5\xf69C\x9a\x9dvvu\xf4\xfd\xfa\
+\xcd\xa6\xbb\xe7\x0d\xd3\x8b]\x8f\xdd\xf4\xbd\x1a\xb1'^\
+\xddP\xb0\xe3\xe7\x0e\xbdf\xa7\xb0-\xc8Z\xcd\xcd\xee\
+\xf6\xfe\x85#\xb0\x8e\xce=\xb7=\x19\x18\xd5\xbb\xad\x9d\
+\x8a\xce\x0cE`\xed\x9f\xb2D\xdd\x16\x8a\xabJ=\xaa\
+\xb9\x98}Q\x83\xba\xd3\xf2\xb2\xbb]\x99\xb7\x15k\xa9\
+\xde\xba\x12\x9f@7\x06\xe8\x1c\x0d^\xf6.\x17\x86\xd0\
+}\xc1+\xa6\x8f\xed\xd2\xdc\x8d\xdc\xecn{&\xfe\x0b\
+\xeb\xe9\xdc\x0fe\xf3\x90\x85\x00\x9d\x93\x81\xb0\xbb8\x93\
+\x0b3\xb8g\xde0\xd3\xc7\xb7\xef\xa2\x91\xdc\x98\xed\xaa\
+\xc3\xa9XS\xe7\x1d%\xd8\x22+\xc1\xe9\x96\x1eE@\
+[\xaf\x0f\xb6L\xe6\xe6\xc6\xd35\xd1\x0f\xf8\xe5\x88&\
+\xfd\xd8\x01n\x0c\x972O\xb0\xaelV\x09\xcc\xe5\x96\
+\x22\x10\xcc\xd6\xe9\x1f\xb1\x8f\xab'OWra\x02{\
+K\x0e\xf9m\x9c\xa9:\x18n\x95\xf1zn+\x84\xb1\
+\xed\xb4\xaa\xe3\x02\xd4Bh\xfd\x8eku\xfe6nL\
+\x80\xb2\x1c\xfc5\xd6\x1d\x22C\xd4\xdc\xf2#\xdc\x8c5\
+u\xba\xc0\x1a\xabS+\x81\xe9]\xed\x14\xe9\x16\x04\xb1\
+uz\x91\xa3\xdd\x16\xddn\xfbK\xcc#\xcc\x5c\x83f\
+\x9d9\x19\xc9Xcu\xf3\xbc\xdd\xd2M\xec~\x1c\x93\
+\xc5\xb7\x10D\xefug\xdc\xd3jy\xf5In\x16\xbf\
+\x15Z\xb9P\xb1q\xear\xc0\xcb\x1f7\xeaj\x81\xb5\
+\xf6\xb3F\xb1\x9c_\xbb\x02\x01\xf4N\xd4\x8ez[\xd1\
+^n\x8c\xf6`i\xaeeZp\xcf:\xb0\x94\x9bq\
+\xffa\xd7\x1c\xac\xb7_\xb4\x84\xe5\x94\xafj\x04\xd0\xbb\
+sZ\xfa\x89\xc7\x0b\xd4\x0d\x96.\x16Xe\xfc\x1fX\
+\xf4\x1a7c_Q]\x89N\xbc\xbf\xe4\xdbV1\x99\
+\x02F\xb5\x22\x11<\xefD\x15\xb9x\x81\x8eIz$\
+\xbeb\xb9?vt5\x99\x17\xde\xd9\xf8-\xd6\xddO\
+9\xb7\x8a\x18\xc2^~\xad,|\x84\xe0\xb5\x5cTw\
+\x96\x17\xe8\xcb\xff\xdd~\xb8\xc0\x80\x0fe\xf5\x8fp\xa8\
+\x08\x10\xd6\x9f\xbe\xbb\xfd\x0f\xcek98:\xe0iG\
+K;G+7#\xa4\xac\x88\xd35g\xb8\x89\xc7\xc0\
+\xa5c\xb0\x0ek\xb5\x94-\xa7\x8d\x19x\x89\xf6\xd0\x15\
+\x08\x5c\xf3\xf3;\xa7\xefO\xe2faG\xef_\xc4D\
+\xdd\x5c\x9e\xea%\xcc\xcb\x5c\x89\xb5X\xab\x13\x8ed\xf1\
+\x22vJ**Aw\x22h\xcd\xbf\x1d\xc6K\xd6A\
+A\xc5Q\xbd#0+\xb1y!\xe5#n\xcc\x96\xd2\
+\xdd\xfcqM\xda\x9a\xb5\x12\xa4.\x0c]\xd1\x15F\x22\
+hM\xeb\xd1\xa5o\xe9\x9d\x12x\x80n\xc1Q\x1d[\
+\x96\xe2C\xb5w\x1bk\xaai7^[\xfb9\xd6\xa5\
+.i8\x1a;\xdaD\x94H\xceK\xb3AJ-\xa2\
+E\xccj\x87\xdf\xe4\xbc\xcd\xdc\x98\xed\x9a\xfc\xedX\x9f\
+\xb5u\x12f\xb2d\xb69\x08Z\xc3\xb7\x93\xe8#\xd8\
+\x89\xea\x0a.\x16\xef\x9e\x92LK\xe5\xcfz#J\x8b\
+\xe2\x05*\xfe~\x836G\xb1V\x85CL\x18\xed\xe5\
+\x91=\xae@\xb0\xce\x15u\x1e\xa0\x9b:\xbc\x5c\xbd\xa5\
+2\x89\x93w\xc5\xa9WN\xed\xc9|\xec(5\x8d'\
+\xa8\x16\x07\xd6\xac\xa8\xb6Q\x82\xdb\xb1P\xbf6\x18\xc1\
+\xfa%\xcb`S\xe1N\xae\x16+\x1d\x1b<\x95\xfc\xbe\
+\xadR\xf2\x8a*K\xb8\x89\xdf\x8c\xfdIX\xbb$Y\
+\x14\xf1q\x8c1Q3C^\xa0l\x03)\xe1E\xdb\
+\xc5\x90\xa7\x86\x90y\xe5\x85X\xb7\xba\xd9\x0a\xaf\xa2X\
+8c\xa26\xe0\xb4\xdb\xb3;\xb4\xfb\xbbk\xeeP[\
+\xc6\xf0\xb3\xed\x91\x5c\xfd:\xa1,\x0c\xee?\x92)\xd2\
+\x0f,|\x1c\xdb\x0c\x93=W\xd4\xae\xdb\xde9\x9a\xa7\
+l]\x88\xfa\xb9\x94q\x5c\x99\xadU\xafP\x9bj\xb6\
+\xb2\xb8\xde\xdaN\x9b,^D\xcd\xd3`\xb0\xe7\xaa\xbd\
+\x12\xac\xae\xcd\xdfn\xdb\xc59>5\xc2\xd6\xf1\x0b\x99\
+\xff2Wf\xdb\x7f\xf1h\xac[\xbaI\x16\x1az\xa1\
+e\xbd\xb6\x9d,\xfe\x19A\xf2\x9c\xf6\x95Y\x96g\xbb\
+\x85I5\x0e\xa8\xf3\xaf\x9dcwG\xdcS\x5c\x99\xad\
+?Z\xc9[\xf3&Y\xd0\xf5V.>\xd3\x0fAj\
+\xfc2CF\xa9\xbd\x0c\xf7\xed\x8d\xdf\xd8>nt\xf3\
+\xcd\xee\x19$9'\x0a\xd4\x1f\x8f\xee\xd3\xebAt\x9c\
+\xda\x1d\xebU?\xb7\x15\x1f\xb0\xae\xd9*\xd2\xeb\x08R\
+\xe3\xfas\xcc\x00u\xd3\x91t\xdb,\xd4[c\x07\xdb\
+>f\xb7\xc5>\xc1L<(\x97;[3N\xaa\xb7\
+A\xc6I]'\xc2v\xc6\xaa\x1f\xa7\xca\xea\xe8\xf5_\
+\xaa\xc3V~\xa0\xf6K\x1a\xa5\xe7~\xd3\x1f\x11;\xe4\
+BsymW3\xdb\x89\x08P\xf3\xf2o\xbfJ\x9b\
+\xce|\x09?\xba\x09\xc7\xea5\xdc\x96\x88\x8a\xe7\x98\xcd\
+\xa93\xd5j~E\x91\x9aZ\xb4G]\x94\xbdV\xcf\
+\x7f\x9d\xa4\x99\xe6'\xdb\xdc\xea[\x1b\xbe\xd6\xdb\xae\x93\
+iR\x06\x08\xfd\x01\x87i\x1ab\xb6_X9\x13!\
+\x1e\x01j\xbe\x84\x84\xe7\xd5U\x87S\x995[\xdaA\
+\xf1\x10\xa7w[ye\xf7\xe4\xe9J=\x7f5\xfd\xd8\
+\x01=\xde\xf1\x99)\xaa\xb2w\xbe~u\xfb\xfd\xcd\x93\
+\xd4W\xd7\xfcW}b\xf9{j\x9f\x85\xc3\xd5\xaes\
+\x9f\xd1\xcd\xd3\xee\xe7\xe0\x8ch\x8e\x95\xcd6\x0d\x01\xf2\
+\xcet#\xf7.P\xcbN\x95\xfb\xd5<i\xa7}\xb8\
+\xbcH\xddR\xb8K/\xc0\xf2\x93V\xe4mQwh\
+FA\x97\x16\xea\xee\xc6\x8f\x9c,\xe6\xa2\xa8{\xda\xd1\
+\xfd\xfa\xfbV\x9d\xddm\xee*\xce\xd0\xb3K\xe6\x1fZ\
+\xa5N\xdd\x9b\xa8N\xdc1C\xfd\xcf\x96\xc9\xea\x88\xb5\
+\x9f\xeb\xb7\xe7\xa8\x87\xd9=\xf3\x86\xa9\x7f\x8d\x19h\x99\
+&\x96\x90WJ\xb5\xb2\xd9\x96!@\xde\xeb\xf7Q\xbd\
+\xd5!\xcb\xc7\xaa\xe1\xbb\xe7\xea\x1f+N\xf9\xa8\xbc\x1f\
+\xed\xac\xb2\xca\xf2\xd5\x8dGv\xa8\x89YkTyO\
+\x82\xfes\x94\xaaq=\xb6\xec\x1d=G\xf6O3\x07\
+4\xab5\x0a\xd5<%C!\xa3!\xe3\xbd*\xaa\x97\
+\xadcB\x85thG\xba\xbe M?\x03\x8d\xcbH\
+V\xa3\xf6%\xea1\xa2\x9d)\xb5\xcf\xa1\x9d/\x8d%\
+\x9d\x87\xd2\x0e\x95~\xde\x07\xcf\x7fI\xcfW\xa5z\xc5\
+\xd7M\x7f\x10\xa6\xcb\xa6\x8a-i\xb4m\xa2\xc5\xf6\x08\
+\x8eoE_\x85\xef\x8c{Z_\xbc/\xaf\xfaX\xfd\
+(5B_\xe4d\x96uE\xff\xd9\x17?F\xa9\xa1\
+\x9b\xc3\xf4E\xfft\xf2\xbf\xd5\xde\xdaO\xd2;\xe2\x9e\
+4\xb4#\x02\xfd\xec\xbd\xc7\xe6\x09\xf0\xaf\xac\xfe\xd4\x80\
+K UjqU\xa9\xbeK\xde]\x9c\xa9\x1b9\xfd\
+\x82\xf8\xe9l\x96b\xfa\xd3\xf9,\xc5\xf4\xa73\xda\xa1\
++B\xf5?\x8e\xbd\x12_\xd5\xff@\xfet^\xdb9\
+\xba/z\x88\x19W#\xc1e\xbd\x024\x91\xe2\xed\x08\
+\x0ed7}\x996\x9d\x99\x8f\x95T\x88\x9eR\x0b\xe9\
+\xd8\x832^\xc8\xc0\xe9|8\xe6\xc0\x12\xdd\xc0\xe9\xb8\
+\xe3\xbf\xdb\x14\xdd\xc0G\xae\xfbB\xff\x03N\x06\xfe\xf0\
+\xe2\xd1?\x1b8\x0f\x1f<[$\xa5\xdb\xad\xd6k]\
+.\x0b}\x11\x1c\xc8nZ\x9c\xbd\x9e\x9b\xcb\x0ct\xdc\
+\x84\x98\x9f\x7fmW\xeac\xc5j_\xcf 8\x90\xdd\
+t\xa8\xec07f\x9b\xc3IvI\x0b\xd3\xbf\x9e\xb2\
+\xde1\x82,\xbc\x81\xc0@v\xfb`I\x85\xd0y\x81\
+.B \xee\xe7\x1f#H\xaf[\xf0\x18A\xfc\x04\xc1\
+\x81\xec$\xaa\xcd\xcb\x13Ks6 \xee\xe7\xd7G\x90\
+\x85\x8f\xac\x98\xf65\x19\xc1\x81\xec$\xca\x00\xe0\x09t\
+ih\xb0\xd4\xe2$+\x9am\x1c\x0f\x83\xffP\xd2\xeb\
+\xfa\x97\xdde\xb9\x9b\xf4\xab\x94\x901\xa2vB\x0b\xb3\
+\xd6\xa8\x13~\x9c\xa6\xdf\xe3\xf7G\xac\xe9\xdf\xe6\x89o\
+\xd2c`\xb0\xf55\xdb\x8af\x9bb\xe7A\xa7\xa4t\
+\xca\x83\x04\xe6C\xe7\xa6TL\xa5\x9d\x12dj\xcc\xe9\
+\x02\x08O\x84n\xf9\x01\xe6Z_\xc9V\xccFH\xb7\
+\xf3\xa0G\xef_\x04\xd7\xf33\x9fnSL\x8d\xf9\xc1\
+\xd2\x5c\xae\xc6\x97j4\xc0\x5c\xeb\xe9G+\x9a\xed!\
+\xbb\x0ex\x979C\xb8\xfa*mU\xa8\xfd\x0e\xd5\x1b\
+0#\xe6TE\xebL\x0d_1\xa7\xdbi0\xd7z\
+\xca\xb0\xe21B\xbe]\x07|\xcc\x86\x89p:\x8b\xf0\
+\xce\xc6oM\xab\x89\xc0\x1b!\x0b\xfe\x09s\xad'!\
+\xd7\x8af{\xcc\xae\x03N\x1f\x0e\x805\xa0\xe3\x1c3\
+b\xfe|\xca\x87\xdc\x8d-\x0f\x85\xe0\xbdP\x91\x15\xcd\
+\xf6\x84]\x07\x9c\xce\x0a\x815\x98\x93\x91lJ\xcc?\
+\xdf>\x95\xbb\xb1\xfd\x83\x81E\x8b\x18V\xa9\x15\xcd\xb6\
+\x1a\x95\x9f\x80\xd1|\xbfs\xb6)1O8\x94\xc2\xd9\
+yx\x15\x8c\xb5\xe1c\x84*k9mh\xe8\x85v\
+\x1ep\xaaI\xca\xdb\xc7\x12\xabB\xb5t\xcd\x88\xf9\xbe\
+\xe3\xd9\x5c\x8dkn\xf9\x11\x18k\xc3\xaaq\xa8\x8e\x0b\
+,\xe3\xb5\x9de\xf1\xd7v\x1f\xf4%9\xeb\xe1t~\
+\x86\x8a\xc2\x98\xd1.\x86\xea\x08\xb3\xde\x1f\xae\xa5l?\
+\x8a\xba\x08\x9e\xe4\x88\x19x\x89e\xcc60\xaaw[\
+\xbb\x0f\xf8\x1dqO\xa9%Uep<?A\xed\xb6\
+\xa9 \xba\x19\xb1\xa6\x82\xe8\xbcA](`\xac\x0d\xab\
+\xfd\x94{\xda\xc0lM\x16U\xc6\xa7k\xba\xd55\xa7\
+\xe1~&A\x1d\x0d\xe6e\xae\xd4\x1b!\x9a\x15gj\
+o\xc3\x1b3\x0f,\x86\xb1\xb2`\xb6<\x1c#\xd4\xd5\
+\xd6\xa2\xddpA\x93\x18\x9f\x1a\x81\xec\x13\x13\xf8\x16u\
+\x11\xd88F\xb0\xfb\x07\xb2\xf3EmF\x809P&\
+\x88\xd9\xf1\x9d\x9b\xb9\x82\xbbq\xa6\xee\xc00V\x06>\
+\x90\x9dM\xfd:\xc5K\x00\xa8\xf1\x220\x07\xea\x8fe\
+v|\xf7\x94dr7\xce\xc3\xd7|\x06ce\x22\xf5\
+\xcb\xe6\x97\x1a\xce\xd73+B\xe1\x82&A\x1f&\xcd\
+\x8c-e;\xf8\xaa\x85<K<\x8e\xba\x08L]j\
+8\xc6K\x00\xee\x8d\x7f\x16.h\x12WE\xf52\xfd\
+#(\x8ft_\xf0\x0a\x8c\xb5a\x15Z\xaf\x07\x99[\
+<\xccK\x00x\xac\x08\xe5\xafL\x04\xb3c;\x94\xd3\
+_-\xb7\xc5>\x01ce\xa7\x10\x8d}K,6\xa4\
+\xac\xb2|\xb8\xa1\xc1\xec8v\xc0\xf4\xb8~\x9c*s\
+9\xd6WG\xdf\x0fcmX\x07Q<\xdc\xcf\xa2|\
+[`,\x8b\xb3\xd7\x9b\x1e\xd7\xd8\x8c\xe5\xdc\x8d3\xd5\
+\x09\x86\xa9\xb2U<|%OA\xa06-\xc0X\x22\
+\xf6\xc4\x9b\x1e\xd7\x9d\xc5\x07\xb9\x1b\xe7\xbc\xf2B\x98\xaa\
+g-\xb7\x9e\xd9*B,OA\x18\xbd\xfeK\xb8\xa1\
+\xc1|\xb8u\x8a\xb97\x85\x94`\xb5\x8a\xc3L\x84\x1f\
+\x8f\xee\x83\xa9z\xea\xae\xabH1\x963[\xed\xa1~\
+\xe0)\x08\xfd\x92F\xc1\x0d\x0d\xe6\xe5U\x1f\x9b^\xff\
+\x82G\xe8H\x0c\xc6\xda\xb0\x9cn\xf1{\x0bf#H\
+\xe3y\x0a\xc2M\xb3\x1e\x85\x1b\x1a\xcc\x83I#M\x8d\
+\xe9\x93\xc9c\xb9\x1cg\xba\x11\x09c\xf5\xa8qV\xcc\
+\xb3\x1d\xc5\xd5\xcf\x0b\xb7\xa4\x9e\xa8\xae\x80#\x1a\x085\
+\xda43\xa6tl\xc1#\xdf\xa5\xcf\x82\xa9z\x92,\
+\xbef=\xb3\x95\xc5\xa1\xbc\x05\x82j\x80\x02\xe3\xa0|\
+f3\xe39\xeb\xc0R.\xc7\xf9\x03\xd4Eh\xc4l\
+\x85'\xadwf+\x0b}y\x0bD\xec\xc1epD\
+\x838Zy\xdc\xf4x\xa6\x1d\xdd\xcf\xe5X\x8fX\xfb\
+9L\xd5\xd3/XY\xeac\xbd3\xdb\x88\xa0\xdbx\
+\x0b\xc4'\xdb\xdcpE\x9b|!o\xa7\x04\xe9}\xb8\
+xd\xf0\xb2wa\xac\x9e4E\xba\xc5rf\xdb6\
+\xbcg o\x81xv\xe58\xb8\xa2A,\xccZc\
+j,\xe9|\x98Wz$\xa2.\x82'Qc\x04\x87\
+\x15\xd1\x1e\xae\x84\xa7@\x08\x09\xcf\xc3\x15\x0db\xca\xee\
+\xb9\xa6\xc6\x92vw\xf8\x10\x09\x9dW\x17\xe1\xa8\xc3\xaa\
+\xb8\x14q\x1bO\xc1\xa0\x8aT5*\x0a\xd2\x18\x81\xd9\
+\xc5\xac\xe9\xdf\xe3\x95k\xa2\x1f\x80\xb16l\xb6[\xac\
+k\xb6\xb28\x97\xb7\x80P\x0bh\xe0{^\x5c5\xde\
+\xd48\xce\xd8\x9f\xc4\xe58\xd3\x8d9\x98\xaaG\xcd\xb6\
+\xb2\xd9~\xc9[@V\xe4m\x813\x1a\xc0\x03\x8b^\
+35\x8e\xa9E{\xb8\x1c\xe7\xc3\xe5E0U\xcf\xfa\
+\xdc\xcaf\xfb\x1ao\x01\x09\xdf=\x17\xceh\x00\xb7\xc6\
+\x0e6\xef#\x88\x22\xe9\xad\xd2y\x84\xd2\xdd`\xaa\x9e\
+..\x89\xafX\xd9l\xfb\xf1\x16\x901\x1b&\xc2\x19\
+}\x0c\x9d\x83w\x9c\xda\xdd\xb4\x18\xfe#\xf6qn\xc7\
+z9\xea\x224R\x84F|\xc0\xb2f\xdbV\xeev\
+\x03o\x01\x19\xb0\xf8\x0d\xb8\xa3\x8f9r\xb2\xd8\xd4\x18\
+\x0eZ\xfa6\xb7cM\xb7\xe6`\xac\x1e\xaf\xeav\xb6\
+\xac\xd9\x9emi~\x82\xa7\x80\xfcm\xf6 \xb8\xa3\x8f\
+\xd9V\xb4\xd7\xd4\x18\xfe{\xf3$n\xc7\xfa\xfb\x9d\xb3\
+a\xaa\x0dg\x22\x1c\xb7\x5c\x0b\xf3\x06\x8a\x88o\xe0*\
+\xe9\x99\xe3\xf3>\xa3X\x90\xb5\xda\xd4\x18N\xdb\xb7\x90\
+\xdb\xb1\x1e\xb75\x1c\xc6\xda\x90\x14a\x8d\xc3\xeah\x0f\
+:\x99\xb7\xc0P\xaf,\xe0;~\xd85\xc7\xd4\xf8m\
+.\xdc\xc5\xedX\xbf\x86\xba\x08\xec\xd4\xb1\xado\xb6\xd2\
+p\xde\x02\x13\x97\x91\x0c\x87\xf4!\xa1\x9b\xc3P*\xd3\
+$\x9eX\xfe\x1e\xcc\xb5\xe1\x0e\x0d\xff\xb4\xbe\xd9\xca\xa2\
+\xc8[`>\xdb\x1e\x09\x87\xf4!\xcf\xa5\x8c\xc3\x99\xbb\
+I\xf4L\xfc\x17\xcc\xb5\xc1j_\xc2}\x967[\x1e\
+\x0b\xd2\xbc\x90\xf2\x11\x1c\xd2\x87\xf4^8\xdc\xb4\xd8=\
+\xb2d\x0c\xd7c};\xea\x224\xa4\x9a\x80\xb0\x10\xa7\
+\x83\x05\xb4\x87\xcd\xe1)8A\xf3_\x82C\xfa\x90[\
+f?nZ\xec\xde\xdb\xf4\x1d\xd7c\xdd9\xba/\xcc\
+\xb5~&\xc2!\x07+\x04\xc8\xe2\x0c\x9e\x82\xd3iZ\
+\x1f\x14\xa4\xf1\x11gjj\xd4+\x22CL\x8b]\xe4\
+\xde\x05\xdc\x8e\xf5\xa93\xd5\xfa\x995\xcc\xf5\xbc\x8fc\
+\x8a0\x8d\x19\xb3u\xc9\xc2\xab\xbc\x05(\xbf\xa2\x08N\
+\xe9\x03\x0a*\x8e\x9a\x1a\xb7\x8dGvp;\xd64g\
+a\xae\x8c~\x1c\xe3\xb9k\xc3\xaa\xc3\xa9pJ\x1f\xb0\
+\xa5p\x97\xa9\x99\x08\xa5\xa7\xca\xb9\x1dkJY\x84\xb9\
+2\xd2\x9d\xc1#1\x03\x7f\xa5=t)O\x01\x8a\xd8\
+\x13\x0f\xa7\xf4\x01\x09\x87RL\x8b\xd9_c\x06r=\
+\xd6T\xb1\x0e\xe6ZO%t\x13\xd6\xc1\x12\xdaC/\
+\xe5)H\xefl\xfc\x16N\xe9\x03&\xed\x8c5-f\
+\xfd\x17\x8f\xe6z\xacg\x1fD]\x84\xfa)_\xe2\x22\
+\x07k\xb8\xdc\xc2\x7fx\x0a\xd2\xc0\xa5c\xe0\x94>\xe0\
+\xfd\xcd\x93L\x8b\xd9\xdb\x1b\xbf\xc1\x1f6\x18\xec\xf9\xad\
+\xcb\xc72g\xb6\x01\x8a\xd0\x9b\xa7 \xf1\x5c\xa6\xcf\x97\
+\x0c[\xf9\x01\xb7G?\x85'\x8bM\xfd\xf7>J\x8d\
+\x80\xb9\xd6\xcbD\x10C\x983\xdb\x8e\x91=~\xab=\
+|%O\x05ixm\x85\xedK\xcc\xbc\xd1\xb4\xae\xe0\
+G\xcb\xbcw\xe5\xe9S\xea}\xf1\xcf\xe9mj\xccb\
+\xe4\xda\xff\xc1`\xcf\xcd\xaf-\xef,\x8b\xbfv\xb0\x88\
+\xf6\x02Kx\x0a\xd6\xae\xe2\x0c\xb8e+\xb9y\xd6\xa3\
+\xa6\xc5\xab\xb8\xaa\xd42\xef\xfd\xbf\x1f\xa3LOE{\
+2y,\x0c\xf6\xdc\xe23\x89\x0eV\xd1^`\x14O\
+\xc1\x8a\xcfL\x81[\xb6\x82\xd35g\xd4\xf6J\xb0)\
+\xb1\xfa\xd3\xcc\x01\x96y\xef\x83\xa5\xb9\xea\x95S{\xea\
+\xcf5\xe1\xc7i\xa6\xfd\xbb\xbd\x12_\x85\xc9\x9e#i\
+8\xb3f\x1b\x18\x11\xfcW\x9e\x82\xf5\x85\xb6;\x01\xde\
+cf\xf3\xc1\x87\x92^\xb7\xcc{SV\x84?>\xb4\
+\xde\x11\xf7$\x0c\xb6\x8e\xda(\xc17:X\xc6\xa5\x88\
+\x99\xbc\x04\xeb\xe5U\x1f\xc31[\xc1\xa6\xc2\x9d\xa6\xc5\
+\xeaM\x8b\xf4\x8e\x8b\xcdX~\xces\xfdaZ\x1f}\
+\x87o\x06\xd7NG]\x84:\xda\xef`\x9d\x00\xb7\x10\
+\xc6K\xc0B\xe6\xbf\x0c\xc7l\x05s3W\x98\x16\xab\
+)\x16\xe8\x8a\x5cRU\xa6\xde8\xb3\xbf_\xda\xaa\xa3\
+.\xc2y\xe7\xb5\xb2\xf0-\xf3f\xebR\x84\x87y\x09\
+\xd85\xd1\x0f\xc01[\xc1w\xe9\xb3\xb8\xba^My\
+\xbe\x0d=\x1b\xf5\x053\x1a\xb3kP0P\xbf\xb6/\
+\xfb;\xdb\xb0\x10'O)`GL\xce\x95\xb4\x13\xef\
+n\xfc\xd6\xb48\x1d\xad<\xee\xd7w\xa5\xac\x03J\x17\
+l\xe8\xd9\xa8{\x82\xd1\xa4\xa3.B\xdd,\x84\x93\x1d\
+b\xc4\xcb\x1dv@{\xa18^\x02\xb76\x7f;\x5c\
+\xd3K\x86\xae\x085%F\x7f\x9c\xd1\xcf\xefY\x17T\
+\x03\xb9\xb1\xe73\xbad\xe7\xca\xbc\xad0\xda_4\xcb\
+a\x17\x02di0/\x81S\xf6\xce\x87kzI\xf7\
+\x05\xaf\x98\x12\xa3\xbe\x8bF\xfa\xf5=\xbfM\x8fi\xf2\
+\x19\xd3\x0dn\x22\x1a{p\x19L\xf6\x97\xf3\xda\x81\xb6\
+1[\xda\xa2k/U\xc1C\xe0\xc6n\xfa\x1e\xae\xe9\
+%T\x85\xcb\x8c\x18\x8d^\xff\xa5\xdf\xde\xf1P\xd9a\
+\xf5wQ=\x9b|\xc6\xc9\xbb\xe2\x0c}\x0e\xd4E\xf8\
+YeW\x85\xf5\xfd\x8d\xc3N\xb8\x14!\x96\x87\xe0\x0d\
+Z\xfa6\x5c\xd3\x0b\xaakN\xab\xed\x94 Sb\x14\
+\xee\xc7L\x84\xe6v\xb3}fE\xa8\xa1\xcf\xf1\xe1\xd6\
+)0\xda\xda*_3\x1cv\xc3\xa9\x88\x83x\x08^\
+\x979C\xe0\x9c^\x90s\xa2\xc0\xb4\x18\xad\xce\xdf\xe6\
+\x97w\x5c\x90\xb5\xba\xd9\xcfH)aF\xf2\xda\xda\xcf\
+a\xb6\xfa\xc71i\x80\xed\xcc\x96\xb6\xea\xda\xcb\x9d\xb0\
+{\xf0\xe8\xba\xa9\x99\xc5D\xec\x02}\x9d7+FE\
+\x95%\xa6\xbf\xdf\x89\xea\x0a\xf5\xa6\x16\xd6}\xd8w<\
+\xdb\xb0\xe7\x19\xb2\x1cu\x11\x5cn\xe18\xb3\x85g\x9a\
+\x91\x950\x9b\x87 \xee-9\x04\xf7l!s2\x92\
+M\x89\xcd\x0d~\xcaD\xa0.\xbe-}V\xf7\x9e\x04\
+\xc3\x9e\xc7\xcc\xeaj\x16N\xf9\x9a\xee\xb0+m#\xa5\
+\x9e<\x04\x91~.\x82\x96\xf1\xf5\x8e\x99\xa6\xc4\xe6\x81\
+E\xaf\x99\xfen\xdb\x8f\xee\xf5\xaa\xc0\xce\x0b)\x1f\x19\
+\xf6Lt\xdc\xc5\xbd\xd9F\x04\x05\xd9\xd6l\xa9\xb7\x8f\
+\xf6\x92\x19v\x0f\xe2\x97i\xd3\xe1\x9e-\xc4\xd3m*\
+\xd63\x11\x9a\xca\xa9\xf5W\x8f\xb4\xab\xa3\xef\xe7\xddl\
+\xf79T\xc7\x05\x0e;Cm'\xec\x1e\xc8\x7f\xad\xf9\
+\x14\xee\xd9B\x9eJ~\xdf\x96\x99\x08T\x83\xa15\xcf\
+K\xa9b\xbe\x86\x0a\x95s\x9f\x85\xe0\x16\xdev\xd8\x9d\
+vJ\xd0\xef\xb5\x97=m\xe7@\xf6H|\x05\xee\xd9\
+B\x82\xbd\xdc\xfdY9\x13\x81JFR\x15\xaf\xd6<\
+\xef\xf4\xfdI>\x7f\xae\xdc\xf2#\xbc\x9b\xed\xa9\x0e\xb2\
+x\xa5\x83\x07\xb4\x97M\xb0s0\xfd}\x1d\x94E\xfe\
+\x12\xf3\x88)\xb11\xb3\xcf\x97/\xfa\xa9\xbd\xba\xe6\xbf\
+\x86\x9c!sn\xb6q\x0e^p\xb9\xa5\x07\xed\x1eP\
+\x7f\x17:a\x09*\xf7\xe7\xa9(\x0b\xab\x7f\x04\x93\xb2\
+\xd7\xf9\xe4\x99o\x8b}\xc2\xe7\xcf\xb64w#\xe7G\
+\x08\xd2\xfd\xdc\x98\xad#\xac\xcb\xc5\xdaK\xe7\xd99\xa0\
+\x1b\x0av\xc0E\x9b\x09\x9dK\xda)\x13\xe1\xe4\xe9J\
+\xf5\xd6\xd8\xc1>{n:\x8e\xf0%3\xf6'\xf1l\
+\xb69\x8ed\xf1\x22\x07O\x04\xc8\xe2[v\x0ej\xd4\
+\xbeD\xb8h3Y\x93\xbf\xdd\x94\x98\x8cZ7\xc1\x94\
+\xf7\x19\xb75\xdc\xa7\xcfMEcXL\xb3\xb3h\xd1\
+\x997\x1c\xbc\xe1\x9cvo\x00\x15\x81\xb0kPC7\
+\x87\xc1E\x9bI\xcc\x81%\xb6\xc9D\xd8]\x9c\xa9^\
+\x11\x19\xe2\xd3\xe7~\xdd\xc7\x7f$hnrj\xb6%\
+\x81Q\xbd\xdb:xD{\xf9\xaf\xed\x1a\xd8\xc1\xcb\xde\
+\x85\x8b6\x13\xea(k\x87\xee\x0cT\x83\xb6\xf7\xc2\xe1\
+>\x7f\xee\xbb\xe6\x0e\xf5\xe9sRj\x22\xa7\xdds\xbf\
+p\xf0\x8a3\xb2\xdb\xb5vM\x03\xbb#\xee)\xb8h\
+3\xa1\x9f\xf7v\xc8D\xa0\xa3#\x83>\xe8\xf8\xb4\x03\
+\x08U\xa6\xe3\xd0l\xab]\xe1A\xd78x\xc6\xae\xa5\
+\x17\xe9\xa7$\x95\x0d\x04\xd6X\xfcFg\x22\x90\x91\x1b\
+\xd9\xad6>3\x85\xb9\x9cf\x94R\xb4\x18\x81\x11A\
+w\xdb5\xc0\xfb\x0d\xac\xdad'\xee\x8d\x7f\xd6\xf0X\
+\xdc\xbfp\x84\xa1\xef\xf0\xcf\xd5\x9f\x18\xfa\xfcom\xf8\
+\xdag\xcfz\xcb\xec\xc7\xf9\xfb0\x16)\xde\xee\x00\xfa\
+\xd9\xedF;\x06xQ\xf6Z8i30rGh\
+F&\x02\xf5\xf32\xba-x\xb7\xf8\xe7}\xf6\xbcW\
+E\xf5\xe2\xcdlW\xc3em^\x0dl\xe2\x8e\x19p\
+\xd2&\xa0:\xaff\xc4\xc2\xa863Tg\xe0v\x13\
+*h\xd1\xa5\x8f\x92\xaa\xb2V?oy\xf5I\xfe\xce\
+k\x15A\x82\xcb\x9e\xb3\xbb\x15V\xda-\xc8\xc3\xd7|\
+\x067m\x02\xaa\xfd\xcbr&\xc2g\xdb#\x99\xfa\xa5\
+d\xd6\x05\x12\x0bi9\xdc\xb5\xfe\x872\xc9n\x81\xa6\
+4 \xd08\xcbr7\x99\x12\x8b#\x06d\x22\xec-\
+\xc9R;N\xedn\xda|z\x7f\xf3\xa4V?\xf3\xe6\
+\xc2]\x5c\x99-}\x13\x82\xbb6|v\xbb\xdcN\x81\
+\xbe\x01\x05i\x9a$r\xef\x02f3\x11\x1e^<\xda\
+\xd4\xf9\x142\xff\xe5V?3\xed\x8e9*\xa3\x98\x04\
+W\xe5(3\xa1\xb8\xaa\x14\x8e\xda\x08\x1f\xa7\xcaLf\
+\x22\xcc>\xb8\xd4/\xfd\xed\xcaN\x95[2\x17\xd8\x82\
+\xaaA\x06BS5\x13\xb4\xbfFv\x0a\xfa\xa6\xc2\x9d\
+p\xd4Fxe\xb5\xf1\xb7\x99|}\xdd\x95\xfe\x80\xde\
+8\xf3a\xbf\xcc\xa7\xe5\xb9\x9bZ\xf5\xec\x13\xd2\xa2y\
+1\xdb\xf9p\xd3\xa6v\xb7\x8a\xd0\x95\xfe*\xd9%\xe8\
+F\x14\x7f\xb6\x13\xfd\x92F\x19\x1e\x83\xb0\x9d\xb1>}\
+\xe677L\xf4\xdb|\x1a\x9f\x1a\xd1\xaag\xf7\xa6\xf1\
+$\x83]s\xcf`W\xdb\xfc\xcc\x04\xc5.\x81\xff`\
+\xcbd8j#\xdc\x11\xf7\xa4\xe11H9\xbc\xd5g\
+\xcfK\xa53\xcd\xa8\xbdk\xd4G\xd7\x17W\x8d\xe7a\
+W\x1b\x0e\x17m&\xbf\x9d\x1c\xdc\x91z\xba\xdb!\xf0\
+O&\x8f\x85\xa36\xc2\xef\xa2z2\x93\x89@E\xce\
+\xef\x9e7\xcc\xaf\xf3\x89\xb2\x1f*OWy\xfd\x0e\x03\
+\x16\xbfa\xfb\xca^\x97G\xf6\xb8\x02.\xda\xb2\xcc\x84\
+\xf7\xec\x10|_Wl\xb2\x13\xd4\xcd\xc2\xe8\xf1\xbf~\
+\xfaC>{\xde\xaf\xd2\xa6[bN\xb5\xa6\x8f\x9a\x90\
+\xf0\xbc\xbd\xaf\xe5\xba\xa57\xe1\x9e-\xa4\xb3,\xfe\xda\
+\x0em\xcfi'B\xed\xacA}\xcc\xe8\x85\xd5\xc7G\
+\xb9\xce\x19\xa5y\xa6\xec\xc2\x9b\xa3O\xb7)^\xbf\x07\
+\xb5G\xb7\xb1\xd9\xeeu\xc4\x0c\xbc\x04\xee\xe9\x05NE\
+\x1cd\x87I@\x0b\x15\xd4'1k\x0d3\x99\x08\x03\
+\x96\xbci\x99\xf9D\x1f\x15\xbd\xc5\xccK\x18\xa6K\x16\
+\xfb\xc15\xbdEu\x5c\xe0t\x8b\xebX\x9f\x04Kr\
+\xd6\xc3Y\x1b\x80\xea\x15\x18=\xf6?\xec\x9a\xd3\xea\xe7\
+\x9c\x97\xb9\xd2R\xf3\x89v\xd8Ug\xaa[\xfc\x1e\xc7\
+\xabN\xd89\x03a%\x0c\xb3\xb5y\xb7\x91\xe2\xcd\xda\
+@V\xb1<\x11\xbeM\x8f\x81\xb36\x80\x19\xedYZ\
+\x9b\x89@\xc5_\xfe4s\x80\xe5\xe6\xd4\xc6#-o\
+(J%?\xedyN+\x9el\xa3\x04\xdf\x08\xb7\xf4\
+I\xdd\x04\xe9\x03\x96'\xc3\xc8\xb5\xff\x83\xb36\xc0\xb3\
++\xc7\x19>\xf6\x05\x15\xc7\x98\xcd\xa9mLt9\xc1\
+\x9b\xb45\x9b\xeel\xdf\x83K\xfa\x8a\x89\xbd/\xd5v\
+\xb7\xe9\xacN\x06\xb3Zh\xb3F\xaf\xc4W-\x9d\x89\
+\xb0\xe9H\xba_sj\x1b\xd3\xc0\xa5cZ\xfc>\xf3\
+\x0f\xad\xb2\xa3\xd1\xa6r\xd7\x9a\xdc\xf0\x9be\xb2x\x17\
+\xdd\x0caqB\xd0\xcfPP\x9f\x9bg=j\xd9L\
+\x04jit\x8f\x9fsj\x1b\xd3\x1f\xa6\xf5iq\x96\
+\x8b\xbc'\xc1nF{\xba\xad\x12t'\xdc\xd1\x88\xec\
+\x04\xb7\xf8=\xab\x13\xa3\xb4\x95\x05D\xec\x06\x19\x05\x15\
+V\xb1j&\xc2w\xe9\xb3,?\xa7R\x8b\xf6\xb4\xe8\
+\x9d\xcc\xac\xbdkNQpi\x22\x5c\xd1\xa8\xddmT\
+\xef\xb6\xda g\xb381\xb6\x16\xed\x86\xc3\xd6!\xb7\
+\xfc\x88e3\x11rN\x14\xa8\x9d\xb4\x9d\xa3\xdd>\xbc\
+\x8e\xb1\xe8\xf9\xb3\x97:\xd81\xb2\xc7o\xe1\x8aF~\
+,\x93\xc5~,N\x8e\x99\x07\x16\xc3a\xeb@_\xd3\
+\x8d\x1es\xea\x0d\xe6\x0dO,\x7f\x8f\x899E\xcfi\
+\xb5\x0f\x92\xe6u\xcb\x15\xfa\xc2\x0dM9N\x90\xbec\
+mr|\xb8u\x0a\x1c\xb6\x0es2\x92-\x99\x89\xb0\
+ k53s\x8a\x1ae\x9e\xa9\xa9i\xf6\xbb=\x94\
+\xf4\xba]rj\xbf\x82\x0b\x9a{\x957\x8d\xa5\x092\
+tE(\x1c\xb6\x0e\xd4\x0c\xd3j\x99\x08\xd4|\xf2&\
+\x83?\xda\xf9Z;\x8b\x0f6\xfb\xfd\xee\xb6\xf0\x07\xbf\
+\x16\x18\xedv\xcaN\x82\x0b\x9a\x9a{\xdb\xedV\x96.\
+;\xd0\x97m`\xde\xf9\xa17\xa5\x08\xdf\xdd\xf8-s\
+\xe6\xd3\x92\xae\xc17\xce\xec\xcf\xfc\xe5\x85@\xb7t\x13\
+\xdc\xcf?\xb5\x13\xc6\xb02Q\xae\x9c\xda\xb3E?\xf9\
+\xec\xce\x90\xe5c\x8d\xbdH\xb2\xee\x8b\x16=\xcf\xb6\xa2\
+\xbdj;%\x889\x03z\xa6\x99\xbf\x98h\xee\xb1\xf8\
+~\xe7e\x1f\xbc\x0e\xd7\xf3\x17\xa1\xa1\x17\xba\x14a\x19\
++\x93%\xab,\x1f.{\x161\xe1\x05\xcbtg\xa0\
+44)\xe1E&\x0d\x88v\xab\xcd\xa1\xa8\xb2\x84\xf5\
+]m\x22\xd5J\x81\xe9\xf9sw\x1b\xd9\xedZ-\x18\
+\xc7X\x980\xcbZ\xd9?\xcaNP\xe7a\xabd\x22\
+P\x8a\x18\xcbF\xb4\xefxv\x93\xef\xb8\xa7$\x93\xe5\
+w,\x0c\x88\x0c\xb9\x1ang\x05\xc3\x8d\x08\x0a\xd2\x02\
+Rm\xf5I3\xc9\xc7\xbd\xb0X\x85:\x0d\x04\xb8%\
+\x833\x11\x8e6\xebY\xf2\xca\x0b\xf5\xdbX,\x9b\xad\
+{OB\x93\xefI\x05\xc7\x19}\xbfS\xd4u\x1b.\
+g\xadt\xb07\xad>qF\xf9\xb8\xcb+\xab\x1c(\
+\xcd1t\x9c\xaf\x9b\xfe`\xb3\x9f\x85\xb2DX\xffB\
+O}\xc5\x9a\x22\xce\x84T;\x9c\xd3\xf2\x82\xea\xb8 \
+\xc0-\xcc\xb4\xf2\xc4\xa1<G\xa0\xeae\x0f\xad\x90\x89\
+\xb0\xd0\x84\xe2\xe5f\x88\xd2\xd5\x9a\x22|\xf7\x5c\x16\xd3\
+\xbc\x14\x18\x9bE\xe9\x10#^\xae\x05i\x87U'\x0f\
+\xb5$\x01\xaa\x1a\xbd\x7f\x91\xdf3\x11\xca\xabO\x1a^\
+\x08\xc7L\x1d*;\xdc\xe8\xfb~\xb2\xcd\xcd\xda;\xa5\
+\xe1:\xae\xc5\xa1\x22\xc2\xd4a\xd3\x92W\x0c\xdd\x92\x9e\
+8\xcf;F\x17DiN&\x82\x19\x85\xcb\xcd\xd4\xf4\
+\xfdI\x8d\xbe/\x1da1\xf4>\xc5m\xa7\x8a\x7f\x84\
+\x9b\xb1q~;\xc0\xaa\xe5\x18\xa9\xc9!\xef\xbc\xb6\xf6\
+sC\xc7xE\xde\x96F\xff\xfd\x1f\x8f\xee3\xbc\xe2\
+\x98\xd9zu\xcd\x7f\x1b}\xe7\xa7\x93\xff\xcd\xca\xd1\xc1\
+\x19\x97\x22=\x04\x17c\xcbp_\xb0\xe2d\x9a}p\
+)\xf7f\xfb\xc8\x921~\xcbD\xa0\xe4\xfe\xe0\xf9/\
+\xd9\xae\x88\xf6m\xb1O4:\xe6T\xdb\x97\x89|Z\
+E|\x0e\xee\xc5 .Y\xfc\xd2j\x93\xe9\xe3T\x99\
+{\xb3\xbdk\xeeP\xbfe\x22D\xec\x89\xb7m\xd3\xc3\
+\xc3\xe5E\x1e\xdf\xfb\xce\xb8\xa7Yx\x87\xcf\xe1Z\xac\
+B7\xcc\xdcb\x9c\x95&\xd4\xb0\x95\x1fpo\xb6F\
+\xd6\x8am,\x13\x81\xcc\xe8\xea\xe8\xfbmk\xb6\xb1\x07\
+\x97y|w\xfa#d\xed\x14/!\x96\xd6+L\x8b\
+a:\xc5t\xbd,@\x16\xd7[eRu\x8b\x7f\x9e\
+k\xa35\xba\x9dvc\xcd5\x9fK\x19g[\xa3m\
+\xac3\x05\xb5\xf81\xfa\x12I+\xaf\xe2\xae\xa5u\x0a\
+\xb7\xb2\x01\x81Qb'-\xa89V\x98XWE\xf5\
+RkT~\x0b\xd2PI@\x7f\xdc\xd2[\x9c\xbd\xde\
+\xd6FK\xa2\xe3\x99\x86\xa03l\x0b?wV\xfb)\
+\xdd\xaf\x82K\xd9\x08J%\xd1\x02\x9bg\x85\x09F-\
+ax\xc5h\xd3k(\x13\xe1\xe4\xe9J\xfd\x03\x92\xdd\
+\xcd\x96v\xafGN\x16\xd7{\xff\x1d\xc7\x0eX5\xf3\
+ \xd7\xe9\x0e\xba\x1e\xeedC\x02\x22\xc5\x9b\xb5 \x17\
+\xf9{\x92%\xe7m\xe6\xd6l\x8d\xfe@\x95_Q\xff\
+#\x11u\xc9\xb0\xbb\xd1\xfe\xa4\xf8\xcc\x94z\xefO\xf3\
+\xcd\x82\xcf\x9aO9\xf1p%{g(\xfc\xc3\xdfU\
+\xc2ZR\xf0\xd9n\x8c\xdb\x1anh\x9b\x98\xf3\xd9]\
+\x9c\xa9^\x11\x19\xc2\x8d\xd9\xbe\xb5\xe1\xebzc@\xe9\
+\x86\x16\xdb\xd1\x1euM\x91n\x81\x1b\xf1p\x86\xab\x08\
+]\xb5\xa0\x97\xf9k\xb2\xbd\xb9a\x22\xb7f\xfb\xd2\xaa\
+\xf1\x86\x8dk\xaf\xc4W\xcf\xf9\xb7\xe8l\xbc7#\xf9\
+\xa5F~\x80\xfd~\xe7l+=ci\xa0,\xde\x05\
+\x17\xe2\x08\xa7[\x0a\xa66\x1b\xfe\x98p\xfd\x17\x8f\xe6\
+\xd6l\x1fX\xf4\x9ai\x99\x08S\xf7&re\xb4\xa4\
+@ERK\xaa\xcaL\xfb5\xd1\xd2\xb66T\x0e\x15\
+\xee\xc3\xe3\x91\x82\x22<\xec\x8f>f\x7f\x9b=\x88[\
+\xb3\xbd5v\xb0)\x99\x08\xf4\xa1\x88\x8e\x15x3[\
+RR\xf6\xbas\xc6|\x84\xc1\xd7\xa3\x9bytP\x85\
+k\xb8\xbc\x1bn\xa4$\x98}\xa4@\xbb\x8f\x8a\xeaJ\
+\xee\x8c\x96~\xd6w\x9c\xda\xdd\xb0qM8\xf4\xcb\xc7\
+\xa1\xe1k>\xe3\xd2hITd\xa7.O,\x7f\xcf\
+\xefG\x07.wP7\xb8\x0d\xa0,\x85{\xb5\xbf\xbc\
+\xc7\xcd\x9c\x80iG\xf7sg\xb6\x05\x15\xc7\x0c\x1d\xd3\
+\xbe\x8bF\xea\xad\x87\xc6\xa7FX:\x89\xdf\x8cR\x9e\
+Ks6\xe8\xedr\x16d\xad\xd6\xdb\xba\xfb\xf1yJ\
+\xb4X\xdc\x03\x97\x01u\xcfp\xbb\x98\x99\x166'#\
+\x99;\xb3\xddR\xb8\x8b[\x03\xe4T\x85\xce\x88\xa0\xdb\
+\xe0.\xc0SZ\xd8\x11\xb3\xaa\xebS\x87Y\x9e\xd4e\
+\xce\x10\x18\x10?\xca\x0b\x8c\x08\xfe+\x5c\x054\xf2\xd1\
+\xac\xdb\xadN\xb7x\x18\x8b\x05\x82\xbc\xbf\x19\x16\xa0\x04\
+\xff\x1dn\x02\x9a\xa4\xfd\xd4\xfb~\xa7M\x9a\xcdX4\
+\x10\xd4bm\xec \x8bW\xc2E@\xb3\xa1\xfeG\xda\
+\xc4\x89\xc7\xe2\x81\xa0fJ\x16\xe7\xa2o\x18\xf0\x8e\x98\
+\x81\xbfr)\xd2D,$\x08j\xd2hC\xa9\xc35\
+L\x03\xb4\xf2\x1cW\x1c\xa1M\xa8\xd3XT\x10TO\
+\xd5NYx\x1e.\x01|\x99\x1a\xf6\xa86\xb1N`\
+qA\xd0\xcf*s\xc9R\x7f\xb8\x03\xf09m\xe5n\
+7h\x13l\x07\x16\x19\x04\x89ih7\x0e\x0c\xa5C\
+\x8cx\xb96\xd1fc\xb1A\xbc*@\x91bh\x1d\
+\xc0\x0d\x80\xf1\xa8\x8e\x0b\x9c\x8a8\x06\xe7\xb8\x10o\xe7\
+\xb3\xf4\xfd\x02\x1f\xc2\x80\xe9\x04\xcab/\x7f\x17\x22\x87\
+ \x93.*\x14P\xd1&\xacz\xe0\xe7s\x5ca\x03\
+\x16#dWQ\xf7[gD\xc8uX\xed\xc0\xff\x84\
+\x86^X\x9b\x1ef~m\x5c\x082\xb6\x06-\x8e\x0d\
+\x80%w\xb9\xc2\x1d\xda\x04\xdd\x83E\x0a\xb1\xff\x11L\
+\xdcM\x95\xf0\xb0\xaa\x81e\xe9\x14\xd3\xf52\xcdp\xbf\
+\xc2\x82\x85\x18\xde\xd1~E\xf3\x18\xab\x190A\x80[\
+x\x9c\xeayb\xe1B,}\x04\xa3\xcb;X\xbd\x80\
+=\xc3\x0d\x0bqj\xa6\x1b\xa6M\xe4\x1a,d\xc8\xc2\
+&{\x86v\xb34_\xb1j\x01\xdb\xa6+\x0b\xf7\xd1\
+\x19\x18\x165d\xc1L\x83]\xd4\x16\x0a\xab\x14\xd8\xea\
+,7@\x16?\xc1E\x08\xc82\x99\x06\xb2\x18\xdaY\
+\x16\x7f\x8d\xd5\x09lz\x96+\xdd\xa3M\xf6T,v\
+\xc8\x8f\xda\x1c(\x8bwa5\x02\xfbC\xd7}ea\
+\xa0K\x113\xb1\xf0!\x13\x95\x11 \x0b}\xb1\x00\x01\
+w\x5c\x15\xd6\xf77gk,\x94\xc1\x08 \x03UJ\
+\xf3\x0c\xe9\x5c\x80{\xda)A\xbfw)R$\xb2\x16\
+ _g\x19P6L\xfb)\xdd\xaf\xc2*\x03\xa0\x0e\
+T\xe8C[$\xaba\x12\x90\x0f\x8cv%\xb2\x0c\x00\
+h\xdeG\xb4\xe50\x0c\xa8\xc5R\x84e\x81\x8a\xd0\x15\
+\xab\x08\x80\x16\xe0T\xc4\x10j\x0d\x0d\x13\x81\xb0\x93\x05\
+\xc0hBC/\x0c\x90\xa5\xc1\xdabJ\x87\xa1@\x0d\
+\xb5\xa7\xd1\xfe(\x0f\xa2y\x82\xc5\x02\x80\xaf\x8e\x17\xb4\
+\x9d\x8b\xb6\xb8\x12\xf0!\x8d{Q\xfc\x13\xb0\x93\x05\xc0\
+`\xce\x16,\xff\xca\xe9\x16O\xc2x\xb8R\x05\xc5\x1d\
+\x8d\x16\x010\x19\x97,v\xae-\xe7(\x1c\x87\x11\xd9\
+Z%\x9a&\xb8\xc2\x83\xae\xc1\xac\x07\xc0\x9fL\xec}\
+\xa9~#\xcd-.\xc1\x11\x83\xad\x8e\x0a\x96P\x5c\x1d\
+1\x03/\xc1$\x07\xc0\x82G\x0c\xb5\x05o\x84\x02\x18\
+\x16\x93\xca\xa2\x0218*\x00\x80\x11j;FHO\
+\x9d\xdd\xedV\xc3\xc4\xac\xdd\x22<\xc0-$\x05(\xe2\
+\x10T\xe1\x02\x80a\xa8\x06\x03\x15 9{%\xf8\x04\
+\xcc\xcd\x12:A\xf1\xa0\xb8P|0K\x01\xb0\x19m\
+\x94\xe0vNE|\x8evR\xd8\xf1\x9a\xaeSN\xb7\
+\xb8\xd0%K\xc3\xda\x86\xf7\x0c\xc4l\x04\x80\xa3\xa3\x86\
+\xda[j\xc2W(\xf7h`'\x04Y\xfc\x84\xc6\x19\
+U\xb7\x00\x00:\xce\x88\x90\xeb4\xd3\x1dQ{\xce+\
+T\xc1,\xbdR%]8p\xba\xa5\x17h<1\xab\
+\x00\x00M\x1e7\xb8\xdc\xd2\x83\x01n\xe1S\xcd<V\
+\xe1\x02\x85\xc7\x9d+\x8dK\x8a\xb6s\xfd\x98\xce_q\
+<\x00\x00h\x1d\x13{_\x1a\x18\x11t\xb7f.\xa3\
+]\xb28W\xdb\xf9\xe6rZ\xf0\x85\xde;N\xd3(\
+\xbd\xba\x16r`\x01\x00F\xd3~\xca=m\xb4\x9f\xcb\
+]jS\xcc\xe8&\x9b^\x8b\xd7.]'\xcaj\xdf\
+\x87\xdeKz\x8a\xde\x93\xde\x17Q\x07\x00X\x83\xb0.\
+\x17\x07(\xc1\x7f\xd7\xcci\x00\xed\xfe4}\xe3T\x84\
+\x05g\xab\x96UX\xb0\xd6\x00=\xd7|M_\xbb\x14\
+\xe9u\x97,\xf5\x0f\x90\xbb\xfd\x8d\xde\x03\xc1\x04\x000\
+K\x07Y\xbc\x92~~\xeby\xbf\xb28\x94\x0c\x99\xce\
+;\xb5\xff\x19~\xf6\xe7yJ\xad\x01\x0a\x07j%\x16\
+j:\xe6\xb9\xfe\x83\xfe\x9f\x1f\xab\xfd\xdf\xfb\xe9\xbf\xa3\
+\xff\xf7Wj\xff\xd9\x1cM\x935\xe3\x1f\xaf\x1b\xbf\xf6\
+\xef\xd1\xbfK\x9de\xe99\x10\x0d\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x8c\xe0\xff\x01/\x9b\xa0\xe9\xec\
+0\x8e\x92\x00\x00\x00\x00IEND\xaeB`\x82\
+"
+
+qt_resource_name = b"\
+\x00\x06\
+\x07\x03}\xc3\
+\x00i\
+\x00m\x00a\x00g\x00e\x00s\
+\x00\x09\
+\x08\x97\x8a'\
+\x00h\
+\x00e\x00a\x00r\x00t\x00.\x00p\x00n\x00g\
+\x00\x07\
+\x08wW\x87\
+\x00b\
+\x00a\x00d\x00.\x00p\x00n\x00g\
+\x00\x09\
+\x08\x9b\xa0G\
+\x00t\
+\x00r\x00a\x00s\x00h\x00.\x00p\x00n\x00g\
+"
+
+qt_resource_struct = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00*\x00\x00\x00\x00\x00\x01\x00\x00d\xb8\
+\x00\x00\x01r\x0e\xc2\x8cT\
+\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x01r\x0e\xc2\x8cW\
+\x00\x00\x00>\x00\x00\x00\x00\x00\x01\x00\x00n|\
+\x00\x00\x01r\x0e\xc2\x8cW\
+"
+
+def qInitResources():
+ QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
diff --git a/examples/widgets/systray/systray.pyproject b/examples/widgets/systray/systray.pyproject
new file mode 100644
index 000000000..eadfb0d7a
--- /dev/null
+++ b/examples/widgets/systray/systray.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "window.py", "systray.qrc"]
+}
diff --git a/examples/widgets/systray/systray.qrc b/examples/widgets/systray/systray.qrc
new file mode 100644
index 000000000..a8b653584
--- /dev/null
+++ b/examples/widgets/systray/systray.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file>images/bad.png</file>
+ <file>images/heart.png</file>
+ <file>images/trash.png</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/systray/window.py b/examples/widgets/systray/window.py
new file mode 100644
index 000000000..ca65f04e1
--- /dev/null
+++ b/examples/widgets/systray/window.py
@@ -0,0 +1,273 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from PySide2.QtCore import Slot
+from PySide2.QtGui import QIcon
+from PySide2.QtWidgets import (QAction, QCheckBox, QComboBox, QDialog,
+ QGridLayout, QGroupBox, QHBoxLayout, QLabel,
+ QLineEdit, QMenu, QMessageBox, QPushButton,
+ QSpinBox, QStyle, QSystemTrayIcon, QTextEdit,
+ QVBoxLayout)
+
+import rc_systray
+
+
+class Window(QDialog):
+ def __init__(self, parent=None):
+ super(Window, self).__init__(parent)
+
+ self.iconGroupBox = QGroupBox()
+ self.iconLabel = QLabel()
+ self.iconComboBox = QComboBox()
+ self.showIconCheckBox = QCheckBox()
+
+ self.messageGroupBox = QGroupBox()
+ self.typeLabel = QLabel()
+ self.durationLabel = QLabel()
+ self.durationWarningLabel = QLabel()
+ self.titleLabel = QLabel()
+ self.bodyLabel = QLabel()
+
+ self.typeComboBox = QComboBox()
+ self.durationSpinBox = QSpinBox()
+ self.titleEdit = QLineEdit()
+ self.bodyEdit = QTextEdit()
+ self.showMessageButton = QPushButton()
+
+ self.minimizeAction = QAction()
+ self.maximizeAction = QAction()
+ self.restoreAction = QAction()
+ self.quitAction = QAction()
+
+ self.trayIcon = QSystemTrayIcon()
+ self.trayIconMenu = QMenu()
+
+ self.createIconGroupBox()
+ self.createMessageGroupBox()
+
+ self.iconLabel.setMinimumWidth(self.durationLabel.sizeHint().width())
+
+ self.createActions()
+ self.createTrayIcon()
+
+ self.showMessageButton.clicked.connect(self.showMessage)
+ self.showIconCheckBox.toggled.connect(self.trayIcon.setVisible)
+ self.iconComboBox.currentIndexChanged.connect(self.setIcon)
+ self.trayIcon.messageClicked.connect(self.messageClicked)
+ self.trayIcon.activated.connect(self.iconActivated)
+
+ self.mainLayout = QVBoxLayout()
+ self.mainLayout.addWidget(self.iconGroupBox)
+ self.mainLayout.addWidget(self.messageGroupBox)
+ self.setLayout(self.mainLayout)
+
+ self.iconComboBox.setCurrentIndex(1)
+ self.trayIcon.show()
+
+ self.setWindowTitle("Systray")
+ self.resize(400, 300)
+
+ def setVisible(self, visible):
+ self.minimizeAction.setEnabled(visible)
+ self.maximizeAction.setEnabled(not self.isMaximized())
+ self.restoreAction.setEnabled(self.isMaximized() or not visible)
+ super().setVisible(visible)
+
+ def closeEvent(self, event):
+ if not event.spontaneous() or not self.isVisible():
+ return
+ if self.trayIcon.isVisible():
+ QMessageBox.information(self, "Systray",
+ "The program will keep running in the system tray. "
+ "To terminate the program, choose <b>Quit</b> in the context "
+ "menu of the system tray entry.")
+ self.hide()
+ event.ignore()
+
+ @Slot(int)
+ def setIcon(self, index):
+ icon = self.iconComboBox.itemIcon(index)
+ self.trayIcon.setIcon(icon)
+ self.setWindowIcon(icon)
+ self.trayIcon.setToolTip(self.iconComboBox.itemText(index))
+
+ @Slot(str)
+ def iconActivated(self, reason):
+ if reason == QSystemTrayIcon.Trigger:
+ pass
+ if reason == QSystemTrayIcon.DoubleClick:
+ self.iconComboBox.setCurrentIndex(
+ (self.iconComboBox.currentIndex() + 1) % self.iconComboBox.count()
+ )
+ if reason == QSystemTrayIcon.MiddleClick:
+ self.showMessage()
+
+ @Slot()
+ def showMessage(self):
+ self.showIconCheckBox.setChecked(True)
+ selectedIcon = self.typeComboBox.itemData(self.typeComboBox.currentIndex())
+ msgIcon = QSystemTrayIcon.MessageIcon(selectedIcon)
+
+ if selectedIcon == -1: # custom icon
+ icon = QIcon(self.iconComboBox.itemIcon(self.iconComboBox.currentIndex()))
+ self.trayIcon.showMessage(
+ self.titleEdit.text(),
+ self.bodyEdit.toPlainText(),
+ icon,
+ self.durationSpinBox.value() * 1000,
+ )
+ else:
+ self.trayIcon.showMessage(
+ self.titleEdit.text(),
+ self.bodyEdit.toPlainText(),
+ msgIcon,
+ self.durationSpinBox.value() * 1000,
+ )
+
+ @Slot()
+ def messageClicked(self):
+ QMessageBox.information(None, "Systray",
+ "Sorry, I already gave what help I could.\n"
+ "Maybe you should try asking a human?")
+
+ def createIconGroupBox(self):
+ self.iconGroupBox = QGroupBox("Tray Icon")
+
+ self.iconLabel = QLabel("Icon:")
+
+ self.iconComboBox = QComboBox()
+ self.iconComboBox.addItem(QIcon(":/images/bad.png"), "Bad")
+ self.iconComboBox.addItem(QIcon(":/images/heart.png"), "Heart")
+ self.iconComboBox.addItem(QIcon(":/images/trash.png"), "Trash")
+
+ self.showIconCheckBox = QCheckBox("Show icon")
+ self.showIconCheckBox.setChecked(True)
+
+ iconLayout = QHBoxLayout()
+ iconLayout.addWidget(self.iconLabel)
+ iconLayout.addWidget(self.iconComboBox)
+ iconLayout.addStretch()
+ iconLayout.addWidget(self.showIconCheckBox)
+ self.iconGroupBox.setLayout(iconLayout)
+
+ def createMessageGroupBox(self):
+ self.messageGroupBox = QGroupBox("Balloon Message")
+
+ self.typeLabel = QLabel("Type:")
+
+ self.typeComboBox = QComboBox()
+ self.typeComboBox.addItem("None", QSystemTrayIcon.NoIcon)
+ self.typeComboBox.addItem(
+ self.style().standardIcon(QStyle.SP_MessageBoxInformation),
+ "Information",
+ QSystemTrayIcon.Information,
+ )
+ self.typeComboBox.addItem(
+ self.style().standardIcon(QStyle.SP_MessageBoxWarning),
+ "Warning",
+ QSystemTrayIcon.Warning,
+ )
+ self.typeComboBox.addItem(
+ self.style().standardIcon(QStyle.SP_MessageBoxCritical),
+ "Critical",
+ QSystemTrayIcon.Critical,
+ )
+ self.typeComboBox.addItem(QIcon(), "Custom icon", -1)
+ self.typeComboBox.setCurrentIndex(1)
+
+ self.durationLabel = QLabel("Duration:")
+
+ self.durationSpinBox = QSpinBox()
+ self.durationSpinBox.setRange(5, 60)
+ self.durationSpinBox.setSuffix(" s")
+ self.durationSpinBox.setValue(15)
+
+ self.durationWarningLabel = QLabel("(some systems might ignore this hint)")
+ self.durationWarningLabel.setIndent(10)
+
+ self.titleLabel = QLabel("Title:")
+ self.titleEdit = QLineEdit("Cannot connect to network")
+ self.bodyLabel = QLabel("Body:")
+
+ self.bodyEdit = QTextEdit()
+ self.bodyEdit.setPlainText("Don't believe me. Honestly, I don't have a clue."
+ "\nClick this balloon for details.")
+
+ self.showMessageButton = QPushButton("Show Message")
+ self.showMessageButton.setDefault(True)
+
+ messageLayout = QGridLayout()
+ messageLayout.addWidget(self.typeLabel, 0, 0)
+ messageLayout.addWidget(self.typeComboBox, 0, 1, 1, 2)
+ messageLayout.addWidget(self.durationLabel, 1, 0)
+ messageLayout.addWidget(self.durationSpinBox, 1, 1)
+ messageLayout.addWidget(self.durationWarningLabel, 1, 2, 1, 3)
+ messageLayout.addWidget(self.titleLabel, 2, 0)
+ messageLayout.addWidget(self.titleEdit, 2, 1, 1, 4)
+ messageLayout.addWidget(self.bodyLabel, 3, 0)
+ messageLayout.addWidget(self.bodyEdit, 3, 1, 2, 4)
+ messageLayout.addWidget(self.showMessageButton, 5, 4)
+ messageLayout.setColumnStretch(3, 1)
+ messageLayout.setRowStretch(4, 1)
+ self.messageGroupBox.setLayout(messageLayout)
+
+ def createActions(self):
+ self.minimizeAction = QAction("Minimize", self)
+ self.minimizeAction.triggered.connect(self.hide)
+
+ self.maximizeAction = QAction("Maximize", self)
+ self.maximizeAction.triggered.connect(self.showMaximized)
+
+ self.restoreAction = QAction("Restore", self)
+ self.restoreAction.triggered.connect(self.showNormal)
+
+ self.quitAction = QAction("Quit", self)
+ self.quitAction.triggered.connect(qApp.quit)
+
+ def createTrayIcon(self):
+ self.trayIconMenu = QMenu(self)
+ self.trayIconMenu.addAction(self.minimizeAction)
+ self.trayIconMenu.addAction(self.maximizeAction)
+ self.trayIconMenu.addAction(self.restoreAction)
+ self.trayIconMenu.addSeparator()
+ self.trayIconMenu.addAction(self.quitAction)
+
+ self.trayIcon = QSystemTrayIcon(self)
+ self.trayIcon.setContextMenu(self.trayIconMenu)
diff --git a/sources/cmake_helpers/helpers.cmake b/sources/cmake_helpers/helpers.cmake
index 81b52920c..fed96b5cd 100644
--- a/sources/cmake_helpers/helpers.cmake
+++ b/sources/cmake_helpers/helpers.cmake
@@ -2,7 +2,15 @@ macro(collect_essential_modules)
# Collect all essential modules.
# note: the order of this list is relevant for dependencies.
# For instance: Qt5Printsupport must come before Qt5WebKitWidgets.
-set(ALL_ESSENTIAL_MODULES Core Gui Widgets PrintSupport Sql Network Test Concurrent)
+set(ALL_ESSENTIAL_MODULES
+ Core
+ Gui
+ Widgets
+ PrintSupport
+ Sql
+ Network
+ Test
+ Concurrent)
if(UNIX AND NOT APPLE)
list(APPEND ALL_ESSENTIAL_MODULES X11Extras)
endif()
@@ -16,10 +24,31 @@ endmacro()
macro(collect_optional_modules)
# Collect all optional modules.
-set(ALL_OPTIONAL_MODULES Xml XmlPatterns Help Multimedia
-MultimediaWidgets OpenGL OpenGLFunctions Positioning Location Qml Quick QuickWidgets RemoteObjects Scxml Script ScriptTools Sensors TextToSpeech Charts Svg DataVisualization)
-find_package(Qt5UiTools)
-if(Qt5UiTools_FOUND)
+set(ALL_OPTIONAL_MODULES
+ Xml
+ XmlPatterns
+ Help Multimedia
+ MultimediaWidgets
+ OpenGL
+ OpenGLFunctions
+ Positioning
+ Location
+ Qml
+ Quick
+ QuickControls2
+ QuickWidgets
+ RemoteObjects
+ Scxml
+ Script
+ ScriptTools
+ Sensors
+ SerialPort
+ TextToSpeech
+ Charts
+ Svg
+ DataVisualization)
+find_package(Qt${QT_MAJOR_VERSION}UiTools)
+if(Qt${QT_MAJOR_VERSION}UiTools_FOUND)
list(APPEND ALL_OPTIONAL_MODULES UiTools)
else()
set(DISABLE_QtUiTools 1)
@@ -31,7 +60,7 @@ endif()
# If WebKit support is needed add the following elements
# to the list: WebKit WebKitWidgets
list(APPEND ALL_OPTIONAL_MODULES WebChannel WebEngineCore WebEngine WebEngineWidgets WebSockets)
-if (Qt5Core_VERSION VERSION_GREATER 5.9.3) # Depending on fixes in Qt3D
+if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 5.9.3) # Depending on fixes in Qt3D
list(APPEND ALL_OPTIONAL_MODULES 3DCore 3DRender 3DInput 3DLogic 3DAnimation 3DExtras)
endif()
endmacro()
@@ -89,10 +118,10 @@ endforeach()
endmacro()
macro(COLLECT_MODULE_IF_FOUND shortname)
- set(name "Qt5${shortname}")
+ set(name "Qt${QT_MAJOR_VERSION}${shortname}")
set(_qt_module_name "${name}")
if ("${shortname}" STREQUAL "OpenGLFunctions")
- set(_qt_module_name "Qt5Gui")
+ set(_qt_module_name "Qt${QT_MAJOR_VERSION}Gui")
endif()
# Determine essential/optional/missing
set(module_state "missing")
@@ -122,7 +151,7 @@ macro(COLLECT_MODULE_IF_FOUND shortname)
# directory, to avoid CMake looking in another path.
# This will be saved in a global variable at the beginning of the modules
# collection process.
- string(FIND "${name}" "Qt5Core" qtcore_found)
+ string(FIND "${name}" "Qt${QT_MAJOR_VERSION}Core" qtcore_found)
if(("${qtcore_found}" GREATER "0") OR ("${qtcore_found}" EQUAL "0"))
get_filename_component(_core_abs_dir "${${_name_dir}}/../" ABSOLUTE)
# Setting the absolute path where the Qt5Core was found
@@ -143,6 +172,16 @@ macro(COLLECT_MODULE_IF_FOUND shortname)
message(STATUS "${module_state} module ${name} found (${ARGN})${looked_in_message}")
# record the shortnames for the tests
list(APPEND all_module_shortnames ${shortname})
+ # Build Qt 5 compatibility variables
+ if(${QT_MAJOR_VERSION} GREATER_EQUAL 6)
+ get_target_property(Qt6${shortname}_INCLUDE_DIRS Qt6::${shortname}
+ INTERFACE_INCLUDE_DIRECTORIES)
+ get_target_property(Qt6${shortname}_PRIVATE_INCLUDE_DIRS
+ Qt6::${shortname}Private
+ INTERFACE_INCLUDE_DIRECTORIES)
+ get_target_property(Qt6${shortname}_LIBRARIES Qt6::${shortname}
+ INTERFACE_LINK_LIBRARIES)
+ endif()
else()
if("${module_state}" STREQUAL "optional")
message(STATUS "optional module ${name} skipped${looked_in_message}")
diff --git a/sources/pyside2-tools b/sources/pyside2-tools
-Subproject 1e8ec62d53f2c7ad579292b2948ebf3aaded420
+Subproject a8448837204faee0b457d1e2d4cbf574a281111
diff --git a/sources/pyside2/CMakeLists.txt b/sources/pyside2/CMakeLists.txt
index 1efcb53ed..dc2beded0 100644
--- a/sources/pyside2/CMakeLists.txt
+++ b/sources/pyside2/CMakeLists.txt
@@ -6,6 +6,8 @@ cmake_policy(VERSION 3.1)
# Don't ignore targets that do not exist, inside add_dependencies calls.
cmake_policy(SET CMP0046 NEW)
+set (QT_MAJOR_VERSION 5)
+
project(pysidebindings)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_helpers/
@@ -77,11 +79,11 @@ if (SHIBOKEN_PYTHON_LIMITED_API)
message(STATUS "******************************************************")
endif()
-find_package(Qt5 5.12 REQUIRED COMPONENTS Core)
-add_definitions(${Qt5Core_DEFINITIONS})
+find_package(Qt${QT_MAJOR_VERSION} 5.12 REQUIRED COMPONENTS Core)
+add_definitions(${Qt${QT_MAJOR_VERSION}Core_DEFINITIONS})
find_file(GL_H "gl.h" PATH_SUFFIXES "GL")
-message("result:" "${GL_H}")
+message(STATUS "GL Headers path:" "${GL_H}")
include(FindQt5Extra)
set(XVFB_EXEC "")
@@ -108,17 +110,26 @@ endif()
# Force usage of the C++11 standard, without a silent fallback
# to C++98 if the compiler does not support C++11.
-set(CMAKE_CXX_STANDARD 11)
+if(${QT_MAJOR_VERSION} GREATER_EQUAL 6)
+ set(CMAKE_CXX_STANDARD 17)
+else()
+ set(CMAKE_CXX_STANDARD 11)
+endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
-# Qt5: QT_INCLUDE_DIR does no longer exist.
-# On Windows, macOS, and Linux it can be computed from Qt5Core_INCLUDE_DIRS, which contains
-# a list of include directories. We take the first one.
-message(STATUS "*** Qt5Core_INCLUDE_DIRS = ${Qt5Core_INCLUDE_DIRS}")
-list(GET Qt5Core_INCLUDE_DIRS 0 QT_INCLUDE_DIR)
+# >= Qt5: QT_INCLUDE_DIR does no longer exist. Derive from QtCore
+if(${QT_MAJOR_VERSION} GREATER_EQUAL 6)
+ get_target_property(QT_INCLUDE_DIR Qt6::Core INTERFACE_INCLUDE_DIRECTORIES)
+ get_filename_component(QT_INCLUDE_DIR "${QT_INCLUDE_DIR}" DIRECTORY)
+else()
+ # On Windows, macOS, and Linux it can be computed from Qt5Core_INCLUDE_DIRS, which contains
+ # a list of include directories. We take the first one.
+ list(GET Qt5Core_INCLUDE_DIRS 0 QT_INCLUDE_DIR)
+endif()
+message(STATUS "*** Qt ${QT_MAJOR_VERSION}, QT_INCLUDE_DIR= ${QT_INCLUDE_DIR}")
# On macOS, check if Qt is a framework build. This affects how include paths should be handled.
-get_target_property(QtCore_is_framework Qt5::Core FRAMEWORK)
+get_target_property(QtCore_is_framework Qt${QT_MAJOR_VERSION}::Core FRAMEWORK)
if (QtCore_is_framework)
# Get the path to the framework dir.
@@ -151,9 +162,9 @@ compute_config_py_values(BINDING_API_VERSION)
include(PySideModules)
# Set default values for pyside2_global.h
-set (Qt5X11Extras_FOUND "0")
-set (Qt5Test_FOUND "0")
-set (Qt5Widgets_FOUND "0")
+set (Qt${QT_MAJOR_VERSION}X11Extras_FOUND "0")
+set (Qt${QT_MAJOR_VERSION}Test_FOUND "0")
+set (Qt${QT_MAJOR_VERSION}Widgets_FOUND "0")
collect_essential_modules()
collect_optional_modules()
@@ -175,7 +186,7 @@ foreach(m ${DISABLED_MODULES})
endforeach()
-string(REGEX MATCHALL "[0-9]+" qt_version_helper "${Qt5Core_VERSION}")
+string(REGEX MATCHALL "[0-9]+" qt_version_helper "${Qt${QT_MAJOR_VERSION}Core_VERSION}")
list(GET qt_version_helper 0 QT_VERSION_MAJOR)
list(GET qt_version_helper 1 QT_VERSION_MINOR)
@@ -241,8 +252,9 @@ endif()
#####################################################################
add_subdirectory(libpyside)
-find_package(Qt5Designer)
-if(Qt5UiTools_FOUND AND Qt5Designer_FOUND)
+find_package(Qt${QT_MAJOR_VERSION}Designer)
+if(${QT_MAJOR_VERSION} LESS 6 AND Qt${QT_MAJOR_VERSION}UiTools_FOUND
+ AND Qt${QT_MAJOR_VERSION}Designer_FOUND)
add_subdirectory(plugins)
endif()
diff --git a/sources/pyside2/PySide2/CMakeLists.txt b/sources/pyside2/PySide2/CMakeLists.txt
index aa37f19bc..120bc8e52 100644
--- a/sources/pyside2/PySide2/CMakeLists.txt
+++ b/sources/pyside2/PySide2/CMakeLists.txt
@@ -49,10 +49,10 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/deprecated.py"
file(READ "${CMAKE_CURRENT_BINARY_DIR}/pyside2_global.h" pyside2_global_contents)
foreach(shortname IN LISTS all_module_shortnames)
- set(name "Qt5${shortname}")
+ set(name "Qt${QT_MAJOR_VERSION}${shortname}")
set(_qt_module_name "${name}")
if ("${shortname}" STREQUAL "OpenGLFunctions")
- set(_qt_module_name "Qt5Gui")
+ set(_qt_module_name "Qt${QT_MAJOR_VERSION}Gui")
endif()
HAS_QT_MODULE(${_qt_module_name}_FOUND Qt${shortname})
diff --git a/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt
index 6d90f76e8..970c9102c 100644
--- a/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt
@@ -31,11 +31,11 @@ set(Qt3DAnimation_include_dirs
${Qt3DAnimation_SOURCE_DIR}
${Qt3DAnimation_BINARY_DIR}
${pyside2_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIR}
- ${Qt53DCore_INCLUDE_DIRS}
- ${Qt53DRender_INCLUDE_DIRS}
- ${Qt53DAnimation_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIR}
+ ${Qt${QT_MAJOR_VERSION}3DCore_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DRender_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DAnimation_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
@@ -44,7 +44,7 @@ set(Qt3DAnimation_include_dirs
${Qt3DAnimation_GEN_DIR})
set(Qt3DAnimation_libraries pyside2
- ${Qt53DAnimation_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}3DAnimation_LIBRARIES})
set(Qt3DAnimation_deps Qt3DRender)
diff --git a/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt
index e28de3f05..aa40c6ec8 100644
--- a/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt
@@ -32,7 +32,7 @@ ${Qt3DCore_GEN_DIR}/qt3dcore_qtransform_wrapper.cpp
# module is always needed
${Qt3DCore_GEN_DIR}/qt3dcore_module_wrapper.cpp)
-if (Qt53DCore_VERSION VERSION_EQUAL 5.10.0 OR Qt53DCore_VERSION VERSION_GREATER 5.10.0)
+if (Qt${QT_MAJOR_VERSION}3DCore_VERSION VERSION_EQUAL 5.10.0 OR Qt${QT_MAJOR_VERSION}3DCore_VERSION VERSION_GREATER 5.10.0)
list(APPEND Qt3DCore_SRC
${Qt3DCore_GEN_DIR}/qt3dcore_qarmature_wrapper.cpp
${Qt3DCore_GEN_DIR}/qt3dcore_qjoint_wrapper.cpp
@@ -46,17 +46,17 @@ set(Qt3DCore_include_dirs
${Qt3DCore_SOURCE_DIR}
${Qt3DCore_BINARY_DIR}
${pyside2_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
- ${Qt53DCore_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DCore_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${QtNetwork_GEN_DIR})
set(Qt3DCore_libraries pyside2
- ${Qt53DCore_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}3DCore_LIBRARIES})
set(Qt3DCore_deps QtGui QtNetwork)
diff --git a/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt
index e581bc269..947c90bf3 100644
--- a/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt
@@ -36,7 +36,8 @@ ${Qt3DExtras_GEN_DIR}/qt3dextras_qt3dwindow_wrapper.cpp
# module is always needed
${Qt3DExtras_GEN_DIR}/qt3dextras_module_wrapper.cpp)
-if (Qt53DExtras_VERSION VERSION_EQUAL 5.10.0 OR Qt53DExtras_VERSION VERSION_GREATER 5.10.0)
+if (Qt${QT_MAJOR_VERSION}3DExtras_VERSION VERSION_EQUAL 5.10.0
+ OR Qt${QT_MAJOR_VERSION}3DExtras_VERSION VERSION_GREATER 5.10.0)
list(APPEND Qt3DExtras_SRC
${Qt3DExtras_GEN_DIR}/qt3dextras_qabstractcameracontroller_wrapper.cpp
${Qt3DExtras_GEN_DIR}/qt3dextras_qabstractcameracontroller_inputstate_wrapper.cpp
@@ -51,11 +52,11 @@ set(Qt3DExtras_include_dirs
${Qt3DExtras_SOURCE_DIR}
${Qt3DExtras_BINARY_DIR}
${pyside2_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt53DCore_INCLUDE_DIRS}
- ${Qt53DRender_INCLUDE_DIRS}
- ${Qt53DExtras_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DCore_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DRender_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DExtras_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
@@ -63,7 +64,7 @@ set(Qt3DExtras_include_dirs
${Qt3DRender_GEN_DIR})
set(Qt3DExtras_libraries pyside2
- ${Qt53DExtras_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}3DExtras_LIBRARIES})
set(Qt3DExtras_deps Qt3DRender)
diff --git a/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt
index a910e30df..8c87b4332 100644
--- a/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt
@@ -31,14 +31,14 @@ set(Qt3DInput_include_dirs
${Qt3DInput_SOURCE_DIR}
${Qt3DInput_BINARY_DIR}
${pyside2_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${Qt3DCore_GEN_DIR})
set(Qt3DInput_libraries pyside2
- ${Qt53DInput_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}3DInput_LIBRARIES})
set(Qt3DInput_deps Qt3DCore)
diff --git a/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt
index 09306f480..9197c3542 100644
--- a/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt
@@ -11,15 +11,15 @@ set(Qt3DLogic_include_dirs
${Qt3DLogic_SOURCE_DIR}
${Qt3DLogic_BINARY_DIR}
${pyside2_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${Qt3DCore_GEN_DIR})
set(Qt3DLogic_libraries pyside2
- ${Qt53DLogic_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}3DLogic_LIBRARIES})
set(Qt3DLogic_deps Qt3DCore)
diff --git a/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt
index edd023840..32f28e032 100644
--- a/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt
@@ -106,7 +106,8 @@ ${Qt3DRender_GEN_DIR}/qt3drender_qviewport_wrapper.cpp
# module is always needed
${Qt3DRender_GEN_DIR}/qt3drender_module_wrapper.cpp)
-if (Qt53DRender_VERSION VERSION_EQUAL 5.10.0 OR Qt53DRender_VERSION VERSION_GREATER 5.10.0)
+if (Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_EQUAL 5.10.0
+ OR Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_GREATER 5.10.0)
list(APPEND Qt3DRender_SRC
${Qt3DRender_GEN_DIR}/qt3drender_qblitframebuffer_wrapper.cpp
${Qt3DRender_GEN_DIR}/qt3drender_qlinewidth_wrapper.cpp
@@ -117,7 +118,8 @@ if (Qt53DRender_VERSION VERSION_EQUAL 5.10.0 OR Qt53DRender_VERSION VERSION_GREA
)
endif()
-if (Qt53DRender_VERSION VERSION_EQUAL 5.11.0 OR Qt53DRender_VERSION VERSION_GREATER 5.11.0)
+if (Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_EQUAL 5.11.0
+ OR Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_GREATER 5.11.0)
list(APPEND Qt3DRender_SRC
${Qt3DRender_GEN_DIR}/qt3drender_qabstractraycaster_wrapper.cpp
${Qt3DRender_GEN_DIR}/qt3drender_qraycaster_wrapper.cpp
@@ -125,32 +127,40 @@ if (Qt53DRender_VERSION VERSION_EQUAL 5.11.0 OR Qt53DRender_VERSION VERSION_GREA
${Qt3DRender_GEN_DIR}/qt3drender_qscreenraycaster_wrapper.cpp)
endif()
-if (Qt53DRender_VERSION VERSION_EQUAL 5.13.0 OR Qt53DRender_VERSION VERSION_GREATER 5.13.0)
+if (Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_EQUAL 5.13.0
+ OR Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_GREATER 5.13.0)
list(APPEND Qt3DRender_SRC
${Qt3DRender_GEN_DIR}/qt3drender_qsetfence_wrapper.cpp
${Qt3DRender_GEN_DIR}/qt3drender_qsharedgltexture_wrapper.cpp
${Qt3DRender_GEN_DIR}/qt3drender_qwaitfence_wrapper.cpp)
endif()
-if (Qt53DRender_VERSION VERSION_EQUAL 5.14.0 OR Qt53DRender_VERSION VERSION_GREATER 5.14.0)
+if (Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_EQUAL 5.14.0
+ OR Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_GREATER 5.14.0)
list(APPEND Qt3DRender_SRC
${Qt3DRender_GEN_DIR}/qt3drender_qnopicking_wrapper.cpp
${Qt3DRender_GEN_DIR}/qt3drender_qshaderimage_wrapper.cpp)
endif()
+if (Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_EQUAL 5.15.0
+ OR Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_GREATER 5.15.0)
+ list(APPEND Qt3DRender_SRC
+ ${Qt3DRender_GEN_DIR}/qt3drender_qrendercapabilities_wrapper.cpp)
+endif()
+
set(Qt3DRender_include_dirs
${Qt3DRender_SOURCE_DIR}
${Qt3DRender_BINARY_DIR}
${pyside2_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${Qt3DCore_GEN_DIR})
set(Qt3DRender_libraries pyside2
- ${Qt53DRender_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}3DRender_LIBRARIES})
set(Qt3DRender_deps Qt3DCore)
diff --git a/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml b/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml
index 477dc605d..1ab13d7d7 100644
--- a/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml
+++ b/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml
@@ -184,6 +184,10 @@
<object-type name="QRenderAspect">
<enum-type name="RenderType"/>
</object-type>
+ <object-type name="QRenderCapabilities" since="5.15">
+ <enum-type name="API"/>
+ <enum-type name="Profile"/>
+ </object-type>
<object-type name="QRenderCapture"/>
<object-type name="QRenderCaptureReply"/>
<object-type name="QRenderPass"/>
diff --git a/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt b/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt
index d7de684b9..38e764405 100644
--- a/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt
@@ -18,17 +18,17 @@ set(QtAxContainer_include_dirs
${QtAxContainer_SOURCE_DIR}
${QtAxContainer_BINARY_DIR}
${pyside2_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${QtWidgets_GEN_DIR})
set(QtAxContainer_libraries pyside2
- ${Qt5AxContainer_LIBRARIES}
- ${Qt5AxBase_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}AxContainer_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}AxBase_LIBRARIES})
set(QtAxContainer_deps QtWidgets)
diff --git a/sources/pyside2/PySide2/QtCharts/CMakeLists.txt b/sources/pyside2/PySide2/QtCharts/CMakeLists.txt
index a327017a7..f73a28b7d 100644
--- a/sources/pyside2/PySide2/QtCharts/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtCharts/CMakeLists.txt
@@ -60,20 +60,20 @@ ${QtCharts_GEN_DIR}/qtcharts_module_wrapper.cpp
set(QtCharts_include_dirs ${QtCharts_SOURCE_DIR}
${QtCharts_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5Charts_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Charts_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${QtWidgets_GEN_DIR})
set(QtCharts_libraries pyside2
- ${Qt5Charts_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Charts_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES})
set(QtCharts_deps QtCore QtGui QtWidgets)
diff --git a/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt b/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt
index b9c5e4b75..145a8bfc3 100644
--- a/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt
@@ -8,14 +8,14 @@ ${QtConcurrent_GEN_DIR}/qtconcurrent_module_wrapper.cpp
set(QtConcurrent_include_dirs ${QtConcurrent_SOURCE_DIR}
${QtConcurrent_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Concurrent_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Concurrent_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
)
set(QtConcurrent_libraries pyside2
${QtConcurrent_LIBRARIES}
- ${Qt5Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
)
set(QtConcurrent_deps QtCore)
diff --git a/sources/pyside2/PySide2/QtCore/CMakeLists.txt b/sources/pyside2/PySide2/QtCore/CMakeLists.txt
index c1add5f21..cfba8d3f1 100644
--- a/sources/pyside2/PySide2/QtCore/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtCore/CMakeLists.txt
@@ -129,6 +129,7 @@ ${QtCore_GEN_DIR}/qsignalmapper_wrapper.cpp
${QtCore_GEN_DIR}/qsignaltransition_wrapper.cpp
${QtCore_GEN_DIR}/qsize_wrapper.cpp
${QtCore_GEN_DIR}/qsizef_wrapper.cpp
+${QtCore_GEN_DIR}/qsocketdescriptor_wrapper.cpp
${QtCore_GEN_DIR}/qsocketnotifier_wrapper.cpp
${QtCore_GEN_DIR}/qsortfilterproxymodel_wrapper.cpp
${QtCore_GEN_DIR}/qstate_wrapper.cpp
@@ -181,13 +182,15 @@ ${SPECIFIC_OS_FILES}
${QtCore_GEN_DIR}/qtcore_module_wrapper.cpp
)
-if (Qt5Core_VERSION VERSION_EQUAL 5.13.0 OR Qt5Core_VERSION VERSION_GREATER 5.13.0)
+if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_EQUAL 5.13.0
+ OR Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 5.13.0)
list(APPEND QtCore_SRC
${QtCore_GEN_DIR}/qconcatenatetablesproxymodel_wrapper.cpp
${QtCore_GEN_DIR}/qtransposeproxymodel_wrapper.cpp)
endif()
-if (Qt5Core_VERSION VERSION_EQUAL 5.14.0 OR Qt5Core_VERSION VERSION_GREATER 5.14.0)
+if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_EQUAL 5.14.0
+ OR Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 5.14.0)
list(APPEND QtCore_SRC
${QtCore_GEN_DIR}/qcalendar_wrapper.cpp
${QtCore_GEN_DIR}/qcalendar_yearmonthday_wrapper.cpp
@@ -204,11 +207,11 @@ configure_file("${QtCore_SOURCE_DIR}/typesystem_core.xml.in"
set(QtCore_include_dirs ${QtCore_SOURCE_DIR}
${QtCore_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
)
set(QtCore_libraries pyside2
- ${Qt5Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
)
create_pyside_module(NAME QtCore
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
index 26193a0aa..e79123398 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
@@ -656,6 +656,13 @@
</namespace-type>
+ <add-function signature="QEnum(PyObject*)" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qenum"/>
+ </add-function>
+ <add-function signature="QFlag(PyObject*)" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qflag"/>
+ </add-function>
+
<add-function signature="qAbs(double)" return-type="double">
<inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qabs"/>
</add-function>
@@ -789,7 +796,7 @@
</modify-function>
</object-type>
- <value-type name="QBasicTimer"/>
+ <object-type name="QBasicTimer"/>
<value-type name="QByteArrayMatcher"/>
<value-type name="QCalendar" since="5.14">
<value-type name="YearMonthDay"/>
@@ -1467,6 +1474,7 @@
<modify-function signature="msleep(unsigned long)" allow-thread="yes"/>
<modify-function signature="sleep(unsigned long)" allow-thread="yes"/>
<modify-function signature="usleep(unsigned long)" allow-thread="yes"/>
+ <modify-function signature="wait(QDeadlineTimer)" allow-thread="yes"/>
<modify-function signature="wait(unsigned long)" allow-thread="yes"/>
<modify-function signature="yieldCurrentThread()" allow-thread="yes"/>
<modify-function signature="start(QThread::Priority)" allow-thread="yes">
@@ -1541,7 +1549,7 @@
<enum-type name="SelectionFlag" flags="SelectionFlags"/>
</object-type>
- <value-type name="QItemSelectionRange" hash-function="qHash">
+ <value-type name="QItemSelectionRange">
</value-type>
<object-type name="QAbstractProxyModel" polymorphic-id-expression="qobject_cast&lt;QAbstractProxyModel*&gt;(%1)">
<extra-includes>
@@ -2342,6 +2350,9 @@
</object-type>
<object-type name="QSemaphoreReleaser" since="5.10"/>
+ <value-type name="QSocketDescriptor" since="5.15">
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qsocketdescriptor"/>
+ </value-type>
<object-type name="QSocketNotifier">
<enum-type name="Type"/>
<add-function signature="QSocketNotifier(PyObject*, QSocketNotifier::Type, QObject*)">
@@ -2417,7 +2428,9 @@
</modify-function>
</object-type>
<object-type name="QWaitCondition">
+ <modify-function signature="wait(QMutex*,QDeadlineTimer)" allow-thread="yes"/>
<modify-function signature="wait(QMutex*,unsigned long)" allow-thread="yes"/>
+ <modify-function signature="wait(QReadWriteLock*,QDeadlineTimer)" allow-thread="yes"/>
<modify-function signature="wait(QReadWriteLock*,unsigned long)" allow-thread="yes"/>
</object-type>
<object-type name="QFileSystemWatcher">
diff --git a/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt b/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt
index 40dafdc4e..46868fe35 100644
--- a/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt
@@ -43,17 +43,17 @@ ${QtDataVisualization_GEN_DIR}/qtdatavisualization_module_wrapper.cpp
set(QtDataVisualization_include_dirs ${QtDataVisualization_SOURCE_DIR}
${QtDataVisualization_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5DataVisualization_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}DataVisualization_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR})
set(QtDataVisualization_libraries pyside2
- ${Qt5DataVisualization_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}DataVisualization_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES})
set(QtDataVisualization_deps QtCore QtGui)
diff --git a/sources/pyside2/PySide2/QtGui/CMakeLists.txt b/sources/pyside2/PySide2/QtGui/CMakeLists.txt
index 9e6bd099f..0001d51d6 100644
--- a/sources/pyside2/PySide2/QtGui/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtGui/CMakeLists.txt
@@ -1,10 +1,14 @@
project(QtGui)
-qt5_wrap_cpp(QPYTEXTOBJECT_MOC "${pyside2_SOURCE_DIR}/qpytextobject.h")
+if (${QT_MAJOR_VERSION} GREATER_EQUAL 6)
+ qt6_wrap_cpp(QPYTEXTOBJECT_MOC "${pyside2_SOURCE_DIR}/qpytextobject.h")
+else()
+ qt5_wrap_cpp(QPYTEXTOBJECT_MOC "${pyside2_SOURCE_DIR}/qpytextobject.h")
+endif()
set(QtGui_DROPPED_ENTRIES)
-get_property(QtGui_enabled_features TARGET Qt5::Gui PROPERTY INTERFACE_QT_ENABLED_FEATURES)
+get_property(QtGui_enabled_features TARGET Qt${QT_MAJOR_VERSION}::Gui PROPERTY INTERFACE_QT_ENABLED_FEATURES)
set(QtGui_SRC
${QtGui_GEN_DIR}/qabstractopenglfunctions_wrapper.cpp
@@ -134,6 +138,7 @@ ${QtGui_GEN_DIR}/qpytextobject_wrapper.cpp
${QtGui_GEN_DIR}/qquaternion_wrapper.cpp
${QtGui_GEN_DIR}/qradialgradient_wrapper.cpp
${QtGui_GEN_DIR}/qregexpvalidator_wrapper.cpp
+${QtGui_GEN_DIR}/qregularexpressionvalidator_wrapper.cpp
${QtGui_GEN_DIR}/qregion_wrapper.cpp
${QtGui_GEN_DIR}/qresizeevent_wrapper.cpp
${QtGui_GEN_DIR}/qsessionmanager_wrapper.cpp
@@ -210,7 +215,8 @@ ${QtGui_GEN_DIR}/qwindowstatechangeevent_wrapper.cpp
${QtGui_GEN_DIR}/qtgui_module_wrapper.cpp
)
-if (Qt5Gui_VERSION VERSION_EQUAL 5.14.0 OR Qt5Gui_VERSION VERSION_GREATER 5.14.0)
+if (Qt${QT_MAJOR_VERSION}Gui_VERSION VERSION_EQUAL 5.14.0
+ OR Qt${QT_MAJOR_VERSION}Gui_VERSION VERSION_GREATER 5.14.0)
list(APPEND QtGui_SRC ${QtGui_GEN_DIR}/qcolorspace_wrapper.cpp)
endif()
@@ -219,12 +225,12 @@ list(FIND QtGui_enabled_features "opengles2" _opengles2Index)
# ### fixme: For cmake >= 3.3: if(opengles2 IN_LIST QtGui_enabled_features)
if(_opengles2Index GREATER -1)
list(APPEND QtGui_DROPPED_ENTRIES QOpenGLTimeMonitor QOpenGLTimerQuery)
- message(STATUS "Qt5Gui: Dropping Desktop OpenGL classes (GLES2)")
+ message(STATUS "Qt${QT_MAJOR_VERSION}Gui: Dropping Desktop OpenGL classes (GLES2)")
else()
list(APPEND QtGui_SRC
${QtGui_GEN_DIR}/qopengltimemonitor_wrapper.cpp
${QtGui_GEN_DIR}/qopengltimerquery_wrapper.cpp)
- message(STATUS "Qt5Gui: Adding Desktop OpenGL classes")
+ message(STATUS "Qt${QT_MAJOR_VERSION}Gui: Adding Desktop OpenGL classes")
endif()
configure_file("${QtGui_SOURCE_DIR}/typesystem_gui.xml.in"
@@ -236,13 +242,13 @@ configure_file("${QtGui_SOURCE_DIR}/QtGui_global.post.h.in"
set(QtGui_include_dirs ${QtGui_SOURCE_DIR}
${QtGui_BINARY_DIR}
${pyside2_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
)
set(QtGui_libraries pyside2
- ${Qt5Gui_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES})
set(QtGui_deps QtCore)
create_pyside_module(NAME QtGui
diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
index 13f8f3cbf..f72259569 100644
--- a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
+++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
@@ -1273,6 +1273,7 @@
</object-type>
<object-type name="QRegExpValidator"/>
+ <object-type name="QRegularExpressionValidator"/>
<object-type name="QStandardItem">
<enum-type name="ItemType"/>
diff --git a/sources/pyside2/PySide2/QtHelp/CMakeLists.txt b/sources/pyside2/PySide2/QtHelp/CMakeLists.txt
index 4262bcd1a..267703f6e 100644
--- a/sources/pyside2/PySide2/QtHelp/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtHelp/CMakeLists.txt
@@ -17,29 +17,38 @@ ${QtHelp_GEN_DIR}/qhelpsearchresultwidget_wrapper.cpp
${QtHelp_GEN_DIR}/qthelp_module_wrapper.cpp
)
-if (Qt5Help_VERSION VERSION_EQUAL 5.13.0 OR Qt5Help_VERSION VERSION_GREATER 5.13.0)
+if (Qt${QT_MAJOR_VERSION}Help_VERSION VERSION_EQUAL 5.13.0
+ OR Qt${QT_MAJOR_VERSION}Help_VERSION VERSION_GREATER 5.13.0)
list(APPEND QtHelp_SRC
${QtHelp_GEN_DIR}/qcompressedhelpinfo_wrapper.cpp
${QtHelp_GEN_DIR}/qhelpfilterdata_wrapper.cpp
${QtHelp_GEN_DIR}/qhelpfilterengine_wrapper.cpp)
endif()
+if (Qt${QT_MAJOR_VERSION}Help_VERSION VERSION_EQUAL 5.15.0
+ OR Qt${QT_MAJOR_VERSION}Help_VERSION VERSION_GREATER 5.15.0)
+ list(APPEND QtHelp_SRC
+ ${QtHelp_GEN_DIR}/qhelpfiltersettingswidget_wrapper.cpp
+ ${QtHelp_GEN_DIR}/qhelplink_wrapper.cpp)
+endif()
+
+
set(QtHelp_include_dirs ${QtHelp_SOURCE_DIR}
${QtHelp_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5Help_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Help_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtWidgets_GEN_DIR}
${QtGui_GEN_DIR}
${QtCore_GEN_DIR}
)
set(QtHelp_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
- ${Qt5Help_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Help_LIBRARIES})
set(QtHelp_deps QtWidgets)
diff --git a/sources/pyside2/PySide2/QtHelp/typesystem_help.xml b/sources/pyside2/PySide2/QtHelp/typesystem_help.xml
index cd62f8afd..76013d1ac 100644
--- a/sources/pyside2/PySide2/QtHelp/typesystem_help.xml
+++ b/sources/pyside2/PySide2/QtHelp/typesystem_help.xml
@@ -57,8 +57,10 @@
<object-type name="QHelpEngineCore"/>
<value-type name="QHelpFilterData" since="5.13"/>
<object-type name="QHelpFilterEngine" since="5.13"/>
+ <object-type name="QHelpFilterSettingsWidget" since="5.15"/>
<object-type name="QHelpIndexModel"/>
<object-type name="QHelpIndexWidget"/>
+ <value-type name="QHelpLink" since="5.15"/>
<object-type name="QHelpSearchEngine"/>
<value-type name="QHelpSearchQuery">
<enum-type name="FieldName"/>
diff --git a/sources/pyside2/PySide2/QtLocation/CMakeLists.txt b/sources/pyside2/PySide2/QtLocation/CMakeLists.txt
index 37cc7e6e5..fa21310b7 100644
--- a/sources/pyside2/PySide2/QtLocation/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtLocation/CMakeLists.txt
@@ -47,21 +47,22 @@ ${QtLocation_GEN_DIR}/qplacesupplier_wrapper.cpp
${QtLocation_GEN_DIR}/qtlocation_module_wrapper.cpp
)
-if (Qt5Location_VERSION VERSION_EQUAL 5.11.0 OR Qt5Location_VERSION VERSION_GREATER 5.11.0)
+if (Qt${QT_MAJOR_VERSION}Location_VERSION VERSION_EQUAL 5.11.0
+ OR Qt${QT_MAJOR_VERSION}Location_VERSION VERSION_GREATER 5.11.0)
list(APPEND QtLocation_SRC
${QtLocation_GEN_DIR}/qgeoserviceproviderfactoryv2_wrapper.cpp)
endif()
set(QtLocation_include_dirs ${QtLocation_SOURCE_DIR}
${QtLocation_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Location_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Location_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtPositioning_GEN_DIR})
set(QtLocation_libraries pyside2
- ${Qt5Location_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Location_LIBRARIES})
set(QtLocation_deps QtCore QtPositioning)
diff --git a/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt b/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt
index efa7944b1..6e3d0f25c 100644
--- a/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt
@@ -11,17 +11,17 @@ ${QtMacExtras_GEN_DIR}/qtmacextras_module_wrapper.cpp
set(QtMacExtras_include_dirs ${QtMacExtras_SOURCE_DIR}
${QtMacExtras_BINARY_DIR}
- ${Qt5MacExtras_INCLUDE_DIRS}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}MacExtras_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${libpyside_SOURCE_DIR})
set(QtMacExtras_libraries pyside2
- ${Qt5MacExtras_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}MacExtras_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES})
set(QtMacExtras_deps QtCore QtGui)
diff --git a/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt b/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt
index cbdd9a1c2..64e6a3a4e 100644
--- a/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt
@@ -97,27 +97,28 @@ ${QtMultimedia_GEN_DIR}/qvideowindowcontrol_wrapper.cpp
${QtMultimedia_GEN_DIR}/qtmultimedia_module_wrapper.cpp
)
-if (Qt5Multimedia_VERSION VERSION_EQUAL 5.11.0 OR Qt5Multimedia_VERSION VERSION_GREATER 5.11.0)
+if (Qt${QT_MAJOR_VERSION}Multimedia_VERSION VERSION_EQUAL 5.11.0
+ OR Qt${QT_MAJOR_VERSION}Multimedia_VERSION VERSION_GREATER 5.11.0)
list(APPEND QtMultimedia_SRC
${QtMultimedia_GEN_DIR}/qcustomaudiorolecontrol_wrapper.cpp)
endif()
set(QtMultimedia_include_dirs ${QtMultimedia_SOURCE_DIR}
${QtMultimedia_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
- ${Qt5Multimedia_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Multimedia_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${QtNetwork_GEN_DIR})
set(QtMultimedia_libraries pyside2
- ${Qt5Multimedia_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Multimedia_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
)
set(QtMultimedia_deps QtCore QtGui QtNetwork)
diff --git a/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt
index 7448f5f38..052db6c42 100644
--- a/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt
@@ -11,12 +11,12 @@ ${QtMultimediaWidgets_GEN_DIR}/qtmultimediawidgets_module_wrapper.cpp
set(QtMultimediaWidgets_include_dirs ${QtMultimediaWidgets_SOURCE_DIR}
${QtMultimediaWidgets_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5Multimedia_INCLUDE_DIRS}
- ${Qt5MultimediaWidgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Multimedia_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}MultimediaWidgets_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
@@ -25,12 +25,12 @@ set(QtMultimediaWidgets_include_dirs ${QtMultimediaWidgets_SOURCE_DIR}
${QtMultimedia_GEN_DIR})
set(QtMultimediaWidgets_libraries pyside2
- ${Qt5Multimedia_LIBRARIES}
- ${Qt5MultimediaWidgets_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Network_LIBRARIES}
- ${Qt5Widgets_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Multimedia_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}MultimediaWidgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES})
set(QtMultimediaWidgets_deps QtCore QtGui QtNetwork QtWidgets QtMultimedia)
diff --git a/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt b/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt
index 7ca3fbb53..7a9dcc23f 100644
--- a/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt
@@ -47,8 +47,10 @@ ${QtNetwork_GEN_DIR}/qudpsocket_wrapper.cpp
${QtNetwork_GEN_DIR}/qtnetwork_module_wrapper.cpp
)
-get_property(QtNetwork_enabled_features TARGET Qt5::Network PROPERTY INTERFACE_QT_ENABLED_FEATURES)
-get_property(QtNetwork_disabled_features TARGET Qt5::Network PROPERTY INTERFACE_QT_DISABLED_FEATURES)
+get_property(QtNetwork_enabled_features TARGET Qt${QT_MAJOR_VERSION}::Network
+ PROPERTY INTERFACE_QT_ENABLED_FEATURES)
+get_property(QtNetwork_disabled_features TARGET Qt${QT_MAJOR_VERSION}::Network
+ PROPERTY INTERFACE_QT_DISABLED_FEATURES)
# ### fixme: For cmake >= 3.3, use if( needle IN_LIST list)
list(FIND QtNetwork_enabled_features "ssl" _sslEnabledIndex)
@@ -59,7 +61,7 @@ if(_sslEnabledIndex EQUAL -1)
list(APPEND QtNetwork_DROPPED_ENTRIES QOcspResponse QSslCipher
QSslConfiguration QSslDiffieHellmanParameters QSslError
QSslKey QSslPreSharedKeyAuthenticator QSslSocket)
- message(STATUS "Qt5Network: Dropping SSL classes")
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Dropping SSL classes")
else()
# Problems with operator==(QSslEllipticCurve,QSslEllipticCurve)
# check_qt_class(QtNetwork QSslEllipticCurve QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
@@ -71,41 +73,42 @@ else()
${QtNetwork_GEN_DIR}/qsslkey_wrapper.cpp
${QtNetwork_GEN_DIR}/qsslpresharedkeyauthenticator_wrapper.cpp
${QtNetwork_GEN_DIR}/qsslsocket_wrapper.cpp)
- if (Qt5Network_VERSION VERSION_EQUAL 5.13.0 OR Qt5Network_VERSION VERSION_GREATER 5.13.0)
+ if (Qt${QT_MAJOR_VERSION}Network_VERSION VERSION_EQUAL 5.13.0
+ OR Qt${QT_MAJOR_VERSION}Network_VERSION VERSION_GREATER 5.13.0)
list(APPEND QtNetwork_SRC
${QtNetwork_GEN_DIR}/qocspresponse_wrapper.cpp)
endif()
- message(STATUS "Qt5Network: Adding SSL classes")
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Adding SSL classes")
endif()
if(_dtlsDisabledIndex GREATER -1)
list(APPEND QtNetwork_DROPPED_ENTRIES QDtls)
- message(STATUS "Qt5Network: Dropping DTLS classes")
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Dropping DTLS classes")
else()
list(APPEND QtNetwork_SRC
${QtNetwork_GEN_DIR}/qdtls_wrapper.cpp)
- message(STATUS "Qt5Network: Adding DTLS classes")
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Adding DTLS classes")
endif()
if(_sctpDisabledIndex GREATER -1)
list(APPEND QtNetwork_DROPPED_ENTRIES QSctpServer QSctpSocket)
- message(STATUS "Qt5Network: Dropping SCTP classes")
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Dropping SCTP classes")
else()
list(APPEND QtNetwork_SRC
${QtNetwork_GEN_DIR}/qsctpserver_wrapper.cpp
${QtNetwork_GEN_DIR}/qsctpsocket_wrapper.cpp)
- message(STATUS "Qt5Network: Adding SCTP classes")
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Adding SCTP classes")
endif()
set(QtNetwork_include_dirs ${QtNetwork_SOURCE_DIR}
${QtNetwork_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR})
set(QtNetwork_libraries pyside2
- ${Qt5Network_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES})
set(QtNetwork_deps QtCore)
diff --git a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
index e128d431e..1e473b3a6 100644
--- a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
+++ b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
@@ -258,6 +258,7 @@
<enum-type name="CacheLoadControl"/>
<enum-type name="KnownHeaders"/>
<enum-type name="RedirectPolicy" since="5.9"/>
+ <enum-type name="TransferTimeoutConstant" since="5.15"/>
</value-type>
<value-type name="QNetworkConfiguration" since="4.7">
@@ -284,6 +285,7 @@
<!-- The following entries may be present in the system or not. Keep this section organized. -->
<value-type name="QSslCertificate">
+ <enum-type name="PatternSyntax" since="5.15"/>
<enum-type name="SubjectInfo"/>
</value-type>
diff --git a/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt b/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt
index 1ca245fea..1d2c406fc 100644
--- a/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt
@@ -17,10 +17,10 @@ ${QtOpenGL_GEN_DIR}/qtopengl_module_wrapper.cpp
)
set(QtOpenGL_include_dirs ${QtOpenGL_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5OpenGL_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}OpenGL_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtWidgets_GEN_DIR}
${QtGui_GEN_DIR}
@@ -28,10 +28,10 @@ set(QtOpenGL_include_dirs ${QtOpenGL_SOURCE_DIR}
${QtOpenGL_GEN_DIR}
)
set(QtOpenGL_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
- ${Qt5OpenGL_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}OpenGL_LIBRARIES})
set(QtOpenGL_deps QtWidgets)
create_pyside_module(NAME QtOpenGL
diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt b/sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt
index 72b3a16ca..eab543b6a 100644
--- a/sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt
@@ -2,7 +2,8 @@ project(QtOpenGLFunctions)
set(QtOpenGLFunctions_DROPPED_ENTRIES)
-get_property(QtOpenGLFunctions_enabled_features TARGET Qt5::Gui PROPERTY INTERFACE_QT_ENABLED_FEATURES)
+get_property(QtOpenGLFunctions_enabled_features TARGET Qt${QT_MAJOR_VERSION}::Gui
+ PROPERTY INTERFACE_QT_ENABLED_FEATURES)
set(QtOpenGLFunctions_SRC ${QtOpenGLFunctions_GEN_DIR}/qtopenglfunctions_module_wrapper.cpp)
@@ -13,7 +14,7 @@ if(_opengles2Index GREATER -1)
list(APPEND QtOpenGLFunctions_DROPPED_ENTRIES QOpenGLTimeMonitor QOpenGLTimerQuery)
list(APPEND QtOpenGLFunctions_SRC
${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_es2_wrapper.cpp)
- message(STATUS "Qt5OpenGLFunctions: Dropping Desktop OpenGL classes (GLES2)")
+ message(STATUS "Qt${QT_MAJOR_VERSION}OpenGLFunctions: Dropping Desktop OpenGL classes (GLES2)")
else()
list(APPEND QtOpenGLFunctions_SRC
${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_1_0_wrapper.cpp
@@ -42,7 +43,7 @@ else()
${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_4_core_wrapper.cpp
${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_5_compatibility_wrapper.cpp
${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_5_core_wrapper.cpp)
- message(STATUS "Qt5OpenGLFunctions: Adding Desktop OpenGL classes")
+ message(STATUS "Qt${QT_MAJOR_VERSION}OpenGLFunctions: Adding Desktop OpenGL classes")
endif()
configure_file("${QtOpenGLFunctions_SOURCE_DIR}/QtOpenGLFunctions_global.post.h.in"
@@ -51,14 +52,14 @@ configure_file("${QtOpenGLFunctions_SOURCE_DIR}/QtOpenGLFunctions_global.post.h.
set(QtOpenGLFunctions_include_dirs ${QtGOpenGLFunctions_SOURCE_DIR}
${QtOpenGLFunctions_BINARY_DIR}
${pyside2_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
)
set(QtOpenGLFunctions_libraries pyside2
- ${Qt5Gui_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES})
set(QtOpenGLFunctions_deps QtGui)
diff --git a/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt b/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt
index 4745cb492..321478c3e 100644
--- a/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt
@@ -23,20 +23,21 @@ ${QtPositioning_GEN_DIR}/qnmeapositioninfosource_wrapper.cpp
${QtPositioning_GEN_DIR}/qtpositioning_module_wrapper.cpp
)
-if (Qt5Positioning_VERSION VERSION_EQUAL 5.10.0 OR Qt5Positioning_VERSION VERSION_GREATER 5.10.0)
+if (Qt${QT_MAJOR_VERSION}Positioning_VERSION VERSION_EQUAL 5.10.0
+ OR Qt${QT_MAJOR_VERSION}Positioning_VERSION VERSION_GREATER 5.10.0)
list(APPEND QtPositioning_SRC
${QtPositioning_GEN_DIR}/qgeopolygon_wrapper.cpp)
endif()
set(QtPositioning_include_dirs ${QtPositioning_SOURCE_DIR}
${QtPositioning_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Positioning_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Positioning_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR})
set(QtPositioning_libraries pyside2
- ${Qt5Positioning_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Positioning_LIBRARIES})
set(QtPositioning_deps QtCore)
diff --git a/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt b/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt
index 74d3dfb88..fd39797da 100644
--- a/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt
@@ -18,20 +18,20 @@ configure_file("${QtPrintSupport_SOURCE_DIR}/typesystem_printsupport.xml.in"
set(QtPrintSupport_include_dirs ${QtPrintSupport_SOURCE_DIR}
${QtPrintSupport_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5PrintSupport_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}PrintSupport_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${QtWidgets_GEN_DIR}
)
set(QtPrintSupport_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
- ${Qt5PrintSupport_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}PrintSupport_LIBRARIES}
)
set(QtPrintSupport_deps QtWidgets)
create_pyside_module(NAME QtPrintSupport
diff --git a/sources/pyside2/PySide2/QtQml/CMakeLists.txt b/sources/pyside2/PySide2/QtQml/CMakeLists.txt
index 9912016ef..3c5dd43fc 100644
--- a/sources/pyside2/PySide2/QtQml/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtQml/CMakeLists.txt
@@ -36,10 +36,10 @@ ${QtQml_GEN_DIR}/qtqml_module_wrapper.cpp
)
set(QtQml_include_dirs ${QtQml_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
- ${Qt5Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtGui_GEN_DIR}
${QtCore_GEN_DIR}
@@ -47,10 +47,10 @@ set(QtQml_include_dirs ${QtQml_SOURCE_DIR}
${QtQml_GEN_DIR})
set(QtQml_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Network_LIBRARIES}
- ${Qt5Qml_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES})
set(QtQml_deps QtGui QtNetwork)
diff --git a/sources/pyside2/PySide2/QtQuick/CMakeLists.txt b/sources/pyside2/PySide2/QtQuick/CMakeLists.txt
index 6707c210a..0f453c90e 100644
--- a/sources/pyside2/PySide2/QtQuick/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtQuick/CMakeLists.txt
@@ -51,7 +51,7 @@ ${QtQuick_GEN_DIR}/qsgtransformnode_wrapper.cpp
${QtQuick_GEN_DIR}/qtquick_module_wrapper.cpp
)
-if (Qt5Quick_VERSION VERSION_GREATER 5.5.1)
+if (Qt${QT_MAJOR_VERSION}Quick_VERSION VERSION_GREATER 5.5.1)
set(QtQuick_SRC ${QtQuick_SRC}
${QtQuick_GEN_DIR}/qquickasyncimageprovider_wrapper.cpp
${QtQuick_GEN_DIR}/qquickimageresponse_wrapper.cpp
@@ -60,11 +60,11 @@ endif()
set(QtQuick_include_dirs ${QtQuick_SOURCE_DIR}
${QtQml_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
- ${Qt5Qml_INCLUDE_DIRS}
- ${Qt5Quick_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtGui_GEN_DIR}
${QtCore_GEN_DIR}
@@ -73,11 +73,11 @@ set(QtQuick_include_dirs ${QtQuick_SOURCE_DIR}
${QtQuick_GEN_DIR})
set(QtQuick_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Network_LIBRARIES}
- ${Qt5Qml_LIBRARIES}
- ${Qt5Quick_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Quick_LIBRARIES})
set(QtQuick_deps QtGui QtNetwork QtQml)
diff --git a/sources/pyside2/PySide2/QtQuickControls2/CMakeLists.txt b/sources/pyside2/PySide2/QtQuickControls2/CMakeLists.txt
new file mode 100644
index 000000000..8321d8a3e
--- /dev/null
+++ b/sources/pyside2/PySide2/QtQuickControls2/CMakeLists.txt
@@ -0,0 +1,41 @@
+project(QtQuickControls2)
+
+set(QtQuickControls2_SRC
+${QtQuickControls2_GEN_DIR}/qquickstyle_wrapper.cpp
+# module is always needed
+${QtQuickControls2_GEN_DIR}/qtquickcontrols2_module_wrapper.cpp
+)
+
+
+set(QtQuickControls2_include_dirs ${QtQuickControls2_SOURCE_DIR}
+ ${QtQml_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}QuickControls2_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtQml_GEN_DIR}
+ ${QtQuick_GEN_DIR}
+ ${QtQuickControls2_GEN_DIR})
+
+set(QtQuickControls2_libraries pyside2
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Quick_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}QuickControls2_LIBRARIES})
+
+set(QtQuickControls2_deps QtGui QtNetwork QtQml QtQuick)
+
+create_pyside_module(NAME QtQuickControls2
+ INCLUDE_DIRS QtQuickControls2_include_dirs
+ LIBRARIES QtQuickControls2_libraries
+ DEPS QtQuickControls2_deps
+ TYPESYSTEM_PATH QtQuickControls2_SOURCE_DIR
+ SOURCES QtQuickControls2_SRC)
diff --git a/sources/pyside2/libpyside/destroylistener.cpp b/sources/pyside2/PySide2/QtQuickControls2/typesystem_quickcontrols2.xml
index 319a126cf..51d42b46b 100644
--- a/sources/pyside2/libpyside/destroylistener.cpp
+++ b/sources/pyside2/PySide2/QtQuickControls2/typesystem_quickcontrols2.xml
@@ -1,6 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -36,68 +38,10 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+-->
+<typesystem package="PySide2.QtQuickControls2">
+ <load-typesystem name="QtQuick/typesystem_quick.xml" generate="no"/>
-#include <sbkpython.h>
-#include "destroylistener.h"
-
-#include <shiboken.h>
-
-PySide::DestroyListener *PySide::DestroyListener::m_instance = nullptr;
-
-namespace PySide
-{
-
-struct DestroyListenerPrivate
-{
- static bool m_destroyed;
-};
-
-
-DestroyListener *DestroyListener::instance()
-{
- if (!m_instance)
- m_instance = new DestroyListener(0);
- return m_instance;
-}
-
-void DestroyListener::destroy()
-{
- if (m_instance) {
- m_instance->disconnect();
- delete m_instance;
- m_instance = 0;
- }
-}
-
-void DestroyListener::listen(QObject *obj)
-{
- SbkObject *wrapper = Shiboken::BindingManager::instance().retrieveWrapper(obj);
- if (!wrapper) // avoid problem with multiple inheritance
- return;
-
- if (Py_IsInitialized() == 0)
- onObjectDestroyed(obj);
- else
- QObject::connect(obj, SIGNAL(destroyed(QObject *)), this, SLOT(onObjectDestroyed(QObject *)), Qt::DirectConnection);
-}
-
-void DestroyListener::onObjectDestroyed(QObject *obj)
-{
- SbkObject *wrapper = Shiboken::BindingManager::instance().retrieveWrapper(obj);
- if (wrapper) //make sure the object exists before destroy
- Shiboken::Object::destroy(wrapper, obj);
-}
-
-DestroyListener::DestroyListener(QObject *parent)
- : QObject(parent)
-{
- m_d = new DestroyListenerPrivate();
-}
-
-DestroyListener::~DestroyListener()
-{
- delete m_d;
-}
-
-}//namespace
+ <object-type name="QQuickStyle" since="5.7"/>
+</typesystem>
diff --git a/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt
index 1f5ae7980..4da9bf838 100644
--- a/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt
@@ -8,13 +8,13 @@ ${QtQuickWidgets_GEN_DIR}/qtquickwidgets_module_wrapper.cpp
set(QtQuickWidgets_include_dirs ${QtQuickWidgets_SOURCE_DIR}
${QtQml_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
- ${Qt5Quick_INCLUDE_DIRS}
- ${Qt5Qml_INCLUDE_DIRS}
- ${Qt5QuickWidgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}QuickWidgets_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtGui_GEN_DIR}
${QtCore_GEN_DIR}
@@ -25,13 +25,13 @@ set(QtQuickWidgets_include_dirs ${QtQuickWidgets_SOURCE_DIR}
${QtQuickWidgets_GEN_DIR})
set(QtQuickWidgets_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Network_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
- ${Qt5Quick_LIBRARIES}
- ${Qt5Qml_LIBRARIES}
- ${Qt5QuickWidgets_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Quick_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}QuickWidgets_LIBRARIES})
set(QtQuickWidgets_deps QtGui QtQml QtQuick QtWidgets QtNetwork)
diff --git a/sources/pyside2/PySide2/QtRemoteObjects/CMakeLists.txt b/sources/pyside2/PySide2/QtRemoteObjects/CMakeLists.txt
index 29b49d895..d8fd6674f 100644
--- a/sources/pyside2/PySide2/QtRemoteObjects/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtRemoteObjects/CMakeLists.txt
@@ -21,7 +21,7 @@ ${QtRemoteObjects_GEN_DIR}/qtremoteobjects_module_wrapper.cpp
set(QtRemoteObjects_include_dirs ${QtRemoteObjects_SOURCE_DIR}
${QtRemoteObjects_BINARY_DIR}
- ${Qt5RemoteObjects_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}RemoteObjects_INCLUDE_DIRS}
${SHIBOKEN_INCLUDE_DIR}
${libpyside_SOURCE_DIR}
${SHIBOKEN_PYTHON_INCLUDE_DIR}
@@ -30,7 +30,7 @@ set(QtRemoteObjects_include_dirs ${QtRemoteObjects_SOURCE_DIR}
set(QtRemoteObjects_libraries pyside2
${SHIBOKEN_PYTHON_LIBRARIES}
${SHIBOKEN_LIBRARY}
- ${Qt5RemoteObjects_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}RemoteObjects_LIBRARIES})
set(QtRemoteObjects_deps QtCore QtNetwork)
diff --git a/sources/pyside2/PySide2/QtScript/CMakeLists.txt b/sources/pyside2/PySide2/QtScript/CMakeLists.txt
index 12453729b..81d6c03d3 100644
--- a/sources/pyside2/PySide2/QtScript/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtScript/CMakeLists.txt
@@ -24,14 +24,14 @@ set(QtScript_glue_sources
set(QtScript_include_dirs ${QtScript_SOURCE_DIR}
${QtScript_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Script_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Script_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
)
set(QtScript_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Script_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Script_LIBRARIES})
set(QtScript_deps QtCore)
create_pyside_module(NAME QtScript
INCLUDE_DIRS QtScript_include_dirs
diff --git a/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt b/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt
index ddb4bec8f..7c19856cb 100644
--- a/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt
@@ -8,11 +8,11 @@ ${QtScriptTools_GEN_DIR}/qtscripttools_module_wrapper.cpp
set(QtScriptTools_include_dirs ${QtScriptTools_SOURCE_DIR}
${QtScriptTools_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5Script_INCLUDE_DIRS}
- ${Qt5ScriptTools_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Script_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}ScriptTools_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
@@ -21,11 +21,11 @@ set(QtScriptTools_include_dirs ${QtScriptTools_SOURCE_DIR}
)
set(QtScriptTools_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
- ${Qt5Script_LIBRARIES}
- ${Qt5ScriptTools_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Script_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}ScriptTools_LIBRARIES})
set(QtScriptTools_deps QtCore QtScript QtGui QtWidgets)
diff --git a/sources/pyside2/PySide2/QtScxml/CMakeLists.txt b/sources/pyside2/PySide2/QtScxml/CMakeLists.txt
index 9cf2f0b22..732253bba 100644
--- a/sources/pyside2/PySide2/QtScxml/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtScxml/CMakeLists.txt
@@ -24,7 +24,8 @@ ${QtScxml_GEN_DIR}/qscxmlexecutablecontent_parameterinfo_wrapper.cpp
${QtScxml_GEN_DIR}/qtscxml_module_wrapper.cpp
)
-if (Qt5Scxml_VERSION VERSION_EQUAL 5.12.0 OR Qt5Scxml_VERSION VERSION_GREATER 5.12.0)
+if (Qt${QT_MAJOR_VERSION}Scxml_VERSION VERSION_EQUAL 5.12.0
+ OR Qt${QT_MAJOR_VERSION}Scxml_VERSION VERSION_GREATER 5.12.0)
list(APPEND QtScxml_SRC
${QtScxml_GEN_DIR}/qscxmldatamodel_wrapper.cpp
${QtScxml_GEN_DIR}/qscxmldatamodel_foreachloopbody_wrapper.cpp
@@ -35,13 +36,13 @@ endif()
set(QtScxml_include_dirs ${QtScxml_SOURCE_DIR}
${QtScxml_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Scxml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Scxml_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR})
set(QtScxml_libraries pyside2
- ${Qt5Scxml_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Scxml_LIBRARIES})
set(QtScxml_deps QtCore)
diff --git a/sources/pyside2/PySide2/QtSensors/CMakeLists.txt b/sources/pyside2/PySide2/QtSensors/CMakeLists.txt
index 2cdd3fe87..0bd6260b7 100644
--- a/sources/pyside2/PySide2/QtSensors/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtSensors/CMakeLists.txt
@@ -81,13 +81,13 @@ set(QtSensors_SRC
set(QtSensors_include_dirs ${QtSensors_SOURCE_DIR}
${QtSensors_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Sensors_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Sensors_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR})
set(QtSensors_libraries pyside2
- ${Qt5Sensors_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Sensors_LIBRARIES})
set(QtSensors_deps QtCore)
diff --git a/sources/pyside2/PySide2/QtSerialPort/CMakeLists.txt b/sources/pyside2/PySide2/QtSerialPort/CMakeLists.txt
new file mode 100644
index 000000000..5242cad4a
--- /dev/null
+++ b/sources/pyside2/PySide2/QtSerialPort/CMakeLists.txt
@@ -0,0 +1,31 @@
+project(QtSerialPort)
+
+set(QtSerialPort_OPTIONAL_SRC )
+set(QtSerialPort_DROPPED_ENTRIES )
+
+set(QtSerialPort_SRC
+ ${QtSerialPort_GEN_DIR}/qserialport_wrapper.cpp
+ ${QtSerialPort_GEN_DIR}/qserialportinfo_wrapper.cpp
+# module is always needed
+ ${QtSerialPort_GEN_DIR}/qtserialport_module_wrapper.cpp
+)
+
+set(QtSerialPort_include_dirs ${QtSerialPort_SOURCE_DIR}
+ ${QtSerialPort_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}SerialPort_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtSerialPort_libraries pyside2
+ ${Qt${QT_MAJOR_VERSION}SerialPort_LIBRARIES})
+
+set(QtSerialPort_deps QtCore)
+
+create_pyside_module(NAME QtSerialPort
+ INCLUDE_DIRS QtSerialPort_include_dirs
+ LIBRARIES QtSerialPort_libraries
+ DEPS QtSerialPort_deps
+ TYPESYSTEM_PATH QtSerialPort_SOURCE_DIR
+ SOURCES QtSerialPort_SRC
+ DROPPED_ENTRIES QtSerialPort_DROPPED_ENTRIES)
diff --git a/sources/pyside2/PySide2/QtSerialPort/typesystem_serialport.xml b/sources/pyside2/PySide2/QtSerialPort/typesystem_serialport.xml
new file mode 100644
index 000000000..8548c543e
--- /dev/null
+++ b/sources/pyside2/PySide2/QtSerialPort/typesystem_serialport.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+-->
+<typesystem package="PySide2.QtSerialPort">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <object-type name="QSerialPort">
+ <enum-type name="BaudRate"/>
+ <enum-type name="DataBits"/>
+ <enum-type name="DataErrorPolicy"/>
+ <enum-type name="Direction" flags="Directions"/>
+ <enum-type name="FlowControl"/>
+ <enum-type name="Parity"/>
+ <enum-type name="PinoutSignal" flags="PinoutSignals"/>
+ <enum-type name="SerialPortError"/>
+ <enum-type name="StopBits"/>
+ </object-type>
+ <value-type name="QSerialPortInfo"/>
+</typesystem>
diff --git a/sources/pyside2/PySide2/QtSql/CMakeLists.txt b/sources/pyside2/PySide2/QtSql/CMakeLists.txt
index 4abd46694..40a253393 100644
--- a/sources/pyside2/PySide2/QtSql/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtSql/CMakeLists.txt
@@ -25,20 +25,20 @@ configure_file("${QtSql_SOURCE_DIR}/QtSql_global.pre.h.in"
set(QtSql_include_dirs ${QtSql_SOURCE_DIR}
${QtSql_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5Sql_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Sql_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${QtWidgets_GEN_DIR}
)
set(QtSql_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
- ${Qt5Sql_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Sql_LIBRARIES})
set(QtSql_deps QtWidgets)
create_pyside_module(NAME QtSql
diff --git a/sources/pyside2/PySide2/QtSvg/CMakeLists.txt b/sources/pyside2/PySide2/QtSvg/CMakeLists.txt
index 75b6f2bf5..19768274d 100644
--- a/sources/pyside2/PySide2/QtSvg/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtSvg/CMakeLists.txt
@@ -11,20 +11,20 @@ ${QtSvg_GEN_DIR}/qtsvg_module_wrapper.cpp
set(QtSvg_include_dirs ${QtSvg_SOURCE_DIR}
${QtSvg_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5Svg_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Svg_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${QtWidgets_GEN_DIR}
)
set(QtSvg_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
- ${Qt5Svg_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Svg_LIBRARIES}
)
set(QtSvg_deps QtWidgets)
diff --git a/sources/pyside2/PySide2/QtTest/CMakeLists.txt b/sources/pyside2/PySide2/QtTest/CMakeLists.txt
index 6614bbca1..04bb28cc9 100644
--- a/sources/pyside2/PySide2/QtTest/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtTest/CMakeLists.txt
@@ -15,20 +15,20 @@ configure_file("${QtTest_SOURCE_DIR}/QtTest_global.post.h.in"
set(QtTest_include_dirs ${QtTest_SOURCE_DIR}
${QtTest_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5Test_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Test_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${QtWidgets_GEN_DIR}
)
set(QtTest_libraries pyside2
- ${Qt5Test_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Test_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
)
set(QtTest_deps QtWidgets)
diff --git a/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt b/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt
index c3080c034..ebd95cfbe 100644
--- a/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt
@@ -10,15 +10,15 @@ ${QtTextToSpeech_GEN_DIR}/qttexttospeech_module_wrapper.cpp
set(QtTextToSpeech_include_dirs ${QtTextToSpeech_SOURCE_DIR}
${QtTextToSpeech_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5TextToSpeech_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}TextToSpeech_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR})
set(QtTextToSpeech_libraries pyside2
- ${Qt5Multimedia_LIBRARIES}
- ${Qt5TextToSpeech_LIBRARIES}
- ${Qt5Core_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Multimedia_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}TextToSpeech_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES})
set(QtTextToSpeech_deps QtCore QtMultimedia)
diff --git a/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt b/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt
index 1ae44d4fd..f9ca16e5a 100644
--- a/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt
@@ -12,12 +12,12 @@ set(QtUiTools_glue_sources
set(QtUiTools_include_dirs ${QtUiTools_SOURCE_DIR}
${QtUiTools_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5Xml_INCLUDE_DIRS}
- ${Qt5Designer_INCLUDE_DIRS}
- ${Qt5UiTools_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Xml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Designer_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}UiTools_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${plugins_SOURCE_DIR}
${QtCore_GEN_DIR}
@@ -27,10 +27,10 @@ set(QtUiTools_include_dirs ${QtUiTools_SOURCE_DIR}
)
set(QtUiTools_libraries pyside2
uiplugin
- ${Qt5UiTools_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}UiTools_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
)
set(QtUiTools_deps QtWidgets QtXml)
create_pyside_module(NAME QtUiTools
diff --git a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
index 2ca12e788..85092a5c2 100644
--- a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
+++ b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
@@ -146,31 +146,6 @@
Riverbank's PyQt.
-->
<add-function signature="loadUiType(const QString&amp; @uifile@)" return-type="PyObject*">
- <inject-documentation format="target" mode="append">
- This function will allow users to generate and load a `.ui` file at runtime, and it returns
- a `tuple` containing the reference to the Python class, and the base class.
-
- We don't recommend this approach since the workflow should be to generate a Python file
- from the `.ui` file, and then import and load it to use it, but we do understand that
- there are some corner cases when such functionality is required.
-
- The internal process relies on `uic` being in the PATH, which is the same requirement for
- the new `pyside2-uic` to work (which is just a wrapper around `uic -g python`)
-
- A Simple use can be:
-
- .. code-block:: python
-
- from PySide2.QtUiTools import loadUiType
-
- generated_class, base_class = loadUiType("themewidget.ui")
- # the values will be:
- # (&lt;class '__main__.Ui_ThemeWidgetForm'&gt;, &lt;class 'PySide2.QtWidgets.QWidget'&gt;)
-
-
- In that case, `generated_class` will be a reference to the Python class,
- and `base_class` will be a reference to the base class.
- </inject-documentation>
<inject-code file="../glue/qtuitools.cpp" snippet="loaduitype"/>
</add-function>
diff --git a/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt b/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt
index 58957b21e..df9531809 100644
--- a/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt
@@ -9,14 +9,14 @@ ${QtWebChannel_GEN_DIR}/qtwebchannel_module_wrapper.cpp
set(QtWebChannel_include_dirs ${QtWebChannel_SOURCE_DIR}
${QtWebChannel_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5WebChannel_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebChannel_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
)
set(QtWebChannel_libraries pyside2
- ${Qt5WebChannel_LIBRARIES}
- ${Qt5Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}WebChannel_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
)
set(QtWebChannel_deps QtCore)
diff --git a/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt b/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt
index 25e11d5d9..e1460ff21 100644
--- a/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt
@@ -9,13 +9,13 @@ ${QtWebEngine_GEN_DIR}/qtwebengine_module_wrapper.cpp
set(QtWebEngine_include_dirs
${QtWebEngine_SOURCE_DIR}
${QtWebEngine_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
)
set(QtWebEngine_libraries pyside2
- ${Qt5WebEngine_LIBRARIES}
- ${Qt5Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}WebEngine_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
)
set(QtWebEngine_deps QtCore)
create_pyside_module(NAME QtWebEngine
diff --git a/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt b/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt
index 74c112734..f0fb1eeda 100644
--- a/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt
@@ -11,7 +11,8 @@ ${QtWebEngineCore_GEN_DIR}/qwebengineurlschemehandler_wrapper.cpp
${QtWebEngineCore_GEN_DIR}/qtwebenginecore_module_wrapper.cpp
)
-if (Qt5WebEngineCore_VERSION VERSION_EQUAL 5.12.0 OR Qt5WebEngineCore_VERSION VERSION_GREATER 5.12.0)
+if (Qt${QT_MAJOR_VERSION}WebEngineCore_VERSION VERSION_EQUAL 5.12.0
+ OR Qt${QT_MAJOR_VERSION}WebEngineCore_VERSION VERSION_GREATER 5.12.0)
list(APPEND QtWebEngineCore_SRC
${QtWebEngineCore_GEN_DIR}/qwebengineurlscheme_wrapper.cpp)
endif()
@@ -19,13 +20,13 @@ endif()
set(QtWebEngineCore_include_dirs
${QtWebEngineCore_SOURCE_DIR}
${QtWebEngineCore_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
)
set(QtWebEngineCore_libraries pyside2
- ${Qt5WebEngineCore_LIBRARIES}
- ${Qt5Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}WebEngineCore_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
)
set(QtWebEngineCore_deps QtCore)
create_pyside_module(NAME QtWebEngineCore
diff --git a/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt
index 214ebc56b..b9fc1bc92 100644
--- a/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt
@@ -20,12 +20,12 @@ ${QtWebEngineWidgets_GEN_DIR}/qtwebenginewidgets_module_wrapper.cpp
set(QtWebEngineWidgets_include_dirs
${QtWebEngineWidgets_SOURCE_DIR}
${QtWebEngineWidgets_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
- ${Qt5WebChannel_INCLUDE_DIRS}
- ${Qt5WebEngineWidgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebChannel_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebEngineWidgets_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
@@ -37,13 +37,13 @@ set(QtWebEngineWidgets_include_dirs
${QtPrintSupport_GEN_DIR}
)
set(QtWebEngineWidgets_libraries pyside2
- ${Qt5WebEngineWidgets_LIBRARIES}
- ${Qt5Network_LIBRARIES}
- ${Qt5WebChannel_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5PrintSupport_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}WebEngineWidgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}WebChannel_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}PrintSupport_LIBRARIES}
)
set(QtWebEngineWidgets_deps QtGui QtWidgets QtNetwork QtWebChannel QtPrintSupport)
create_pyside_module(NAME QtWebEngineWidgets
diff --git a/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt b/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt
index cc03b14b4..4220e46bf 100644
--- a/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt
@@ -8,10 +8,10 @@ ${QtWebKit_GEN_DIR}/qtwebkit_module_wrapper.cpp
set(QtWebKit_include_dirs ${QtWebKit_SOURCE_DIR}
${QtWebKit_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
- ${Qt5WebKit_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebKit_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
@@ -19,10 +19,10 @@ set(QtWebKit_include_dirs ${QtWebKit_SOURCE_DIR}
${QtNetwork_GEN_DIR}
)
set(QtWebKit_libraries pyside2
- ${Qt5WebKit_LIBRARIES}
- ${Qt5Network_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}WebKit_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
)
set(QtWebKit_deps QtGui QtNetwork)
create_pyside_module(NAME QtWebKit
diff --git a/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt
index 4ace240c0..0bf660a62 100644
--- a/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt
@@ -32,13 +32,13 @@ ${QtWebKitWidgets_GEN_DIR}/qtwebkitwidgets_module_wrapper.cpp
set(QtWebKitWidgets_include_dirs
${QtWebKitWidgets_SOURCE_DIR}
${QtWebKitWidgets_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
- ${Qt5WebKit_INCLUDE_DIRS}
- ${Qt5PrintSupport_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
- ${Qt5WebKitWidgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebKit_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}PrintSupport_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebKitWidgets_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
@@ -48,12 +48,12 @@ set(QtWebKitWidgets_include_dirs
${QtNetwork_GEN_DIR}
)
set(QtWebKitWidgets_libraries pyside2
- ${Qt5WebKit_LIBRARIES}
- ${Qt5WebKitWidgets_LIBRARIES}
- ${Qt5Network_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}WebKit_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}WebKitWidgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
)
set(QtWebKitWidgets_deps QtWidgets QtPrintSupport QtNetwork)
create_pyside_module(NAME QtWebKitWidgets
diff --git a/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt b/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt
index a28c633af..4a2c765a6 100644
--- a/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt
@@ -12,18 +12,18 @@ ${QtWebSockets_GEN_DIR}/qtwebsockets_module_wrapper.cpp
set(QtWebSockets_include_dirs ${QtWebSockets_SOURCE_DIR}
${QtWebSockets_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Network_INCLUDE_DIRS}
- ${Qt5WebSockets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebSockets_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtWebSockets_GEN_DIR}
${QtNetwork_GEN_DIR}
)
set(QtWebSockets_libraries pyside2
- ${Qt5WebSockets_LIBRARIES}
- ${Qt5Network_LIBRARIES}
- ${Qt5Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}WebSockets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
)
set(QtWebSockets_deps QtNetwork)
diff --git a/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt
index 102c0ee14..506a6fc78 100644
--- a/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt
@@ -213,17 +213,17 @@ configure_file("${QtWidgets_SOURCE_DIR}/typesystem_widgets.xml.in"
set(QtWidgets_include_dirs ${QtWidgets_SOURCE_DIR}
${QtWidgets_BINARY_DIR}
${pyside2_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
)
set(QtWidgets_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
)
set(QtWidgets_deps QtGui)
diff --git a/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt b/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt
index 0e0b3d58b..3593394c3 100644
--- a/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt
@@ -20,17 +20,17 @@ ${QtWinExtras_GEN_DIR}/qtwinextras_module_wrapper.cpp
set(QtWinExtras_include_dirs ${QtWinExtras_SOURCE_DIR}
${QtWinExtras_BINARY_DIR}
- ${Qt5WinExtras_INCLUDE_DIRS}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WinExtras_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${libpyside_SOURCE_DIR})
set(QtWinExtras_libraries pyside2
- ${Qt5WinExtras_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}WinExtras_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES})
set(QtWinExtras_deps QtCore QtGui)
diff --git a/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt b/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt
index 8bc1a7ffd..9008da747 100644
--- a/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt
@@ -11,17 +11,17 @@ configure_file("${QtX11Extras_SOURCE_DIR}/QtX11Extras_global.post.h.in"
set(QtX11Extras_include_dirs ${QtX11Extras_SOURCE_DIR}
${QtX11Extras_BINARY_DIR}
- ${Qt5X11Extras_INCLUDE_DIRS}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}X11Extras_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
${libpyside_SOURCE_DIR})
set(QtX11Extras_libraries pyside2
- ${Qt5X11Extras_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}X11Extras_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES})
set(QtX11Extras_deps QtCore QtGui)
diff --git a/sources/pyside2/PySide2/QtXml/CMakeLists.txt b/sources/pyside2/PySide2/QtXml/CMakeLists.txt
index f17a77240..eb64b4795 100644
--- a/sources/pyside2/PySide2/QtXml/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtXml/CMakeLists.txt
@@ -38,13 +38,13 @@ ${QtXml_GEN_DIR}/qtxml_module_wrapper.cpp
set(QtXml_include_dirs ${QtXml_SOURCE_DIR}
${QtXml_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Xml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Xml_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
)
set(QtXml_libraries pyside2
- ${Qt5Xml_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Xml_LIBRARIES})
set(QtXml_deps QtCore)
create_pyside_module(NAME QtXml
diff --git a/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt b/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt
index 696c09c1a..adc1be516 100644
--- a/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt
@@ -22,14 +22,14 @@ ${QtXmlPatterns_GEN_DIR}/qtxmlpatterns_module_wrapper.cpp
set(QtXmlPatterns_include_dirs ${QtXmlPatterns_SOURCE_DIR}
${QtXmlPatterns_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5XmlPatterns_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}XmlPatterns_INCLUDE_DIRS}
${libpyside_SOURCE_DIR}
${QtCore_GEN_DIR}
)
set(QtXmlPatterns_libraries pyside2
- ${Qt5Core_LIBRARIES}
- ${Qt5XmlPatterns_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}XmlPatterns_LIBRARIES})
set(QtXmlPatterns_deps QtCore)
create_pyside_module(NAME QtXmlPatterns
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index 111e324b9..8bd2baac1 100644
--- a/sources/pyside2/PySide2/glue/qtcore.cpp
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -587,6 +587,14 @@ Py_END_ALLOW_THREADS
PySide::runCleanupFunctions();
// @snippet moduleshutdown
+// @snippet qt-qenum
+%PYARG_0 = PySide::QEnum::QEnumMacro(%1, false);
+// @snippet qt-qenum
+
+// @snippet qt-qflag
+%PYARG_0 = PySide::QEnum::QEnumMacro(%1, true);
+// @snippet qt-qflag
+
// @snippet qt-pysideinit
Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "unicode");
Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "str");
@@ -1288,6 +1296,14 @@ QByteArray ba(1 + int(%2), char(0));
%CPPSELF.%FUNCTION_NAME(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1));
// @snippet qcryptographichash-adddata
+// @snippet qsocketdescriptor
+#ifdef WIN32
+using DescriptorType = Qt::HANDLE;
+#else
+using DescriptorType = int;
+#endif
+// @snippet qsocketdescriptor
+
// @snippet qsocketnotifier
PyObject *socket = %PYARG_1;
if (socket != nullptr) {
@@ -1689,11 +1705,19 @@ Py_END_ALLOW_THREADS
// @snippet conversion-pyunicode
#ifndef Py_LIMITED_API
Py_UNICODE *unicode = PyUnicode_AS_UNICODE(%in);
-# if defined(Py_UNICODE_WIDE)
+# if defined(Py_UNICODE_WIDE)
// cast as Py_UNICODE can be a different type
-%out = QString::fromUcs4((const uint *)unicode);
-# else
-%out = QString::fromUtf16((const ushort *)unicode, PepUnicode_GetLength(%in));
+# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+%out = QString::fromUcs4(reinterpret_cast<const char32_t *>(unicode));
+# else
+%out = QString::fromUcs4(reinterpret_cast<const uint *>(unicode));
+# endif // Qt 6
+# else // Py_UNICODE_WIDE
+# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+%out = QString::fromUtf16(reinterpret_cast<const char16_t *>(unicode), PepUnicode_GetLength(%in));
+# else
+%out = QString::fromUtf16(reinterpret_cast<const ushort *>(unicode), PepUnicode_GetLength(%in));
+# endif // Qt 6
# endif
#else
wchar_t *temp = PyUnicode_AsWideCharString(%in, NULL);
diff --git a/sources/pyside2/cmake/Macros/FindQt5Extra.cmake b/sources/pyside2/cmake/Macros/FindQt5Extra.cmake
index 6bfa5e074..71846e48a 100644
--- a/sources/pyside2/cmake/Macros/FindQt5Extra.cmake
+++ b/sources/pyside2/cmake/Macros/FindQt5Extra.cmake
@@ -4,9 +4,9 @@
# CT: maybe we can remove this.
# For now, I just use the mapping to Qt5
-find_package(Qt5Multimedia)
+find_package(Qt${QT_MAJOR_VERSION}Multimedia)
-if (NOT Qt5Multimedia_FOUND)
+if (NOT Qt${QT_MAJOR_VERSION}Multimedia_FOUND)
find_path(QT_QTMULTIMEDIA_INCLUDE_DIR QtMultimedia
PATHS ${QT_HEADERS_DIR}/QtMultimedia
${QT_LIBRARY_DIR}/QtMultimedia.framework/Headers
diff --git a/sources/pyside2/cmake/Macros/PySideModules.cmake b/sources/pyside2/cmake/Macros/PySideModules.cmake
index dca00ec11..14707f964 100644
--- a/sources/pyside2/cmake/Macros/PySideModules.cmake
+++ b/sources/pyside2/cmake/Macros/PySideModules.cmake
@@ -91,7 +91,10 @@ macro(create_pyside_module)
list(REMOVE_DUPLICATES total_type_system_files)
# Contains include directories to pass to shiboken's preprocessor.
- set(shiboken_include_dirs ${pyside2_SOURCE_DIR}${PATH_SEP}${QT_INCLUDE_DIR})
+ # Workaround: Added ${QT_INCLUDE_DIR}/QtCore until
+ # qtdeclarative/8d560d1bf0a747bf62f73fad6b6774095442d9d2 has reached qt5.git
+ string(REPLACE ";" ${PATH_SEP} core_includes "${Qt5Core_INCLUDE_DIRS}")
+ set(shiboken_include_dirs ${pyside2_SOURCE_DIR}${PATH_SEP}${QT_INCLUDE_DIR}${PATH_SEP}${core_includes})
set(shiboken_framework_include_dirs_option "")
if(CMAKE_HOST_APPLE)
set(shiboken_framework_include_dirs "${QT_FRAMEWORK_INCLUDE_DIR}")
diff --git a/sources/pyside2/doc/CMakeLists.txt b/sources/pyside2/doc/CMakeLists.txt
index 8eb4eca06..ffbb3c1eb 100644
--- a/sources/pyside2/doc/CMakeLists.txt
+++ b/sources/pyside2/doc/CMakeLists.txt
@@ -22,7 +22,7 @@ file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/pyside.qdocconf ${CMAKE_CURRENT_LIST_DIR}/
# - Build include path for qdoc for shiboken
# The last element of the include list is the mkspec directory containing qplatformdefs.h
-list(GET Qt5Core_INCLUDE_DIRS -1 mkspecInclude)
+list(GET Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS -1 mkspecInclude)
configure_file("pyside-config.qdocconf.in" "${CMAKE_CURRENT_LIST_DIR}/pyside-config.qdocconf" @ONLY)
file(READ "${pyside2_BINARY_DIR}/pyside2_global.h" docHeaderContents)
@@ -56,8 +56,8 @@ foreach(moduleIn ${all_module_shortnames})
# -- @TODO fix this for macOS frameworks.
file(APPEND "${CMAKE_CURRENT_LIST_DIR}/pyside-config.qdocconf"
" -I ${QT_INCLUDE_DIR}Qt${module} \\\n"
- " -I ${QT_INCLUDE_DIR}Qt${module}/${Qt5Core_VERSION} \\\n"
- " -I ${QT_INCLUDE_DIR}Qt${module}/${Qt5Core_VERSION}/Qt${module} \\\n")
+ " -I ${QT_INCLUDE_DIR}Qt${module}/${Qt${QT_MAJOR_VERSION}Core_VERSION} \\\n"
+ " -I ${QT_INCLUDE_DIR}Qt${module}/${Qt${QT_MAJOR_VERSION}Core_VERSION}/Qt${module} \\\n")
if (${moduleIn} STREQUAL "X11Extras")
set(globalHeader "QX11Info")
@@ -95,16 +95,51 @@ add_custom_target(qdoc
COMMENT "Running qdoc against Qt source code..."
SOURCE "pyside.qdocconf")
+# conditional tag for sphinx build
+#string(JOIN "_" SPHINX_TAG ${DOC_OUTPUT_FORMAT} "format")
+# Python script to replace the virtualFolder string in the QHP
+set(py_cmd "from __future__ import print_function
+import fileinput
+import re
+try:
+\tfor line in fileinput.input('html/PySide.qhp',inplace=True,backup='.bak'):
+\t\tline_copy=line.strip()
+\t\tif not line_copy: # check for empty line
+\t\t\tcontinue
+\t\tmatch=re.match('(^.*virtualFolder.)doc(.*$)',line)
+\t\tif match:
+\t\t\trepl=''.join([match.group(1),'pyside2',match.group(2)])
+\t\t\tprint(line.replace(match.group(0),repl),end='')
+\t\telse:
+\t\t\tprint(line)
+except:
+\tpass\n")
+file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/py_script.py CONTENT ${py_cmd})
+
add_custom_target(apidoc
- COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} ${SPHINX_BUILD} -b html ${CMAKE_CURRENT_BINARY_DIR}/rst html
- #copying shiboken2 (including ApiExtractor) doc htmls
- COMMENT "Copying over the Shiboken2 doc HTMLs..."
- COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2
- COMMAND ${CMAKE_COMMAND} -E copy_directory
- ${CMAKE_CURRENT_BINARY_DIR}/../../shiboken2/doc/html
- ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2
+ COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} ${SPHINX_BUILD} -b ${DOC_OUTPUT_FORMAT} ${CMAKE_CURRENT_BINARY_DIR}/rst html
+ COMMENT "Generating PySide htmls..."
)
+# create a custom commands to copy the shiboken docs
+# and generate offline help based on the output format.
+if(DOC_OUTPUT_FORMAT STREQUAL "html")
+ add_custom_command(TARGET apidoc POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${CMAKE_CURRENT_BINARY_DIR}/../../shiboken2/doc/html
+ ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2
+ COMMENT "Copying Shiboken docs..."
+ VERBATIM)
+else()
+ file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/html/PySide.qhp QHP_FILE)
+ add_custom_command(TARGET apidoc POST_BUILD
+ COMMAND ${PYTHON_EXECUTABLE} py_script.py
+ COMMAND qhelpgenerator ${QHP_FILE}
+ COMMENT "Generating QCH from a QHP file..."
+ VERBATIM)
+endif()
+
# create conf.py based on conf.py.in
configure_file("conf.py.in" "rst/conf.py" @ONLY)
diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/domainindex.html b/sources/pyside2/doc/_themes/pysidedocs_qthelp/domainindex.html
new file mode 100644
index 000000000..c136cdd1c
--- /dev/null
+++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/domainindex.html
@@ -0,0 +1,57 @@
+{#
+ basic/domainindex.html
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ Template for domain indices (module index, ...).
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+#}
+{% extends "layout.html" %}
+{% set title = indextitle %}
+{% block extrahead %}
+{{ super() }}
+{% if not embedded and collapse_index %}
+ <script type="text/javascript">
+ DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true;
+ </script>
+{% endif %}
+{% endblock %}
+{% block body %}
+<div class="section">
+ {%- set curr_group = 0 %}
+
+ <h1>{{ indextitle }}</h1>
+
+ <div class="modindex-jumpbox">
+ {%- for (letter, entries) in content %}
+ <a href="#cap-{{ letter }}"><strong>{{ letter }}</strong></a>
+ {%- if not loop.last %} | {% endif %}
+ {%- endfor %}
+ </div>
+
+ <table class="indextable modindextable" cellspacing="0" cellpadding="2">
+ {%- for letter, entries in content %}
+ <tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
+ <tr class="cap"><td></td><td><a name="cap-{{ letter }}">
+ <strong>{{ letter }}</strong></a></td><td></td></tr>
+ {%- for (name, grouptype, page, anchor, extra, qualifier, description)
+ in entries %}
+ {%- if grouptype == 1 %}{% set curr_group = curr_group + 1 %}{% endif %}
+ <tr{% if grouptype == 2 %} class="cg-{{ curr_group }}"{% endif %}>
+ <td>{% if grouptype == 1 -%}
+ <img src="{{ pathto('_static/minus.png', 1) }}" id="toggle-{{ curr_group }}"
+ class="toggler" style="display: none" alt="-" />
+ {%- endif %}</td>
+ <td>{% if grouptype == 2 %}&nbsp;&nbsp;&nbsp;{% endif %}
+ {% if page %}<a href="{{ pathto(page) }}#{{ anchor }}">{% endif -%}
+ <tt class="xref">{{ name|e }}</tt>
+ {%- if page %}</a>{% endif %}
+ {%- if extra %} <em>({{ extra|e }})</em>{% endif -%}
+ </td><td>{% if qualifier %}<strong>{{ qualifier|e }}:</strong>{% endif %}
+ <em>{{ description|e }}</em></td></tr>
+ {%- endfor %}
+ {%- endfor %}
+ </table>
+</div>
+{% endblock %}
diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/fakebar.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/fakebar.png
new file mode 100644
index 000000000..b45830e00
--- /dev/null
+++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/fakebar.png
Binary files differ
diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg
new file mode 100644
index 000000000..cd474efba
--- /dev/null
+++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg
Binary files differ
diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png
new file mode 100644
index 000000000..3bc03b7c7
--- /dev/null
+++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png
Binary files differ
diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/minus.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/minus.png
new file mode 100644
index 000000000..da1c5620d
--- /dev/null
+++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/minus.png
Binary files differ
diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/plus.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/plus.png
new file mode 100644
index 000000000..b3cb37425
--- /dev/null
+++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/plus.png
Binary files differ
diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pyside.css b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pyside.css
new file mode 100644
index 000000000..aee5e4420
--- /dev/null
+++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pyside.css
@@ -0,0 +1,1943 @@
+@import url('cookie-confirm.css') screen;
+
+/* -- admonitions -- */
+
+div.admonition {
+ margin: 1.5em 0 1.5em;
+ padding: 0;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+div.admonition dl {
+ margin-bottom: 0;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.admonition code {
+ font-family: inherit;
+}
+
+p.admonition-title + p {
+ padding-left: 1em;
+}
+
+div.admonition a:after {
+ content: ', ';
+}
+
+div.admonition a:last-child:after {
+ content: '';
+}
+
+.body {
+ width: 100%
+}
+.bodywrapper .admonition p.admonition-title {
+ margin-bottom:5px
+}
+
+.bodywrapper .admonition p {
+ margin:0
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+div.warning, div.seealso, div.note {
+ padding: 6px 0px 6px 10px;
+ border: none;
+}
+
+div.warning {
+ background-color: #ffe4e4;
+}
+
+div.seealso {
+ background-color: #fff2d6;
+}
+
+div.note {
+ background-color: #f3f3f4;
+}
+
+table.docutils {
+ margin-right: auto;
+ margin-bottom: 10px;
+ border: none;
+ width: initial;
+}
+
+table.docutils.colwidths-given td {
+ float: none;
+}
+
+table.docutils th,
+table.docutils td {
+ padding-left:0;
+ border: none;
+}
+
+table.docutils td ul {
+ margin:0
+}
+
+table.docutils td ul > li {
+ margin: 0 0 0.5em;
+}
+h2 em {
+ float: right;
+ font-size: 10px;
+ position: relative;
+ top: -20px;
+}
+
+.document {
+ padding-bottom: 20px;
+}
+
+.documentwrapper {
+ margin-left: 20px;
+}
+
+.body blockquote {
+ border: none;
+ padding-left: 0;
+ margin-bottom: 1.5em;
+}
+
+.sphinxsidebar {
+ float: left;
+ width: 186px;
+ padding: 25px;
+ text-align: left;
+ background-color: #fff;
+}
+
+.sphinxsidebar ul {
+ padding: 0px;
+ margin: 0px;
+ list-style-position: inside;
+}
+
+.sphinxsidebar > ul {
+ padding: 0px;
+ margin: 0px;
+}
+
+.sphinxsidebar ul li li {
+ margin-left: 10px;
+ padding: 0px;
+ font-size: 0.95em;
+}
+
+.sphinxsidebar ul a,
+.sphinxsidebar p.topless a {
+ word-break: break-word;
+}
+
+.sphinxsidebar h3, .sphinxsidebar h3 a {
+ color: #333;
+}
+
+.sphinxsidebar p.topless {
+ margin: 1em 0 1em;
+}
+
+.pysidetoc ul {
+ list-style: none;
+ padding: 0px;
+ margin: 0px;
+}
+
+.pysidetoc em {
+ font-style: normal;
+}
+
+.pysidetoc strong {
+ display: block;
+ padding: 5px;
+ margin: 0 10px 10px 0;
+ border: none;
+ background-color: #e2e2e2;
+}
+
+.section .docutils.container td {
+ float:left;
+}
+
+.hide {
+ display: none;
+}
+
+/* copy-notice */
+.document + p {
+ margin-left: 255px;
+ width: 70%;
+ font-size: 0.75em;
+ margin: 0 35px 15px 280px;
+}
+
+#searchbox {
+ border-top: 1px solid #989898;
+ padding-top: 10px;
+ margin-left: -10px;
+ margin-right: -10px;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+#search_button {
+ border: 1px solid #3A393A;
+ background-color: #3A393A;
+ color: white;
+ cursor: pointer;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -khtml-border-radius: 5px;
+
+}
+
+form {
+ margin: 0px;
+ padding: 0px;
+}
+
+#searchbox h3 {
+ padding: 10px 0 0 0;
+ margin-bottom: 5px;
+}
+
+/* search field */
+form #q {
+ width: 136px;
+ /* height: 22px; */
+ /* border: none; */
+ margin: 0px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -khtml-border-radius: 5px;
+ margin-top: 2px;
+ padding: 4px;
+ line-height: 22px;
+}
+
+#search-results h2 {
+ display: none;
+}
+
+#search-results h2 {
+ display: none;
+}
+
+#search-results ul.search {
+ margin: 0px;
+ padding: 0px;
+}
+
+ul.search div.context {
+ padding-left: 40px;
+}
+
+#installation td {
+ text-align: center;
+ font-weight: bold;
+}
+
+em {
+ color: inherit;
+ font-style:italic;
+}
+
+/******** REL bar *********/
+
+.related {
+ display: inline;
+}
+
+.related h3 {
+ display: none;
+}
+
+.align-center {
+ text-align: center;
+}
+
+.contentstable {
+ width: 100%;
+}
+
+.contentstable td {
+ padding-left: 30px;
+ vertical-align: top;
+}
+
+p.biglink a {
+ font-size: 20px;
+}
+
+dt:target, .highlight {
+ background-color: #fbe54e;
+}
+
+p.highlight-link {
+ margin-top: 10px;
+ font-size: 0.8em;
+}
+
+#synopsis table, table.field-list {
+ margin: 1em 0 1em 0;
+}
+
+table.field-list tr {
+ text-align: left;
+}
+
+tt.descname {
+ font-size: 120%;
+ font-weight: bold;
+}
+
+#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul {
+ margin: 0;
+ padding: 6px;
+ border: 1px solid #ddd;
+ border-radius: 0;
+ background-color: #e2e2e2;
+}
+
+#functions p, #virtual-functions p, #slots p, #signals p, #static-functions p {
+ margin: 0;
+ padding: 0;
+}
+
+#functions li, #virtual-functions li, #slots li, #signals li, #static-functions li {
+ list-style: none;
+ margin: 5px;
+ padding: 0;
+ font-size: 90%;
+}
+
+#synopsis span.pre {
+ color: #009491;
+ font-weight: bolder;
+}
+
+#detailed-description .class dt,
+#detailed-description .method dt,
+#detailed-description .staticmethod dt,
+#detailed-description .attribute dt {
+ margin: 0px;
+ margin-bottom: 10px;
+ padding: 10px;
+ font-weight: bold;
+ background-color: #e2e2e2;
+ border: none;
+ border-radius: 0;
+}
+
+#detailed-description dd > blockquote,
+#detailed-description dd > .field-list {
+ font-family: monospace;
+ font-size: small;
+ border-left: 10px solid #e2e2e2;
+ padding-left: 10px;
+ margin-bottom: 1.5em;
+}
+
+#detailed-description dd > blockquote blockquote {
+ border: none;
+ padding: 0;
+}
+
+#detailed-description .class .field-odd,
+#detailed-description .method .field-odd,
+#detailed-description .staticmethod .field-odd,
+#detailed-description .attribute .field-odd {
+ margin: 0;
+ padding: 1px 0 0 0;
+ background-color: #ffffff;
+
+}
+
+#detailed-description .class .field-even,
+#detailed-description .method .field-even,
+#detailed-description .staticmethod .field-even,
+#detailed-description .attribute .field-even {
+ margin: 0;
+ padding: 1px 0 0 0;
+ background-color: #ffffff;
+}
+
+#detailed-description .class .field-odd li,
+#detailed-description .method .field-odd li,
+#detailed-description .staticmethod .field-odd li,
+#detailed-description .attribute .field-odd li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+
+}
+
+#detailed-description .class .field-even li,
+#detailed-description .method .field-even li,
+#detailed-description .staticmethod .field-even li,
+#detailed-description .attribute .field-even li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+#detailed-description .class .field-odd p,
+#detailed-description .method .field-odd p,
+#detailed-description .staticmethod .field-odd p,
+#detailed-description .attribute .field-odd p{
+ margin: 0;
+ margin-left: 20px;
+
+}
+
+#detailed-description .class .field-even p,
+#detailed-description .method .field-even p,
+#detailed-description .staticmethod .field-even p,
+#detailed-description .attribute .field-even p{
+ margin: 0;
+ margin-left: 20px;
+}
+
+#detailed-description .class .field-odd p:last-child,
+#detailed-description .method .field-odd p:last-child,
+#detailed-description .staticmethod .field-odd p:last-child,
+#detailed-description .attribute .field-odd p:last-child {
+ margin-bottom: 10px;
+
+}
+
+#detailed-description .class .field-even p:last-child,
+#detailed-description .method .field-even p:last-child,
+#detailed-description .staticmethod .field-even p:last-child,
+#detailed-description .attribute .field-even p:last-child{
+ margin-bottom: 10px;
+}
+
+.document dl.attribute,
+.document dl.class,
+.document dl.method,
+.document dl.staticmethod {
+ margin-top: 2em;
+}
+
+.document dl.attribute dd,
+.document dl.class dd,
+.document dl.method dd,
+.document dl.staticmethod dd {
+ padding-left: 1em;
+}
+
+#detailed-description .attribute td:nth-child(1) {
+ font-family: monospace;
+}
+
+/* Qt theme */
+#navbar {
+ position:fixed;
+ top:0;
+ left:0;
+ z-index:100;
+ background:#fff;
+ width:100%
+}
+#navbar .container, .fixed .container {
+ max-width:1280px;
+ margin:0 auto;
+ padding:0 3.9%; /* 0? */
+ position:relative;
+ overflow:visible
+}
+#navbar .navbar-header {
+ position:relative
+}
+#menuextras li a:hover span {
+ color: #41cd52;
+}
+/* new header */
+#mm-wrap, #mm-wrap #mm-helper,
+#mm-wrap #mm-helper li.mm-item,
+#mm-wrap #mm-helper a.mm-link {
+ -moz-transition: none;
+ -o-transition: none;
+ -webkit-transition: none;
+ transition: none;
+ -webkit-border-radius: 0 0 0 0;
+ -moz-border-radius: 0 0 0 0;
+ -ms-border-radius: 0 0 0 0;
+ -o-border-radius: 0 0 0 0;
+ border-radius: 0 0 0 0;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ -ms-box-shadow: none;
+ -o-box-shadow: none;
+ box-shadow: none;
+ background: none;
+ border: 0;
+ bottom: auto;
+ box-sizing: border-box;
+ clip: auto;
+ color: #090e21;
+ display: block;
+ float: none;
+ font-family: inherit;
+ font-size: 14px;
+ height: auto;
+ left: auto;
+ line-height: 1.7;
+ list-style-type: none;
+ margin: 0;
+ min-height: 0;
+ opacity: 1;
+ outline: none;
+ overflow: visible;
+ padding: 0;
+ position: relative;
+ right: auto;
+ text-align: left;
+ text-decoration: none;
+ text-transform: none;
+ top: auto;
+ vertical-align: baseline;
+ visibility: inherit;
+ width: auto;
+}
+#mm-wrap #mm-helper {
+ visibility:visible;
+ text-align:right;
+ padding:0 0px 0 0px
+}
+#navbar #mm-wrap #mm-helper li.mm-item {
+ border-right:solid #f3f3f4 1px;
+ padding-right:30px;
+ padding-left:30px
+}
+#navbar #mm-wrap #mm-helper li.mm-item > a:hover {
+ opacity: .5
+}
+#mm-wrap #mm-helper > li.mm-item {
+ margin:0 0 0 0;
+ display:inline-block;
+ height:auto;
+ vertical-align:middle
+}
+#navbar #mm-wrap #mm-helper li.mm-item:nth-child(3) {
+ border-right:0
+}
+#mm-wrap #mm-helper a.mm-link {
+ cursor: pointer
+}
+@media (max-width: 1279px) {
+ #navbar {
+ padding:0;
+ position:relative;
+ }
+ #navbar .container {
+ max-width:100%
+ }
+ .container {
+ padding:0 2%
+ }
+}
+#navbar .navbar-oneQt {
+ display:inline;
+ float:left;
+ width:31px;
+ color:#41cd52
+}
+#navbar .navbar-oneQt:before {
+ content:attr(data-icon);
+ position:absolute;
+ top:14px;
+ left:0;
+ color:#41cd52;
+ font-family:'Qt Icons';
+ line-height:1;
+ font-size:40px;
+ transition:all 0.3s ease-in-out;
+}
+#mm-wrap {
+ clear:both;
+ background:rgba(255, 255, 255, 0.1);
+ -webkit-border-radius:0px 0px 0px 0px;
+ -moz-border-radius:0px 0px 0px 0px;
+ -ms-border-radius:0px 0px 0px 0px;
+ -o-border-radius:0px 0px 0px 0px;
+ border-radius:0px 0px 0px 0px
+}
+#mm-wrap #mm-helper li.mm-item:last-child a {
+ background:transparent url("icon_avatar.png") 50% 50% no-repeat !important;
+ background-size:24px !important;
+ width:24px !important;
+ height:24px !important;
+}
+#navbar #mm-wrap #mm-helper li.mm-item > a {
+ opacity:1;
+ -webkit-transition:all 0.3s ease-in-out;
+ -moz-transition:all 0.3s ease-in-out;
+ -ms-transition:all 0.3s ease-in-out;
+ -o-transition:all 0.3s ease-in-out;
+ transition:all 0.3s ease-in-out;
+}
+#mm-wrap #mm-helper > li.mm-item > a.mm-link {
+ border-top:0px solid #fff;
+ border-left:0px solid #fff;
+ border-right:0px solid #fff;
+ border-bottom:0px solid #fff;
+ outline:none;
+ text-decoration:none;
+ padding:0 0 0 0;
+ line-height:70px;
+ font-weight:normal;
+ height:70px;
+ vertical-align:baseline;
+ text-align:left;
+ width:auto;
+ display:block;
+ color:#090e21;
+ text-transform:none;
+ text-decoration:none;
+ background:rgba(0, 0, 0, 0);
+ -webkit-border-radius:0px 0px 0px 0px;
+ -moz-border-radius:0px 0px 0px 0px;
+ -ms-border-radius:0px 0px 0px 0px;
+ -o-border-radius:0px 0px 0px 0px;
+ border-radius:0px 0px 0px 0px;
+ font-family:inherit;
+ font-size:14px;
+}
+/* end new header */
+@media (min-width: 1320px) {
+ .body .flowListDiv dl.flowList {
+ -webkit-column-count:3;
+ -moz-column-count:3;
+ column-count:3
+ }
+}
+@media (min-width: 1120px) {
+ #navbar.fixed {
+ -moz-box-shadow:0px 0px 8px rgba(0,0,0,0.23);
+ -webkit-box-shadow:0px 0px 8px rgba(0,0,0,0.23);
+ box-shadow:0px 0px 8px rgba(0,0,0,0.23)
+ }
+ #navbar.fixed #mm-wrap #mm-helper > li.mm-item > a.mm-link {
+ height:50px;
+ line-height:50px
+ }
+ #navbar.fixed .navbar-oneQt:before {
+ font-size:35px;
+ top:7px
+ }
+
+ .flowListDiv dl.flowList {
+ -webkit-column-count:2;
+ -moz-column-count:2;
+ column-count:2
+ }
+}
+@media (max-width: 1120px) {
+ #navbar {
+ padding:0;
+ position:relative
+ }
+ #navbar .navbar-oneQt:before {
+ left:10px
+ }
+ #navbar .container {
+ max-width:100%;
+ padding:0
+ }
+ #footerbar .container {
+ padding:0
+ }
+ body .main {
+ margin-top:0px
+ }
+ #footerbar .footer-main .footer-nav {
+ padding:3.9% 0 3.9% 3%;
+ border-bottom:1px solid #413d3b;
+ float:none;
+ display:block;
+ width:auto
+ }
+ #footerbar .footer-main .theqtcompany {
+ clear:both;
+ float:left;
+ margin:30px 0 8px 3%
+ }
+ #footerbar .footer-main .footer-social {
+ float:left;
+ padding:50px 0px 0px 3%
+ }
+ #footerbar #menu-footer-submenu {
+ clear:both;
+ float:none;
+ display:block;
+ padding:0px 0px 3.9% 3%
+ }
+ ul#menu-footer-submenu {
+ margin-left: 0
+ }
+}
+.cookies_yum {
+ background-color:#cecfd5;
+ display:none;
+ width:100%
+}
+.cookies_yum img {
+ width:25px;
+ top:6px;
+ display:inline-block;
+ position:absolute;
+ left:13px
+}
+.cookies_yum div {
+ margin:0 auto;
+ max-width:1280px;
+ min-height:30px;
+ padding:6px 0px 6px 0px;
+ position:relative
+}
+.cookies_yum p {
+ color:#09102b;
+ margin:0px;
+ font-size:0.79em;
+ display:inline-block;
+ line-height:1.2;
+ padding:0 30px 0 50px
+}
+.cookies_yum p a {
+ white-space:nowrap
+}
+.cookies_yum a:hover {
+ color:#46a2da
+}
+.cookies_yum .close {
+ width:15px;
+ height:15px;
+ background-image:url("cookiebar-x.png");
+ background-size:15px 30px;
+ background-position:top left;
+ cursor:pointer;
+ top:13px;
+ right:13px;
+ position:absolute;
+ transition:none
+}
+.cookies_yum .close:hover {
+ background-position:bottom left
+}
+#sidebar-toggle,#toc-toggle {
+ width:24px;
+ height:14px;
+ background-size:24px 28px;
+ cursor:pointer;
+ background-image:url("list_expand.png");
+ float:right
+}
+#sidebar-toggle.collapsed,
+#toc-toggle.collapsed {
+ background-position:bottom left
+}
+#sidebar-content > h2 {
+ display:none
+}
+#footerbar {
+ background:#222840;
+ color:#fff;
+ font-size: 0.9em;
+}
+#footerbar.fixed {
+ bottom:0;
+ left:0;
+ width:100%
+}
+#footerbar .footer-nav {
+ display:inline;
+ float:left
+}
+#footerbar .footer-main .footer-nav li {
+ float:left;
+ margin-right:1em
+}
+#footerbar .footer-main .footer-nav li a {
+ display:block;
+ padding:30px 0 10px 0;
+ line-height:20px;
+ height:20px;
+ color:#fff;
+ font-weight: 600;
+}
+#footerbar .footer-main .footer-nav li a:hover,#footerbar .footer-main .footer-nav li.current-menu-item a {
+ color:#eee
+}
+#footerbar .footer-main .footer-nav .sub-menu {
+ margin-left:0;
+ margin-bottom:0
+}
+#footerbar .footer-main .footer-nav .sub-menu li {
+ float:none;
+ width: 100%;
+}
+#footerbar .footer-main .footer-nav .sub-menu ul {
+ padding:1px 1em;
+ font-size:0.786em;
+ line-height:8px;
+ float:none;
+ color:#5d5b59;
+ margin-bottom:0
+}
+#footerbar .footer-main .footer-nav .sub-menu li a {
+ padding:2px 0;
+ font-size:1em;
+ float:none;
+ color:#cecfd5;
+ font-weight: 400;
+}
+#footerbar .footer-main .footer-nav .sub-menu li a:hover,#footerbar .footer-main .footer-nav .sub-menu li.current-menu-item a {
+ color:#eee
+}
+#footerbar .theqtcompany {
+ background:url("theqtcompany.png") no-repeat;
+ background-size:100%;
+ width:215px;
+ height:68px;
+ display:inline;
+ float:right;
+ margin:29px 0 28px 30px
+}
+#footerbar .footer-social {
+ display:inline;
+ float:right;
+ width:164px
+}
+#footerbar .footer-main .footer-social>div {
+ margin-left:0.1em;
+ margin-bottom:10px
+}
+#footerbar .disclaimer {
+ font-size:0.786em;
+ line-height:2.73;
+ color:#868584;
+ padding-top:20px;
+ padding-bottom:0.5%
+}
+#footerbar .disclaimer a {
+ color:#bdbebf
+}
+#footerbar .disclaimer a:hover {
+ color:#d6d6d6
+}
+#footerbar .disclaimer ul li {
+ float:left;
+ vertical-align:middle;
+ margin-left:1.18em
+}
+#footerbar .disclaimer ul li:first-child {
+ margin-left:0
+}
+#footerbar .disclaimer ul.lang-selector a {
+ color:#506a34;
+ color:rgba(128,195,66,0.3)
+}
+#footerbar .disclaimer ul.lang-selector a:hover {
+ color:#80c342;
+ color:rgba(128,195,66,0.7)
+}
+#menu-footer-menu, #menu-footer-menu ul {
+ margin-left:0;
+ margin-bottom:0
+}
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: normal;
+ font-weight: 400;
+ src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot");
+ /* IE9 Compat Modes */
+ src: local("Titillium Web"), local("TitilliumWeb-Regular"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.svg#TitilliumWeb") format("svg");
+ /* Legacy iOS */
+}
+/* titillium-web-italic - latin_latin-ext */
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: italic;
+ font-weight: 400;
+ src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot");
+ /* IE9 Compat Modes */
+ src: local("Titillium WebItalic"), local("TitilliumWeb-Italic"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.svg#TitilliumWeb") format("svg");
+ /* Legacy iOS */
+}
+/* titillium-web-600 - latin_latin-ext */
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: normal;
+ font-weight: 600;
+ src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot");
+ /* IE9 Compat Modes */
+ src: local("Titillium WebSemiBold"), local("TitilliumWeb-SemiBold"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.svg#TitilliumWeb") format("svg");
+ /* Legacy iOS */
+}
+@font-face {
+ font-family:monospace;
+ font-style:normal;
+ font-weight:400;
+ src:local("Droid Sans Mono"),local("DroidSansMono"),url(//fonts.gstatic.com/s/droidsansmono/v7/ns-m2xQYezAtqh7ai59hJUYuTAAIFFn5GTWtryCmBQ4.woff) format("woff")
+}
+@font-face {
+ font-family:'Qt Icons';
+ src:url("../style/icomoon.eot?-tgjuoj");
+ src:url("../style/icomoon.eot?#iefix-tgjuoj") format("embedded-opentype"),url("../style/icomoon.woff?-tgjuoj") format("woff"),url("../style/icomoon.ttf?-tgjuoj") format("truetype"),url("../style/icomoon.svg?-tgjuoj#icomoon") format("svg");
+ font-weight:normal;
+ font-style:normal
+}
+@font-face {
+ font-family:'social-icons';
+ src:url("../style/social-icons.eot?54625607");
+ src:url("../style/social-icons.eot?54625607#iefix") format("embedded-opentype"),
+ url("../style/social-icons.woff?54625607") format("woff");
+ font-weight:normal;
+ font-style:normal
+}
+.clearfix:before,.clearfix:after {
+ content:" ";
+ display:table
+}
+.clearfix:after {
+ clear:both
+}
+.clearfix {
+ *zoom:1
+}
+.clearfix .right {
+ float:right
+}
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
+ margin:0;
+ padding:0;
+ border:0;
+ font-size:100%;
+ line-height: 1.4;
+}
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
+ vertical-align:baseline
+}
+h1,h2,h3,h4,h5,h6 {
+ font-weight:300
+}
+.body h2,.body h3,.body h4,.body h5,.body h6 {
+ margin:1.5em 0 0.75em
+}
+.body h1 {
+ margin-bottom:0.75em;
+ font-size:2.25em;
+}
+.body h3.fn,.body h3.flags {
+ color:#26282a;
+ font-size:1.46em;
+ padding:15px 0 15px 0;
+ border-bottom:2px #eee solid;
+ word-wrap:break-word
+}
+.body .fngroup {
+ border-bottom:2px #eee solid;
+ padding-bottom:15px;
+ margin-bottom:1.5em
+}
+.body .fngroup h3.fngroupitem {
+ margin:0;
+ padding-bottom:0;
+ border:none
+}
+.body h3.fn .name,
+.body h3 span.type,
+.qmlname span.name {
+ font-weight: 400
+}
+.qmlname {
+ font-size:1.46em
+}
+.qmlproto table {
+ border:none;
+ border-bottom:2px #eee solid
+}
+.qmlproto table p {
+ max-width:100%
+}
+.qmlproto table tr {
+ background-color:#fff
+}
+.qmlname td, .qmlname th {
+ border:none;
+ text-align:left;
+ padding:5px 0 0 0
+}
+.qmlreadonly,.qmldefault {
+ padding:0 5px 0 5px;
+ font-size:0.75em;
+ background-color:#eee;
+ float:right
+}
+.qmlreadonly {
+ color:#414141
+}
+.qmldefault {
+ color:#D14141
+}
+.rightAlign {
+ padding:3px 5px 3px 10px;
+ text-align:right
+}
+.centerAlign.functionIndex {
+ text-align:center;
+ font-size:150%;
+ margin-bottom: 1em
+}
+article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section {
+ display:block
+}
+body {
+ line-height:1.25em;
+ font-family: Arial, Helvitica;
+ font-weight:400;
+ transition-duration:1s;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ font-size: 16px;
+ background-color:#f3f3f4;
+ color:#404244;
+}
+ol,ul {
+ list-style-type: square;
+ #color: #17a81a;
+}
+.body ol,.body ul {
+ margin-top:0.75em;
+ margin-left:20px
+}
+.bodywrapper ol>li {
+ list-style-type:decimal;
+ margin-left:15px
+}
+.bodywrapper ol.a >li {
+ list-style-type:lower-alpha;
+}
+.bodywrapper ol.A >li {
+ list-style-type:upper-alpha;
+}
+.bodywrapper ol.i >li {
+ list-style-type:lower-roman;
+}
+.bodywrapper ol.I >li {
+ list-style-type:upper-roman;
+}
+.body li p {
+ margin-top:1em
+}
+blockquote,q {
+ quotes:none;
+ border-left:10px solid #ddd;
+ padding-left:10px
+}
+blockquote:before,blockquote:after,q:before,q:after {
+ content:'';
+ content:none;
+ width:100%
+}
+table {
+ border-collapse:collapse;
+ border-spacing:0;
+ margin-bottom:5px;
+ width:100%
+}
+a {
+ color:#17a81a;
+ text-decoration:none;
+ transition-duration:0.3s
+}
+a:hover {
+ color:#17a81a
+}
+.main,#footerbar>div {
+ max-width:1280px;
+ width:95%;
+ margin:0 auto
+}
+.main {
+ margin-top:80px
+}
+@media (max-width: 1120px) {
+ .main,.navbar-header,#footerbar>div {
+ width: 100%;
+ margin: 0;
+ }
+ .main .main-rounded {
+ padding: 0 15px;
+ }
+}
+.main_index {
+ background-color:#fff
+}
+.sectionlist {
+ margin-bottom:2em
+}
+[class*="col-"] {
+ letter-spacing:normal
+}
+.landing,.main_index .row {
+ letter-spacing:-0.31em
+}
+.main_index .row>div {
+ letter-spacing:normal
+}
+.col-1,.body {
+ display:inline-block;
+ background-color:#fff;
+ padding: 25px 35px 20px 30px;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+}
+.col-1 h2 {
+ font-size:1.8em;
+ font-weight:300;
+ line-height:1.1;
+ margin-bottom:0.83em;
+ margin-top:1em
+}
+.icons1of3 img {
+ display:inline-block;
+ float:left;
+ margin-right:0.75em;
+ margin-top:-5px;
+ width:2.75em
+}
+div.multi-column {
+ position:relative
+}
+div.multi-column div {
+ display:-moz-inline-box;
+ display:inline-block;
+ vertical-align:top;
+ margin-top:1em;
+ margin-right:2em;
+ width:16em
+}
+.sidebar {
+ display:block;
+ position:relative;
+ position:sticky;
+ float:left;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ width:20%;
+ padding-right:20px
+}
+.sidebar li {
+ text-overflow:ellipsis;
+ overflow:hidden
+}
+.toc,.sectionlist {
+ padding:25px;
+ background-color:#fff;
+ margin-bottom:1.25em
+}
+.sidebar .sectionlist p {
+ margin-bottom:0
+}
+.sectionlist.promo {
+ padding:0;
+ background-color:#f3f3f4
+}
+.sidebar-content:empty {
+ display:none;
+ visibility:hidden
+}
+.col-2 h2,.toc h3,.sidebar-content h2,
+.sidebar-content h3,.sectionlist h2,
+.sphinxsidebar {
+ position: fixed;
+ overflow: scroll;
+ overflow-x: hidden;
+ overflow-y: hidden;
+}
+.sphinxsidebar h3 {
+ font-weight: bold;
+ margin-bottom:1em;
+}
+.toc h3 a {
+ color:#404244
+}
+.title {
+ font-size:2.25em;
+ font-weight:300;
+ letter-spacing:-1px;
+ line-height:1.15em;
+ margin-bottom:0.5em;
+ word-wrap:break-word
+}
+.navigationbar,col-1 h2 {
+ font-size:0.85em
+}
+.navigationbar h1 {
+ font-size:2.5em;
+ margin-bottom:0.85em;
+ margin-top:0.85em
+}
+.navigationbar li {
+ display:inline-block;
+ margin-right:5px;
+ position:relative;
+ padding-right:10px;
+ color:#585a5c
+}
+.navigationbar ul:last-of-type li a {
+ color:#404244
+}
+.sectionlist li, .sphinxsidebar li {
+ padding-bottom: 10px;
+ line-height: 1.75em;
+}
+.col-1 ul {
+ margin-bottom:1.56em
+}
+.bodywrapper li {
+ margin-top:0.5em;
+ line-height:1.25em
+}
+.bodywrapper li.level2 {
+ margin-left:10px;
+ margin-top:0.4em;
+ font-size:0.9375em;
+}
+.bodywrapper p,
+.bodywrapper dd {
+ line-height:1.25em;
+ margin:1em 0 1em;
+ color:#404244
+}
+.bodywrapper b {
+ font-weight:600
+}
+.body ul,.body ol {
+ /* margin-bottom:1.5em */
+}
+.bodywrapper ul ul {
+ margin-top:0.5em
+}
+.bodywrapper .naviNextPrevious {
+ margin-top:25px;
+ max-width:100%
+}
+.naviNextPrevious.headerNavi,
+p.naviNextPrevious + p {
+ display:none
+}
+.nextPage {
+ float:right
+}
+.prevPage:before {
+ content:"< "
+}
+.nextPage:after {
+ content:" >"
+}
+.navigationbar li a {
+ color:#404244
+}
+.navigationbar li:after {
+ color:#404244;
+ content:"›";
+ display:inline-block;
+ font-size:1.5em;
+ line-height:1;
+ position:absolute;
+ right:-2px;
+ top:-4px
+}
+.sub-navigation {
+ margin-top:10px
+}
+.navigationbar li:last-child:after,.sub-navigation li:after {
+ content:none
+}
+.navigationbar {
+ margin-bottom:10px;
+ line-height:1em
+}
+#buildversion {
+ margin-bottom:10px;
+ font-style:italic;
+ font-size:small;
+ float:right
+}
+.copy-notice {
+ width:75%;
+ font-size:0.75em;
+ margin:20px 35px 0 10px;
+ line-height:1.75em;
+ float:right;
+ color:#585a5c
+}
+.copy-notice.index {
+ margin-top:10px;
+ float:none
+}
+li a.active {
+ color:#585a5c
+}
+.flowList {
+ padding:25px
+}
+.flowListDiv dl {
+ -webkit-column-count:1;
+ -moz-column-count:1;
+ column-count:1
+}
+.flowList dd {
+ display:inline-block;
+ margin-left:10px;
+ width:90%;
+ line-height:1.15em;
+ overflow-x:hidden;
+ text-overflow:ellipsis
+}
+.alphaChar {
+ font-size:2em;
+ position:absolute
+}
+.flowList.odd {
+ background-color:#f9f9f9
+}
+.body ul>li,.doc-column ul>li {
+ list-style-image:url("list_arrow.png");
+ margin-left:15px;
+ color:#404244;
+ margin-top:0.65em;
+ line-height:1em
+}
+.bodywrapper table p {
+ margin:0px;
+ padding:0px
+}
+.bodywrapper table p {
+ margin:0px;
+ padding:0px;
+ min-height:1.25em
+}
+.bodywrapper .qmldoc {
+ margin-top:0.75em
+}
+.body h2 {
+ margin-top: 1.5em;
+ font-size:1.75em
+}
+.body h3 {
+ font-size:1.35em
+}
+.body h4 {
+ font-size:1.15em
+}
+.body p img {
+ margin-top:0.75em;
+ max-width:100%
+}
+.body .border img {
+ box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5)
+}
+.body .border .player {
+ box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5)
+}
+.body p.figCaption {
+ transform:translateY(-30px);
+ color:#606366;
+ font-size:95%;
+ margin-left:3px;
+ font-style:italic
+}
+.body table {
+ width:initial;
+ vertical-align:initial
+}
+table .odd {
+ background-color:#f9f9f9
+}
+table thead {
+ text-align:left;
+ padding-left:20px
+}
+table,table td,table th {
+ border:1px solid #eee
+}
+table td,table th {
+ padding:5px 20px;
+ line-height:1.3
+}
+.body .fixed table td {
+ min-width:50%;
+ width:50%
+}
+table.alignedsummary,table.propsummary {
+ width:initial
+}
+table.valuelist td.tblval {
+ font-size:0.75em
+}
+div.main_index .row {
+ border-bottom:10px solid #f3f3f4
+}
+div.main_index .row {
+ position:relative
+}
+div.main_index .row>div {
+ display:inline-block;
+ width:50%;
+ vertical-align:top;
+ padding:2em 3em;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box
+}
+div.main_index h2 {
+ font-size:2.1875em;
+ margin-bottom:1em
+}
+#search_bar {
+ width:40%;
+ float:right
+}
+div.main_index .row:after {
+ content:"";
+ position:absolute;
+ top:0;
+ right:50%;
+ height:100%;
+ width:10px;
+ background-color:#f3f3f4
+}
+div.table {
+ overflow-x:auto
+}
+.body tr > td > pre {
+ font-size:0.75em
+}
+p.qt_commercial {
+ border:3px solid #5caa15;
+ margin:0 auto;
+ padding:15px;
+ width:28%;
+ text-align:center;
+ clear:both
+}
+h1.qt_commercial {
+ padding:20px;
+ background-color:#5caa15;
+ display:inline;
+ float:right;
+ font-size:1.25em;
+ line-height:1.25em;
+ height:1.25em;
+ color:#fff
+}
+div.qt_commercial {
+ border-top:5px solid #5caa15;
+ margin-bottom:50px
+}
+div.pre {
+ position:relative;
+ height:auto
+}
+pre, .LegaleseLeft {
+ background-color:#222840;
+ color:#fff;
+ display:block;
+ font-family:monospace;
+ line-height:1.5;
+ overflow-x:auto;
+ margin-bottom:25px;
+ padding:25px;
+ margin-top:0.75em;
+ font-size: .8em;
+}
+.bodywrapper .LegaleseLeft p {
+ color:#fff;
+ white-space: pre-wrap
+}
+pre .str,code .str {
+ color:#aaaaaa
+}
+pre .kwd,code .kwd {
+ color:#ffff55
+}
+pre .com,code .com {
+ color:#55ffff
+}
+pre .typ,code .typ {
+ color:#4f9d08
+}
+pre a .typ,code a .typ {
+ color:#21be2b
+}
+pre .lit,code .lit {
+ color:#ff55ff
+}
+pre .pun,code .pun {
+ color:#fff
+}
+pre .pln,code .pln {
+ color:#fff
+}
+@media print {
+ pre {
+ background-color:#eee !important
+ }
+ pre .str,code .str {
+ color:#060
+ }
+ pre .kwd,code .kwd{
+ color:#006;
+ font-weight:bold
+ }
+ pre .com,code .com {
+ color:#600
+ }
+ pre .typ,code .typ {
+ color:#404;
+ font-weight:bold
+ }
+ pre .lit,code .lit {
+ color:#044
+ }
+ pre .pun,code .pun {
+ color:#440
+ }
+ pre .pln,code .pln {
+ color:#000
+ }
+}
+pre.wrap {
+ white-space:pre-wrap
+}
+pre span.wrap {
+ display:none;
+ background:url("wrap.png") no-repeat;
+ right:0;
+ top:2px;
+ position:absolute;
+ width:20px;
+ height:14px;
+ margin:4px;
+ opacity:0.65
+}
+
+span.pre {
+ color: #09102d;
+}
+
+span.wrap:hover {
+ opacity:1
+}
+span.wrap:active {
+ opacity:0.75
+}
+.copy_text {
+ background-color:#46a2da;
+ color:#fff;
+ border:2px solid #46a2da;
+ padding:10px 16px;
+ margin-left:-10px;
+ margin-top:-50px;
+ position:absolute;
+ opacity:0;
+ cursor:pointer;
+ float:right
+}
+.copy_text:hover {
+ background-color:#fff;
+ color:#46a2da
+}
+code,.codelike {
+ font-family:monospace;
+}
+#detailed-description .function dt > code,
+#detailed-description .function dt > em {
+ font-weight:bold
+}
+h3.fn code {
+ font-size:0.75em;
+ float:right;
+ background-color:#eee;
+ padding:3px;
+ margin: 3px 0 0 20px
+}
+pre:hover>.copy_text {
+ display:inline-block;
+ opacity:1;
+ transition:0.5s ease
+}
+#main_title_bar {
+ background:url("pyside-logo.png") no-repeat;
+ background-size:100%;
+ width:366px;
+ height:86px;
+ margin:15px 0 15px 0
+}
+#main_title_bar h1 {
+ visibility:hidden
+}
+#main_title_bar .search_bar {
+ letter-spacing:normal;
+ width:50%;
+ display:inline-block;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ vertical-align:middle
+}
+#main_title_bar h1 {
+ letter-spacing:normal;
+ display:inline-block;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ vertical-align:middle
+}
+#main_title_bar .search_bar * {
+ letter-spacing:normal;
+ padding:0;
+ margin:0;
+ border:none
+}
+#sidebar-toggle,#toc-toggle {
+ display:none
+}
+@media (max-width: 980px) {
+ body {
+ font-size:calc-em(14px)
+ }
+ #main_title_bar>h1,#main_title_bar .search_bar {
+ width:100%
+ }
+ #main_title_bar .search_bar {
+ margin-bottom:15px
+ }
+ .main {
+ margin-top:0px
+ }
+ .main_index .row {
+ border:none !important
+ }
+ .title {
+ font-size:1.5em;
+ font-weight:400;
+ word-wrap:break-word
+ }
+ .col-1,.body,.naviNextPrevious,.sidebar {
+ padding:10px
+ }
+ .sidebar {
+ position:relative;
+ padding-top:0
+ }
+ .search .sidebar {
+ display:none;
+ visibility:hidden
+ }
+ .col-2 h2,.toc h3,.sidebar-content h2,.sidebar-content h3,.sectionlist h2 {
+ text-align:center;
+ margin-bottom:5px
+ }
+ div.main_index .row:after {
+ content:none
+ }
+ div.main_index .row>div {
+ display:block !important;
+ width:100%;
+ padding:15px;
+ margin:0
+ }
+ .body,.sidebar,.col-1 {
+ width:100%
+ }
+ .sidebar-content,.col-2,.toc {
+ background-color:#fff;
+ margin-bottom:1em;
+ padding:20px
+ }
+ #sidebar-toggle,#toc-toggle {
+ display:block
+ }
+ #sidebar-toggle.collapsed + h2 {
+ display:block
+ }
+ .bodywrapper p {
+ margin-bottom:1em;
+ max-width:100%
+ }
+ table td,table th {
+ padding:5px 5px
+ }
+ .sectionlist {
+ padding:0
+ }
+ .sidebar > .sectionlist {
+ padding:20px
+ }
+ .sectionlist.promo {
+ max-width:46%;
+ margin:0 auto 1em auto;
+ float:left;
+ padding:0 2%
+ }
+ .sidebar .sidebar-content {
+ clear:both
+ }
+ .copy-notice {
+ float:none;
+ width:initial
+ }
+}
+[id]:target > *:first-child,
+dt[id]:target {
+ -webkit-animation:highlighter 3s;
+ animation:highlighter 3s
+}
+@-webkit-keyframes highlighter {
+ 25% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+ 75% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+}
+@keyframes highlighter {
+ 25% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+ 75% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+}
+@-webkit-keyframes copypaste {
+ 25% {
+ opacity:1
+ }
+ 100% {
+ border-radius:10px;
+ margin-top:-50px;
+ opacity:1
+ }
+}
+@keyframes copypaste {
+ 25% {
+ opacity:1
+ }
+ 100% {
+ border-radius:10px;
+ margin-top:-50px;
+ opacity:1
+ }
+}
+#footer {
+ clear:both
+}
+.footer-social i {
+ font-family: "social-icons";
+ font-style: normal;
+ font-size:150%;
+ margin: .55em;
+ color: #cecfd5
+}
+.footer-social i:hover {
+ color: #eee
+}
+.footer-social .icon-twitter:before {
+ content: '\f099'
+}
+.footer-social .icon-facebook:before {
+ content: '\f09a'
+}
+.footer-social .icon-youtube:before {
+ content: '\f16a'
+}
+.menuextraslanguages {
+ display:none;
+ visibility:hidden
+}
+
+input:focus {
+ border-color: #46a2da;
+ box-shadow: 0 0 5px #46a2da;
+ color: #000;
+}
+
+.animation {
+ width: 100%;
+ border-style: none;
+ border-width: 0
+}
+
+.player {
+ width: auto;
+ position: relative;
+ display: table;
+ margin-bottom:1.5em;
+}
+
+.playcontrol {
+ display: none;
+ background: url("play_icon.svg") no-repeat center,
+ linear-gradient(
+ rgba(0,0,0,0.15), rgba(0,0,0,0.15)
+ );
+ background-size: 25%;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ left: 0%;
+ right: 0%;
+ top: 0%;
+ bottom: 0%;
+ margin: auto
+}
+
+/* expand/collapse code sections */
+pre input {
+ display:none;
+ visibility:hidden
+}
+pre label {
+ display:block;
+ margin:-3px 3px 0 -16px;
+ text-align:center;
+ color:#21be2b;
+ float:left;
+}
+pre label:hover {
+ color:#fff
+}
+pre label::before {
+ font-weight:600;
+ font-size:16px;
+ content:"+";
+ display:inline-block;
+ width:16px;
+ height:16px
+}
+#ec_expand {
+ height:16px;
+ overflow:hidden;
+ transition:height 0.35s;
+}
+#ec_expand::before {
+ content:"...*/";
+ color:#aaa;
+ background-color:#3a4055;
+ z-index:99 !important;
+ right:25px;
+ position:absolute
+}
+#ec_toggle:checked ~ #ec_expand {
+ height:initial
+}
+#ec_toggle:checked ~ #ec_expand::before {
+ content:""
+}
+#ec_toggle:checked ~ label::before {
+ content:"-"
+}
+
+/* permalinks */
+h1:hover > .headerlink,
+h2:hover > .plink,
+h2:hover > .headerlink,
+h3:hover > .plink,
+h3:hover > .headerlink,
+h4:hover > .plink,
+h4:hover > .headerlink,
+h5:hover > .plink,
+h5:hover > .headerlink {
+ opacity:1
+}
+a.plink, a.headerlink {
+ opacity: 0;
+ padding-left: 8px;
+ font-size: 0.8em;
+ font-weight: 600;
+ transition: opacity 180ms ease-in-out
+}
+a.plink::before {
+ content:'\00B6'
+}
+
+table.special {
+ border: 3px;
+ padding: 0px;
+ border-collapse: separate;
+ border-spacing: 20px;
+ line-height: 1.5em;
+}
+
+.special p {
+ text-align: center;
+ color: #3a4055;
+}
+
+.special a {
+ display: block;
+ border-bottom: 0;
+ text-decoration: none;
+}
+
+.special a:hover {
+ border-bottom: 0;
+ text-decoration: none;
+}
+
+.special strong {
+ color: #17a81a;
+ font-size: 110%;
+ font-weight: normal;
+}
+
+table.special th,
+table.special td {
+ border: 1px solid #888;
+ padding-top: 14px;
+ padding-bottom: 14px;
+ padding-left: 6px;
+ padding-right: 5px;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -khtml-border-radius: 5px;
+}
+
+.special td:hover {
+ padding-top: 2px;
+ padding-bottom: 2px;
+ border-bottom: 4px solid #41cd52;
+}
diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png
new file mode 100644
index 000000000..3a2f2bd17
--- /dev/null
+++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png
Binary files differ
diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png
new file mode 100644
index 000000000..4036733a7
--- /dev/null
+++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png
Binary files differ
diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/theme.conf b/sources/pyside2/doc/_themes/pysidedocs_qthelp/theme.conf
new file mode 100644
index 000000000..4384b459c
--- /dev/null
+++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/theme.conf
@@ -0,0 +1,7 @@
+[theme]
+inherit = default
+stylesheet = pyside.css
+pygments_style = none
+
+[options]
+nosidebar = true
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.py
index 726ceb818..1cbd56241 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.py
@@ -65,10 +65,9 @@ def __init__(self, parent):
previousItems = QListWidget(centralWidget)
//! [0]
- connect(clipboard, SIGNAL("dataChanged()"), self, SLOT("updateClipboard()"))
+ clipboard.dataChanged.connect(self.updateClipboard)
//! [0]
- connect(mimeTypeCombo, SIGNAL("activated(const QString &)"),
- self, SLOT("updateData(const QString &))")
+ mimeTypeCombo.activated[str].connect(self.updateData)
currentLayout = QVBoxLayout(currentItem)
currentLayout.addWidget(mimeTypeLabel)
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qobject.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qobject.py
index 1de4dbbe8..7e50f6701 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qobject.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qobject.py
@@ -1,52 +1,52 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+############################################################################
+##
+## Copyright (C) 2016 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the documentation of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## BSD License Usage
+## Alternatively, you may use this file under the terms of the BSD license
+## as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+############################################################################
//! [0]
lineEdit = qt_find_obj_child(myWidget, "QLineEdit", "my line edit")
@@ -96,8 +96,8 @@ layout.inherits("QLayoutItem") # returns false
//! [5]
-print "MyClass::setPrecision(): (%s) invalid precision %f" % \
- (qPrintable(objectName()), newPrecision)
+print("MyClass.setPrecision(): ({}) invalid precision {}".format(qPrintable(objectName()),
+ newPrecision))
//! [5]
@@ -112,7 +112,7 @@ class MainWindow(QMainWindow):
if obj == textEdit:
if event.type() == QEvent.KeyPress:
keyEvent = event
- print "Ate key press", keyEvent.key()
+ print("Ate key press", keyEvent.key())
return true
else:
return false
@@ -138,14 +138,14 @@ class MyObject(QObject):
def timerEvent(self, event):
- print "Timer ID:", event.timerId()
+ print("Timer ID:", event.timerId())
//! [8]
//! [9]
-list = window().queryList("QAbstractButton")
-for obj in list:
+a_list = window().queryList("QAbstractButton")
+for obj in a_list:
obj.setEnabled(false)
//! [9]
@@ -156,7 +156,7 @@ button = parentWidget.findChild(QPushButton, "button1")
//! [11]
-list = parentWidget.findChild(QListWidget)
+a_list = parentWidget.findChild(QListWidget)
//! [11]
@@ -179,7 +179,7 @@ monitoredObj.installEventFilter(filterObj)
class KeyPressEater(QObject):
def eventFilter(self, obj, event):
if event.type() == QEvent.KeyPress:
- print "Ate key press", event.key()
+ print("Ate key press", event.key())
return True
else:
# standard event processing
@@ -234,15 +234,16 @@ if receivers(SIGNAL('valueChanged()')) > 0:
//! [22]
label = QLabel()
scrollBar = QScrollBar()
-QObject.connect(scrollBar, SIGNAL('valueChanged()'),
- label, SLOT('setNum()'))
+QObject.connect(scrollBar, SIGNAL('valueChanged(int)'),
+ label, SLOT('setNum(int)'));
+# or scrollBar.valueChanged.connect(label.setNum)
//! [22]
//! [23]
// WRONG
-QObject.connect(scrollBar, SIGNAL('valueChanged()'),
- label, SLOT('setNum()'));
+QObject.connect(scrollBar, SIGNAL('valueChanged(int value)'),
+ label, SLOT('setNum(int value)'));
//! [23]
@@ -250,8 +251,7 @@ QObject.connect(scrollBar, SIGNAL('valueChanged()'),
class MyWidget(QWidget):
def __init__(self):
myButton = QPushButton(self)
- connect(myButton, SIGNAL('clicked()'),
- self, SIGNAL('buttonClicked()'))
+ myButton.clicked.connect(self.buttonClicked)
//! [24]
@@ -323,7 +323,7 @@ Q_PROPERTY(type name
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
- [USER bool])
+ [USER bool])
//! [36]
@@ -333,34 +333,40 @@ Q_PROPERTY(QString title READ title WRITE setTitle USER true)
//! [38]
-#this not apply for Python
+#this does not apply to Python
class MyClass(QObject):
- Q_OBJECT
- Q_ENUMS(Priority)
+ #Q_OBJECT, not needed
+ #Q_ENUMS(Priority), not supported
-public:
- MyClass(QObject *parent = 0);
- ~MyClass();
+ def __init__(self, parent=None):
+ pass
- enum Priority { High, Low, VeryHigh, VeryLow };
- void setPriority(Priority priority);
- Priority priority() const;
+ class Priority(Enum):
+ High = 1
+ Low = 2
+ VeryHigh = 3
+ VeryLow 4
+
+ def setPriority(self, priority):
+ pass
+
+ priority = Property(...)
};
//! [38]
//! [39]
-#this not apply for Python
+#this does not apply to Python
Q_FLAGS(Options Alignment)
//! [39]
//! [40]
-//: This name refers to a host name.
+# This name refers to a host name.
hostNameLabel.setText(self.tr("Name:"))
-#: This text refers to a C++ code example.
+# This text refers to a C++ code example.
example = self.tr("Example")
//! [40]
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.py
new file mode 100644
index 000000000..6cf5dd21c
--- /dev/null
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.py
@@ -0,0 +1,74 @@
+############################################################################
+##
+## Copyright (C) 2016 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the documentation of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## BSD License Usage
+## Alternatively, you may use this file under the terms of the BSD license
+## as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+############################################################################
+
+//! [0]
+ formWindow = QDesignerFormWindowInterface()
+ formWindow = QDesignerFormWindowInterface.findFormWindow(myWidget)
+//! [0]
+
+
+//! [1]
+ forms = [] # QList<QDesignerFormWindowInterface>
+ formWindow = QDesignerFormWindowInterface()
+
+ manager = formEditor.formWindowManager()
+
+ for i in range(manager.formWindowCount()):
+ formWindow = manager.formWindow(i)
+ forms.append(formWindow)
+//! [1]
+
+
+//! [2]
+ if formWindow.isManaged(myWidget):
+ formWindow.manageWidget(myWidget.childWidget)
+//! [2]
+
+
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.cpp
deleted file mode 100644
index 255231512..000000000
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//! [0]
- QDesignerPropertyEditorInterface *propertyEditor = 0;
- propertyEditor = formEditor->propertyEditor();
-
- connect(propertyEditor, SIGNAL(propertyChanged(QString, QVariant)),
- this, SLOT(checkProperty(QString, QVariant)));
-//! [0]
-
-
-//! [1]
- void checkProperty(QString property, QVariant value) {
- QDesignerPropertyEditorInterface *propertyEditor = 0;
- propertyEditor = formEditor->propertyEditor();
-
- QObject *object = propertyeditor->object();
- MyCustomWidget *widget = qobject_cast<MyCustomWidget>(object);
-
- if (widget && property == aProperty && value != expectedValue)
- {...}
- }
-//! [1]
-
-
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.py
new file mode 100644
index 000000000..1e2ac506f
--- /dev/null
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.py
@@ -0,0 +1,71 @@
+############################################################################
+##
+## Copyright (C) 2016 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the documentation of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## BSD License Usage
+## Alternatively, you may use this file under the terms of the BSD license
+## as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+############################################################################
+
+//! [0]
+ propertyEdit = QDesignerPropertyEditorInterface()
+ propertyEditor = formEditor.propertyEditor()
+
+ propertyEditor.propertyChanged.connect(self.checkProperty)
+//! [0]
+
+
+//! [1]
+ def checkProperty(self, property, value):
+ propertyEditor = QDesignerPropertyEditorInterface()
+ propertyEditor = formEditor.propertyEditor()
+
+ object = propertyeditor.object()
+ widget = MyCustomWidget(object)
+
+ if (widget and property == aProperty and value != expectedValue):
+ # ...
+//! [1]
+
+
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.py
index 047434f6d..7bdcb0c91 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.py
@@ -50,12 +50,10 @@
//! [0]
-def find(self)
-
- if !self.findDialog:
+def find(self):
+ if not self.findDialog:
self.findDialog = FindDialog(self)
- connect(findDialog, SIGNAL("findNext()"), self, SLOT("findNext()"))
-
+ self.findDialog.findNext.connect(self.findNext)
self.findDialog.show()
self.findDialog.raise()
@@ -72,58 +70,54 @@ def countWords(self):
//! [1]
//! [2]
- mb = QMessageBox("Application Name",
- "Hardware failure.\n\nDisk error detected\nDo you want to stop?",
- QMessageBox.Question,
- QMessageBox.Yes | QMessageBox.Default,
- QMessageBox.No | QMessageBox.Escape,
- QMessageBox.NoButton)
- if mb.exec() == QMessageBox.No:
- # try again
+ mb = QMessageBox("Application Name",
+ "Hardware failure.\n\nDisk error detected\nDo you want to stop?",
+ QMessageBox.Question,
+ QMessageBox.Yes | QMessageBox.Default,
+ QMessageBox.No | QMessageBox.Escape,
+ QMessageBox.NoButton)
+ if mb.exec() == QMessageBox.No:
+ # try again
//! [2]
//! [3]
progress = QProgressDialog("Copying files...", "Abort Copy", 0, numFiles, self)
progress.setWindowModality(Qt.WindowModal)
- for i in rang(numFiles):
+ for i in range(numFiles):
progress.setValue(i)
if progress.wasCanceled():
break
#... copy one file
-
+
progress.setValue(numFiles)
//! [3]
//! [4]
# Operation constructor
-def __init__(self, parent):
+def __init__(self, parent=None):
QObject.__init__(self, parent)
pd = QProgressDialog("Operation in progress.", "Cancel", 0, 100)
- connect(pd, SIGNAL("canceled()"), self, SLOT("cancel()"))
+ pd.canceled.connect(self.cancel)
t = QTimer(self)
- connect(t, SIGNAL("timeout()"), self, SLOT("perform()"))
+ t.timeout.connect(self.perform)
t.start(0)
//! [4] //! [5]
def perform(self):
-
pd.setValue(steps)
#... perform one percent of the operation
- steps++
+ steps += 1
if steps > pd.maximum():
t.stop()
//! [5] //! [6]
def cancel(self):
-
t.stop()
#... cleanup
//! [6]
-
-
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.h
deleted file mode 100644
index 8607b6953..000000000
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef WINDOW_H
-#define WINDOW_H
-
-#include <QString>
-#include <QStringList>
-#include <QWidget>
-
-class QComboBox;
-class QFrame;
-class QTextBrowser;
-
-class Window : public QWidget
-{
- Q_OBJECT
-
-public:
- Window(QWidget *parent = 0);
-
-protected:
- void dragEnterEvent(QDragEnterEvent *event);
- void dropEvent(QDropEvent *event);
-
-private:
- QComboBox *mimeTypeCombo;
- QFrame *dropFrame;
- QTextBrowser *textBrowser;
- QString oldText;
- QStringList oldMimeTypes;
-};
-
-#endif
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.py
new file mode 100644
index 000000000..66a6a7ba2
--- /dev/null
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.py
@@ -0,0 +1,65 @@
+############################################################################
+##
+## Copyright (C) 2016 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the examples of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## BSD License Usage
+## Alternatively, you may use this file under the terms of the BSD license
+## as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+############################################################################
+
+from PySide2.QtWidgets import QWidget, QComboBox, QFrame, QTextBrowser
+
+class Window(QWidget):
+
+ def __init__(self, parent=None):
+ self.mimeTypeCombo = QComboBox()
+ self.dropFrame = QFrame()
+ self.textBrowser = QTextBrowser()
+ self.oldText = ""
+ self.oldMimeTypes = []
+
+ def dragEnterEvent(self, event):
+ pass
+ def dropEvent(self, event):
+ pass
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedlayout/main.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedlayout/main.py
new file mode 100644
index 000000000..184128406
--- /dev/null
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedlayout/main.py
@@ -0,0 +1,87 @@
+############################################################################
+##
+## Copyright (C) 2016 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the documentation of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## BSD License Usage
+## Alternatively, you may use this file under the terms of the BSD license
+## as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+############################################################################
+
+from PySide2.QtWidgets import QApplication, QWidget, QStackedLayout, QComboBox
+
+class Widget(QWidget)
+ def __init__(self, parent=None):
+ QWidget.__init__(self, parent)
+//! [0]
+ self.firstPageWidget = QWidget()
+ self.secondPageWidget = QWidget()
+ self.thirdPageWidget = QWidget()
+
+ self.stackedLayout = QStackedLayout()
+ self.stackedLayout.addWidget(self.firstPageWidget)
+ self.stackedLayout.addWidget(self.secondPageWidget)
+ self.stackedLayout.addWidget(self.thirdPageWidget)
+
+//! [0] //! [1]
+ self.pageComboBox = QComboBox()
+ self.pageComboBox.addItem(tr("Page 1"))
+ self.pageComboBox.addItem(tr("Page 2"))
+ self.pageComboBox.addItem(tr("Page 3"))
+ self.pageComboBox.activated.connect(self.stackedLayout.setCurrentIndex)
+//! [1]
+
+//! [2]
+ self.mainLayout = QVBoxLayout()
+//! [2]
+ self.mainLayout.addWidget(self.pageComboBox)
+//! [3]
+ self.mainLayout.addLayout(self.stackedLayout)
+ self.setLayout(self.mainLayout)
+//! [3]
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ widget = Widget()
+ widget.show()
+ sys.exit(app.exec_())
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.py
index 98a08be98..6f2c49d8e 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.py
@@ -64,8 +64,7 @@
pageComboBox.addItem(tr("Page 1"))
pageComboBox.addItem(tr("Page 2"))
pageComboBox.addItem(tr("Page 3"))
- connect(pageComboBox, SIGNAL("activated(int)"),
- stackedWidget, SLOT("setCurrentIndex(int)"))
+ pageComboBox.activated[int].connect(stackedWidget.setCurrentIndex)
//! [1] //! [2]
layout = QVBoxLayout()
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlquery/bindingExample.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlquery/bindingExample.py
index 734f603a9..16c12b7bc 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlquery/bindingExample.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlquery/bindingExample.py
@@ -49,11 +49,11 @@
****************************************************************************/
//! [0]
- QBuffer device;
- device.setData(myQString.toUtf8());
- device.open(QIODevice::ReadOnly);
+ device = QBuffer()
+ device.setData(myQString.toUtf8())
+ device.open(QIODevice.ReadOnly)
- QXmlQuery query;
- query.setQuery("doc($inputDocument)/query[theDocument]");
- query.bindVariable("inputDocument", &device);
+ query = QXmlQuery()
+ query.setQuery("doc($inputDocument)/query[theDocument]")
+ query.bindVariable("inputDocument", device)
//! [0]
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.py
index 29ac9c87d..7c28cf5e6 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.py
@@ -77,7 +77,7 @@ def QSqlField_snippets():
//! [3]
field = QSqlField("age", QVariant.Int)
- field.setValue(QString("123")) # casts QString to int
+ field.setValue(str(123)) # casts str to int
//! [3]
//! [4]
@@ -247,7 +247,7 @@ def QSqlTableModel_snippets():
//! [25]
model = QSqlTableModel()
model.setTable("employee")
- QString name = model.record(4).value("name")
+ name = model.record(4).value("name")
//! [25]
def sql_intro_snippets():
@@ -351,7 +351,7 @@ def sql_intro_snippets():
employeeId = query.value(0)
query.exec_("INSERT INTO project (id, name, ownerid) "
"VALUES (201, 'Manhattan Project', "
- + QString.number(employeeId) + ')')
+ + str(employeeId) + ')')
QSqlDatabase.database().commit()
//! [39]
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/widgets-tutorial/template.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/widgets-tutorial/template.py
new file mode 100644
index 000000000..d38829fc7
--- /dev/null
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/widgets-tutorial/template.py
@@ -0,0 +1,66 @@
+############################################################################
+##
+## Copyright (C) 2016 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the documentation of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## BSD License Usage
+## Alternatively, you may use this file under the terms of the BSD license
+## as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+############################################################################
+
+//! [main.cpp body]
+import sys
+from PySide2.QtWidgets import QApplication
+
+# Include header files for application components.
+# ...
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ # Set up and show widgets.
+ # ...
+
+ sys.exit(app.exec_())
+}
+//! [main.cpp body]
diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.cpp b/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.py
index 897410ed7..08032cf2a 100644
--- a/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.cpp
+++ b/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.py
@@ -142,8 +142,7 @@ class ClassInfoPage(QWizardPage):
defaultCtorRadioButton.setChecked(True)
- self.connect(defaultCtorRadioButton, SIGNAL("toggled(bool)"),
- copyCtorCheckBox, SLOT("setEnabled(bool)"))
+ defaultCtorRadioButton.toggled[bool].connect(copyCtorCheckBox.setEnabled)
//! [11] //! [12]
registerField("className*", classNameLineEdit)
@@ -201,14 +200,10 @@ class CodeStylePage(QWizardPage):
baseIncludeLineEdit = QLineEdit()
baseIncludeLabel.setBuddy(baseIncludeLineEdit)
- self.connect(protectCheckBox, SIGNAL("toggled(bool)"),
- macroNameLabel, SLOT("setEnabled(bool)"))
- self.connect(protectCheckBox, SIGNAL("toggled(bool)"),
- macroNameLineEdit, SLOT("setEnabled(bool)"))
- self.connect(includeBaseCheckBox, SIGNAL("toggled(bool)"),
- baseIncludeLabel, SLOT("setEnabled(bool)"))
- self.connect(includeBaseCheckBox, SIGNAL(toggled(bool)),
- baseIncludeLineEdit, SLOT("setEnabled(bool)"))
+ protectCheckBox.toggled[bool].connect(macroNameLabel.setEnabled)
+ protectCheckBox.toggled[bool].connect(macroNameLineEdit.setEnabled)
+ includeBaseCheckBox.toggled[bool].connect(baseIncludeLabel.setEnabled)
+ includeBaseCheckBox.toggled[bool].connect(baseIncludeLineEdit.setEnabled)
self.registerField("comment", commentCheckBox)
self.registerField("protect", protectCheckBox)
diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.cpp b/sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.py
index a8496f4c8..1872e631b 100644
--- a/sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.cpp
+++ b/sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.py
@@ -85,7 +85,7 @@ def __init__(self, parent):
//! [2]
//! [3]
- connect(moreButton, SIGNAL("toggled(bool)"), extension, SLOT("setVisible(bool)"))
+ moreButton.toggled[bool].connect(extension.setVisible)
extensionLayout = QVBoxLayout()
extensionLayout.setMargin(0)
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.h
index f9d97e6ce..bdb7bcf22 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.cpp
+++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.h
@@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of Qt for Python.
+** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
@@ -48,28 +48,65 @@
**
****************************************************************************/
+from PySide2.QtWidgets import (QAction, QApplication, QMainWindow, QMenu,
+ QPlainTextEdit, QSessionManager)
+
+
//! [0]
- QDesignerFormWindowInterface *formWindow;
- formWindow = QDesignerFormWindowInterface::findFormWindow(myWidget);
-//! [0]
+class MainWindow(QMainWindow):
+ def __init__(self, parent=None):
+ self.textEdit = QPlainTextEdit()
+ self.curFile = ""
+ # ...
+
+ def loadFile(self, fileName):
+ pass
+
+ def closeEvent(self, event):
+ pass
+
+ def newFile(self):
+ pass
+ def open(self):
+ pass
-//! [1]
- QList<QDesignerFormWindowInterface *> forms;
- QDesignerFormWindowInterface *formWindow;
+ def save(self):
+ pass
- QDesignerFormWindowManagerInterface *manager = formEditor->formWindowManager();
+ def saveAs(self):
+ pass
- for (int i = 0; i < manager->formWindowCount(); i++) {
- formWindow = manager->formWindow(i);
- forms.append(formWindow);
- }
-//! [1]
+ def about(self):
+ pass
+ def documentWasModified(self):
+ pass
+ # Enable this only if QT_NO_SESSIONMANAGER is not defined
+ # def commitData(self):
+ # pass
-//! [2]
- if (formWindow->isManaged(myWidget))
- formWindow->manageWidget(myWidget->childWidget);
-//! [2]
+ def createActions(self):
+ pass
+ def createStatusBar(self):
+ pass
+ def readSettings(self):
+ pass
+
+ def writeSettings(self):
+ pass
+
+ def maybeSave(self):
+ pass
+
+ def saveFile(self, fileName):
+ pass
+
+ def setCurrentFile(self, fileName):
+ pass
+
+ def strippedName(self, fullFileName):
+ pass
+//! [0]
diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.py
index b0331aa79..f976bb8e3 100644
--- a/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.cpp
+++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.py
@@ -49,28 +49,30 @@
############################################################################
//! [0]
-from PySide2.QtGui import *
+from PySide2.QtCore import Qt, QFile, QFileInfo, QSettings, QTextStream
+from PySide2.QtGui import QIcon
+from PySide2.Widgets import (QAction, QApplication, QFileDialog, QMainWindow,
+ QPlainTextEdit, QFileDialog, QMessageBox, )
//! [0]
//! [1]
-def __init__(self):
+def __init__(self, parent=None):
QMainWindow.__init__(self)
//! [1] //! [2]
- textEdit = QPlainTextEdit()
- setCentralWidget(textEdit)
+ self.textEdit = QPlainTextEdit()
+ self.setCentralWidget(textEdit)
- createActions()
- createMenus()
- createToolBars()
- createStatusBar()
+ self.createActions()
+ self.createMenus()
+ self.createToolBars()
+ self.createStatusBar()
- readSettings()
+ self.readSettings()
- connect(textEdit.document(), SIGNAL("contentsChanged()"),
- self, SLOT("documentWasModified()"))
+ self.textEdit.document().contentsChanged.connect(self.documentWasModified)
- setCurrentFile("")
- setUnifiedTitleAndToolBarOnMac(True)
+ self.setCurrentFile("")
+ self.setUnifiedTitleAndToolBarOnMac(True)
//! [2]
@@ -97,7 +99,7 @@ def open(self):
//! [7] //! [8]
if maybeSave():
fileName = QFileDialog.getOpenFileName(self)
- if !fileName.isEmpty():
+ if not fileName.isEmpty():
loadFile(fileName)
//! [8]
@@ -142,70 +144,68 @@ def MainWindow.createActions(self):
Act = QAction(QIcon(":/images/new.png"), tr("&New"), self)
Act.setShortcuts(QKeySequence.New)
Act.setStatusTip(tr("Create a new file"))
- connect(Act, SIGNAL("triggered()"), self, SLOT("newFile()"))
+ Act.triggered.connect(newFile)
//! [19]
- openAct = QAction(QIcon(":/images/open.png"), tr("&Open..."), self)
+ openAct = QAction(QIcon(":/images/open.png"), tr("&Open..."), self)
openAct.setShortcuts(QKeySequence.Open)
openAct.setStatusTip(tr("Open an existing file"))
- connect(openAct, SIGNAL("triggered()"), self, SLOT("open()"))
+ openAct.triggered.connect(open)
//! [18] //! [19]
- saveAct = QAction(QIcon(":/images/save.png"), tr("&Save"), self)
+ saveAct = QAction(QIcon(":/images/save.png"), tr("&Save"), self)
saveAct.setShortcuts(QKeySequence.Save)
saveAct.setStatusTip(tr("Save the document to disk"))
- connect(saveAct, SIGNAL("triggered()"), self, SLOT("save()"))
+ saveAct.triggered.connect(save)
- saveAsAct = QAction(tr("Save &As..."), self)
+ saveAsAct = QAction(tr("Save &As..."), self)
saveAsAct.setShortcuts(QKeySequence.SaveAs)
saveAsAct.setStatusTip(tr("Save the document under a name"))
- connect(saveAsAct, SIGNAL("triggered()"), self, SLOT("saveAs()"))
+ saveAsAct.triggered.connect(saveAs)
//! [20]
- exitAct = QAction(tr("E&xit"), self)
+ exitAct = QAction(tr("E&xit"), self)
exitAct.setShortcut(tr("Ctrl+Q"))
//! [20]
exitAct.setStatusTip(tr("Exit the application"))
- connect(exitAct, SIGNAL("triggered()"), self, SLOT("close()"))
+ exitAct.triggered.connect(close)
//! [21]
- cutAct = QAction(QIcon(":/images/cut.png"), tr("Cu&t"), self)
+ cutAct = QAction(QIcon(":/images/cut.png"), tr("Cu&t"), self)
//! [21]
cutAct.setShortcuts(QKeySequence.Cut)
cutAct.setStatusTip(tr("Cut the current selection's contents to the "
"clipboard"))
- connect(cutAct, SIGNAL("triggered()"), textEdit, SLOT("cut()"))
+ cutAct.triggered.connect(cut)
- copyAct = QAction(QIcon(":/images/copy.png"), tr("&Copy"), self)
+ copyAct = QAction(QIcon(":/images/copy.png"), tr("&Copy"), self)
copyAct.setShortcuts(QKeySequence.Copy)
copyAct.setStatusTip(tr("Copy the current selection's contents to the "
"clipboard"))
- connect(copyAct, SIGNAL("triggered()"), textEdit, SLOT("copy()"))
+ copyAct.triggered.connect(copy)
- pasteAct = QAction(QIcon(":/images/paste.png"), tr("&Paste"), self)
+ pasteAct = QAction(QIcon(":/images/paste.png"), tr("&Paste"), self)
pasteAct.setShortcuts(QKeySequence.Paste)
pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current "
"selection"))
- connect(pasteAct, SIGNAL("triggered()"), textEdit, SLOT("paste()"))
+ pasteAct.triggered.connect(textEdit.paste)
- aboutAct = QAction(tr("&About"), self)
+ aboutAct = QAction(tr("&About"), self)
aboutAct.setStatusTip(tr("Show the application's About box"))
- connect(aboutAct, SIGNAL("triggered()"), self, SLOT("about()"))
+ aboutAct.triggered.connect(about)
//! [22]
aboutQtAct = QAction(tr("About &Qt"), self)
aboutQtAct.setStatusTip(tr("Show the Qt library's About box"))
- connect(aboutQtAct, SIGNAL("triggered()"), qApp, SLOT("aboutQt()"))
+ aboutQtAct.triggered.connect(qApp.aboutQt)
//! [22]
//! [23]
cutAct.setEnabled(False)
//! [23] //! [24]
copyAct.setEnabled(False)
- connect(textEdit, SIGNAL("copyAvailable(bool)"),
- cutAct, SLOT("setEnabled(bool)"))
- connect(textEdit, SIGNAL("copyAvailable(bool)"),
- copyAct, SLOT("setEnabled(bool)"))
+ textEdit.copyAvailable[bool].connect(cutAct.setEnabled)
+ textEdit.copyAvailable[bool].connect(copyAct.setEnabled)
}
//! [24]
@@ -298,10 +298,8 @@ def loadFile(self, fileName):
//! [42] //! [43]
file = QFile(fileName)
if !file.open(QFile.ReadOnly | QFile.Text):
- QMessageBox.warning(self, tr("Application"),
- tr("Cannot read file %1:\n%2.")
- .arg(fileName)
- .arg(file.errorString()))
+ QMessageBox.warning(self, tr("Application"), tr("Cannot read file "
+ "{}:\n{}.".format(fileName, file.errorString())))
return
in = QTextStream(file)
@@ -309,8 +307,8 @@ def loadFile(self, fileName):
textEdit.setPlainText(in.readAll())
QApplication.restoreOverrideCursor()
- setCurrentFile(fileName)
- statusBar().showMessage(tr("File loaded"), 2000)
+ self.setCurrentFile(fileName)
+ self.statusBar().showMessage(tr("File loaded"), 2000)
//! [43]
diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.py
index e1a9f556e..55d551c24 100644
--- a/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.cpp
+++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.py
@@ -142,7 +142,7 @@ def save(self):
.arg(fileName)
.arg(file.errorString()))
return
-
+
out = QTextStream(file)
QApplication.setOverrideCursor(Qt::WaitCursor)
@@ -177,7 +177,7 @@ def insertCustomer(self, customer):
for i in range(customerList.size()):
cursor.insertBlock()
cursor.insertText(customerList.at(i))
-
+
cursor.endEditBlock()
else:
oldcursor.endEditBlock()
@@ -248,8 +248,6 @@ def createDockWindows(self):
addDockWidget(Qt.RightDockWidgetArea, dock)
viewMenu.addAction(dock.toggleViewAction())
- connect(customerList, SIGNAL("currentTextChanged(const QString &)"),
- self, SLOT("insertCustomer(const QString &)"))
- connect(paragraphsList, SIGNAL("currentTextChanged(const QString &)"),
- self, SLOT("addParagraph(const QString &)"))
+ customerList.currentTextChanged[str].connect(self.insertCostumer)
+ paragraphsList.currentTextChanged[str].connect(self.addParagraph)
//! [9]
diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.py
index 6ed5f5466..b0bbed810 100644
--- a/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.cpp
+++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.py
@@ -196,63 +196,63 @@ def createActions(self):
Act = new QAction(tr("&New"), self)
Act.setShortcuts(QKeySequence.New)
Act.setStatusTip(tr("Create a new file"))
- connect(Act, SIGNAL("triggered()"), self, SLOT("newFile()"))
+ Act.triggered.connect(newFile)
//! [4]
openAct = QAction(tr("&Open..."), self)
openAct.setShortcuts(QKeySequence.Open)
openAct.setStatusTip(tr("Open an existing file"))
- connect(openAct, SIGNAL("triggered()"), self, SLOT("open()"))
+ openAct.triggered.connect(open)
//! [5]
saveAct = QAction(tr("&Save"), self)
saveAct.setShortcuts(QKeySequence.Save)
saveAct.setStatusTip(tr("Save the document to disk"))
- connect(saveAct, SIGNAL("triggered()"), self, SLOT("save()"))
+ saveAct.triggered.connect(save)
printAct = QAction(tr("&Print..."), self)
printAct.setShortcuts(QKeySequence.Print)
printAct.setStatusTip(tr("Print the document"))
- connect(printAct, SIGNAL("triggered()"), self, SLOT("print_()"))
+ printAct.triggered.connect(print_)
exitAct = QAction(tr("E&xit"), self)
exitAct.setShortcut(tr("Ctrl+Q"))
exitAct.setStatusTip(tr("Exit the application"))
- connect(exitAct, SIGNAL("triggered()"), self, SLOT("close()"))
+ exitAct.triggered.connect(close)
undoAct = QAction(tr("&Undo"), self)
undoAct.setShortcuts(QKeySequence.Undo)
undoAct.setStatusTip(tr("Undo the last operation"))
- connect(undoAct, SIGNAL("triggered()"), self, SLOT("undo()"))
+ undoAct.triggered.connect(undo)
redoAct = QAction(tr("&Redo"), self)
redoAct.setShortcuts(QKeySequence.Redo)
redoAct.setStatusTip(tr("Redo the last operation"))
- connect(redoAct, SIGNAL("triggered()"), self, SLOT("redo()"))
+ redoAct.triggered.connect(redo)
cutAct = QAction(tr("Cu&t"), self)
cutAct.setShortcuts(QKeySequence.Cut)
cutAct.setStatusTip(tr("Cut the current selection's contents to the "
"clipboard"))
- connect(cutAct, SIGNAL("triggered()"), self, SLOT("cut()"))
+ cutAct.triggered.connect(cut)
copyAct = QAction(tr("&Copy"), self)
copyAct.setShortcut(tr("Ctrl+C"))
copyAct.setStatusTip(tr("Copy the current selection's contents to the "
"clipboard"))
- connect(copyAct, SIGNAL("triggered()"), self, SLOT("copy()"))
+ copyAct.triggered.connect(copy)
pasteAct = QAction(tr("&Paste"), self)
pasteAct.setShortcuts(QKeySequence.Paste)
pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current "
"selection"))
- connect(pasteAct, SIGNAL("triggered()"), self, SLOT("paste()"))
+ pasteAct.triggered.connect(paste)
boldAct = QAction(tr("&Bold"), self)
boldAct.setCheckable(True)
boldAct.setShortcut(tr("Ctrl+B"))
boldAct.setStatusTip(tr("Make the text bold"))
- connect(boldAct, SIGNAL("triggered()"), self, SLOT("bold()"))
+ boldAct.triggered.connect(bold)
QFont boldFont = boldAct.font()
boldFont.setBold(True)
@@ -262,7 +262,7 @@ def createActions(self):
italicAct.setCheckable(True)
italicAct.setShortcut(tr("Ctrl+I"))
italicAct.setStatusTip(tr("Make the text italic"))
- connect(italicAct, SIGNAL("triggered()"), self, SLOT("italic()"))
+ italicAct.triggered.connect(italic)
QFont italicFont = italicAct.font()
italicFont.setItalic(True)
@@ -271,45 +271,44 @@ def createActions(self):
setLineSpacingAct = QAction(tr("Set &Line Spacing..."), self)
setLineSpacingAct.setStatusTip(tr("Change the gap between the lines of a "
"paragraph"))
- connect(setLineSpacingAct, SIGNAL("triggered()"), self, SLOT("setLineSpacing()"))
+ setLineSpacingAct.triggered.connect(setLineSpacing)
setParagraphSpacingAct = QAction(tr("Set &Paragraph Spacing..."), self)
setLineSpacingAct.setStatusTip(tr("Change the gap between paragraphs"))
- connect(setParagraphSpacingAct, SIGNAL("triggered()"),
- self, SLOT("setParagraphSpacing()"))
+ setParagraphSpacingAct.triggered.connect(setParagraphSpacing)
aboutAct = QAction(tr("&About"), self)
aboutAct.setStatusTip(tr("Show the application's About box"))
- connect(aboutAct, SIGNAL("triggered()"), self, SLOT("about()"))
+ aboutAct.triggered.connect(about)
aboutQtAct = QAction(tr("About &Qt"), self)
aboutQtAct.setStatusTip(tr("Show the Qt library's About box"))
- connect(aboutQtAct, SIGNAL("triggered()"), qApp, SLOT("aboutQt()"))
- connect(aboutQtAct, SIGNAL("triggered()"), self, SLOT("aboutQt()"))
+ aboutQtAct.triggered.connect(qApp.aboutQt)
+ aboutQtAct.triggered.connect(aboutQt)
leftAlignAct = QAction(tr("&Left Align"), self)
leftAlignAct.setCheckable(True)
leftAlignAct.setShortcut(tr("Ctrl+L"))
leftAlignAct.setStatusTip(tr("Left align the selected text"))
- connect(leftAlignAct, SIGNAL("triggered()"), self, SLOT("leftAlign()"))
+ leftAlignAct.triggered.connect(leftAlign)
rightAlignAct = QAction(tr("&Right Align"), self)
rightAlignAct.setCheckable(True)
rightAlignAct.setShortcut(tr("Ctrl+R"))
rightAlignAct.setStatusTip(tr("Right align the selected text"))
- connect(rightAlignAct, SIGNAL("triggered()"), self, SLOT("rightAlign()"))
+ rightAlignAct.triggered.connect.(rightAlign)
justifyAct = QAction(tr("&Justify"), self)
justifyAct.setCheckable(True)
justifyAct.setShortcut(tr("Ctrl+J"))
justifyAct.setStatusTip(tr("Justify the selected text"))
- connect(justifyAct, SIGNAL("triggered()"), self, SLOT("justify()"))
+ justifyAct.triggered.connect(justify)
centerAct = QAction(tr("&Center"), self)
centerAct.setCheckable(True)
centerAct.setShortcut(tr("Ctrl+E"))
centerAct.setStatusTip(tr("Center the selected text"))
- connect(centerAct, SIGNAL("triggered()"), self, SLOT("center()"))
+ centerAct.triggered.connect(center)
//! [6] //! [7]
alignmentGroup = QActionGroup(self)
diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.cpp
deleted file mode 100644
index cfee5cdca..000000000
--- a/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the examples of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:BSD$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## BSD License Usage
-## Alternatively, you may use this file under the terms of the BSD license
-## as follows:
-##
-## "Redistribution and use in source and binary forms, with or without
-## modification, are permitted provided that the following conditions are
-## met:
-## * Redistributions of source code must retain the above copyright
-## notice, this list of conditions and the following disclaimer.
-## * Redistributions in binary form must reproduce the above copyright
-## notice, this list of conditions and the following disclaimer in
-## the documentation and/or other materials provided with the
-## distribution.
-## * Neither the name of The Qt Company Ltd nor the names of its
-## contributors may be used to endorse or promote products derived
-## from this software without specific prior written permission.
-##
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-##
-## $QT_END_LICENSE$
-##
-############################################################################
-
-from PySide2.QtGui import *
-
-def __init__(self):
-
- mdiArea = QMdiArea()
- mdiArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
- mdiArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
- setCentralWidget(mdiArea)
- connect(mdiArea, SIGNAL("subWindowActivated(QMdiSubWindow *)"),
- self, SLOT("updateMenus()"))
- windowMapper = QSignalMapper(self)
- connect(windowMapper, SIGNAL("mapped(QWidget *)"),
- self, SLOT("setActiveSubWindow(QWidget *)"))
-
- createActions()
- createMenus()
- createToolBars()
- createStatusBar()
- updateMenus()
-
- readSettings()
-
- setWindowTitle(tr("MDI"))
- setUnifiedTitleAndToolBarOnMac(True)
-
-
-def closeEvent(self, event):
- mdiArea.closeAllSubWindows()
- if self.activeMdiChild():
- event.ignore()
- else:
- self.writeSettings()
- event.accept()
-
-def File(self):
- child = self.createMdiChild()
- child.File()
- child.show()
-
-
-def open(self):
- fileName = QFileDialog.getOpenFileName(self)
- if !fileName.isEmpty()):
- existing = self.findMdiChild(fileName)
- if existing:
- mdiArea.setActiveSubWindow(existing)
- return
-
- child = createMdiChild()
- if child.loadFile(fileName)):
- statusBar().showMessage(tr("File loaded"), 2000)
- child.show()
- else:
- child.close()
-
-def save(self):
- if self.activeMdiChild() && self.activeMdiChild().save():
- self.statusBar().showMessage(tr("File saved"), 2000)
-
-def saveAs(self):
- if self.activeMdiChild() && self.activeMdiChild().saveAs():
- self.statusBar().showMessage(tr("File saved"), 2000)
-
-def cut(self):
- if self.activeMdiChild():
- self.activeMdiChild().cut()
-
-def copy(self):
- if self.activeMdiChild():
- activeMdiChild().copy()
-
-def paste(self):
- if self.activeMdiChild():
- activeMdiChild().paste()
-
-def about(self):
- QMessageBox.about(self, tr("About MDI"),
- tr("The <b>MDI</b> example demonstrates how to write multiple "
- "document interface applications using Qt.")")
-
-def updateMenus(self):
- hasMdiChild = (activeMdiChild() != 0)
- self.saveAct.setEnabled(hasMdiChild)
- self.saveAsAct.setEnabled(hasMdiChild)
- self.pasteAct.setEnabled(hasMdiChild)
- self.closeAct.setEnabled(hasMdiChild)
- self.closeAllAct.setEnabled(hasMdiChild)
- self.tileAct.setEnabled(hasMdiChild)
- self.cascadeAct.setEnabled(hasMdiChild)
- self.nextAct.setEnabled(hasMdiChild)
- self.previousAct.setEnabled(hasMdiChild)
- self.separatorAct.setVisible(hasMdiChild)
-
- hasSelection = (self.activeMdiChild() &&
- self.activeMdiChild().textCursor().hasSelection()")
- self.cutAct.setEnabled(hasSelection)
- self.copyAct.setEnabled(hasSelection)
-
-def updateWindowMenu(self):
- self.windowMenu.clear()
- self.windowMenu.addAction(closeAct)
- self.windowMenu.addAction(closeAllAct)
- self.windowMenu.addSeparator()
- self.windowMenu.addAction(tileAct)
- self.windowMenu.addAction(cascadeAct)
- self.windowMenu.addSeparator()
- self.windowMenu.addAction(nextAct)
- self.windowMenu.addAction(previousAct)
- self.windowMenu.addAction(separatorAct)
-
- windows = mdiArea.subWindowList()
- separatorAct.setVisible(!windows.isEmpty()")
-
- for i in range((int i = 0 i < windows.size(); ++i)
- MdiChild *child = qobject_cast<MdiChild *>(windows.at(i).widget()")
-
- QString text
- if (i < 9)
- text = tr("&%1 %2").arg(i + 1)
- .arg(child.userFriendlyCurrentFile()")
- else
- text = tr("%1 %2").arg(i + 1)
- .arg(child.userFriendlyCurrentFile()")
-
- QAction *action = windowMenu.addAction(text)
- action.setCheckable(True)
- action .setChecked(child == activeMdiChild()")
- connect(action, SIGNAL("triggered()"), windowMapper, SLOT("map()"))
- windowMapper.setMapping(action, windows.at(i)")
-
-
-
-MdiChild *createMdiChild()
-
- MdiChild *child = MdiChild
- mdiArea.addSubWindow(child)
-
- connect(child, SIGNAL("copyAvailable(bool)"),
- cutAct, SLOT("setEnabled(bool)"))
- connect(child, SIGNAL("copyAvailable(bool)"),
- copyAct, SLOT("setEnabled(bool)"))
-
- return child
-
-
-def createActions()
-
- Act = new QAction(QIcon(":/images/new.png"), tr("&New"), self)
- Act.setShortcuts(QKeySequence.New)
- Act.setStatusTip(tr("Create a new file")")
- connect(Act, SIGNAL("triggered()"), self, SLOT("newFile()"))
-
- openAct = QAction(QIcon(":/images/open.png"), tr("&Open..."), self)
- openAct.setShortcuts(QKeySequence.Open)
- openAct.setStatusTip(tr("Open an existing file")")
- connect(openAct, SIGNAL("triggered()"), self, SLOT("open()"))
-
- saveAct = QAction(QIcon(":/images/save.png"), tr("&Save"), self)
- saveAct.setShortcuts(QKeySequence.Save)
- saveAct.setStatusTip(tr("Save the document to disk")")
- connect(saveAct, SIGNAL("triggered()"), self, SLOT("save()"))
-
- saveAsAct = QAction(tr("Save &As..."), self)
- saveAsAct.setShortcuts(QKeySequence.SaveAs)
- saveAsAct.setStatusTip(tr("Save the document under a name")")
- connect(saveAsAct, SIGNAL("triggered()"), self, SLOT("saveAs()"))
-
-//! [0]
- exitAct = QAction(tr("E&xit"), self)
- exitAct.setShortcut(tr("Ctrl+Q")")
- exitAct.setStatusTip(tr("Exit the application")")
- connect(exitAct, SIGNAL("triggered()"), qApp, SLOT("closeAllWindows()"))
-//! [0]
-
- cutAct = QAction(QIcon(":/images/cut.png"), tr("Cu&t"), self)
- cutAct.setShortcuts(QKeySequence.Cut)
- cutAct.setStatusTip(tr("Cut the current selection's contents to the "
- "clipboard")")
- connect(cutAct, SIGNAL("triggered()"), self, SLOT("cut()"))
-
- copyAct = QAction(QIcon(":/images/copy.png"), tr("&Copy"), self)
- copyAct.setShortcuts(QKeySequence.Copy)
- copyAct.setStatusTip(tr("Copy the current selection's contents to the "
- "clipboard")")
- connect(copyAct, SIGNAL("triggered()"), self, SLOT("copy()"))
-
- pasteAct = QAction(QIcon(":/images/paste.png"), tr("&Paste"), self)
- pasteAct.setShortcuts(QKeySequence.Paste)
- pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current "
- "selection")")
- connect(pasteAct, SIGNAL("triggered()"), self, SLOT("paste()"))
-
- closeAct = QAction(tr("Cl&ose"), self)
- closeAct.setShortcut(tr("Ctrl+F4")")
- closeAct.setStatusTip(tr("Close the active window")")
- connect(closeAct, SIGNAL("triggered()"),
- mdiArea, SLOT("closeActiveSubWindow()"))
-
- closeAllAct = QAction(tr("Close &All"), self)
- closeAllAct.setStatusTip(tr("Close all the windows")")
- connect(closeAllAct, SIGNAL("triggered()"),
- mdiArea, SLOT("closeAllSubWindows()"))
-
- tileAct = QAction(tr("&Tile"), self)
- tileAct.setStatusTip(tr("Tile the windows")")
- connect(tileAct, SIGNAL("triggered()"), mdiArea, SLOT("tileSubWindows()"))
-
- cascadeAct = QAction(tr("&Cascade"), self)
- cascadeAct.setStatusTip(tr("Cascade the windows")")
- connect(cascadeAct, SIGNAL("triggered()"), mdiArea, SLOT("cascadeSubWindows()"))
-
- nextAct = QAction(tr("Ne&xt"), self)
- nextAct.setShortcuts(QKeySequence.NextChild)
- nextAct.setStatusTip(tr("Move the focus to the next window")")
- connect(nextAct, SIGNAL("triggered()"),
- mdiArea, SLOT("activateNextSubWindow()"))
-
- previousAct = QAction(tr("Pre&vious"), self)
- previousAct.setShortcuts(QKeySequence.PreviousChild)
- previousAct.setStatusTip(tr("Move the focus to the previous "
- "window")")
- connect(previousAct, SIGNAL("triggered()"),
- mdiArea, SLOT("activatePreviousSubWindow()"))
-
- separatorAct = QAction(self)
- separatorAct.setSeparator(True)
-
- aboutAct = QAction(tr("&About"), self)
- aboutAct.setStatusTip(tr("Show the application's About box")")
- connect(aboutAct, SIGNAL("triggered()"), self, SLOT("about()"))
-
- aboutQtAct = QAction(tr("About &Qt"), self)
- aboutQtAct.setStatusTip(tr("Show the Qt library's About box")")
- connect(aboutQtAct, SIGNAL("triggered()"), qApp, SLOT("aboutQt()"))
-
-
-def createMenus()
-
- fileMenu = menuBar().addMenu(tr("&File")")
- fileMenu.addAction(Act)
- fileMenu.addAction(openAct)
- fileMenu.addAction(saveAct)
- fileMenu.addAction(saveAsAct)
- fileMenu.addSeparator()
- QAction *action = fileMenu.addAction(tr("Switch layout direction")")
- connect(action, SIGNAL("triggered()"), self, SLOT("switchLayoutDirection()"))
- fileMenu.addAction(exitAct)
-
- editMenu = menuBar().addMenu(tr("&Edit")")
- editMenu.addAction(cutAct)
- editMenu.addAction(copyAct)
- editMenu.addAction(pasteAct)
-
- windowMenu = menuBar().addMenu(tr("&Window")")
- updateWindowMenu()
- connect(windowMenu, SIGNAL("aboutToShow()"), self, SLOT("updateWindowMenu()"))
-
- menuBar().addSeparator()
-
- helpMenu = menuBar().addMenu(tr("&Help")")
- helpMenu.addAction(aboutAct)
- helpMenu.addAction(aboutQtAct)
-
-
-def createToolBars()
-
- fileToolBar = addToolBar(tr("File")")
- fileToolBar.addAction(Act)
- fileToolBar.addAction(openAct)
- fileToolBar.addAction(saveAct)
-
- editToolBar = addToolBar(tr("Edit")")
- editToolBar.addAction(cutAct)
- editToolBar.addAction(copyAct)
- editToolBar.addAction(pasteAct)
-
-
-def createStatusBar()
-
- statusBar().showMessage(tr("Ready")")
-
-
-def readSettings()
-
- QSettings settings("Trolltech", "MDI Example")
- QPoint pos = settings.value("pos", QPoint(200, 200)").toPoint()
- QSize size = settings.value("size", QSize(400, 400)").toSize()
- move(pos)
- resize(size)
-
-
-def writeSettings()
-
- QSettings settings("Trolltech", "MDI Example")
- settings.setValue("pos", pos()")
- settings.setValue("size", size()")
-
-
-MdiChild *activeMdiChild()
-
- if (QMdiSubWindow *activeSubWindow = mdiArea.activeSubWindow()")
- return qobject_cast<MdiChild *>(activeSubWindow.widget()")
- return 0
-
-
-QMdiSubWindow *findMdiChild(const QString &fileName)
-
- QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath()
-
- foreach (QMdiSubWindow *window, mdiArea.subWindowList()")
- MdiChild *mdiChild = qobject_cast<MdiChild *>(window.widget()")
- if (mdiChild.currentFile() == canonicalFilePath)
- return window
-
- return 0
-
-
-def switchLayoutDirection()
-
- if (layoutDirection() == Qt.LeftToRight)
- qApp.setLayoutDirection(Qt.RightToLeft)
- else
- qApp.setLayoutDirection(Qt.LeftToRight)
-
-
-def setActiveSubWindow(QWidget *window)
-
- if (!window)
- return
- mdiArea.setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window)")
-
diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.py b/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.py
new file mode 100644
index 000000000..41f515847
--- /dev/null
+++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.py
@@ -0,0 +1,360 @@
+############################################################################
+##
+## Copyright (C) 2016 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the examples of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## BSD License Usage
+## Alternatively, you may use this file under the terms of the BSD license
+## as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+############################################################################
+
+from PySide2.QtGui import *
+
+class QMdiSubWindow(QMainWindow):
+ def __init__(self, parent=None):
+ QMainWindow.__init__(self, parent)
+
+ mdiArea = QMdiArea()
+ mdiArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
+ mdiArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
+ setCentralWidget(mdiArea)
+ mdiArea.subWindowActivated[QMdiSubWindow].connect(updateMenus)
+ windowMapper = QSignalMapper(self)
+ windowMapper.mapped[QWidget].connect(setActiveSubWindow)
+
+ self.createActions()
+ self.createMenus()
+ self.createToolBars()
+ self.createStatusBar()
+ self.updateMenus()
+ self.readSettings()
+ self.setWindowTitle(tr("MDI"))
+ self.setUnifiedTitleAndToolBarOnMac(True)
+
+
+ def closeEvent(self, event):
+ mdiArea.closeAllSubWindows()
+ if self.activeMdiChild():
+ event.ignore()
+ else:
+ self.writeSettings()
+ event.accept()
+
+ def File(self):
+ child = self.createMdiChild()
+ child.File()
+ child.show()
+
+
+ def open(self):
+ fileName = QFileDialog.getOpenFileName(self)
+ if not fileName.isEmpty():
+ existing = self.findMdiChild(fileName)
+ if existing:
+ mdiArea.setActiveSubWindow(existing)
+ return
+
+ child = createMdiChild()
+ if child.loadFile(fileName):
+ statusBar().showMessage(tr("File loaded"), 2000)
+ child.show()
+ else:
+ child.close()
+
+ def save(self):
+ if self.activeMdiChild() and self.activeMdiChild().save():
+ self.statusBar().showMessage(tr("File saved"), 2000)
+
+ def saveAs(self):
+ if self.activeMdiChild() and self.activeMdiChild().saveAs():
+ self.statusBar().showMessage(tr("File saved"), 2000)
+
+ def cut(self):
+ if self.activeMdiChild():
+ self.activeMdiChild().cut()
+
+ def copy(self):
+ if self.activeMdiChild():
+ activeMdiChild().copy()
+
+ def paste(self):
+ if self.activeMdiChild():
+ activeMdiChild().paste()
+
+ def about(self):
+ QMessageBox.about(self, tr("About MDI"),
+ tr("The <b>MDI</b> example demonstrates how to write multiple "
+ "document interface applications using Qt."))
+
+ def updateMenus(self):
+ hasMdiChild = (activeMdiChild() != 0)
+ self.saveAct.setEnabled(hasMdiChild)
+ self.saveAsAct.setEnabled(hasMdiChild)
+ self.pasteAct.setEnabled(hasMdiChild)
+ self.closeAct.setEnabled(hasMdiChild)
+ self.closeAllAct.setEnabled(hasMdiChild)
+ self.tileAct.setEnabled(hasMdiChild)
+ self.cascadeAct.setEnabled(hasMdiChild)
+ self.nextAct.setEnabled(hasMdiChild)
+ self.previousAct.setEnabled(hasMdiChild)
+ self.separatorAct.setVisible(hasMdiChild)
+
+ hasSelection = (self.activeMdiChild() and
+ self.activeMdiChild().textCursor().hasSelection())
+ self.cutAct.setEnabled(hasSelection)
+ self.copyAct.setEnabled(hasSelection)
+
+ def updateWindowMenu(self):
+ self.windowMenu.clear()
+ self.windowMenu.addAction(closeAct)
+ self.windowMenu.addAction(closeAllAct)
+ self.windowMenu.addSeparator()
+ self.windowMenu.addAction(tileAct)
+ self.windowMenu.addAction(cascadeAct)
+ self.windowMenu.addSeparator()
+ self.windowMenu.addAction(nextAct)
+ self.windowMenu.addAction(previousAct)
+ self.windowMenu.addAction(separatorAct)
+
+ windows = mdiArea.subWindowList()
+ separatorAct.setVisible(not windows.isEmpty())
+
+ for i in range(0, windows.size()):
+ child = windows.at(i).widget()
+
+ text = ""
+ if i < 9:
+ text = "{} {}".format(i + 1, child.userFriendlyCurrentFile())
+ else:
+ text = "{} {}".format(i + 1, child.userFriendlyCurrentFile())
+
+ action = windowMenu.addAction(text)
+ action.setCheckable(True)
+ action.setChecked(child == activeMdiChild())
+ action.triggered.connect(windowMapper.map)
+ windowMapper.setMapping(action, windows.at(i))
+
+ createMdiChild = MdiChild()
+
+ child = MdiChild()
+ mdiArea.addSubWindow(child)
+
+ child.copyAvailable[bool].connect(cutAct.setEnabled)
+ child.copyAvailable[bool].connect(copyAct.setEnabled)
+
+ return child
+
+
+ def createActions(self):
+
+ Act = QAction(QIcon(":/images/new.png"), tr("&New"), self)
+ Act.setShortcuts(QKeySequence.New)
+ Act.setStatusTip(tr("Create a new file"))
+ Act.triggered.connect(self.newFile)
+
+ openAct = QAction(QIcon(":/images/open.png"), tr("&Open..."), self)
+ openAct.setShortcuts(QKeySequence.Open)
+ openAct.setStatusTip(tr("Open an existing file"))
+ openAct.triggered.connect(self.open)
+
+ saveAct = QAction(QIcon(":/images/save.png"), tr("&Save"), self)
+ saveAct.setShortcuts(QKeySequence.Save)
+ saveAct.setStatusTip(tr("Save the document to disk"))
+ saveAct.triggered.connect(self.save)
+
+ saveAsAct = QAction(tr("Save &As..."), self)
+ saveAsAct.setShortcuts(QKeySequence.SaveAs)
+ saveAsAct.setStatusTip(tr("Save the document under a name"))
+ saveAsAct.triggered.connect(self.saveAs)
+
+//! [0]
+ exitAct = QAction(tr("E&xit"), self)
+ exitAct.setShortcut(tr("Ctrl+Q"))
+ exitAct.setStatusTip(tr("Exit the application"))
+ exitAct.triggered.connect(qApp.closeAllWindows)
+//! [0]
+
+ cutAct = QAction(QIcon(":/images/cut.png"), tr("Cu&t"), self)
+ cutAct.setShortcuts(QKeySequence.Cut)
+ cutAct.setStatusTip(tr("Cut the current selection's contents to the "
+ "clipboard"))
+ cutAct.triggered.connect(self.cut)
+
+ copyAct = QAction(QIcon(":/images/copy.png"), tr("&Copy"), self)
+ copyAct.setShortcuts(QKeySequence.Copy)
+ copyAct.setStatusTip(tr("Copy the current selection's contents to the "
+ "clipboard"))
+ copyAct.triggered.connect(self.copy)
+
+ pasteAct = QAction(QIcon(":/images/paste.png"), tr("&Paste"), self)
+ pasteAct.setShortcuts(QKeySequence.Paste)
+ pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current "
+ "selection"))
+ pasteAct.triggered.connect(self.paste)
+
+ closeAct = QAction(tr("Cl&ose"), self)
+ closeAct.setShortcut(tr("Ctrl+F4"))
+ closeAct.setStatusTip(tr("Close the active window"))
+ closeAct.triggered.connect(mdiArea.closeActiveSubWindow)
+
+ closeAllAct = QAction(tr("Close &All"), self)
+ closeAllAct.setStatusTip(tr("Close all the windows"))
+ closeAllAct.triggered.connect(mdiArea.closeAllSubWindows)
+
+ tileAct = QAction(tr("&Tile"), self)
+ tileAct.setStatusTip(tr("Tile the windows"))
+ tileAct.triggered.connect(mdiArea.tileSubWindows)
+
+ cascadeAct = QAction(tr("&Cascade"), self)
+ cascadeAct.setStatusTip(tr("Cascade the windows"))
+ cascadeAct.triggered.connect(mdiArea.cascadeSubWindows)
+
+ nextAct = QAction(tr("Ne&xt"), self)
+ nextAct.setShortcuts(QKeySequence.NextChild)
+ nextAct.setStatusTip(tr("Move the focus to the next window"))
+ nextAct.triggered.connect(mdiArea.activateNextSubWindow)
+
+ previousAct = QAction(tr("Pre&vious"), self)
+ previousAct.setShortcuts(QKeySequence.PreviousChild)
+ previousAct.setStatusTip(tr("Move the focus to the previous "
+ "window"))
+ previousAct.triggered.connect(mdiArea.activatePreviousSubWindow)
+
+ separatorAct = QAction(self)
+ separatorAct.setSeparator(True)
+
+ aboutAct = QAction(tr("&About"), self)
+ aboutAct.setStatusTip(tr("Show the application's About box"))
+ aboutAct.triggered.connect(self.about)
+
+ aboutQtAct = QAction(tr("About &Qt"), self)
+ aboutQtAct.setStatusTip(tr("Show the Qt library's About box"))
+ aboutQtAct.triggered.connect(qApp.aboutQt)
+
+
+ def createMenus(self):
+
+ fileMenu = menuBar().addMenu(tr("&File"))
+ fileMenu.addAction(Act)
+ fileMenu.addAction(openAct)
+ fileMenu.addAction(saveAct)
+ fileMenu.addAction(saveAsAct)
+ fileMenu.addSeparator()
+ action = fileMenu.addAction(tr("Switch layout direction"))
+ action.triggered.connect(self.switchLayoutDirection)
+ fileMenu.addAction(exitAct)
+
+ editMenu = menuBar().addMenu(tr("&Edit"))
+ editMenu.addAction(cutAct)
+ editMenu.addAction(copyAct)
+ editMenu.addAction(pasteAct)
+
+ windowMenu = menuBar().addMenu(tr("&Window"))
+ updateWindowMenu()
+ windowMenu.aboutToShow.connect(self.updateWindowMenu)
+
+ menuBar().addSeparator()
+
+ helpMenu = menuBar().addMenu(tr("&Help"))
+ helpMenu.addAction(aboutAct)
+ helpMenu.addAction(aboutQtAct)
+
+
+ def createToolBars(self):
+ fileToolBar = addToolBar(tr("File"))
+ fileToolBar.addAction(Act)
+ fileToolBar.addAction(openAct)
+ fileToolBar.addAction(saveAct)
+
+ editToolBar = addToolBar(tr("Edit"))
+ editToolBar.addAction(cutAct)
+ editToolBar.addAction(copyAct)
+ editToolBar.addAction(pasteAct)
+
+
+ def createStatusBar(self):
+ statusBar().showMessage(tr("Ready"))
+
+
+ def readSettings(self):
+ settings = QSettings("Trolltech", "MDI Example")
+ QPoint pos = settings.value("pos", QPoint(200, 200)").toPoint()
+ QSize size = settings.value("size", QSize(400, 400)").toSize()
+ move(pos)
+ resize(size)
+
+ def writeSettings(self):
+ QSettings settings("Trolltech", "MDI Example")
+ settings.setValue("pos", pos()")
+ settings.setValue("size", size()")
+
+
+ activeMdiChild = MdiChild()
+ activeSubWindow = mdiArea.activeSubWindow()
+ if activeSubWindow:
+ return activeSubWindow.widget()
+ return 0
+
+
+ def findMdiChild(self, fileName):
+
+ canonicalFilePath = QFileInfo(fileName).canonicalFilePath()
+
+ for window in mdiArea.subWindowList():
+ mdiChild = window.widget()
+ if mdiChild.currentFile() == canonicalFilePath:
+ return window
+ return 0
+
+
+ def switchLayoutDirection(self)
+ if layoutDirection() == Qt.LeftToRight:
+ qApp.setLayoutDirection(Qt.RightToLeft)
+ else:
+ qApp.setLayoutDirection(Qt.LeftToRight)
+
+
+ def setActiveSubWindow(self, window):
+ if not window:
+ return
+ mdiArea.setActiveSubWindow(window)
diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.py
index 6ed5f5466..6505f1f1a 100644
--- a/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.cpp
+++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.py
@@ -196,63 +196,63 @@ def createActions(self):
Act = new QAction(tr("&New"), self)
Act.setShortcuts(QKeySequence.New)
Act.setStatusTip(tr("Create a new file"))
- connect(Act, SIGNAL("triggered()"), self, SLOT("newFile()"))
+ Act.triggered.connect(newFile)
//! [4]
openAct = QAction(tr("&Open..."), self)
openAct.setShortcuts(QKeySequence.Open)
openAct.setStatusTip(tr("Open an existing file"))
- connect(openAct, SIGNAL("triggered()"), self, SLOT("open()"))
+ openAct.triggered.connect(open)
//! [5]
saveAct = QAction(tr("&Save"), self)
saveAct.setShortcuts(QKeySequence.Save)
saveAct.setStatusTip(tr("Save the document to disk"))
- connect(saveAct, SIGNAL("triggered()"), self, SLOT("save()"))
+ saveAct.triggered.connect(save)
printAct = QAction(tr("&Print..."), self)
printAct.setShortcuts(QKeySequence.Print)
printAct.setStatusTip(tr("Print the document"))
- connect(printAct, SIGNAL("triggered()"), self, SLOT("print_()"))
+ printAct.triggered.connect(print_)
exitAct = QAction(tr("E&xit"), self)
exitAct.setShortcut(tr("Ctrl+Q"))
exitAct.setStatusTip(tr("Exit the application"))
- connect(exitAct, SIGNAL("triggered()"), self, SLOT("close()"))
+ exitAct.triggered.connect(close)
undoAct = QAction(tr("&Undo"), self)
undoAct.setShortcuts(QKeySequence.Undo)
undoAct.setStatusTip(tr("Undo the last operation"))
- connect(undoAct, SIGNAL("triggered()"), self, SLOT("undo()"))
+ undoAct.triggered.connect(undo)
redoAct = QAction(tr("&Redo"), self)
redoAct.setShortcuts(QKeySequence.Redo)
redoAct.setStatusTip(tr("Redo the last operation"))
- connect(redoAct, SIGNAL("triggered()"), self, SLOT("redo()"))
+ redoAct.triggered.connect(redo)
cutAct = QAction(tr("Cu&t"), self)
cutAct.setShortcuts(QKeySequence.Cut)
cutAct.setStatusTip(tr("Cut the current selection's contents to the "
"clipboard"))
- connect(cutAct, SIGNAL("triggered()"), self, SLOT("cut()"))
+ cutAct.triggered.connect(cut)
copyAct = QAction(tr("&Copy"), self)
copyAct.setShortcut(tr("Ctrl+C"))
copyAct.setStatusTip(tr("Copy the current selection's contents to the "
"clipboard"))
- connect(copyAct, SIGNAL("triggered()"), self, SLOT("copy()"))
+ copyAct.triggered.connect(copy)
pasteAct = QAction(tr("&Paste"), self)
pasteAct.setShortcuts(QKeySequence.Paste)
pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current "
"selection"))
- connect(pasteAct, SIGNAL("triggered()"), self, SLOT("paste()"))
+ pasteAct.triggered.connect(paste)
boldAct = QAction(tr("&Bold"), self)
boldAct.setCheckable(True)
boldAct.setShortcut(tr("Ctrl+B"))
boldAct.setStatusTip(tr("Make the text bold"))
- connect(boldAct, SIGNAL("triggered()"), self, SLOT("bold()"))
+ boldAct.triggered.connect(bold)
QFont boldFont = boldAct.font()
boldFont.setBold(True)
@@ -262,7 +262,7 @@ def createActions(self):
italicAct.setCheckable(True)
italicAct.setShortcut(tr("Ctrl+I"))
italicAct.setStatusTip(tr("Make the text italic"))
- connect(italicAct, SIGNAL("triggered()"), self, SLOT("italic()"))
+ italicAct.triggered.connect(italic)
QFont italicFont = italicAct.font()
italicFont.setItalic(True)
@@ -271,45 +271,44 @@ def createActions(self):
setLineSpacingAct = QAction(tr("Set &Line Spacing..."), self)
setLineSpacingAct.setStatusTip(tr("Change the gap between the lines of a "
"paragraph"))
- connect(setLineSpacingAct, SIGNAL("triggered()"), self, SLOT("setLineSpacing()"))
+ setLineSpacingAct.triggered.connect(setLineSpacing)
setParagraphSpacingAct = QAction(tr("Set &Paragraph Spacing..."), self)
setLineSpacingAct.setStatusTip(tr("Change the gap between paragraphs"))
- connect(setParagraphSpacingAct, SIGNAL("triggered()"),
- self, SLOT("setParagraphSpacing()"))
+ setParagraphSpacingAct.triggered.connect(setParagraphSpacing)
aboutAct = QAction(tr("&About"), self)
aboutAct.setStatusTip(tr("Show the application's About box"))
- connect(aboutAct, SIGNAL("triggered()"), self, SLOT("about()"))
+ aboutAct.triggered.connect(about)
aboutQtAct = QAction(tr("About &Qt"), self)
aboutQtAct.setStatusTip(tr("Show the Qt library's About box"))
- connect(aboutQtAct, SIGNAL("triggered()"), qApp, SLOT("aboutQt()"))
- connect(aboutQtAct, SIGNAL("triggered()"), self, SLOT("aboutQt()"))
+ aboutQtAct.triggered.connect(qApp.aboutQt)
+ aboutQtAct.triggered.connect(aboutQt)
leftAlignAct = QAction(tr("&Left Align"), self)
leftAlignAct.setCheckable(True)
leftAlignAct.setShortcut(tr("Ctrl+L"))
leftAlignAct.setStatusTip(tr("Left align the selected text"))
- connect(leftAlignAct, SIGNAL("triggered()"), self, SLOT("leftAlign()"))
+ leftAlignAct.triggered.connect(leftAlign)
rightAlignAct = QAction(tr("&Right Align"), self)
rightAlignAct.setCheckable(True)
rightAlignAct.setShortcut(tr("Ctrl+R"))
rightAlignAct.setStatusTip(tr("Right align the selected text"))
- connect(rightAlignAct, SIGNAL("triggered()"), self, SLOT("rightAlign()"))
+ rightAlignAct.triggered.connect(rightAlign)
justifyAct = QAction(tr("&Justify"), self)
justifyAct.setCheckable(True)
justifyAct.setShortcut(tr("Ctrl+J"))
justifyAct.setStatusTip(tr("Justify the selected text"))
- connect(justifyAct, SIGNAL("triggered()"), self, SLOT("justify()"))
+ justifyAct.triggered.connect(justify)
centerAct = QAction(tr("&Center"), self)
centerAct.setCheckable(True)
centerAct.setShortcut(tr("Ctrl+E"))
centerAct.setStatusTip(tr("Center the selected text"))
- connect(centerAct, SIGNAL("triggered()"), self, SLOT("center()"))
+ centerAct.triggered.connect(center)
//! [6] //! [7]
alignmentGroup = QActionGroup(self)
diff --git a/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.cpp b/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.py
index 7eace108a..40fe28bf1 100644
--- a/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.cpp
+++ b/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.py
@@ -147,8 +147,7 @@ def createDateTimeEdits(self):
formatComboBox.addItem("hh:mm ap")
//! [9] //! [10]
- connect(formatComboBox, SIGNAL("activated(const QString &)"),
- self, SLOT("setFormatString(const QString &)"))
+ formatComboBox.activated[str].connect(setFormatString)
//! [10]
setFormatString(formatComboBox.currentText())
@@ -174,12 +173,12 @@ def setFormatString(self, formatString):
meetingEdit.setDateRange(QDate(2004, 11, 1), QDate(2005, 11, 30))
meetingLabel.setText(tr("Meeting date (between %0 and %1):")
.arg(meetingEdit.minimumDate().toString(Qt.ISODate))
- .arg(meetingEdit.maximumDate().toString(Qt.ISODate)))
+ .arg(meetingEdit.maximumDate().toString(Qt.ISODate)))
else:
meetingEdit.setTimeRange(QTime(0, 7, 20, 0), QTime(21, 0, 0, 0))
meetingLabel.setText(tr("Meeting time (between %0 and %1):")
.arg(meetingEdit.minimumTime().toString(Qt.ISODate))
- .arg(meetingEdit.maximumTime().toString(Qt.ISODate)))
+ .arg(meetingEdit.maximumTime().toString(Qt.ISODate)))
//! [13]
//! [14]
@@ -222,9 +221,8 @@ def createDoubleSpinBoxes():
priceSpinBox.setPrefix("$")
priceSpinBox.setValue(99.99)
- connect(precisionSpinBox, SIGNAL("valueChanged(int)"),
+ precisionSpinBox.valueChanged[int].connect(changePrecision)
//! [17]
- self, SLOT("changePrecision(int))")
//! [18]
spinBoxLayout = QVBoxLayout()
diff --git a/sources/pyside2/doc/conf.py.in b/sources/pyside2/doc/conf.py.in
index e197b1ac7..e37abcb24 100644
--- a/sources/pyside2/doc/conf.py.in
+++ b/sources/pyside2/doc/conf.py.in
@@ -31,6 +31,11 @@ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.ifconfig',
'sphinx.ext.graphviz', 'inheritance_diagram', 'pysideinclude',
'sphinx.ext.viewcode']
+output_format='@DOC_OUTPUT_FORMAT@'
+
+def setup(app):
+ app.add_config_value('output_format','qthelp','env')
+
rst_epilog = """
.. |project| replace:: Qt for Python
.. |pymodname| replace:: PySide2
@@ -170,6 +175,10 @@ html_show_sourcelink = False
# Link to the shiboken2 sphinx project to enable linking
# between the two projects.
-intersphinx_mapping = {'shiboken2': ('shiboken2','@CMAKE_BINARY_DIR@/../shiboken2/doc/html/objects.inv')}
+intersphinx_mapping = {'shiboken2': ('shiboken2','@CMAKE_BINARY_DIR@/doc/html/shiboken2/doc/html/objects.inv')}
add_module_names = False
+
+# -- Options for qthelp output ---------------------------------------------------
+qthelp_theme = 'pysidedocs_qthelp'
+
diff --git a/sources/pyside2/doc/extras/QtCore.QEnum.rst b/sources/pyside2/doc/extras/QtCore.QEnum.rst
new file mode 100644
index 000000000..a5a2e31fd
--- /dev/null
+++ b/sources/pyside2/doc/extras/QtCore.QEnum.rst
@@ -0,0 +1,92 @@
+.. currentmodule:: PySide2.QtCore
+.. _QEnum:
+
+QEnum/QFlag
+***********
+
+This class decorator is equivalent to the `Q_ENUM` macro from Qt.
+The decorator is used to register an Enum to the meta-object system,
+which is available via `QObject.staticMetaObject`.
+The enumerator must be in a QObject derived class to be registered.
+
+
+Example
+-------
+
+::
+
+ from enum import Enum, Flag, auto
+
+ from PySide2.QtCore import QEnum, QFlag, QObject
+
+ class Demo(QObject):
+
+ @QEnum
+ class Orientation(Enum):
+ North, East, South, West = range(4)
+
+ class Color(Flag):
+ RED = auto()
+ BLUE = auto()
+ GREEN = auto()
+ WHITE = RED | BLUE | GREEN
+
+ QFlag(Color) # identical to @QFlag usage
+
+
+Caution:
+--------
+
+QEnum registers a Python Enum derived class.
+QFlag treats a variation of the Python Enum, the Flag class.
+
+Please do not confuse that with the Qt QFlags concept. Python does
+not use that concept, it has its own class hierarchy, instead.
+For more details, see the `Python enum documentation <https://docs.python.org/3/library/enum.html>`_.
+
+
+Details about Qt Flags:
+-----------------------
+
+There are some small differences between Qt flags and Python flags.
+In Qt, we have for instance these declarations:
+
+::
+
+ enum QtGui::RenderHint { Antialiasing, TextAntialiasing, SmoothPixmapTransform,
+ HighQualityAntialiasing, NonCosmeticDefaultPen }
+ flags QtGui::RenderHints
+
+The equivalent Python notation would look like this:
+
+::
+
+ @QFlag
+ class RenderHints(enum.Flag)
+ Antialiasing = auto()
+ TextAntialiasing = auto()
+ SmoothPixmapTransform = auto()
+ HighQualityAntialiasing = auto()
+ NonCosmeticDefaultPen = auto()
+
+
+As another example, the Qt::AlignmentFlag flag has 'AlignmentFlag' as the enum
+name, but 'Alignment' as the type name. Non flag enums have the same type and
+enum names.
+
+::
+
+ enum Qt::AlignmentFlag
+ flags Qt::Alignment
+
+The Python way to specify this would be
+
+::
+
+ @QFlag
+ class Alignment(enum.Flag):
+ ...
+
+We are considering to map all builtin enums and flags to Python enums as well
+in a later release.
+
diff --git a/sources/pyside2/doc/extras/QtUiTools.loadUiType.rst b/sources/pyside2/doc/extras/QtUiTools.loadUiType.rst
new file mode 100644
index 000000000..9ca330dea
--- /dev/null
+++ b/sources/pyside2/doc/extras/QtUiTools.loadUiType.rst
@@ -0,0 +1,36 @@
+.. currentmodule:: PySide2.QtUiTools
+.. _loadUiType:
+
+loadUiType
+***********
+
+.. py:function:: loadUiType(uifile: str) -> tuple(object, object)
+
+ :param str uifile: The name of the `.ui` file
+ :return: tuple(object, object)
+
+ This function generates and loads a `.ui` file at runtime, and it returns
+ a `tuple` containing the reference to the Python class, and the base class.
+
+ We recommend not to use this approach as the workflow should be to generate a Python file
+ from the `.ui` file, and then import and load it to use it, but we do understand that
+ there are some corner cases when such functionality is required.
+
+ The internal process relies on `uic` being in the PATH.
+ The `pyside2-uic` wrapper uses a shipped `uic` that is located in the
+ `site-packages/PySide2/uic`, so PATH needs to be updated to use that if there
+ is no `uic` in the system.
+
+ A simple use case is::
+
+ from PySide2.QtUiTools import loadUiType
+
+ generated_class, base_class = loadUiType("themewidget.ui")
+ # the values will be:
+ # (<class '__main__.Ui_ThemeWidgetForm'>, <class 'PySide2.QtWidgets.QWidget'>)
+
+ widget = base_class()
+ form = generated_class()
+ form.setupUi(widget)
+ # form.a_widget_member.a_method_of_member()
+ widget.show()
diff --git a/sources/pyside2/doc/extras/QtUiTools.rst b/sources/pyside2/doc/extras/QtUiTools.rst
index 553224527..598d69dda 100644
--- a/sources/pyside2/doc/extras/QtUiTools.rst
+++ b/sources/pyside2/doc/extras/QtUiTools.rst
@@ -6,4 +6,4 @@ To include the definitions of the module's classes, use the following directive:
::
- import PySide..QtUiTools
+ import PySide.QtUiTools
diff --git a/sources/pyside2/doc/gettingstarted.rst b/sources/pyside2/doc/gettingstarted.rst
index dbe22a806..b8d6f9e45 100644
--- a/sources/pyside2/doc/gettingstarted.rst
+++ b/sources/pyside2/doc/gettingstarted.rst
@@ -63,7 +63,8 @@ Other important options to consider are:
* ``--reuse-build``, to rebuild only the modified files,
* ``--openssl=/path/to/openssl/bin``, to use a different path for OpenSSL,
* ``--standalone``, to copy over the Qt libraries into the final package
- to make it work on other machines.
+ to make it work on other machines,
+ * ``--doc-build-online``, to build documentation using the online template.
Testing the installation
-------------------------
@@ -110,7 +111,32 @@ directory, and run::
make apidoc
-Finally, you will get a ``html`` directory containing all the generated documentation.
+.. note:: The ``apidoc`` make target builds offline documenation in QCH (Qt Creator Help) format
+ by default. You can switch to building for the online use with the ``--doc-build-online``
+ configure option.
+
+Finally, you will get a ``html`` directory containing all the generated documentation. The offline
+help files, ``PySide.qch`` and ``Shiboken.qch``, can be moved to any directory of your choice. You
+can find ``Shiboken.qch`` in the build directory, ``*_build\*_release\shiboken2\doc\html``.
+
+Viewing offline documentation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The offline documentation (QCH) can be viewed using the Qt Creator IDE or Qt Assistant, which is
+a standalone application for viewing QCH files.
+
+To view the QCH using Qt Creator, following the instructions outlined in
+`Using Qt Creator Help Mode <https://doc.qt.io/qtcreator/creator-help.html>`_. If you chose to
+use Qt Assistant instead, use the following command to register the QCH file before launching
+Qt Assistant:
+
+ assistant -register PySide.qch
+
+.. note:: Qt Assistant renders the QCH content using the QTextBrowser backend, which supports
+ a subset of the CSS styles, However, Qt Creator offers an alternative litehtml-based
+ backend, which offers better browsing experience. At the moment, this is not the default
+ backend, so you have to select the litehtml backend
+ explicitly under the ``General`` tab in ``Qt Creator >> Tools >> Options >> Help``.
Using the internal tools
------------------------
diff --git a/sources/pyside2/doc/index.rst b/sources/pyside2/doc/index.rst
index 96cbf2ab2..72a26d19d 100644
--- a/sources/pyside2/doc/index.rst
+++ b/sources/pyside2/doc/index.rst
@@ -1,45 +1,84 @@
|project|
*********
-**Qt for Python** offers the official Python bindings for `Qt`_ (`PySide2`_),
-so that you can use Qt5 APIs in your Python applications, and a binding generator tool (`Shiboken2`_)
-which can be used to expose C++ projects into Python.
+.. ifconfig:: output_format == 'html'
+
+ **Qt for Python** offers the official Python bindings for `Qt`_ (`PySide2`_),
+ so that you can use Qt5 APIs in your Python applications, and a binding generator tool
+ (`Shiboken2 <shiboken2/index.html>`_) which can be used to expose C++ projects into Python.
+
+.. ifconfig:: output_format == 'qthelp'
+
+ **Qt for Python** offers the official Python bindings for `Qt`_ (`PySide2`_),
+ so that you can use Qt5 APIs in your Python applications, and a binding generator tool
+ (`Shiboken2 <../shiboken2/index.html>`_) which can be used to expose C++ projects into Python.
|project| is available under the LGPLv3/GPLv3 and the Qt commercial license.
.. _Qt: https://doc.qt.io
.. _PySide2: quickstart.html
-.. _Shiboken2: shiboken2/index.html
+
Documentation
=============
-.. raw:: html
-
- <table class="special">
- <colgroup>
- <col style="width: 33%" />
- <col style="width: 33%" />
- <col style="width: 33%" />
- </colgroup>
- <tr>
- <td><a href="quickstart.html"><p><strong>Check It Out!</strong><br/>Write your first Qt app.</p></a></td>
- <td><a href="gettingstarted.html"><p><strong>Getting Started</strong><br/>Install and build from source.</p></a></td>
- <td><a href="api.html"><p><strong>API Docs</strong><br/>Qt for Python API reference.</p></a></td>
- </tr>
-
- <tr>
- <td><a href="tutorials/index.html"><p><strong>Tutorials</strong><br/>Learn with step-by-step guides.</p></a></td>
- <td><a href="examples/index.html"><p><strong>Examples</strong><br/>Check all the available examples.</p></a></td>
- <td><a href="videos.html"><p><strong>Videos</strong><br/>Watch webinars, Talks, and more.</p></a></td>
- </tr>
-
- <tr>
- <td><a href="deployment.html" style="display: block;"><p><strong>Deployment</strong><br/>Learn to deploy your apps.</p></a></td>
- <td><a href="considerations.html" style="display: block;"><p><strong>Considerations</strong><br/>API differences and known issues.</p></a></td>
- <td><a href="shiboken2/index.html" style="display: block;"><p><strong>Shiboken</strong><br/>Generate C++ to Python binding.</p></a></td>
- </tr>
- </table>
+.. ifconfig:: output_format == 'html'
+
+ .. raw:: html
+
+ <table class="special">
+ <colgroup>
+ <col style="width: 33%" />
+ <col style="width: 33%" />
+ <col style="width: 33%" />
+ </colgroup>
+ <tr>
+ <td><a href="quickstart.html"><p><strong>Check It Out!</strong><br/>Write your first Qt app.</p></a></td>
+ <td><a href="gettingstarted.html"><p><strong>Getting Started</strong><br/>Install and build from source.</p></a></td>
+ <td><a href="api.html"><p><strong>API Docs</strong><br/>Qt for Python API reference.</p></a></td>
+ </tr>
+
+ <tr>
+ <td><a href="tutorials/index.html"><p><strong>Tutorials</strong><br/>Learn with step-by-step guides.</p></a></td>
+ <td><a href="examples/index.html"><p><strong>Examples</strong><br/>Check all the available examples.</p></a></td>
+ <td><a href="videos.html"><p><strong>Videos</strong><br/>Watch webinars, Talks, and more.</p></a></td>
+ </tr>
+
+ <tr>
+ <td><a href="deployment.html" style="display: block;"><p><strong>Deployment</strong><br/>Learn to deploy your apps.</p></a></td>
+ <td><a href="considerations.html" style="display: block;"><p><strong>Considerations</strong><br/>API differences and known issues.</p></a></td>
+ <td><a href="shiboken2/index.html" style="display: block;"><p><strong>Shiboken</strong><br/>Generate C++ to Python binding.</p></a></td>
+ </tr>
+ </table>
+
+.. ifconfig :: output_format == 'qthelp'
+
+ .. raw:: html
+
+ <table class="special">
+ <colgroup>
+ <col style="width: 33%" />
+ <col style="width: 33%" />
+ <col style="width: 33%" />
+ </colgroup>
+ <tr>
+ <td><a href="quickstart.html"><p><strong>Check It Out!</strong><br/>Write your first Qt app.</p></a></td>
+ <td><a href="gettingstarted.html"><p><strong>Getting Started</strong><br/>Install and build from source.</p></a></td>
+ <td><a href="api.html"><p><strong>API Docs</strong><br/>Qt for Python API reference.</p></a></td>
+ </tr>
+
+ <tr>
+ <td><a href="tutorials/index.html"><p><strong>Tutorials</strong><br/>Learn with step-by-step guides.</p></a></td>
+ <td><a href="examples/index.html"><p><strong>Examples</strong><br/>Check all the available examples.</p></a></td>
+ <td><a href="videos.html"><p><strong>Videos</strong><br/>Watch webinars, Talks, and more.</p></a></td>
+ </tr>
+
+ <tr>
+ <td><a href="deployment.html" style="display: block;"><p><strong>Deployment</strong><br/>Learn to deploy your apps.</p></a></td>
+ <td><a href="considerations.html" style="display: block;"><p><strong>Considerations</strong><br/>API differences and known issues.</p></a></td>
+ <td><a href="../shiboken2/index.html" style="display: block;"><p><strong>Shiboken</strong><br/>Generate C++ to Python binding.</p></a></td>
+ </tr>
+ </table>
.. toctree::
:hidden:
diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons.png b/sources/pyside2/doc/tutorials/basictutorial/icons.png
new file mode 100644
index 000000000..0bcfd7d77
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/icons.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/forward.png b/sources/pyside2/doc/tutorials/basictutorial/icons/forward.png
new file mode 100644
index 000000000..c7a532dfe
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/icons/forward.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/pause.png b/sources/pyside2/doc/tutorials/basictutorial/icons/pause.png
new file mode 100644
index 000000000..d0beadb43
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/icons/pause.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/play.png b/sources/pyside2/doc/tutorials/basictutorial/icons/play.png
new file mode 100644
index 000000000..345685337
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/icons/play.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/previous.png b/sources/pyside2/doc/tutorials/basictutorial/icons/previous.png
new file mode 100644
index 000000000..979f18565
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/icons/previous.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/stop.png b/sources/pyside2/doc/tutorials/basictutorial/icons/stop.png
new file mode 100644
index 000000000..1e88ded3a
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/icons/stop.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/basictutorial/player-new.png b/sources/pyside2/doc/tutorials/basictutorial/player-new.png
new file mode 100644
index 000000000..e1f660e5f
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/player-new.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/basictutorial/player.png b/sources/pyside2/doc/tutorials/basictutorial/player.png
new file mode 100644
index 000000000..3060a990d
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/player.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/basictutorial/qrcfiles.rst b/sources/pyside2/doc/tutorials/basictutorial/qrcfiles.rst
new file mode 100644
index 000000000..2f986875c
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/qrcfiles.rst
@@ -0,0 +1,169 @@
+Using `.qrc` Files (`pyside2-rcc`)
+**********************************
+
+The `Qt Resource System`_ is a mechanism for storing binary files
+in an application.
+
+The most common uses are for custom images, icons, fonts, among others.
+
+In this tutorial you will learn how to load custom images as button icons.
+
+For inspiration, we will try to adapt the multimedia player example
+from Qt.
+
+As you can see on the following image, the `QPushButton` that are used
+for the media actions (play, pause, stop, and so on) are using the
+default icons meant for such actions.
+
+.. image:: player.png
+ :alt: Multimedia Player Qt Example
+
+You could make the application more attractive by designing the icons,
+but in case you don't want to design them, `download the following set`_
+and use them.
+
+.. image:: icons.png
+ :alt: New Multimedia icons
+
+You can find more information about the `rcc` command, and `.qrc` file
+format, and the resource system in general in the `Qt Resource System`_
+site.
+
+.. _`download the following set`: icons/
+
+
+The `.qrc` file
+================
+
+Before running any command, add information about the resources to a `.qrc`
+file.
+In the following example, notice how the resources are listed in `icons.qrc`
+
+::
+
+ </ui>
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource>
+ <file>icons/play.png</file>
+ <file>icons/pause.png</file>
+ <file>icons/stop.png</file>
+ <file>icons/previous.png</file>
+ <file>icons/forward.png</file>
+ </qresource>
+ </RCC>
+
+
+Generating a Python file
+=========================
+
+Now that the `icons.qrc` file is ready, use the `pyside2-rcc` tool to generate
+a Python class containing the binary information about the resources
+
+To do this, we need to run::
+
+ pyside2-rcc icons.rc -o rc_icons.py
+
+The `-o` option lets you specify the output filename,
+which is `rc_icons.py` in this case.
+
+To use the generated file, add the following import at the top of your main Python file::
+
+ import rc_icons
+
+
+Changes in the code
+===================
+
+As you are modifying an existing example, you need to modify the following
+lines:
+
+.. code-block:: python
+
+ from PySide2.QtGui import QIcon, QKeySequence
+ playIcon = self.style().standardIcon(QStyle.SP_MediaPlay)
+ previousIcon = self.style().standardIcon(QStyle.SP_MediaSkipBackward)
+ pauseIcon = self.style().standardIcon(QStyle.SP_MediaPause)
+ nextIcon = self.style().standardIcon(QStyle.SP_MediaSkipForward)
+ stopIcon = self.style().standardIcon(QStyle.SP_MediaStop)
+
+and replace them with the following:
+
+.. code-block:: python
+
+ from PySide2.QtGui import QIcon, QKeySequence, QPixmap
+ playIcon = QIcon(QPixmap(":/icons/play.png"))
+ previousIcon = QIcon(QPixmap(":/icons/previous.png"))
+ pauseIcon = QIcon(QPixmap(":/icons/pause.png"))
+ nextIcon = QIcon(QPixmap(":/icons/forward.png"))
+ stopIcon = QIcon(QPixmap(":/icons/stop.png"))
+
+This ensures that the new icons are used instead of the default ones provided
+by the application theme.
+Notice that the lines are not consecutive, but are in different parts
+of the file.
+
+After all your imports, add the following
+
+.. code-block:: python
+
+ import rc_icons
+
+Now, the constructor of your class should look like this:
+
+.. code-block:: python
+
+ def __init__(self):
+ super(MainWindow, self).__init__()
+
+ self.playlist = QMediaPlaylist()
+ self.player = QMediaPlayer()
+
+ toolBar = QToolBar()
+ self.addToolBar(toolBar)
+
+ fileMenu = self.menuBar().addMenu("&File")
+ openAction = QAction(QIcon.fromTheme("document-open"),
+ "&Open...", self, shortcut=QKeySequence.Open,
+ triggered=self.open)
+ fileMenu.addAction(openAction)
+ exitAction = QAction(QIcon.fromTheme("application-exit"), "E&xit",
+ self, shortcut="Ctrl+Q", triggered=self.close)
+ fileMenu.addAction(exitAction)
+
+ playMenu = self.menuBar().addMenu("&Play")
+ playIcon = QIcon(QPixmap(":/icons/play.png"))
+ self.playAction = toolBar.addAction(playIcon, "Play")
+ self.playAction.triggered.connect(self.player.play)
+ playMenu.addAction(self.playAction)
+
+ previousIcon = QIcon(QPixmap(":/icons/previous.png"))
+ self.previousAction = toolBar.addAction(previousIcon, "Previous")
+ self.previousAction.triggered.connect(self.previousClicked)
+ playMenu.addAction(self.previousAction)
+
+ pauseIcon = QIcon(QPixmap(":/icons/pause.png"))
+ self.pauseAction = toolBar.addAction(pauseIcon, "Pause")
+ self.pauseAction.triggered.connect(self.player.pause)
+ playMenu.addAction(self.pauseAction)
+
+ nextIcon = QIcon(QPixmap(":/icons/forward.png"))
+ self.nextAction = toolBar.addAction(nextIcon, "Next")
+ self.nextAction.triggered.connect(self.playlist.next)
+ playMenu.addAction(self.nextAction)
+
+ stopIcon = QIcon(QPixmap(":/icons/stop.png"))
+ self.stopAction = toolBar.addAction(stopIcon, "Stop")
+ self.stopAction.triggered.connect(self.player.stop)
+ playMenu.addAction(self.stopAction)
+
+ # many lines were omitted
+
+Executing the example
+=====================
+
+Run the application by calling `python main.py` to checkout the new icon-set:
+
+.. image:: player-new.png
+ :alt: New Multimedia Player Qt Example
+
+.. _`Qt Resource System`: https://doc.qt.io/qt-5/resources.html
diff --git a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
index 2c0178e2e..804905eb8 100644
--- a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
+++ b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
@@ -1,5 +1,5 @@
-Using UI Files
-***************
+Using `.ui` Files (`QUiLoader` and `pyside2-uic`)
+*************************************************
This page describes the use of Qt Creator to create graphical
interfaces for your Qt for Python project.
@@ -158,7 +158,7 @@ The complete code of this example looks like this:
import sys
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication
- from PySide2.QtCore import QFile
+ from PySide2.QtCore import QFile, QIODevice
if __name__ == "__main__":
app = QApplication(sys.argv)
diff --git a/sources/pyside2/doc/tutorials/expenses/expenses.rst b/sources/pyside2/doc/tutorials/expenses/expenses.rst
index f643ec299..640feb487 100644
--- a/sources/pyside2/doc/tutorials/expenses/expenses.rst
+++ b/sources/pyside2/doc/tutorials/expenses/expenses.rst
@@ -3,12 +3,12 @@ Expenses Tool Tutorial
######################
In this tutorial you will learn the following concepts:
-* creating user interfaces programatically,
-* layouts and widgets,
-* overloading Qt classes,
-* connecting signal and slots,
-* interacting with QWidgets,
-* and building your own application.
+ * creating user interfaces programatically,
+ * layouts and widgets,
+ * overloading Qt classes,
+ * connecting signal and slots,
+ * interacting with QWidgets,
+ * and building your own application.
The requirements:
* A simple window for the application
diff --git a/sources/pyside2/doc/tutorials/index.rst b/sources/pyside2/doc/tutorials/index.rst
index 73e6b6b26..598b42ca1 100644
--- a/sources/pyside2/doc/tutorials/index.rst
+++ b/sources/pyside2/doc/tutorials/index.rst
@@ -18,6 +18,7 @@ Basic tutorials
basictutorial/clickablebutton.rst
basictutorial/dialog.rst
basictutorial/uifiles.rst
+ basictutorial/qrcfiles.rst
Real use-cases applications
---------------------------
diff --git a/sources/pyside2/doc/videos.rst b/sources/pyside2/doc/videos.rst
index cda84f419..511bc0d66 100644
--- a/sources/pyside2/doc/videos.rst
+++ b/sources/pyside2/doc/videos.rst
@@ -15,7 +15,7 @@ Webinar: Creating user interfaces with Qt for Python
</div>
Webinar: Develop your first Qt for Python application
-------------------------------------------------------
+-----------------------------------------------------
.. raw:: html
@@ -26,3 +26,68 @@ Webinar: Develop your first Qt for Python application
width: 100%; height: 100%;">
</iframe>
</div>
+
+Webinar: Python and C++ interoperability with Shiboken
+------------------------------------------------------
+
+.. raw:: html
+
+ <div style="position: relative; padding-bottom: 56.25%; height: 0;
+ overflow: hidden; max-width: 100%; height: auto;">
+ <iframe src="https://www.youtube.com/embed/wOMlDutOWXI" frameborder="0"
+ allowfullscreen style="position: absolute; top: 0; left: 0;
+ width: 100%; height: 100%;">
+ </iframe>
+ </div>
+
+QtWS2018: Mastering Qt for Python in 20 min
+--------------------------------------------
+
+.. raw:: html
+
+ <div style="position: relative; padding-bottom: 56.25%; height: 0;
+ overflow: hidden; max-width: 100%; height: auto;">
+ <iframe src="https://www.youtube.com/embed/IhxZ99usPqY" frameborder="0"
+ allowfullscreen style="position: absolute; top: 0; left: 0;
+ width: 100%; height: 100%;">
+ </iframe>
+ </div>
+
+QtWS2019: Utilizing Shiboken to Enhance your Qt for Python Application
+----------------------------------------------------------------------
+
+.. raw:: html
+
+ <div style="position: relative; padding-bottom: 56.25%; height: 0;
+ overflow: hidden; max-width: 100%; height: auto;">
+ <iframe src="https://www.youtube.com/embed/mAfEVPgHRt8" frameborder="0"
+ allowfullscreen style="position: absolute; top: 0; left: 0;
+ width: 100%; height: 100%;">
+ </iframe>
+ </div>
+
+QtWS2019: Introduction to Qt for Python
+---------------------------------------
+
+.. raw:: html
+
+ <div style="position: relative; padding-bottom: 56.25%; height: 0;
+ overflow: hidden; max-width: 100%; height: auto;">
+ <iframe src="https://www.youtube.com/embed/214TWASZVgA" frameborder="0"
+ allowfullscreen style="position: absolute; top: 0; left: 0;
+ width: 100%; height: 100%;">
+ </iframe>
+ </div>
+
+QtWS2019: How to bring your C++ project to Python land
+------------------------------------------------------
+
+.. raw:: html
+
+ <div style="position: relative; padding-bottom: 56.25%; height: 0;
+ overflow: hidden; max-width: 100%; height: auto;">
+ <iframe src="https://www.youtube.com/embed/XmY-tWTi9gY" frameborder="0"
+ allowfullscreen style="position: absolute; top: 0; left: 0;
+ width: 100%; height: 100%;">
+ </iframe>
+ </div>
diff --git a/sources/pyside2/libpyside/CMakeLists.txt b/sources/pyside2/libpyside/CMakeLists.txt
index 7493a453a..31f68749a 100644
--- a/sources/pyside2/libpyside/CMakeLists.txt
+++ b/sources/pyside2/libpyside/CMakeLists.txt
@@ -1,33 +1,33 @@
project(libpyside)
-if(${Qt5Qml_FOUND})
- if(NOT "${Qt5Qml_PRIVATE_INCLUDE_DIRS}" MATCHES "/QtQml/")
- string(REPLACE "/QtCore" "/QtQml" replaceme "${Qt5Core_PRIVATE_INCLUDE_DIRS}")
- list(APPEND Qt5Qml_PRIVATE_INCLUDE_DIRS ${replaceme})
- list(REMOVE_DUPLICATES Qt5Qml_PRIVATE_INCLUDE_DIRS)
+if(${Qt${QT_MAJOR_VERSION}Qml_FOUND})
+ if(NOT "${Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS}" MATCHES "/QtQml/")
+ string(REPLACE "/QtCore" "/QtQml" replaceme "${Qt${QT_MAJOR_VERSION}Core_PRIVATE_INCLUDE_DIRS}")
+ list(APPEND Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS ${replaceme})
+ list(REMOVE_DUPLICATES Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS)
endif()
endif()
-if(${Qt5Quick_FOUND})
- if(NOT "${Qt5Quick_PRIVATE_INCLUDE_DIRS}" MATCHES "/QtQuick/")
- string(REPLACE "/QtCore" "/QtQuick" replaceme "${Qt5Core_PRIVATE_INCLUDE_DIRS}")
- list(APPEND Qt5Quick_PRIVATE_INCLUDE_DIRS ${Qt5Qml_PRIVATE_INCLUDE_DIRS})
- list(APPEND Qt5Quick_PRIVATE_INCLUDE_DIRS ${replaceme})
- list(REMOVE_DUPLICATES Qt5Quick_PRIVATE_INCLUDE_DIRS)
+if(${Qt${QT_MAJOR_VERSION}Quick_FOUND})
+ if(NOT "${Qt${QT_MAJOR_VERSION}Quick_PRIVATE_INCLUDE_DIRS}" MATCHES "/QtQuick/")
+ string(REPLACE "/QtCore" "/QtQuick" replaceme "${Qt${QT_MAJOR_VERSION}Core_PRIVATE_INCLUDE_DIRS}")
+ list(APPEND Qt${QT_MAJOR_VERSION}Quick_PRIVATE_INCLUDE_DIRS ${Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS})
+ list(APPEND Qt${QT_MAJOR_VERSION}Quick_PRIVATE_INCLUDE_DIRS ${replaceme})
+ list(REMOVE_DUPLICATES Qt${QT_MAJOR_VERSION}Quick_PRIVATE_INCLUDE_DIRS)
endif()
endif()
set(QML_PRIVATE_API_SUPPORT 0)
-if(Qt5Qml_FOUND)
+if(Qt${QT_MAJOR_VERSION}Qml_FOUND)
# Used for registering custom QQuickItem classes defined in Python code.
set(QML_SUPPORT 1)
- set(QML_INCLUDES ${Qt5Qml_INCLUDE_DIRS})
- set(QML_LIBRARIES ${Qt5Qml_LIBRARIES})
+ set(QML_INCLUDES ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS})
+ set(QML_LIBRARIES ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES})
- if(Qt5Qml_PRIVATE_INCLUDE_DIRS)
+ if(Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS)
# Used for transforming QML exceptions into Python exceptions.
set(QML_PRIVATE_API_SUPPORT 1)
- set(QML_INCLUDES ${QML_INCLUDES} ${Qt5Qml_PRIVATE_INCLUDE_DIRS})
+ set(QML_INCLUDES ${QML_INCLUDES} ${Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS})
else()
message(WARNING "QML private API include files could not be found, support for catching QML exceptions inside Python code will not work.")
endif()
@@ -38,14 +38,12 @@ else()
set(QML_LIBRARIES "")
endif()
-qt5_wrap_cpp(DESTROYLISTENER_MOC "destroylistener.h")
-
set(libpyside_SRC
dynamicqmetaobject.cpp
- destroylistener.cpp
signalmanager.cpp
globalreceiverv2.cpp
pysideclassinfo.cpp
+ pysideqenum.cpp
pysidemetafunction.cpp
pysidesignal.cpp
pysideslot.cpp
@@ -54,7 +52,6 @@ set(libpyside_SRC
pysideweakref.cpp
pyside.cpp
pysidestaticstrings.cpp
- ${DESTROYLISTENER_MOC}
)
# Add python files to project explorer in Qt Creator, when opening the CMakeLists.txt as a project,
@@ -84,8 +81,8 @@ add_library(PySide2::pyside2 ALIAS pyside2)
target_include_directories(pyside2 PRIVATE
${QML_INCLUDES}
- ${Qt5Core_PRIVATE_INCLUDE_DIRS}
- ${Qt5Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_PRIVATE_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
)
target_include_directories(pyside2 PUBLIC
@@ -96,7 +93,7 @@ target_include_directories(pyside2 PUBLIC
target_link_libraries(pyside2
PRIVATE Shiboken2::libshiboken
PRIVATE ${QML_LIBRARIES}
- PRIVATE ${Qt5Core_LIBRARIES})
+ PRIVATE ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES})
set_target_properties(pyside2 PROPERTIES
VERSION ${BINDING_API_VERSION}
@@ -104,7 +101,9 @@ set_target_properties(pyside2 PROPERTIES
OUTPUT_NAME "pyside2${pyside2_SUFFIX}${SHIBOKEN_PYTHON_SHARED_LIBRARY_SUFFIX}"
DEFINE_SYMBOL PYSIDE_EXPORTS)
-if(Qt5Core_VERSION VERSION_GREATER "5.7.1")
+if(${QT_MAJOR_VERSION} GREATER_EQUAL 6)
+ set_property(TARGET pyside2 PROPERTY CXX_STANDARD 17)
+else()
set_property(TARGET pyside2 PROPERTY CXX_STANDARD 11)
endif()
@@ -125,9 +124,9 @@ endif()
#
set(libpyside_HEADERS
- destroylistener.h
dynamicqmetaobject.h
pysideclassinfo.h
+ pysideqenum.h
pysidemacros.h
signalmanager.h
pyside.h
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject.cpp b/sources/pyside2/libpyside/dynamicqmetaobject.cpp
index dae9e2059..efdf33ac9 100644
--- a/sources/pyside2/libpyside/dynamicqmetaobject.cpp
+++ b/sources/pyside2/libpyside/dynamicqmetaobject.cpp
@@ -44,6 +44,7 @@
#include "pysideproperty.h"
#include "pysideproperty_p.h"
#include "pysideslot_p.h"
+#include "pysideqenum.h"
#include <shiboken.h>
@@ -91,6 +92,10 @@ public:
int addProperty(const QByteArray &property, PyObject *data);
void addInfo(const QByteArray &key, const QByteArray &value);
void addInfo(const QMap<QByteArray, QByteArray> &info);
+ void addEnumerator(const char *name,
+ bool flag,
+ bool scoped,
+ const QVector<QPair<QByteArray, int> > &entries);
void removeProperty(int index);
const QMetaObject *update();
@@ -357,6 +362,28 @@ void MetaObjectBuilder::addInfo(const QMap<QByteArray, QByteArray> &info)
m_d->addInfo(info);
}
+void MetaObjectBuilder::addEnumerator(const char *name, bool flag, bool scoped,
+ const QVector<QPair<QByteArray, int> > &entries)
+{
+ m_d->addEnumerator(name, flag, scoped, entries);
+}
+
+void MetaObjectBuilderPrivate::addEnumerator(const char *name, bool flag, bool scoped,
+ const QVector<QPair<QByteArray, int> > &entries)
+{
+ auto builder = ensureBuilder();
+ int have_already = builder->indexOfEnumerator(name);
+ if (have_already >= 0)
+ builder->removeEnumerator(have_already);
+ auto enumbuilder = builder->addEnumerator(name);
+ enumbuilder.setIsFlag(flag);
+ enumbuilder.setIsScoped(scoped);
+
+ for (auto item : entries)
+ enumbuilder.addKey(item.first, item.second);
+ m_dirty = true;
+}
+
void MetaObjectBuilderPrivate::removeProperty(int index)
{
index -= m_baseObject->propertyCount();
@@ -430,6 +457,8 @@ const QMetaObject *MetaObjectBuilder::update()
return m_d->update();
}
+using namespace Shiboken;
+
void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
{
// Get all non-QObject-derived base types in method resolution order, filtering out the types
@@ -439,7 +468,7 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
// existing connections.
const PyObject *mro = type->tp_mro;
const Py_ssize_t basesCount = PyTuple_GET_SIZE(mro);
- PyTypeObject *qObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
+ PyTypeObject *qObjectType = Conversions::getPythonTypeObject("QObject*");
std::vector<PyTypeObject *> basesToCheck;
// Prepend the actual type that we are parsing.
@@ -470,7 +499,7 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
// Register signals.
auto data = reinterpret_cast<PySideSignal *>(value);
if (data->data->signalName.isEmpty())
- data->data->signalName = Shiboken::String::toCString(key);
+ data->data->signalName = String::toCString(key);
for (const auto &s : data->data->signatures) {
const auto sig = data->data->signalName + '(' + s.signature + ')';
if (m_baseObject->indexOfSignal(sig) == -1) {
@@ -489,7 +518,7 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
}
}
- Shiboken::AutoDecRef slotAttrName(Shiboken::String::fromCString(PYSIDE_SLOT_LIST_ATTR));
+ AutoDecRef slotAttrName(String::fromCString(PYSIDE_SLOT_LIST_ATTR));
// PYSIDE-315: Now take care of the rest.
// Signals and slots should be separated, unless the types are modified, later.
// We check for this using "is_sorted()". Sorting no longer happens at all.
@@ -501,16 +530,16 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
while (PyDict_Next(attrs, &pos, &key, &value)) {
if (Property::checkType(value)) {
- const int index = m_baseObject->indexOfProperty(Shiboken::String::toCString(key));
+ const int index = m_baseObject->indexOfProperty(String::toCString(key));
if (index == -1)
- addProperty(Shiboken::String::toCString(key), value);
+ addProperty(String::toCString(key), value);
} else if (PyFunction_Check(value)) {
// Register slots.
if (PyObject_HasAttr(value, slotAttrName)) {
PyObject *signatureList = PyObject_GetAttr(value, slotAttrName);
for (Py_ssize_t i = 0, i_max = PyList_Size(signatureList); i < i_max; ++i) {
PyObject *pySignature = PyList_GET_ITEM(signatureList, i);
- QByteArray signature(Shiboken::String::toCString(pySignature));
+ QByteArray signature(String::toCString(pySignature));
// Split the slot type and its signature.
QByteArray type;
const int spacePos = signature.indexOf(' ');
@@ -530,4 +559,29 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
}
}
}
+ // PYSIDE-957: Collect the delayed QEnums
+ auto collectedEnums = PySide::QEnum::resolveDelayedQEnums(type);
+ for (PyObject *obEnumType : collectedEnums) {
+ bool isFlag = PySide::QEnum::isFlag(obEnumType);
+ AutoDecRef obName(PyObject_GetAttr(obEnumType, PyMagicName::name()));
+ // Everything has been checked already in resolveDelayedQEnums.
+ // Therefore, we don't need to error-check here again.
+ auto name = String::toCString(obName);
+ AutoDecRef members(PyObject_GetAttr(obEnumType, PyMagicName::members()));
+ AutoDecRef items(PepMapping_Items(members));
+ Py_ssize_t nr_items = PySequence_Length(items);
+
+ QVector<QPair<QByteArray, int> > entries;
+ for (Py_ssize_t idx = 0; idx < nr_items; ++idx) {
+ AutoDecRef item(PySequence_GetItem(items, idx));
+ AutoDecRef key(PySequence_GetItem(item, 0));
+ AutoDecRef member(PySequence_GetItem(item, 1));
+ AutoDecRef value(PyObject_GetAttr(member, Shiboken::PyName::value()));
+ auto ckey = String::toCString(key);
+ auto ivalue = PyInt_AsSsize_t(value); // int/long cheating
+ auto thing = QPair<QByteArray, int>(ckey, int(ivalue));
+ entries.push_back(thing);
+ }
+ addEnumerator(name, isFlag, true, entries);
+ }
}
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject.h b/sources/pyside2/libpyside/dynamicqmetaobject.h
index 1fbe73ea4..7279d5c26 100644
--- a/sources/pyside2/libpyside/dynamicqmetaobject.h
+++ b/sources/pyside2/libpyside/dynamicqmetaobject.h
@@ -68,7 +68,10 @@ public:
int addProperty(const char *property, PyObject *data);
void addInfo(const char *key, const char *value);
void addInfo(const QMap<QByteArray, QByteArray> &info);
-
+ void addEnumerator(const char *name,
+ bool flag,
+ bool scoped,
+ const QVector<QPair<QByteArray, int> > &entries);
void removeProperty(int index);
const QMetaObject *update();
diff --git a/sources/pyside2/libpyside/pyside.cpp b/sources/pyside2/libpyside/pyside.cpp
index e2b8708ce..66e931164 100644
--- a/sources/pyside2/libpyside/pyside.cpp
+++ b/sources/pyside2/libpyside/pyside.cpp
@@ -50,7 +50,6 @@
#include "pysidemetafunction_p.h"
#include "pysidemetafunction.h"
#include "dynamicqmetaobject.h"
-#include "destroylistener.h"
#include <autodecref.h>
#include <basewrapper.h>
@@ -166,12 +165,10 @@ void registerCleanupFunction(CleanupFunction func)
void runCleanupFunctions()
{
- //PySide::DestroyListener::instance()->destroy();
while (!cleanupFunctionList.isEmpty()) {
CleanupFunction f = cleanupFunctionList.pop();
f();
}
- PySide::DestroyListener::destroy();
}
static void destructionVisitor(SbkObject *pyObj, void *data)
@@ -226,8 +223,7 @@ std::size_t getSizeOfQObject(SbkObjectType *type)
void initDynamicMetaObject(SbkObjectType *type, const QMetaObject *base, std::size_t cppObjSize)
{
//create DynamicMetaObject based on python type
- auto userData =
- new TypeUserData(reinterpret_cast<PyTypeObject *>(type), base, cppObjSize);
+ auto userData = new TypeUserData(reinterpret_cast<PyTypeObject *>(type), base, cppObjSize);
userData->mo.update();
Shiboken::ObjectType::setTypeUserData(type, userData, Shiboken::callCppDestructor<TypeUserData>);
@@ -271,11 +267,6 @@ const QMetaObject *retrieveMetaObject(PyObject *pyObj)
return retrieveMetaObject(pyTypeObj);
}
-void initDynamicMetaObject(SbkObjectType *type, const QMetaObject *base)
-{
- initDynamicMetaObject(type, base, 0);
-}
-
void initQObjectSubType(SbkObjectType *type, PyObject *args, PyObject * /* kwds */)
{
PyTypeObject *qObjType = Shiboken::Conversions::getPythonTypeObject("QObject*");
diff --git a/sources/pyside2/libpyside/pyside.h b/sources/pyside2/libpyside/pyside.h
index ae400e1fe..95abaeeb1 100644
--- a/sources/pyside2/libpyside/pyside.h
+++ b/sources/pyside2/libpyside/pyside.h
@@ -99,7 +99,6 @@ template<typename T>
struct initQtMetaType<T, false> {
};
-PYSIDE_DEPRECATED(PYSIDE_API void initDynamicMetaObject(SbkObjectType *type, const QMetaObject *base));
PYSIDE_API void initDynamicMetaObject(SbkObjectType *type, const QMetaObject *base,
std::size_t cppObjSize);
PYSIDE_API void initQObjectSubType(SbkObjectType *type, PyObject *args, PyObject *kwds);
diff --git a/sources/pyside2/libpyside/pysideproperty.cpp b/sources/pyside2/libpyside/pysideproperty.cpp
index 77dc6f3fc..e9548dc22 100644
--- a/sources/pyside2/libpyside/pysideproperty.cpp
+++ b/sources/pyside2/libpyside/pysideproperty.cpp
@@ -377,11 +377,6 @@ bool checkType(PyObject *pyObj)
return false;
}
-bool isPropertyType(PyObject *pyObj)
-{
- return checkType(pyObj);
-}
-
int setValue(PySideProperty *self, PyObject *source, PyObject *value)
{
PyObject *fset = self->d->fset;
diff --git a/sources/pyside2/libpyside/pysideproperty.h b/sources/pyside2/libpyside/pysideproperty.h
index 0ea5e84d6..a97b2a48f 100644
--- a/sources/pyside2/libpyside/pysideproperty.h
+++ b/sources/pyside2/libpyside/pysideproperty.h
@@ -64,9 +64,6 @@ typedef void (*MetaCallHandler)(PySideProperty*,PyObject*,QMetaObject::Call, voi
PYSIDE_API bool checkType(PyObject* pyObj);
-/// @deprecated Use checkType
-PYSIDE_DEPRECATED(PYSIDE_API bool isPropertyType(PyObject* pyObj));
-
/**
* This function call set property function and pass value as arg
* This function does not check the property object type
diff --git a/sources/pyside2/libpyside/pysideqenum.cpp b/sources/pyside2/libpyside/pysideqenum.cpp
new file mode 100644
index 000000000..f46b5536c
--- /dev/null
+++ b/sources/pyside2/libpyside/pysideqenum.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <shiboken.h>
+
+#include "pysideqenum.h"
+#include "dynamicqmetaobject.h"
+#include "pyside_p.h"
+
+
+///////////////////////////////////////////////////////////////
+//
+// PYSIDE-957: Create QEnum dynamically from Python Enum
+//
+//
+extern "C" {
+
+using namespace Shiboken;
+
+static PyObject *analyzePyEnum(PyObject *pyenum, PyObject *container = nullptr)
+{
+ /*
+ * This is the straight-forward implementation of QEnum/QFlag. It does no
+ * longer create an equivalent Qt enum but takes the Python enum as-is.
+ *
+ * It parses an Enum/Flag derived Python enum completely so that
+ * registering can be done without error checks. This would be impossible
+ * in MetaObjectBuilderPrivate::parsePythonType.
+ */
+ AutoDecRef members(PyObject_GetAttr(pyenum, Shiboken::PyMagicName::members()));
+ if (members.isNull())
+ return nullptr;
+ AutoDecRef items(PepMapping_Items(members));
+ if (items.isNull())
+ return nullptr;
+ int iflag = PySide::QEnum::isFlag(pyenum);
+ if (iflag < 0)
+ return nullptr;
+ Py_ssize_t nr_items = PySequence_Length(items);
+ if (nr_items < 0)
+ return nullptr;
+
+ for (Py_ssize_t idx = 0; idx < nr_items; ++idx) {
+ AutoDecRef item(PySequence_GetItem(items, idx));
+ if (item.isNull())
+ return nullptr;
+
+ // The item should be a 2-element sequence of the key name and an
+ // object containing the value.
+ AutoDecRef key(PySequence_GetItem(item, 0));
+ AutoDecRef member(PySequence_GetItem(item, 1));
+ if (key.isNull() || member.isNull())
+ return nullptr;
+ if (!Shiboken::String::check(key)) {
+ // '%.200s' is the safety stringbuffer size of most CPython functions.
+ PyErr_Format(PyExc_TypeError,
+ "QEnum expected a string mapping as __members__, got '%.200s'",
+ Py_TYPE(key)->tp_name);
+ return nullptr;
+ }
+
+ // Get the value.
+ AutoDecRef value(PyObject_GetAttr(member, Shiboken::PyName::value()));
+ if (value.isNull())
+ return nullptr;
+ if (!PyInt_Check(value)) { // int/long cheating
+ PyErr_Format(PyExc_TypeError,
+ "QEnum expected an int value as '%.200s', got '%.200s'",
+ Shiboken::String::toCString(key), Py_TYPE(value)->tp_name);
+ return nullptr;
+ }
+ }
+ Py_RETURN_NONE;
+}
+
+static Py_ssize_t get_lineno()
+{
+ PyObject *frame = reinterpret_cast<PyObject *>(PyEval_GetFrame()); // borrowed ref
+ AutoDecRef ob_lineno(PyObject_GetAttr(frame, Shiboken::PyName::f_lineno()));
+ if (ob_lineno.isNull() || !PyInt_Check(ob_lineno)) // int/long cheating
+ return -1;
+ return PyInt_AsSsize_t(ob_lineno); // int/long cheating
+}
+
+static bool is_module_code()
+{
+ PyObject *frame = reinterpret_cast<PyObject *>(PyEval_GetFrame()); // borrowed ref
+ AutoDecRef ob_code(PyObject_GetAttr(frame, Shiboken::PyName::f_code()));
+ if (ob_code.isNull())
+ return false;
+ AutoDecRef ob_name(PyObject_GetAttr(ob_code, Shiboken::PyName::co_name()));
+ if (ob_name.isNull())
+ return false;
+ const char *codename = Shiboken::String::toCString(ob_name);
+ return strcmp(codename, "<module>") == 0;
+}
+
+} // extern "C"
+
+namespace PySide { namespace QEnum {
+
+static std::map<int, PyObject *> enumCollector;
+
+int isFlag(PyObject *obType)
+{
+ /*
+ * Find out if this is an Enum or a Flag derived class.
+ * It checks also if things come from the enum module and if it is
+ * an Enum or Flag class at all.
+ *
+ * The function is called in MetaObjectBuilderPrivate::parsePythonType
+ * again to obtain the flag value.
+ */
+ if (!PyType_Check(obType)) {
+ PyErr_Format(PyExc_TypeError, "a class argument was expected, not a '%.200s' instance",
+ Py_TYPE(obType)->tp_name);
+ return -1;
+ };
+ auto *type = reinterpret_cast<PyTypeObject *>(obType);
+ PyObject *mro = type->tp_mro;
+ Py_ssize_t i, n = PyTuple_GET_SIZE(mro);
+ bool right_module = false;
+ bool have_enum = false;
+ bool have_flag = false;
+ bool have_members = PyObject_HasAttr(obType, PyMagicName::members());
+ for (i = 0; i < n; i++) {
+ obType = PyTuple_GET_ITEM(mro, i);
+ type = reinterpret_cast<PyTypeObject *>(obType);
+ AutoDecRef mod(PyObject_GetAttr(obType, PyMagicName::module()));
+ QByteArray cmod = String::toCString(mod);
+ QByteArray cname = type->tp_name;
+ if (cmod == "enum") {
+ right_module = true;
+ if (cname == "Enum")
+ have_enum = true;
+ else if (cname == "Flag")
+ have_flag = true;
+ }
+ }
+ if (!right_module || !(have_enum || have_flag) || !have_members) {
+ PyErr_Format(PyExc_TypeError, "type %.200s does not inherit from 'Enum' or 'Flag'",
+ type->tp_name);
+ return -1;
+ }
+ return bool(have_flag);
+}
+
+PyObject *QEnumMacro(PyObject *pyenum, bool flag)
+{
+ /*
+ * This is the official interface of 'QEnum'. It first calls 'analyzePyEnum'.
+ * When called as toplevel enum, it simply returns after some checks.
+ * Otherwise, 'pyenum' is stored for later use by the meta class registation.
+ */
+ int computedFlag = isFlag(pyenum);
+ if (computedFlag < 0)
+ return nullptr;
+ if (bool(computedFlag) != flag) {
+ AutoDecRef name(PyObject_GetAttr(pyenum, PyMagicName::qualname()));
+ auto cname = String::toCString(name);
+ const char *e = "Enum";
+ const char *f = "Flag";
+ PyErr_Format(PyExc_TypeError, "expected '%s' but got '%s' (%.200s)",
+ flag ? f : e, flag ? e : f, cname);
+ return nullptr;
+ }
+ auto ok = analyzePyEnum(pyenum);
+ if (ok == nullptr)
+ return nullptr;
+ if (is_module_code()) {
+ // This is a toplevel enum which we resolve immediately.
+ Py_INCREF(pyenum);
+ return pyenum;
+ }
+
+ Py_ssize_t lineno = get_lineno();
+ if (lineno < 0)
+ return nullptr;
+ // Handle the rest via line number and the meta class.
+ Py_INCREF(pyenum);
+ Py_XDECREF(enumCollector[lineno]);
+ enumCollector[lineno] = pyenum;
+ Py_RETURN_NONE;
+}
+
+std::vector<PyObject *> resolveDelayedQEnums(PyTypeObject *containerType)
+{
+ /*
+ * This is the internal interface of 'QEnum'.
+ * It is called at the end of the meta class call 'SbkObjectTypeTpNew' via
+ * MetaObjectBuilderPrivate::parsePythonType and resolves the collected
+ * Python Enum arguments. The result is then registered.
+ */
+ if (enumCollector.empty())
+ return {};
+ PyObject *obContainerType = reinterpret_cast<PyObject *>(containerType);
+ Py_ssize_t lineno = get_lineno();
+
+ std::vector<PyObject *> result;
+
+ auto it = enumCollector.begin();
+ while (it != enumCollector.end()) {
+ int nr = it->first;
+ PyObject *pyenum = it->second;
+ if (nr >= lineno) {
+ AutoDecRef name(PyObject_GetAttr(pyenum, PyMagicName::name()));
+ if (name.isNull() || PyObject_SetAttr(obContainerType, name, pyenum) < 0)
+ return {};
+ result.push_back(pyenum);
+ it = enumCollector.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ return result;
+}
+
+} // namespace Enum
+} // namespace Shiboken
+
+//
+///////////////////////////////////////////////////////////////
diff --git a/sources/pyside2/libpyside/destroylistener.h b/sources/pyside2/libpyside/pysideqenum.h
index dedcca662..fc4e55982 100644
--- a/sources/pyside2/libpyside/destroylistener.h
+++ b/sources/pyside2/libpyside/pysideqenum.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -37,36 +37,21 @@
**
****************************************************************************/
-#ifndef PYSIDE_DESTROY_LISTENER
-#define PYSIDE_DESTROY_LISTENER
+#ifndef PYSIDE_QENUM_H
+#define PYSIDE_QENUM_H
-#include "pysidemacros.h"
+#include <pysidemacros.h>
+#include <vector>
-#include <QtCore/QObject>
+namespace PySide { namespace QEnum {
-namespace PySide
-{
-struct DestroyListenerPrivate;
-/// \deprecated This class is deprecated and isn't used by libpyside anymore.
-class PYSIDE_API DestroyListener : public QObject
-{
- Q_OBJECT
- public:
- PYSIDE_DEPRECATED(static DestroyListener *instance());
- static void destroy();
- void listen(QObject *obj);
+// PYSIDE-957: Support the QEnum macro
+PYSIDE_API PyObject *QEnumMacro(PyObject *, bool);
+PYSIDE_API int isFlag(PyObject *);
+PYSIDE_API std::vector<PyObject *> resolveDelayedQEnums(PyTypeObject *);
+PYSIDE_API void init();
- public Q_SLOTS:
- void onObjectDestroyed(QObject *obj);
-
- private:
- static DestroyListener *m_instance;
- DestroyListenerPrivate *m_d;
- DestroyListener(QObject *parent);
- ~DestroyListener() override;
-};
-
-}//namespace
+} // namespace QEnum
+} // namespace PySide
#endif
-
diff --git a/sources/pyside2/libpyside/pysideqflags.cpp b/sources/pyside2/libpyside/pysideqflags.cpp
index d7e6b4f4c..b141ce157 100644
--- a/sources/pyside2/libpyside/pysideqflags.cpp
+++ b/sources/pyside2/libpyside/pysideqflags.cpp
@@ -175,18 +175,18 @@ namespace QFlags
// PYSIDE-747: Here we insert now the full class name.
strcpy(qualname, name);
// Careful: SbkType_FromSpec does not allocate the string.
- PyType_Spec *newspec = new PyType_Spec;
- newspec->name = strdup(qualname);
- newspec->basicsize = SbkNewQFlagsType_spec.basicsize;
- newspec->itemsize = SbkNewQFlagsType_spec.itemsize;
- newspec->flags = SbkNewQFlagsType_spec.flags;
+ PyType_Spec newspec;
+ newspec.name = strdup(qualname);
+ newspec.basicsize = SbkNewQFlagsType_spec.basicsize;
+ newspec.itemsize = SbkNewQFlagsType_spec.itemsize;
+ newspec.flags = SbkNewQFlagsType_spec.flags;
int idx = -1;
while (numberMethods[++idx].slot) {
assert(SbkNewQFlagsType_slots[idx].slot == numberMethods[idx].slot);
SbkNewQFlagsType_slots[idx].pfunc = numberMethods[idx].pfunc;
}
- newspec->slots = SbkNewQFlagsType_spec.slots;
- PyTypeObject *type = (PyTypeObject *)SbkType_FromSpec(newspec);
+ newspec.slots = SbkNewQFlagsType_spec.slots;
+ PyTypeObject *type = (PyTypeObject *)SbkType_FromSpec(&newspec);
Py_TYPE(type) = &PyType_Type;
PySideQFlagsType *flagsType = reinterpret_cast<PySideQFlagsType *>(type);
diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp
index 0fa33254c..32e1bb0c6 100644
--- a/sources/pyside2/libpyside/pysidesignal.cpp
+++ b/sources/pyside2/libpyside/pysidesignal.cpp
@@ -54,7 +54,6 @@
#include <utility>
#define QT_SIGNAL_SENTINEL '2'
-#define PyEnumMeta_Check(x) (strcmp(Py_TYPE(arg)->tp_name, "EnumMeta") == 0)
namespace PySide {
namespace Signal {
@@ -805,32 +804,6 @@ PySideSignalInstance *newObjectFromMethod(PyObject *source, const QList<QMetaMet
return root;
}
-PySideSignal *newObject(const char *name, ...)
-{
- va_list listSignatures;
- char *sig = nullptr;
- PySideSignal *self = PyObject_New(PySideSignal, PySideSignalTypeF());
- self->data = new PySideSignalData;
- self->data->signalName = name;
- self->homonymousMethod = 0;
-
- va_start(listSignatures, name);
- sig = va_arg(listSignatures, char *);
-
- while (sig != NULL) {
- if (strcmp(sig, "void") == 0)
- appendSignature(self, SignalSignature(""));
- else
- appendSignature(self, SignalSignature(sig));
-
- sig = va_arg(listSignatures, char *);
- }
-
- va_end(listSignatures);
-
- return self;
-}
-
template<typename T>
static typename T::value_type join(T t, const char *sep)
{
@@ -914,11 +887,6 @@ PyObject *buildQtCompatible(const QByteArray &signature)
return Shiboken::String::fromStringAndSize(ba, ba.size());
}
-void addSignalToWrapper(SbkObjectType *wrapperType, const char *signalName, PySideSignal *signal)
-{
- _addSignalToWrapper(wrapperType, signalName, signal);
-}
-
PyObject *getObject(PySideSignalInstance *signal)
{
return signal->d->source;
diff --git a/sources/pyside2/libpyside/pysidesignal.h b/sources/pyside2/libpyside/pysidesignal.h
index a2d58a27c..a6742227f 100644
--- a/sources/pyside2/libpyside/pysidesignal.h
+++ b/sources/pyside2/libpyside/pysidesignal.h
@@ -75,16 +75,6 @@ namespace Signal {
PYSIDE_API bool checkType(PyObject* type);
/**
- * This function creates a Signal object which stays attached to QObject class
- *
- * @param name of the Signal to be registered on meta object
- * @param signatures a list of signatures supported by this signal, ended with a NULL pointer
- * @return Return a new reference to PyObject* of type PySideSignal
- * @deprecated Use registerSignals
- **/
-PYSIDE_DEPRECATED(PYSIDE_API PySideSignal* newObject(const char* name, ...));
-
-/**
* Register all C++ signals of a QObject on Python type.
*/
PYSIDE_API void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject);
@@ -133,11 +123,6 @@ PYSIDE_API const char* getSignature(PySideSignalInstance* signal);
PYSIDE_API void updateSourceObject(PyObject* source);
/**
- * @deprecated Use registerSignals
- **/
-PYSIDE_DEPRECATED(PYSIDE_API void addSignalToWrapper(SbkObjectType* wrapperType, const char* signalName, PySideSignal* signal));
-
-/**
* This function verifies if the signature is a QtSignal base on SIGNAL flag
* @param signature The signal signature
* @return Return true if this is a Qt Signal, otherwise return false
diff --git a/sources/pyside2/plugins/CMakeLists.txt b/sources/pyside2/plugins/CMakeLists.txt
index f39575542..c9e652800 100644
--- a/sources/pyside2/plugins/CMakeLists.txt
+++ b/sources/pyside2/plugins/CMakeLists.txt
@@ -9,21 +9,28 @@ set(ui_plugin_moc
customwidget.h
customwidgets.h
)
-include_directories(${Qt5Designer_INCLUDE_DIRS})
+include_directories(${Qt${QT_MAJOR_VERSION}Designer_INCLUDE_DIRS})
+
+if (${QT_MAJOR_VERSION} GREATER_EQUAL 6)
+ qt6_wrap_cpp(MOC_FILES ${ui_plugin_moc})
+else()
+ qt5_wrap_cpp(MOC_FILES ${ui_plugin_moc})
+endif()
-qt5_wrap_cpp(MOC_FILES ${ui_plugin_moc})
add_library(uiplugin STATIC ${ui_plugin_src} ${MOC_FILES})
if(CMAKE_HOST_UNIX AND NOT CYGWIN)
add_definitions(-fPIC)
endif()
add_definitions(-DQT_STATICPLUGIN)
-if(Qt5Core_VERSION VERSION_GREATER "5.7.1")
- set_property(TARGET uiplugin PROPERTY CXX_STANDARD 11)
+if(${QT_MAJOR_VERSION} GREATER_EQUAL 6)
+ set_property(TARGET pyside2 PROPERTY CXX_STANDARD 17)
+else()
+ set_property(TARGET pyside2 PROPERTY CXX_STANDARD 11)
endif()
target_link_libraries(uiplugin
- ${Qt5UiTools_LIBRARY}
+ ${Qt${QT_MAJOR_VERSION}UiTools_LIBRARY}
Shiboken2::libshiboken)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_DEBUG_POSTFIX})
diff --git a/sources/pyside2/pyside_version.py b/sources/pyside2/pyside_version.py
index 0e0943143..f5ef03613 100644
--- a/sources/pyside2/pyside_version.py
+++ b/sources/pyside2/pyside_version.py
@@ -38,13 +38,13 @@
#############################################################################
major_version = "5"
-minor_version = "14"
-patch_version = "2"
+minor_version = "15"
+patch_version = "0"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
# An empty string means the generated package will be an official release.
-pre_release_version_type = "a"
+release_version_type = "a"
# For example: "1", "2" (which means "beta1", "beta2", if type is "b").
pre_release_version = "1"
@@ -52,4 +52,4 @@ pre_release_version = "1"
if __name__ == '__main__':
# Used by CMake.
print('{0};{1};{2};{3};{4}'.format(major_version, minor_version, patch_version,
- pre_release_version_type, pre_release_version))
+ release_version_type, pre_release_version))
diff --git a/sources/pyside2/tests/CMakeLists.txt b/sources/pyside2/tests/CMakeLists.txt
index 60179d81f..285ea872f 100644
--- a/sources/pyside2/tests/CMakeLists.txt
+++ b/sources/pyside2/tests/CMakeLists.txt
@@ -46,7 +46,7 @@ else()
foreach(shortname IN LISTS all_module_shortnames)
message(STATUS "preparing tests for module 'Qt${shortname}'")
- TEST_QT_MODULE(Qt5${shortname}_FOUND Qt${shortname})
+ TEST_QT_MODULE(Qt${QT_MAJOR_VERSION}${shortname}_FOUND Qt${shortname})
endforeach()
#platform specific
diff --git a/sources/pyside2/tests/QtCore/CMakeLists.txt b/sources/pyside2/tests/QtCore/CMakeLists.txt
index 35e42e2ae..a151e6d11 100644
--- a/sources/pyside2/tests/QtCore/CMakeLists.txt
+++ b/sources/pyside2/tests/QtCore/CMakeLists.txt
@@ -52,7 +52,8 @@ PYSIDE_TEST(qbytearray_concatenation_operator_test.py)
PYSIDE_TEST(qbytearray_operator_iadd_test.py)
PYSIDE_TEST(qbytearray_operator_test.py)
PYSIDE_TEST(qbytearray_test.py)
-if (Qt5Core_VERSION VERSION_EQUAL 5.14.0 OR Qt5Core_VERSION VERSION_GREATER 5.14.0)
+if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_EQUAL 5.14.0
+ OR Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 5.14.0)
PYSIDE_TEST(qcalendar_test.py)
endif()
PYSIDE_TEST(qcbor_test.py)
diff --git a/sources/pyside2/tests/QtCore/qenum_test.py b/sources/pyside2/tests/QtCore/qenum_test.py
index 1edb8981a..f99a893d9 100644
--- a/sources/pyside2/tests/QtCore/qenum_test.py
+++ b/sources/pyside2/tests/QtCore/qenum_test.py
@@ -2,7 +2,7 @@
#############################################################################
##
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2020 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the test suite of Qt for Python.
@@ -40,7 +40,7 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide2.QtCore import Qt, QIODevice
+from PySide2.QtCore import Qt, QIODevice, QObject, QEnum, QFlag
class TestEnum(unittest.TestCase):
@@ -68,28 +68,30 @@ class TestEnum(unittest.TestCase):
# Floats
with self.assertRaises(TypeError):
- a = k+2.0
+ a = k + 2.0
with self.assertRaises(TypeError):
- a = k-2.0
+ a = k - 2.0
with self.assertRaises(TypeError):
- a = k*2.0
+ a = k * 2.0
- @unittest.skipUnless(getattr(sys, "getobjects", None), "requires debug build")
+ @unittest.skipUnless(getattr(sys, "getobjects", None), "requires --with-trace-refs")
+ @unittest.skipUnless(getattr(sys, "gettotalrefcount", None), "requires --with-pydebug")
def testEnumNew_NoLeak(self):
gc.collect()
total = sys.gettotalrefcount()
for idx in range(1000):
ret = Qt.Key(42)
+
gc.collect()
delta = sys.gettotalrefcount() - total
print("delta total refcount =", delta)
if abs(delta) >= 10:
- all = sys.getobjects(0)
- all.sort(key=lambda x: sys.getrefcount(x), reverse=True)
+ all = [(sys.getrefcount(x), x) for x in sys.getobjects(0)]
+ all.sort(key=lambda x: x[0], reverse=True)
for ob in all[:10]:
- print(sys.getrefcount(ob), ob)
+ print(ob)
self.assertTrue(abs(delta) < 10)
@@ -141,6 +143,105 @@ class TestEnumPickling(unittest.TestCase):
else:
func()
+# PYSIDE-957: The QEnum macro
+
+try:
+ import enum
+ HAVE_ENUM = True
+except ImportError:
+ HAVE_ENUM = False
+ QEnum = QFlag = lambda x: x
+ import types
+ class Enum: pass
+ enum = types.ModuleType("enum")
+ enum.Enum = enum.Flag = enum.IntEnum = enum.IntFlag = Enum
+ Enum.__module__ = "enum"
+ Enum.__members__ = {}
+ del Enum
+ enum.auto = lambda: 42
+
+HAVE_FLAG = hasattr(enum, "Flag")
+
+@QEnum
+class OuterEnum(enum.Enum):
+ A = 1
+ B = 2
+
+class SomeClass(QObject):
+
+ @QEnum
+ class SomeEnum(enum.Enum):
+ A = 1
+ B = 2
+ C = 3
+
+ @QEnum
+ class OtherEnum(enum.IntEnum):
+ A = 1
+ B = 2
+ C = 3
+
+ class InnerClass(QObject):
+
+ @QEnum
+ class InnerEnum(enum.Enum):
+ X = 42
+
+ class SomeEnum(enum.Enum):
+ A = 4
+ B = 5
+ C = 6
+
+ QEnum(SomeEnum) # works even without the decorator assignment
+
+
+@unittest.skipUnless(HAVE_ENUM, "requires 'enum' module (use 'pip install enum34' for Python 2)")
+class TestQEnumMacro(unittest.TestCase):
+ def testTopLevel(self):
+ self.assertEqual(type(OuterEnum).__module__, "enum")
+ self.assertEqual(type(OuterEnum).__name__, "EnumMeta")
+ self.assertEqual(len(OuterEnum.__members__), 2)
+
+ def testSomeClass(self):
+ self.assertEqual(type(SomeClass.SomeEnum).__module__, "enum")
+ self.assertEqual(type(SomeClass.SomeEnum).__name__, "EnumMeta")
+ self.assertEqual(len(SomeClass.SomeEnum.__members__), 3)
+ with self.assertRaises(TypeError):
+ int(SomeClass.SomeEnum.C) == 6
+ self.assertEqual(SomeClass.OtherEnum.C, 3)
+
+ @unittest.skipIf(sys.version_info[0] < 3, "we cannot support nested classes in Python 2")
+ def testInnerClass(self):
+ self.assertEqual(SomeClass.InnerClass.InnerEnum.__qualname__,
+ "SomeClass.InnerClass.InnerEnum")
+ with self.assertRaises(TypeError):
+ int(SomeClass.InnerClass.InnerEnum.X) == 42
+
+ @unittest.skipUnless(HAVE_FLAG, "some older Python versions have no 'Flag'")
+ def testEnumFlag(self):
+ with self.assertRaises(TypeError):
+ class WrongFlagForEnum(QObject):
+ @QEnum
+ class Bad(enum.Flag):
+ pass
+ with self.assertRaises(TypeError):
+ class WrongEnuForFlag(QObject):
+ @QFlag
+ class Bad(enum.Enum):
+ pass
+
+ def testIsRegistered(self):
+ mo = SomeClass.staticMetaObject
+ self.assertEqual(mo.enumeratorCount(), 2)
+ self.assertEqual(mo.enumerator(0).name(), "OtherEnum")
+ self.assertEqual(mo.enumerator(0).scope(), "SomeClass")
+ self.assertEqual(mo.enumerator(1).name(), "SomeEnum")
+ moi = SomeClass.InnerClass.staticMetaObject
+ self.assertEqual(moi.enumerator(0).name(), "InnerEnum")
+ ## Question: Should that scope not better be "SomeClass.InnerClass"?
+ ## But we have __qualname__ already:
+ self.assertEqual(moi.enumerator(0).scope(), "InnerClass")
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside2/tests/QtNetwork/CMakeLists.txt b/sources/pyside2/tests/QtNetwork/CMakeLists.txt
index 57c5266c8..754f8e5af 100644
--- a/sources/pyside2/tests/QtNetwork/CMakeLists.txt
+++ b/sources/pyside2/tests/QtNetwork/CMakeLists.txt
@@ -2,7 +2,7 @@ PYSIDE_TEST(bug_446.py)
PYSIDE_TEST(bug_1084.py)
PYSIDE_TEST(accessManager_test.py)
PYSIDE_TEST(dnslookup_test.py)
-# Qt5: QHttp is gone PYSIDE_TEST(http_test.py)
+# Qt${QT_MAJOR_VERSION}: QHttp is gone PYSIDE_TEST(http_test.py)
PYSIDE_TEST(qpassworddigestor_test.py)
PYSIDE_TEST(tcpserver_test.py)
PYSIDE_TEST(udpsocket_test.py)
diff --git a/sources/pyside2/tests/QtQuickControls2/CMakeLists.txt b/sources/pyside2/tests/QtQuickControls2/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside2/tests/QtQuickControls2/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside2/tests/QtSerialPort/CMakeLists.txt b/sources/pyside2/tests/QtSerialPort/CMakeLists.txt
new file mode 100644
index 000000000..554373445
--- /dev/null
+++ b/sources/pyside2/tests/QtSerialPort/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(serial.py)
diff --git a/sources/pyside2/tests/QtSerialPort/serial.py b/sources/pyside2/tests/QtSerialPort/serial.py
new file mode 100644
index 000000000..7c0839d8e
--- /dev/null
+++ b/sources/pyside2/tests/QtSerialPort/serial.py
@@ -0,0 +1,95 @@
+#!/usr/bin/python
+
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+'''Test cases for QSerialPort'''
+
+import os
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide2.QtSerialPort import QSerialPort, QSerialPortInfo
+from PySide2.QtCore import QIODevice
+
+class QSerialPortTest(unittest.TestCase):
+ def testDefaultConstructedPort(self):
+ serialPort = QSerialPort()
+
+ self.assertEqual(serialPort.error(), QSerialPort.NoError)
+ self.assertTrue(not serialPort.errorString() == "")
+
+ # properties
+ defaultBaudRate = QSerialPort.Baud9600
+ self.assertEqual(serialPort.baudRate(), defaultBaudRate)
+ self.assertEqual(serialPort.baudRate(QSerialPort.Input), defaultBaudRate)
+ self.assertEqual(serialPort.baudRate(QSerialPort.Output), defaultBaudRate)
+ self.assertEqual(serialPort.dataBits(), QSerialPort.Data8)
+ self.assertEqual(serialPort.parity(), QSerialPort.NoParity)
+ self.assertEqual(serialPort.stopBits(), QSerialPort.OneStop)
+ self.assertEqual(serialPort.flowControl(), QSerialPort.NoFlowControl)
+
+ self.assertEqual(serialPort.pinoutSignals(), QSerialPort.NoSignal)
+ self.assertEqual(serialPort.isRequestToSend(), False)
+ self.assertEqual(serialPort.isDataTerminalReady(), False)
+
+ # QIODevice
+ self.assertEqual(serialPort.openMode(), QIODevice.NotOpen)
+ self.assertTrue(not serialPort.isOpen())
+ self.assertTrue(not serialPort.isReadable())
+ self.assertTrue(not serialPort.isWritable())
+ self.assertTrue(serialPort.isSequential())
+ self.assertEqual(serialPort.canReadLine(), False)
+ self.assertEqual(serialPort.pos(), 0)
+ self.assertEqual(serialPort.size(), 0)
+ self.assertTrue(serialPort.atEnd())
+ self.assertEqual(serialPort.bytesAvailable(), 0)
+ self.assertEqual(serialPort.bytesToWrite(), 0)
+
+ def testOpenExisting(self):
+ allportinfos = QSerialPortInfo.availablePorts()
+ for portinfo in allportinfos:
+ serialPort = QSerialPort(portinfo)
+ self.assertEqual(serialPort.portName(), portinfo.portName())
+
+
+class QSerialPortInfoTest(unittest.TestCase):
+ def test_available_ports(self):
+ allportinfos = QSerialPortInfo.availablePorts()
+ for portinfo in allportinfos:
+ portinfo.description()
+ portinfo.hasProductIdentifier()
+ portinfo.hasVendorIdentifier()
+ portinfo.isNull()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside2/tests/pysidetest/CMakeLists.txt b/sources/pyside2/tests/pysidetest/CMakeLists.txt
index 46a8023c3..bdd88ea37 100644
--- a/sources/pyside2/tests/pysidetest/CMakeLists.txt
+++ b/sources/pyside2/tests/pysidetest/CMakeLists.txt
@@ -5,11 +5,11 @@ cmake_minimum_required(VERSION 3.1)
set(QT_USE_QTCORE 1)
# no more supported: include(${QT_USE_FILE})
-add_definitions(${Qt5Core_DEFINITIONS})
+add_definitions(${Qt${QT_MAJOR_VERSION}Core_DEFINITIONS})
add_definitions(-DQT_SHARED)
add_definitions(-DRXX_ALLOCATOR_INIT_0)
-find_package(Qt5Widgets)
+find_package(Qt${QT_MAJOR_VERSION}Widgets)
set(pysidetest_SRC
testobject.cpp
@@ -23,7 +23,11 @@ testview.h
hiddenobject.h
)
-qt5_wrap_cpp(pysidetest_MOC_SRC ${pysidetest_MOC_HEADERS})
+if (${QT_MAJOR_VERSION} GREATER_EQUAL 6)
+ qt6_wrap_cpp(pysidetest_MOC_SRC ${pysidetest_MOC_HEADERS})
+else()
+ qt5_wrap_cpp(pysidetest_MOC_SRC ${pysidetest_MOC_HEADERS})
+endif()
set(testbinding_SRC
${CMAKE_CURRENT_BINARY_DIR}/testbinding/testobject_wrapper.cpp
@@ -43,9 +47,15 @@ ${CMAKE_CURRENT_BINARY_DIR}/testbinding/testbinding_module_wrapper.cpp
# ./qt/lib/QtCore.framework; ./qt/lib/QtCore.framework/Headers ; ./qt/mkspecs/macx-clang
# Thus we use the second direct path, which contains the actual header files.
-list(GET Qt5Core_INCLUDE_DIRS 1 Qt5Core_DIRECT_INCLUDE_DIR)
-list(GET Qt5Gui_INCLUDE_DIRS 1 Qt5Gui_DIRECT_INCLUDE_DIR)
-list(GET Qt5Widgets_INCLUDE_DIRS 1 Qt5Widgets_DIRECT_INCLUDE_DIR)
+if(${QT_MAJOR_VERSION} GREATER_EQUAL 6)
+ set(Qt6Core_DIRECT_INCLUDE_DIR Qt6Core_INCLUDE_DIRS)
+ set(Qt6Gui_DIRECT_INCLUDE_DIR Qt6Gui_INCLUDE_DIRS)
+ set(Qt6Widgets_DIRECT_INCLUDE_DIR Qt6Widgets_INCLUDE_DIRS)
+else()
+ list(GET Qt5Core_INCLUDE_DIRS 1 Qt5Core_DIRECT_INCLUDE_DIR)
+ list(GET Qt5Gui_INCLUDE_DIRS 1 Qt5Gui_DIRECT_INCLUDE_DIR)
+ list(GET Qt5Widgets_INCLUDE_DIRS 1 Qt5Widgets_DIRECT_INCLUDE_DIR)
+endif()
# Adjust include headers paths for frameworks.
set(shiboken_framework_include_dirs_option "")
@@ -59,9 +69,9 @@ make_path(testbinding_include_dirs ${pyside2_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../PySide2
${CMAKE_CURRENT_SOURCE_DIR}/../../libpyside
${QT_INCLUDE_DIR}
- ${Qt5Core_DIRECT_INCLUDE_DIR}
- ${Qt5Gui_DIRECT_INCLUDE_DIR}
- ${Qt5Widgets_DIRECT_INCLUDE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_DIRECT_INCLUDE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Gui_DIRECT_INCLUDE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Widgets_DIRECT_INCLUDE_DIR}
)
make_path(testbinding_typesystem_path ${pyside2_SOURCE_DIR}
@@ -84,9 +94,9 @@ COMMENT "Running generator for test binding..."
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Gui_INCLUDE_DIRS}
- ${Qt5Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
${pyside2_SOURCE_DIR}
${QtCore_GEN_DIR}
${QtGui_GEN_DIR}
@@ -96,9 +106,9 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
add_library(pysidetest SHARED ${pysidetest_SRC} ${pysidetest_MOC_SRC})
target_link_libraries(pysidetest
Shiboken2::libshiboken
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
)
add_library(testbinding MODULE ${testbinding_SRC})
@@ -119,9 +129,9 @@ target_link_libraries(testbinding
pyside2
${TESTBINDING_PYTHON_LIBS}
Shiboken2::libshiboken
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- ${Qt5Widgets_LIBRARIES})
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES})
add_dependencies(testbinding pyside2 QtCore QtGui QtWidgets pysidetest)
create_generator_target(testbinding)
@@ -129,7 +139,7 @@ create_generator_target(testbinding)
PYSIDE_TEST(constructor_properties_test.py)
PYSIDE_TEST(decoratedslot_test.py)
# Will always crash when built against Qt 5.6, no point in running it.
-if (Qt5Core_VERSION VERSION_GREATER 5.7.0)
+if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 5.7.0)
PYSIDE_TEST(delegatecreateseditor_test.py)
endif()
PYSIDE_TEST(all_modules_load_test.py)
diff --git a/sources/pyside2/tests/registry/init_platform.py b/sources/pyside2/tests/registry/init_platform.py
index a690a3120..e80c3b69f 100644
--- a/sources/pyside2/tests/registry/init_platform.py
+++ b/sources/pyside2/tests/registry/init_platform.py
@@ -141,8 +141,8 @@ Shiboken.__name__ = "Shiboken"
sys.modules["Shiboken"] = sys.modules.pop("shiboken2")
all_modules.append("Shiboken")
-# 'sample' seems to be needed by 'other', so import it first.
-for modname in "minimal sample other smart".split():
+# 'sample/smart' are needed by 'other', so import them first.
+for modname in "minimal sample smart other".split():
sys.path.insert(0, os.path.join(shiboken_build_dir, "tests", modname + "binding"))
__import__(modname)
all_modules.append(modname)
diff --git a/sources/shiboken2/ApiExtractor/CMakeLists.txt b/sources/shiboken2/ApiExtractor/CMakeLists.txt
index 4232fef66..f8e504583 100644
--- a/sources/shiboken2/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/CMakeLists.txt
@@ -30,8 +30,8 @@ parser/enumvalue.cpp
xmlutils.cpp
)
-find_package(Qt5XmlPatterns 5.12)
-find_package(Qt5Xml 5.12)
+find_package(Qt${QT_MAJOR_VERSION}XmlPatterns 5.12)
+find_package(Qt${QT_MAJOR_VERSION}Xml 5.12)
find_package(LibXml2 2.6.32)
find_package(LibXslt 1.1.19)
@@ -40,7 +40,7 @@ if (LIBXSLT_FOUND AND LIBXML2_FOUND)
set(HAS_LIBXSLT 1)
endif()
-if(NOT Qt5XmlPatterns_FOUND AND NOT HAS_LIBXSLT)
+if(NOT Qt${QT_MAJOR_VERSION}XmlPatterns_FOUND AND NOT HAS_LIBXSLT)
set(DISABLE_DOCSTRINGS TRUE)
message(WARNING
"Documentation will not be built due to missing dependency (no Qt5XmlPatterns found).")
@@ -54,7 +54,7 @@ target_include_directories(apiextractor PRIVATE ${CLANG_EXTRA_INCLUDES}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/parser)
-target_link_libraries(apiextractor PUBLIC Qt5::Core)
+target_link_libraries(apiextractor PUBLIC Qt${QT_MAJOR_VERSION}::Core)
target_link_libraries(apiextractor PRIVATE ${CLANG_EXTRA_LIBRARIES})
if (HAS_LIBXSLT)
@@ -66,10 +66,10 @@ if (HAS_LIBXSLT)
PRIVATE ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES})
endif()
-if (Qt5XmlPatterns_FOUND)
+if (Qt${QT_MAJOR_VERSION}XmlPatterns_FOUND)
target_compile_definitions(apiextractor PUBLIC HAVE_QTXMLPATTERNS)
target_sources(apiextractor PRIVATE xmlutils_qt.cpp)
- target_link_libraries(apiextractor PUBLIC Qt5::Xml Qt5::XmlPatterns)
+ target_link_libraries(apiextractor PUBLIC Qt${QT_MAJOR_VERSION}::Xml Qt${QT_MAJOR_VERSION}::XmlPatterns)
endif()
if (NOT DISABLE_DOCSTRINGS)
@@ -87,7 +87,7 @@ target_compile_definitions(apiextractor PRIVATE CMAKE_CXX_COMPILER="${CMAKE_CXX_
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
if (BUILD_TESTS)
- find_package(Qt5Test 5.12 REQUIRED)
+ find_package(Qt${QT_MAJOR_VERSION}Test 5.12 REQUIRED)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests)
enable_testing()
add_subdirectory(tests)
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 8468cf858..dedf0db50 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -270,7 +270,7 @@ void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelI
const ArgumentModelItem &arg = arguments.at(1);
if (AbstractMetaClass *cls = argumentToClass(arg, currentClass)) {
if (arg->type().indirections() < 2)
- cls->setToStringCapability(true, arg->type().indirections());
+ cls->setToStringCapability(true, int(arg->type().indirections()));
}
}
}
@@ -410,6 +410,7 @@ FileModelItem AbstractMetaBuilderPrivate::buildDom(QByteArrayList arguments,
unsigned clangFlags)
{
clang::Builder builder;
+ builder.setSystemIncludes(TypeDatabase::instance()->systemIncludes());
if (level == LanguageLevel::Default)
level = clang::emulatedCompilerLanguageLevel();
arguments.prepend(QByteArrayLiteral("-std=")
@@ -512,7 +513,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
ReportHandler::startProgress("Fixing class inheritance...");
for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) {
- if (!cls->isInterface() && !cls->isNamespace()) {
+ if (!cls->isNamespace()) {
setupInheritance(cls);
if (!cls->hasVirtualDestructor() && cls->baseClass()
&& cls->baseClass()->hasVirtualDestructor())
@@ -530,7 +531,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
.arg(cls->name());
} else {
const bool couldAddDefaultCtors = cls->isConstructible()
- && !cls->isInterface() && !cls->isNamespace()
+ && !cls->isNamespace()
&& (cls->attributes() & AbstractMetaAttributes::HasRejectedConstructor) == 0;
if (couldAddDefaultCtors) {
if (!cls->hasConstructors())
@@ -549,11 +550,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
if (!entry->isPrimitive()) {
if ((entry->isValue() || entry->isObject())
&& !types->shouldDropTypeEntry(entry->qualifiedCppName())
- && !entry->isString()
- && !entry->isChar()
&& !entry->isContainer()
&& !entry->isCustom()
- && !entry->isVariant()
&& (entry->generateCode() & TypeEntry::GenerateTargetLang)
&& !AbstractMetaClass::findClass(m_metaClasses, entry)) {
qCWarning(lcShiboken).noquote().nospace()
@@ -729,12 +727,6 @@ void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls,
m_smartPointers << cls;
} else {
m_metaClasses << cls;
- if (cls->typeEntry()->designatedInterface()) {
- AbstractMetaClass *interface = cls->extractInterface();
- m_metaClasses << interface;
- if (ReportHandler::isDebug(ReportHandler::SparseDebug))
- qCDebug(lcShiboken) << QStringLiteral(" -> interface '%1'").arg(interface->name());
- }
}
}
@@ -758,6 +750,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
return nullptr;
}
+ if (namespaceItem->type() == NamespaceType::Inline) {
+ type->setInlineNamespace(true);
+ TypeDatabase::instance()->addInlineNamespaceLookups(type);
+ }
+
// Continue populating namespace?
AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, type);
if (!metaClass) {
@@ -778,11 +775,6 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
m_itemToClass.insert(namespaceItem.data(), metaClass);
}
- if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
- qCDebug(lcShiboken)
- << QStringLiteral("namespace '%1.%2'").arg(metaClass->package(), namespaceItem->name());
- }
-
traverseEnums(namespaceItem, metaClass, namespaceItem->enumsDeclarations());
pushScope(namespaceItem);
@@ -911,9 +903,6 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
break;
}
- if (ReportHandler::isDebug(ReportHandler::MediumDebug))
- qCDebug(lcShiboken) << " - traversing enum " << metaEnum->fullName();
-
const EnumeratorList &enums = enumItem->enumerators();
for (const EnumeratorModelItem &value : enums) {
@@ -924,11 +913,6 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
metaEnumValue->setStringValue(value->stringValue());
metaEnumValue->setValue(value->value());
metaEnum->addEnumValue(metaEnumValue);
-
- if (ReportHandler::isDebug(ReportHandler::FullDebug)) {
- qCDebug(lcShiboken) << " - " << metaEnumValue->name() << " = "
- << metaEnumValue->value() << " = " << metaEnumValue->value();
- }
}
m_enums.insert(typeEntry, metaEnum);
@@ -1069,11 +1053,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
if (type->stream())
metaClass->setStream(true);
- if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
+ if (ReportHandler::isDebug(ReportHandler::MediumDebug)) {
const QString message = type->isContainer()
? QStringLiteral("container: '%1'").arg(fullClassName)
: QStringLiteral("class: '%1'").arg(metaClass->fullName());
- qCDebug(lcShiboken) << message;
+ qCInfo(lcShiboken, "%s", qPrintable(message));
}
TemplateParameterList template_parameters = classItem->templateParameters();
@@ -1215,7 +1199,7 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(const VariableModel
metaField->setType(metaType);
- AbstractMetaAttributes::Attributes attr = nullptr;
+ AbstractMetaAttributes::Attributes attr;
if (field->isStatic())
attr |= AbstractMetaAttributes::Static;
@@ -1288,7 +1272,7 @@ AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const Sco
AbstractMetaClass::Attributes *constructorAttributes,
AbstractMetaClass *currentClass)
{
- *constructorAttributes = nullptr;
+ *constructorAttributes = {};
AbstractMetaFunctionList result;
const FunctionList &scopeFunctionList = scopeItem->functions();
result.reserve(scopeFunctionList.size());
@@ -1429,8 +1413,6 @@ void AbstractMetaBuilderPrivate::applyFunctionModifications(AbstractMetaFunction
bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
{
- Q_ASSERT(!metaClass->isInterface());
-
if (m_setupInheritanceDone.contains(metaClass))
return true;
@@ -1470,61 +1452,23 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
TypeDatabase* types = TypeDatabase::instance();
- int primary = -1;
- int primaries = 0;
- for (int i = 0; i < baseClasses.size(); ++i) {
-
- if (types->isClassRejected(baseClasses.at(i)))
- continue;
-
- TypeEntry* baseClassEntry = types->findType(baseClasses.at(i));
- if (!baseClassEntry) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("class '%1' inherits from unknown base class '%2'")
- .arg(metaClass->name(), baseClasses.at(i));
- } else if (!baseClassEntry->designatedInterface()) { // true for primary base class
- primaries++;
- primary = i;
- }
- }
-
- if (primary >= 0) {
- AbstractMetaClass *baseClass = AbstractMetaClass::findClass(m_metaClasses, baseClasses.at(primary));
- if (!baseClass) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("unknown baseclass for '%1': '%2'")
- .arg(metaClass->name(), baseClasses.at(primary));
- return false;
- }
- metaClass->setBaseClass(baseClass);
- }
-
- for (int i = 0; i < baseClasses.size(); ++i) {
- if (types->isClassRejected(baseClasses.at(i)))
- continue;
-
- if (i != primary) {
- AbstractMetaClass *baseClass = AbstractMetaClass::findClass(m_metaClasses, baseClasses.at(i));
- if (!baseClass) {
+ for (const auto &baseClassName : baseClasses) {
+ if (!types->isClassRejected(baseClassName)) {
+ if (!types->findType(baseClassName)) {
qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("class not found for setup inheritance '%1'").arg(baseClasses.at(i));
+ << QStringLiteral("class '%1' inherits from unknown base class '%2'")
+ .arg(metaClass->name(), baseClassName);
return false;
}
-
- setupInheritance(baseClass);
-
- QString interfaceName = baseClass->isInterface() ? InterfaceTypeEntry::interfaceName(baseClass->name()) : baseClass->name();
- AbstractMetaClass *iface = AbstractMetaClass::findClass(m_metaClasses, interfaceName);
- if (!iface) {
+ auto baseClass = AbstractMetaClass::findClass(m_metaClasses, baseClassName);
+ if (!baseClass) {
qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("unknown interface for '%1': '%2'").arg(metaClass->name(), interfaceName);
+ << QStringLiteral("class not found for setup inheritance '%1'").arg(baseClassName);
return false;
}
- metaClass->addInterface(iface);
+ metaClass->addBaseClass(baseClass);
- const AbstractMetaClassList &interfaces = iface->interfaces();
- for (AbstractMetaClass* iface : interfaces)
- metaClass->addInterface(iface);
+ setupInheritance(baseClass);
}
}
@@ -1669,7 +1613,12 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
metaFunction->setFunctionType(AbstractMetaFunction::CopyConstructorFunction);
}
} else {
- metaFunction->setFunctionType(AbstractMetaFunction::NormalFunction);
+ auto type = AbstractMetaFunction::NormalFunction;
+ if (metaFunction->name() == QLatin1String("__getattro__"))
+ type = AbstractMetaFunction::GetAttroFunction;
+ else if (metaFunction->name() == QLatin1String("__setattro__"))
+ type = AbstractMetaFunction::SetAttroFunction;
+ metaFunction->setFunctionType(type);
}
metaFunction->setDeclaringClass(metaClass);
@@ -1801,11 +1750,14 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
const QString &signature = functionSignature(functionItem);
const bool rejected =
TypeDatabase::instance()->isFunctionRejected(className, signature, &rejectReason);
- qCDebug(lcShiboken).nospace().noquote() << __FUNCTION__
- << ": Checking rejection for signature \"" << signature << "\" for " << className
- << ": " << rejected;
- if (rejected)
+
+ if (rejected) {
+ if (ReportHandler::isDebug(ReportHandler::MediumDebug)) {
+ qCInfo(lcShiboken, "%s::%s was rejected by the type database (%s).",
+ qPrintable(className), qPrintable(signature), qPrintable(rejectReason));
+ }
return nullptr;
+ }
if (functionItem->isFriend())
return nullptr;
@@ -1826,9 +1778,6 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
metaFunction->setConstant(functionItem->isConstant());
metaFunction->setExceptionSpecification(functionItem->exceptionSpecification());
- if (ReportHandler::isDebug(ReportHandler::MediumDebug))
- qCDebug(lcShiboken).noquote().nospace() << " - " << functionName << "()";
-
metaFunction->setName(functionName);
metaFunction->setOriginalName(functionItem->name());
@@ -2071,6 +2020,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction:
return nullptr;
}
+ // These are only implicit and should not appear in code...
auto *metaType = new AbstractMetaType;
metaType->setTypeEntry(type);
metaType->setIndirections(typeInfo.indirections);
@@ -2104,6 +2054,52 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
return type;
}
+// Helper for translateTypeStatic()
+TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualifiedName,
+ const QString &name,
+ AbstractMetaClass *currentClass,
+ AbstractMetaBuilderPrivate *d)
+{
+ // 5.1 - Try first using the current scope
+ if (currentClass) {
+ if (auto type = findTypeEntryUsingContext(currentClass, qualifiedName))
+ return {type};
+
+ // 5.1.1 - Try using the class parents' scopes
+ if (d && !currentClass->baseClassNames().isEmpty()) {
+ const AbstractMetaClassList &baseClasses = d->getBaseClasses(currentClass);
+ for (const AbstractMetaClass *cls : baseClasses) {
+ if (auto type = findTypeEntryUsingContext(cls, qualifiedName))
+ return {type};
+ }
+ }
+ }
+
+ // 5.2 - Try without scope
+ auto types = TypeDatabase::instance()->findCppTypes(qualifiedName);
+ if (!types.isEmpty())
+ return types;
+
+ // 6. No? Try looking it up as a flags type
+ if (auto type = TypeDatabase::instance()->findFlagsType(qualifiedName))
+ return {type};
+
+ // 7. No? Try looking it up as a container type
+ if (auto type = TypeDatabase::instance()->findContainerType(name))
+ return {type};
+
+ // 8. No? Check if the current class is a template and this type is one
+ // of the parameters.
+ if (currentClass) {
+ const QVector<TypeEntry *> &template_args = currentClass->templateArguments();
+ for (TypeEntry *te : template_args) {
+ if (te->name() == qualifiedName)
+ return {te};
+ }
+ }
+ return {};
+}
+
AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
AbstractMetaClass *currentClass,
TranslateTypeFlags flags,
@@ -2112,6 +2108,12 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
return translateTypeStatic(_typei, currentClass, this, flags, errorMessage);
}
+static bool isNumber(const QString &s)
+{
+ return std::all_of(s.cbegin(), s.cend(),
+ [](QChar c) { return c.isDigit(); });
+}
+
AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
AbstractMetaClass *currentClass,
AbstractMetaBuilderPrivate *d,
@@ -2236,47 +2238,8 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
typeInfo.clearInstantiations();
}
- const TypeEntry *type = nullptr;
- // 5. Try to find the type
-
- // 5.1 - Try first using the current scope
- if (currentClass) {
- type = findTypeEntryUsingContext(currentClass, qualifiedName);
-
- // 5.1.1 - Try using the class parents' scopes
- if (!type && d && !currentClass->baseClassNames().isEmpty()) {
- const AbstractMetaClassList &baseClasses = d->getBaseClasses(currentClass);
- for (const AbstractMetaClass *cls : baseClasses) {
- type = findTypeEntryUsingContext(cls, qualifiedName);
- if (type)
- break;
- }
- }
- }
-
- // 5.2 - Try without scope
- if (!type)
- type = TypeDatabase::instance()->findType(qualifiedName);
-
- // 6. No? Try looking it up as a flags type
- if (!type)
- type = TypeDatabase::instance()->findFlagsType(qualifiedName);
-
- // 7. No? Try looking it up as a container type
- if (!type)
- type = TypeDatabase::instance()->findContainerType(name);
-
- // 8. No? Check if the current class is a template and this type is one
- // of the parameters.
- if (!type && currentClass) {
- const QVector<TypeEntry *> &template_args = currentClass->templateArguments();
- for (TypeEntry *te : template_args) {
- if (te->name() == qualifiedName)
- type = te;
- }
- }
-
- if (!type) {
+ const TypeEntries types = findTypeEntries(qualifiedName, name, currentClass, d);
+ if (types.isEmpty()) {
if (errorMessageIn) {
*errorMessageIn =
msgUnableToTranslateType(_typei, msgCannotFindTypeEntry(qualifiedName));
@@ -2284,11 +2247,10 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
return nullptr;
}
- // These are only implicit and should not appear in code...
- Q_ASSERT(!type->isInterface());
+ const TypeEntry *type = types.constFirst();
+ const TypeEntry::Type typeEntryType = type->type();
- auto *metaType = new AbstractMetaType;
- metaType->setTypeEntry(type);
+ QScopedPointer<AbstractMetaType> metaType(new AbstractMetaType);
metaType->setIndirectionsV(typeInfo.indirectionsV());
metaType->setReferenceType(typeInfo.referenceType());
metaType->setConstant(typeInfo.isConstant());
@@ -2299,23 +2261,78 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
for (int t = 0, size = templateArguments.size(); t < size; ++t) {
const TypeInfo &ti = templateArguments.at(t);
AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage);
+ // For non-type template parameters, create a dummy type entry on the fly
+ // as is done for classes.
+ if (!targType) {
+ const QString value = ti.qualifiedName().join(colonColon());
+ if (isNumber(value)) {
+ TypeDatabase::instance()->addConstantValueTypeEntry(value, type->typeSystemTypeEntry());
+ targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage);
+ }
+ }
if (!targType) {
if (errorMessageIn)
*errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage);
- delete metaType;
return nullptr;
}
metaType->addInstantiation(targType, true);
}
+ if (types.size() > 1) {
+ const bool sameType = std::all_of(types.cbegin() + 1, types.cend(),
+ [typeEntryType](const TypeEntry *e) {
+ return e->type() == typeEntryType; });
+ if (!sameType) {
+ if (errorMessageIn)
+ *errorMessageIn = msgAmbiguousVaryingTypesFound(qualifiedName, types);
+ return nullptr;
+ }
+ // Ambiguous primitive/smart pointer types are possible (when
+ // including type systems).
+ if (typeEntryType != TypeEntry::PrimitiveType
+ && typeEntryType != TypeEntry::SmartPointerType) {
+ if (errorMessageIn)
+ *errorMessageIn = msgAmbiguousTypesFound(qualifiedName, types);
+ return nullptr;
+ }
+ }
+
+ if (typeEntryType == TypeEntry::SmartPointerType) {
+ // Find a matching instantiation
+ if (metaType->instantiations().size() != 1) {
+ if (errorMessageIn)
+ *errorMessageIn = msgInvalidSmartPointerType(_typei);
+ return nullptr;
+ }
+ auto instantiationType = metaType->instantiations().constFirst()->typeEntry();
+ if (instantiationType->type() == TypeEntry::TemplateArgumentType) {
+ // Member functions of the template itself, SharedPtr(const SharedPtr &)
+ type = instantiationType;
+ } else {
+ auto it = std::find_if(types.cbegin(), types.cend(),
+ [instantiationType](const TypeEntry *e) {
+ auto smartPtr = static_cast<const SmartPointerTypeEntry *>(e);
+ return smartPtr->matchesInstantiation(instantiationType);
+ });
+ if (it == types.cend()) {
+ if (errorMessageIn)
+ *errorMessageIn = msgCannotFindSmartPointerInstantion(_typei);
+ return nullptr;
+ }
+ type =*it;
+ }
+ }
+
+ metaType->setTypeEntry(type);
+
// The usage pattern *must* be decided *after* the possible template
// instantiations have been determined, or else the absence of
// such instantiations will break the caching scheme of
// AbstractMetaType::cppSignature().
metaType->decideUsagePattern();
- return metaType;
+ return metaType.take();
}
AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei,
@@ -2626,14 +2643,11 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
// "template <int R, int C> Matrix<R, C>" and subclass
// "typedef Matrix<2,3> Matrix2x3;". If so, create dummy entries of
// EnumValueTypeEntry for the integer values encountered on the fly.
- const bool isNumber = std::all_of(typeName.cbegin(), typeName.cend(),
- [](QChar c) { return c.isDigit(); });
- if (isNumber) {
+ if (isNumber(typeName)) {
t = typeDb->findType(typeName);
if (!t) {
- t = new ConstantValueTypeEntry(typeName, subclass->typeEntry()->typeSystemTypeEntry());
- t->setCodeGeneration(0);
- typeDb->addType(t);
+ auto parent = subclass->typeEntry()->typeSystemTypeEntry();
+ t = TypeDatabase::instance()->addConstantValueTypeEntry(typeName, parent);
}
} else {
QStringList possibleNames;
@@ -2770,7 +2784,6 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
subclass->setTemplateBaseClass(templateClass);
subclass->setTemplateBaseClassInstantiations(templateTypes);
- subclass->setInterfaces(templateClass->interfaces());
subclass->setBaseClass(templateClass->baseClass());
return true;
@@ -2848,11 +2861,9 @@ void AbstractMetaBuilderPrivate::setupClonable(AbstractMetaClass *cls)
QQueue<AbstractMetaClass*> baseClasses;
if (cls->baseClass())
baseClasses.enqueue(cls->baseClass());
- baseClasses << cls->interfaces().toList();
while (!baseClasses.isEmpty()) {
AbstractMetaClass* currentClass = baseClasses.dequeue();
- baseClasses << currentClass->interfaces().toList();
if (currentClass->baseClass())
baseClasses.enqueue(currentClass->baseClass());
@@ -2897,7 +2908,7 @@ static void writeRejectLogFile(const QString &name,
for (int reason = 0; reason < AbstractMetaBuilder::NoReason; ++reason) {
- s << QString(72, QLatin1Char('*')) << endl;
+ s << QString(72, QLatin1Char('*')) << Qt::endl;
switch (reason) {
case AbstractMetaBuilder::NotInTypeSystem:
s << "Not in type system";
@@ -2930,16 +2941,16 @@ static void writeRejectLogFile(const QString &name,
break;
}
- s << endl;
+ s << Qt::endl;
for (QMap<QString, AbstractMetaBuilder::RejectReason>::const_iterator it = rejects.constBegin();
it != rejects.constEnd(); ++it) {
if (it.value() != reason)
continue;
- s << " - " << it.key() << endl;
+ s << " - " << it.key() << Qt::endl;
}
- s << QString(72, QLatin1Char('*')) << endl << endl;
+ s << QString(72, QLatin1Char('*')) << Qt::endl << Qt::endl;
}
}
@@ -3004,10 +3015,6 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const
const AbstractMetaClassList &bases = getBaseClasses(clazz);
for (AbstractMetaClass *baseClass : bases) {
- // Fix polymorphic expression
- if (clazz->baseClass() == baseClass)
- clazz->setBaseClass(baseClass);
-
const auto baseIt = map.constFind(baseClass);
if (baseIt!= map.cend())
graph.addEdge(baseIt.value(), classIndex);
@@ -3048,8 +3055,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const
} else {
for (int i : qAsConst(unmappedResult)) {
Q_ASSERT(reverseMap.contains(i));
- if (!reverseMap[i]->isInterface())
- result << reverseMap[i];
+ result << reverseMap[i];
}
}
@@ -3100,9 +3106,9 @@ AbstractMetaArgumentList AbstractMetaBuilderPrivate::reverseList(const AbstractM
return ret;
}
-void AbstractMetaBuilder::setGlobalHeader(const QString& globalHeader)
+void AbstractMetaBuilder::setGlobalHeaders(const QFileInfoList &globalHeaders)
{
- d->m_globalHeader = QFileInfo(globalHeader);
+ d->m_globalHeaders = globalHeaders;
}
void AbstractMetaBuilder::setHeaderPaths(const HeaderPaths &hp)
@@ -3140,23 +3146,26 @@ static bool matchHeader(const QString &headerPath, const QString &fileName)
&& fileName.startsWith(headerPath, caseSensitivity);
}
-void AbstractMetaBuilderPrivate::setInclude(TypeEntry *te, const QString &fileName) const
+void AbstractMetaBuilderPrivate::setInclude(TypeEntry *te, const QString &path) const
{
- auto it = m_resolveIncludeHash.find(fileName);
+ auto it = m_resolveIncludeHash.find(path);
if (it == m_resolveIncludeHash.end()) {
- QFileInfo info(fileName);
- if (m_globalHeader.fileName() == info.fileName())
+ QFileInfo info(path);
+ const QString fileName = info.fileName();
+ if (std::any_of(m_globalHeaders.cbegin(), m_globalHeaders.cend(),
+ [fileName] (const QFileInfo &fi) {
+ return fi.fileName() == fileName; })) {
return;
+ }
int bestMatchLength = 0;
for (const auto &headerPath : m_headerPaths) {
- if (headerPath.size() > bestMatchLength && matchHeader(headerPath, fileName))
+ if (headerPath.size() > bestMatchLength && matchHeader(headerPath, path))
bestMatchLength = headerPath.size();
}
const QString include = bestMatchLength > 0
- ? fileName.right(fileName.size() - bestMatchLength - 1)
- : info.fileName();
- it = m_resolveIncludeHash.insert(fileName, {Include::IncludePath, include});
+ ? path.right(path.size() - bestMatchLength - 1) : fileName;
+ it = m_resolveIncludeHash.insert(path, {Include::IncludePath, include});
}
te->setInclude(it.value());
}
@@ -3181,7 +3190,7 @@ static void debugFormatSequence(QDebug &d, const char *key, const Container& c,
void AbstractMetaBuilder::formatDebug(QDebug &debug) const
{
- debug << "m_globalHeader=" << d->m_globalHeader.absoluteFilePath();
+ debug << "m_globalHeader=" << d->m_globalHeaders;
debugFormatSequence(debug, "globalEnums", d->m_globalEnums, "\n");
debugFormatSequence(debug, "globalFunctions", d->m_globalFunctions, "\n");
if (const int scopeCount = d->m_scopes.size()) {
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
index 93b9d9fd2..37022a544 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
@@ -35,6 +35,8 @@
#include "clangparser/compilersupport.h"
+#include <QFileInfoList>
+
QT_FORWARD_DECLARE_CLASS(QIODevice)
class AbstractMetaBuilderPrivate;
@@ -85,7 +87,7 @@ public:
* so any class declared under this header wont have the include file
* filled.
*/
- void setGlobalHeader(const QString& globalHeader);
+ void setGlobalHeaders(const QFileInfoList& globalHeaders);
void setHeaderPaths(const HeaderPaths &h);
void setSkipDeprecated(bool value);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index be73697f0..2686ebacb 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -147,6 +147,9 @@ public:
AbstractMetaBuilderPrivate *d = nullptr,
TranslateTypeFlags flags = {},
QString *errorMessageIn = nullptr);
+ static TypeEntries findTypeEntries(const QString &qualifiedName, const QString &name,
+ AbstractMetaClass *currentClass = nullptr,
+ AbstractMetaBuilderPrivate *d = nullptr);
qint64 findOutValueFromString(const QString &stringValue, bool &ok);
@@ -167,7 +170,7 @@ public:
void sortLists();
AbstractMetaArgumentList reverseList(const AbstractMetaArgumentList &list);
- void setInclude(TypeEntry *te, const QString &fileName) const;
+ void setInclude(TypeEntry *te, const QString &path) const;
void fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods);
void fillAddedFunctions(AbstractMetaClass *metaClass);
@@ -194,7 +197,7 @@ public:
QSet<AbstractMetaClass *> m_setupInheritanceDone;
QString m_logDirectory;
- QFileInfo m_globalHeader;
+ QFileInfoList m_globalHeaders;
QStringList m_headerPaths;
mutable QHash<QString, Include> m_resolveIncludeHash;
bool m_skipDeprecated = false;
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index ad694eb4f..390143cda 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -80,15 +80,10 @@ const AbstractMetaClass *recurseClassHierarchy(const AbstractMetaClass *klass,
{
if (pred(klass))
return klass;
- if (auto base = klass->baseClass()) {
+ for (auto base : klass->baseClasses()) {
if (auto r = recurseClassHierarchy(base, pred))
return r;
}
- const auto interfaces = klass->interfaces();
- for (auto i : interfaces) {
- if (auto r = recurseClassHierarchy(i, pred))
- return r;
- }
return nullptr;
}
@@ -268,7 +263,7 @@ QString AbstractMetaType::pythonSignature() const
// PYSIDE-921: Handle container returntypes correctly.
// This is now a clean reimplementation.
if (m_cachedPythonSignature.isEmpty())
- m_cachedPythonSignature = formatPythonSignature(false);
+ m_cachedPythonSignature = formatPythonSignature();
return m_cachedPythonSignature;
}
@@ -310,10 +305,6 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con
if (m_typeEntry->isValue())
return indirections() == 1 ? ValuePointerPattern : ValuePattern;
- if (ReportHandler::isDebug(ReportHandler::FullDebug)) {
- qCDebug(lcShiboken)
- << QStringLiteral("native pointer pattern for '%1'").arg(cppSignature());
- }
return NativePointerPattern;
}
@@ -531,7 +522,7 @@ bool AbstractMetaFunction::operator<(const AbstractMetaFunction &other) const
*/
AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const AbstractMetaFunction *other) const
{
- CompareResult result = nullptr;
+ CompareResult result;
// Enclosing class...
if (ownerClass() == other->ownerClass())
@@ -825,8 +816,8 @@ bool AbstractMetaFunction::allowThread() const
result = false;
break;
}
- if (!result)
- qCDebug(lcShiboken).noquote() << msgDisallowThread(this);
+ if (!result && ReportHandler::isDebug(ReportHandler::MediumDebug))
+ qCInfo(lcShiboken).noquote() << msgDisallowThread(this);
return result;
}
@@ -950,9 +941,6 @@ FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaC
(implementor == implementingClass() && !mods.isEmpty())) {
break;
}
- const AbstractMetaClassList &interfaces = implementor->interfaces();
- for (const AbstractMetaClass *interface : interfaces)
- mods += this->modifications(interface);
implementor = implementor->baseClass();
}
return mods;
@@ -1367,44 +1355,6 @@ bool AbstractMetaClass::inheritsFrom(const AbstractMetaClass *cls) const
}
/*******************************************************************************
- * Constructs an interface based on the functions and enums in this
- * class and returns it...
- */
-AbstractMetaClass *AbstractMetaClass::extractInterface()
-{
- Q_ASSERT(typeEntry()->designatedInterface());
-
- if (!m_extractedInterface) {
- auto *iface = new AbstractMetaClass;
- iface->setAttributes(attributes());
- iface->setBaseClass(nullptr);
-
- iface->setTypeEntry(typeEntry()->designatedInterface());
-
- for (AbstractMetaFunction *function : qAsConst(m_functions)) {
- if (!function->isConstructor())
- iface->addFunction(function->copy());
- }
-
-// iface->setEnums(enums());
-// setEnums(AbstractMetaEnumList());
-
- for (const AbstractMetaField *field : qAsConst(m_fields)) {
- if (field->isPublic()) {
- AbstractMetaField *new_field = field->copy();
- new_field->setEnclosingClass(iface);
- iface->addField(new_field);
- }
- }
-
- m_extractedInterface = iface;
- addInterface(iface);
- }
-
- return m_extractedInterface;
-}
-
-/*******************************************************************************
* Returns a list of all the functions with a given name
*/
AbstractMetaFunctionList AbstractMetaClass::queryFunctionsByName(const QString &name) const
@@ -1426,10 +1376,6 @@ AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const
{
FunctionQueryOptions default_flags = NormalFunctions | Visible | NotRemovedFromTargetLang;
- // Interfaces don't implement functions
- if (isInterface())
- default_flags |= ClassImplements;
-
// Only public functions in final classes
// default_flags |= isFinal() ? WasPublic : 0;
FunctionQueryOptions public_flags;
@@ -1606,11 +1552,19 @@ QString AbstractMetaClass::name() const
return m_typeEntry->targetLangEntryName();
}
+void AbstractMetaClass::addBaseClass(AbstractMetaClass *baseClass)
+{
+ Q_ASSERT(baseClass);
+ m_baseClasses.append(baseClass);
+ m_isPolymorphic |= baseClass->isPolymorphic();
+}
+
void AbstractMetaClass::setBaseClass(AbstractMetaClass *baseClass)
{
- m_baseClass = baseClass;
- if (baseClass)
+ if (baseClass) {
+ m_baseClasses.prepend(baseClass);
m_isPolymorphic |= baseClass->isPolymorphic();
+ }
}
QString AbstractMetaClass::package() const
@@ -1618,11 +1572,6 @@ QString AbstractMetaClass::package() const
return m_typeEntry->targetLangPackage();
}
-bool AbstractMetaClass::isInterface() const
-{
- return m_typeEntry->isInterface();
-}
-
bool AbstractMetaClass::isNamespace() const
{
return m_typeEntry->isNamespace();
@@ -1731,7 +1680,7 @@ void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList
bool AbstractMetaClass::deleteInMainThread() const
{
return typeEntry()->deleteInMainThread()
- || (m_baseClass && m_baseClass->deleteInMainThread());
+ || (!m_baseClasses.isEmpty() && m_baseClasses.constFirst()->deleteInMainThread());
}
static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func)
@@ -1860,6 +1809,14 @@ const AbstractMetaFunction *AbstractMetaField::setter() const
return m_setter;
}
+const AbstractMetaClass *EnclosingClassMixin::targetLangEnclosingClass() const
+{
+ auto result = m_enclosingClass;
+ while (result && !NamespaceTypeEntry::isVisibleScope(result->typeEntry()))
+ result = result->enclosingClass();
+ return result;
+}
+
const AbstractMetaFunction *AbstractMetaField::getter() const
{
if (!m_getter) {
@@ -2108,6 +2065,16 @@ bool AbstractMetaClass::queryFunction(const AbstractMetaFunction *f, FunctionQue
if ((query & GenerateExceptionHandling) && !f->generateExceptionHandling())
return false;
+ if (query.testFlag(GetAttroFunction)
+ && f->functionType() != AbstractMetaFunction::GetAttroFunction) {
+ return false;
+ }
+
+ if (query.testFlag(SetAttroFunction)
+ && f->functionType() != AbstractMetaFunction::SetAttroFunction) {
+ return false;
+ }
+
return true;
}
@@ -2148,57 +2115,6 @@ AbstractMetaFunctionList AbstractMetaClass::cppSignalFunctions() const
return queryFunctions(Signals | Visible | NotRemovedFromTargetLang);
}
-/**
- * Adds the specified interface to this class by adding all the
- * functions in the interface to this class.
- */
-void AbstractMetaClass::addInterface(AbstractMetaClass *interface)
-{
- Q_ASSERT(!m_interfaces.contains(interface));
- m_interfaces << interface;
-
- m_isPolymorphic |= interface->isPolymorphic();
-
- if (m_extractedInterface && m_extractedInterface != interface)
- m_extractedInterface->addInterface(interface);
-
-
-#if 0
- const AbstractMetaFunctionList &funcs = interface->functions();
- for (AbstractMetaFunction *function : funcs)
- if (!hasFunction(function) && !function->isConstructor()) {
- AbstractMetaFunction *cpy = function->copy();
- cpy->setImplementingClass(this);
-
- // Setup that this function is an interface class.
- cpy->setInterfaceClass(interface);
- *cpy += AbstractMetaAttributes::InterfaceFunction;
-
- // Copy the modifications in interface into the implementing classes.
- const FunctionModificationList &mods = function->modifications(interface);
- for (const FunctionModification &mod : mods)
- m_typeEntry->addFunctionModification(mod);
-
- // It should be mostly safe to assume that when we implement an interface
- // we don't "pass on" pure virtual functions to our sublcasses...
-// *cpy -= AbstractMetaAttributes::Abstract;
-
- addFunction(cpy);
- }
-#endif
-
-}
-
-
-void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces)
-{
- m_interfaces = interfaces;
- for (const AbstractMetaClass *interface : interfaces) {
- if (interface)
- m_isPolymorphic |= interface->isPolymorphic();
- }
-}
-
AbstractMetaField *AbstractMetaClass::findField(const QString &name) const
{
return AbstractMetaField::find(m_fields, name);
@@ -2208,10 +2124,6 @@ AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName)
{
if (AbstractMetaEnum *e = findByName(m_enums, enumName))
return e;
-
- if (typeEntry()->designatedInterface())
- return extractInterface()->findEnum(enumName);
-
return nullptr;
}
@@ -2224,10 +2136,6 @@ AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValue
if (AbstractMetaEnumValue *v = e->findEnumValue(enumValueName))
return v;
}
-
- if (typeEntry()->designatedInterface())
- return extractInterface()->findEnumValue(enumValueName);
-
if (baseClass())
return baseClass()->findEnumValue(enumValueName);
@@ -2274,32 +2182,23 @@ void AbstractMetaClass::fixFunctions()
m_functionsFixed = true;
- AbstractMetaClass *superClass = baseClass();
AbstractMetaFunctionList funcs = functions();
- if (superClass)
+ for (auto superClass : m_baseClasses) {
superClass->fixFunctions();
- int iface_idx = 0;
- while (superClass || iface_idx < interfaces().size()) {
// Since we always traverse the complete hierarchy we are only
// interrested in what each super class implements, not what
// we may have propagated from their base classes again.
AbstractMetaFunctionList superFuncs;
- if (superClass) {
- // Super classes can never be final
- if (superClass->isFinalInTargetLang()) {
- qCWarning(lcShiboken).noquote().nospace()
- << "Final class '" << superClass->name() << "' set to non-final, as it is extended by other classes";
- *superClass -= AbstractMetaAttributes::FinalInTargetLang;
- }
- superFuncs = superClass->queryFunctions(AbstractMetaClass::ClassImplements);
- AbstractMetaFunctionList virtuals = superClass->queryFunctions(AbstractMetaClass::VirtualInCppFunctions);
- superFuncs += virtuals;
- } else {
- superFuncs = interfaces().at(iface_idx)->queryFunctions(AbstractMetaClass::NormalFunctions);
- AbstractMetaFunctionList virtuals = interfaces().at(iface_idx)->queryFunctions(AbstractMetaClass::VirtualInCppFunctions);
- superFuncs += virtuals;
+ // Super classes can never be final
+ if (superClass->isFinalInTargetLang()) {
+ qCWarning(lcShiboken).noquote().nospace()
+ << "Final class '" << superClass->name() << "' set to non-final, as it is extended by other classes";
+ *superClass -= AbstractMetaAttributes::FinalInTargetLang;
}
+ superFuncs = superClass->queryFunctions(AbstractMetaClass::ClassImplements);
+ AbstractMetaFunctionList virtuals = superClass->queryFunctions(AbstractMetaClass::VirtualInCppFunctions);
+ superFuncs += virtuals;
QSet<AbstractMetaFunction *> funcsToAdd;
for (auto sf : qAsConst(superFuncs)) {
@@ -2428,11 +2327,6 @@ void AbstractMetaClass::fixFunctions()
(*copy) += AddedMethod;
funcs.append(copy);
}
-
- if (superClass)
- superClass = superClass->baseClass();
- else
- iface_idx++;
}
bool hasPrivateConstructors = false;
@@ -2531,7 +2425,7 @@ QString AbstractMetaType::formatSignature(bool minimal) const
return result;
}
-QString AbstractMetaType::formatPythonSignature(bool minimal) const
+QString AbstractMetaType::formatPythonSignature() const
{
/*
* This is a version of the above, more suitable for Python.
@@ -2554,7 +2448,7 @@ QString AbstractMetaType::formatPythonSignature(bool minimal) const
result += package() + QLatin1Char('.');
if (isArray()) {
// Build nested array dimensions a[2][3] in correct order
- result += m_arrayElementType->formatPythonSignature(true);
+ result += m_arrayElementType->formatPythonSignature();
const int arrayPos = result.indexOf(QLatin1Char('['));
if (arrayPos != -1)
result.insert(arrayPos, formatArraySize(m_arrayElementCount));
@@ -2568,7 +2462,7 @@ QString AbstractMetaType::formatPythonSignature(bool minimal) const
for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
if (i > 0)
result += QLatin1String(", ");
- result += m_instantiations.at(i)->formatPythonSignature(true);
+ result += m_instantiations.at(i)->formatPythonSignature();
}
result += QLatin1Char(']');
}
@@ -2685,6 +2579,63 @@ AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &cla
}
#ifndef QT_NO_DEBUG_STREAM
+
+void AbstractMetaClass::format(QDebug &d) const
+{
+ if (d.verbosity() > 2)
+ d << static_cast<const void *>(this) << ", ";
+ d << '"' << qualifiedCppName();
+ if (const int count = m_templateArgs.size()) {
+ for (int i = 0; i < count; ++i)
+ d << (i ? ',' : '<') << m_templateArgs.at(i)->qualifiedCppName();
+ d << '>';
+ }
+ d << '"';
+ if (isNamespace())
+ d << " [namespace]";
+ if (attributes() & AbstractMetaAttributes::FinalCppClass)
+ d << " [final]";
+ if (attributes().testFlag(AbstractMetaAttributes::Deprecated))
+ d << " [deprecated]";
+ if (!m_baseClasses.isEmpty()) {
+ d << ", inherits ";
+ for (auto b : m_baseClasses)
+ d << " \"" << b->name() << '"';
+ }
+ if (auto templateBase = templateBaseClass()) {
+ const auto instantiatedTypes = templateBaseClassInstantiations();
+ d << ", instantiates \"" << templateBase->name();
+ for (int i = 0, count = instantiatedTypes.size(); i < count; ++i)
+ d << (i ? ',' : '<') << instantiatedTypes.at(i)->name();
+ d << ">\"";
+ }
+}
+
+void AbstractMetaClass::formatMembers(QDebug &d) const
+{
+ if (!m_enums.isEmpty())
+ d << ", enums[" << m_enums.size() << "]=" << m_enums;
+ if (!m_functions.isEmpty()) {
+ const int count = m_functions.size();
+ d << ", functions=[" << count << "](";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ d << ", ";
+ formatMetaFunctionBrief(d, m_functions.at(i));
+ }
+ d << ')';
+ }
+ if (const int count = m_fields.size()) {
+ d << ", fields=[" << count << "](";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ d << ", ";
+ formatMetaField(d, m_fields.at(i));
+ }
+ d << ')';
+ }
+}
+
QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
{
QDebugStateSaver saver(d);
@@ -2692,57 +2643,9 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
d.nospace();
d << "AbstractMetaClass(";
if (ac) {
- d << '"' << ac->fullName() << '"';
- if (ac->attributes() & AbstractMetaAttributes::FinalCppClass)
- d << " [final]";
- if (ac->attributes().testFlag(AbstractMetaAttributes::Deprecated))
- d << " [deprecated]";
- if (ac->m_baseClass)
- d << ", inherits \"" << ac->m_baseClass->name() << '"';
- if (ac->m_templateBaseClass)
- d << ", inherits template \"" << ac->m_templateBaseClass->name() << '"';
- const AbstractMetaEnumList &enums = ac->enums();
- if (!enums.isEmpty())
- d << ", enums[" << enums.size() << "]=" << enums;
- const AbstractMetaFunctionList &functions = ac->functions();
- if (!functions.isEmpty()) {
- const int count = functions.size();
- d << ", functions=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
-#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
- if (d.verbosity() > 2)
- d << functions.at(i);
- else
-#endif
- formatMetaFunctionBrief(d, functions.at(i));
- }
- d << ')';
- }
- const AbstractMetaFieldList &fields = ac->fields();
- if (!fields.isEmpty()) {
- const int count = fields.size();
- d << ", fields=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
- formatMetaField(d, fields.at(i));
- }
- d << ')';
- }
- const auto &templateArguments = ac->templateArguments();
- if (const int count = templateArguments.size()) {
- d << ", templateArguments=[" << count << "](";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
- d << templateArguments.at(i);
- }
- d << ')';
- }
-
-
+ ac->format(d);
+ if (d.verbosity() > 2)
+ ac->formatMembers(d);
} else {
d << '0';
}
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 166e7d0cb..00f137100 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -538,7 +538,7 @@ public:
private:
TypeUsagePattern determineUsagePattern() const;
QString formatSignature(bool minimal) const;
- QString formatPythonSignature(bool minimal) const;
+ QString formatPythonSignature() const;
const TypeEntry *m_typeEntry = nullptr;
AbstractMetaTypeList m_instantiations;
@@ -704,25 +704,26 @@ private:
friend class AbstractMetaClass;
};
+class EnclosingClassMixin {
+public:
+ const AbstractMetaClass *enclosingClass() const { return m_enclosingClass; }
+ void setEnclosingClass(const AbstractMetaClass *cls) { m_enclosingClass = cls; }
+ const AbstractMetaClass *targetLangEnclosingClass() const;
+
+private:
+ const AbstractMetaClass *m_enclosingClass = nullptr;
+};
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const AbstractMetaArgument *aa);
#endif
-class AbstractMetaField : public AbstractMetaVariable, public AbstractMetaAttributes
+class AbstractMetaField : public AbstractMetaVariable, public AbstractMetaAttributes, public EnclosingClassMixin
{
public:
AbstractMetaField();
~AbstractMetaField();
- const AbstractMetaClass *enclosingClass() const
- {
- return m_class;
- }
- void setEnclosingClass(const AbstractMetaClass *cls)
- {
- m_class = cls;
- }
-
const AbstractMetaFunction *getter() const;
const AbstractMetaFunction *setter() const;
@@ -741,7 +742,6 @@ public:
private:
mutable AbstractMetaFunction *m_getter = nullptr;
mutable AbstractMetaFunction *m_setter = nullptr;
- const AbstractMetaClass *m_class = nullptr;
};
#ifndef QT_NO_DEBUG_STREAM
@@ -763,7 +763,9 @@ public:
SignalFunction,
EmptyFunction,
SlotFunction,
- GlobalScopeFunction
+ GlobalScopeFunction,
+ GetAttroFunction,
+ SetAttroFunction
};
Q_ENUM(FunctionType)
@@ -1179,7 +1181,7 @@ private:
Documentation m_doc;
};
-class AbstractMetaEnum : public AbstractMetaAttributes
+class AbstractMetaEnum : public AbstractMetaAttributes, public EnclosingClassMixin
{
public:
AbstractMetaEnum();
@@ -1234,23 +1236,12 @@ public:
m_typeEntry = entry;
}
- AbstractMetaClass *enclosingClass() const
- {
- return m_class;
- }
-
- void setEnclosingClass(AbstractMetaClass *c)
- {
- m_class = c;
- }
-
bool isSigned() const { return m_signed; }
void setSigned(bool s) { m_signed = s; }
private:
AbstractMetaEnumValueList m_enumValues;
EnumTypeEntry *m_typeEntry = nullptr;
- AbstractMetaClass *m_class = nullptr;
EnumKind m_enumKind = CEnum;
uint m_hasQenumsDeclaration : 1;
@@ -1261,7 +1252,7 @@ private:
QDebug operator<<(QDebug d, const AbstractMetaEnum *ae);
#endif
-class AbstractMetaClass : public AbstractMetaAttributes
+class AbstractMetaClass : public AbstractMetaAttributes, public EnclosingClassMixin
{
Q_GADGET
public:
@@ -1282,7 +1273,9 @@ public:
VirtualInTargetLangFunctions = 0x0080000, // Only functions which are virtual in TargetLang
NotRemovedFromTargetLang = 0x0400000, // Only functions that have not been removed from TargetLang
OperatorOverloads = 0x2000000, // Only functions that are operator overloads
- GenerateExceptionHandling = 0x4000000
+ GenerateExceptionHandling = 0x4000000,
+ GetAttroFunction = 0x8000000,
+ SetAttroFunction = 0x10000000
};
Q_DECLARE_FLAGS(FunctionQueryOptions, FunctionQueryOption)
Q_FLAG(FunctionQueryOption)
@@ -1306,7 +1299,6 @@ public:
AbstractMetaClass();
~AbstractMetaClass();
- AbstractMetaClass *extractInterface();
void fixFunctions();
AbstractMetaFunctionList functions() const
@@ -1444,13 +1436,6 @@ public:
AbstractMetaEnum *findEnum(const QString &enumName);
AbstractMetaEnumValue *findEnumValue(const QString &enumName);
- AbstractMetaClassList interfaces() const
- {
- return m_interfaces;
- }
- void addInterface(AbstractMetaClass *interface);
- void setInterfaces(const AbstractMetaClassList &interface);
-
QString fullName() const
{
return package() + QLatin1Char('.') + name();
@@ -1464,32 +1449,24 @@ public:
QString baseClassName() const
{
- return m_baseClass ? m_baseClass->name() : QString();
+ return m_baseClasses.isEmpty() ? QString() : m_baseClasses.constFirst()->name();
}
AbstractMetaClass *baseClass() const
{
- return m_baseClass;
+ return m_baseClasses.value(0, nullptr);
}
+ const AbstractMetaClassList &baseClasses() const { return m_baseClasses; }
+ void addBaseClass(AbstractMetaClass *base_class);
void setBaseClass(AbstractMetaClass *base_class);
- const AbstractMetaClass *enclosingClass() const
- {
- return m_enclosingClass;
- }
-
/**
* \return the namespace from another package which this namespace extends.
*/
AbstractMetaClass *extendedNamespace() const { return m_extendedNamespace; }
void setExtendedNamespace(AbstractMetaClass *e) { m_extendedNamespace = e; }
- void setEnclosingClass(AbstractMetaClass *cl)
- {
- m_enclosingClass = cl;
- }
-
const AbstractMetaClassList& innerClasses() const
{
return m_innerClasses;
@@ -1507,8 +1484,6 @@ public:
QString package() const;
- bool isInterface() const;
-
bool isNamespace() const;
bool isQObject() const;
@@ -1709,6 +1684,8 @@ public:
private:
#ifndef QT_NO_DEBUG_STREAM
+ void format(QDebug &d) const;
+ void formatMembers(QDebug &d) const;
friend QDebug operator<<(QDebug d, const AbstractMetaClass *ac);
#endif
uint m_hasVirtuals : 1;
@@ -1727,21 +1704,19 @@ private:
uint m_hasToStringCapability : 1;
const AbstractMetaClass *m_enclosingClass = nullptr;
- AbstractMetaClass *m_baseClass = nullptr;
+ AbstractMetaClassList m_baseClasses; // Real base classes after setting up inheritance
AbstractMetaClass *m_extendedNamespace = nullptr;
const AbstractMetaClass *m_templateBaseClass = nullptr;
AbstractMetaFunctionList m_functions;
AbstractMetaFieldList m_fields;
AbstractMetaEnumList m_enums;
- AbstractMetaClassList m_interfaces;
- AbstractMetaClass *m_extractedInterface = nullptr;
QVector<QPropertySpec *> m_propertySpecs;
AbstractMetaClassList m_innerClasses;
AbstractMetaFunctionList m_externalConversionOperators;
- QStringList m_baseClassNames;
+ QStringList m_baseClassNames; // Base class names from C++, including rejected
QVector<TypeEntry *> m_templateArgs;
ComplexTypeEntry *m_typeEntry = nullptr;
// FunctionModelItem m_qDebugStreamFunction;
diff --git a/sources/shiboken2/ApiExtractor/apiextractor.cpp b/sources/shiboken2/ApiExtractor/apiextractor.cpp
index 78fa9e313..530ed0252 100644
--- a/sources/shiboken2/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken2/ApiExtractor/apiextractor.cpp
@@ -82,9 +82,9 @@ void ApiExtractor::setLogDirectory(const QString& logDir)
m_logDirectory = logDir;
}
-void ApiExtractor::setCppFileName(const QString& cppFileName)
+void ApiExtractor::setCppFileNames(const QFileInfoList &cppFileName)
{
- m_cppFileName = cppFileName;
+ m_cppFileNames = cppFileName;
}
void ApiExtractor::setTypeSystem(const QString& typeSystemFileName)
@@ -92,11 +92,6 @@ void ApiExtractor::setTypeSystem(const QString& typeSystemFileName)
m_typeSystemFileName = typeSystemFileName;
}
-void ApiExtractor::setDebugLevel(ReportHandler::DebugLevel debugLevel)
-{
- ReportHandler::setDebugLevel(debugLevel);
-}
-
void ApiExtractor::setSkipDeprecated(bool value)
{
m_skipDeprecated = value;
@@ -166,24 +161,6 @@ ContainerTypeEntryList ApiExtractor::containerTypes() const
return TypeDatabase::instance()->containerTypes();
}
-static const AbstractMetaEnum* findEnumOnClasses(AbstractMetaClassList metaClasses, const EnumTypeEntry* typeEntry)
-{
- const AbstractMetaEnum *result = nullptr;
- for (const AbstractMetaClass* metaClass : qAsConst(metaClasses)) {
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (const AbstractMetaEnum *metaEnum : enums) {
- if (metaEnum->typeEntry() == typeEntry) {
- result = metaEnum;
- break;
- }
- }
- if (result)
- break;
- result = findEnumOnClasses(metaClass->innerClasses(), typeEntry);
- }
- return result;
-}
-
const AbstractMetaEnum* ApiExtractor::findAbstractMetaEnum(const TypeEntry* typeEntry) const
{
return m_builder->findEnum(typeEntry);
@@ -205,8 +182,9 @@ bool ApiExtractor::run()
return false;
}
- const QString pattern = QDir::tempPath() + QLatin1Char('/') +
- QFileInfo(m_cppFileName).baseName() + QStringLiteral("_XXXXXX.hpp");
+ const QString pattern = QDir::tempPath() + QLatin1Char('/')
+ + m_cppFileNames.constFirst().baseName()
+ + QStringLiteral("_XXXXXX.hpp");
QTemporaryFile ppFile(pattern);
bool autoRemove = !qEnvironmentVariableIsSet("KEEP_TEMP_FILES");
// make sure that a tempfile can be written
@@ -215,14 +193,16 @@ bool ApiExtractor::run()
<< ": " << qPrintable(ppFile.errorString()) << '\n';
return false;
}
- ppFile.write("#include \"");
- ppFile.write(m_cppFileName.toLocal8Bit());
- ppFile.write("\"\n");
+ for (const auto &cppFileName : qAsConst(m_cppFileNames)) {
+ ppFile.write("#include \"");
+ ppFile.write(cppFileName.absoluteFilePath().toLocal8Bit());
+ ppFile.write("\"\n");
+ }
const QString preprocessedCppFileName = ppFile.fileName();
ppFile.close();
m_builder = new AbstractMetaBuilder;
m_builder->setLogDirectory(m_logDirectory);
- m_builder->setGlobalHeader(m_cppFileName);
+ m_builder->setGlobalHeaders(m_cppFileNames);
m_builder->setSkipDeprecated(m_skipDeprecated);
m_builder->setHeaderPaths(m_includePaths);
QByteArrayList arguments;
@@ -230,8 +210,11 @@ bool ApiExtractor::run()
for (const HeaderPath &headerPath : qAsConst(m_includePaths))
arguments.append(HeaderPath::includeOption(headerPath));
arguments.append(QFile::encodeName(preprocessedCppFileName));
- qCDebug(lcShiboken) << __FUNCTION__ << arguments
- << "level=" << int(m_languageLevel);
+ if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
+ qCInfo(lcShiboken).noquote().nospace()
+ << "clang language level: " << int(m_languageLevel)
+ << "\nclang arguments: " << arguments;
+ }
const bool result = m_builder->build(arguments, m_languageLevel);
if (!result)
autoRemove = false;
@@ -273,8 +256,10 @@ QDebug operator<<(QDebug d, const ApiExtractor &ae)
QDebugStateSaver saver(d);
d.noquote();
d.nospace();
- d << "ApiExtractor(typeSystem=\"" << ae.typeSystem() << "\", cppFileName=\""
- << ae.cppFileName() << ", ";
+ if (ReportHandler::debugLevel() >= ReportHandler::FullDebug)
+ d.setVerbosity(3); // Trigger verbose output of AbstractMetaClass
+ d << "ApiExtractor(typeSystem=\"" << ae.typeSystem() << "\", cppFileNames=\""
+ << ae.cppFileNames() << ", ";
ae.m_builder->formatDebug(d);
d << ')';
return d;
diff --git a/sources/shiboken2/ApiExtractor/apiextractor.h b/sources/shiboken2/ApiExtractor/apiextractor.h
index c8f50f2a5..f6dd2ba8e 100644
--- a/sources/shiboken2/ApiExtractor/apiextractor.h
+++ b/sources/shiboken2/ApiExtractor/apiextractor.h
@@ -29,7 +29,6 @@
#ifndef APIEXTRACTOR_H
#define APIEXTRACTOR_H
-#include "reporthandler.h"
#include "dependency.h"
#include "abstractmetalang_typedefs.h"
#include "apiextractormacros.h"
@@ -37,6 +36,7 @@
#include "typedatabase_typedefs.h"
#include "typesystem_typedefs.h"
#include "clangparser/compilersupport.h"
+#include <QFileInfoList>
#include <QStringList>
class AbstractMetaBuilder;
@@ -65,9 +65,8 @@ public:
void setTypeSystem(const QString& typeSystemFileName);
QString typeSystem() const { return m_typeSystemFileName; }
- void setCppFileName(const QString& cppFileName);
- QString cppFileName() const { return m_cppFileName; }
- void setDebugLevel(ReportHandler::DebugLevel debugLevel);
+ void setCppFileNames(const QFileInfoList &cppFileNames);
+ QFileInfoList cppFileNames() const { return m_cppFileNames; }
void setSkipDeprecated(bool value);
void setSuppressWarnings(bool value);
void setSilent(bool value);
@@ -97,7 +96,7 @@ public:
bool run();
private:
QString m_typeSystemFileName;
- QString m_cppFileName;
+ QFileInfoList m_cppFileNames;
HeaderPaths m_includePaths;
AbstractMetaBuilder* m_builder = nullptr;
QString m_logDirectory;
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index d52e4672b..1eaa36540 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -191,6 +191,8 @@ public:
bool addTemplateInstantiationsRecursion(const CXType &type, TypeInfo *t) const;
void addTypeDef(const CXCursor &cursor, const CXType &cxType);
+ void startTemplateTypeAlias(const CXCursor &cursor);
+ void endTemplateTypeAlias(const CXCursor &typeAliasCursor);
TemplateParameterModelItem createTemplateParameter(const CXCursor &cursor) const;
TemplateParameterModelItem createNonTypeTemplateParameter(const CXCursor &cursor) const;
@@ -216,12 +218,16 @@ public:
CursorTypedefHash m_cursorTypedefHash;
mutable TypeInfoHash m_typeInfoHash; // Cache type information
+ mutable QHash<QString, TemplateTypeAliasModelItem> m_templateTypeAliases;
ClassModelItem m_currentClass;
EnumModelItem m_currentEnum;
FunctionModelItem m_currentFunction;
ArgumentModelItem m_currentArgument;
VariableModelItem m_currentField;
+ TemplateTypeAliasModelItem m_currentTemplateTypeAlias;
+ QByteArrayList m_systemIncludes; // files, like "memory"
+ QByteArrayList m_systemIncludePaths; // paths, like "/usr/include/Qt/"
int m_anonymousEnumCount = 0;
CodeModel::FunctionType m_currentFunctionType = CodeModel::Normal;
@@ -464,6 +470,8 @@ void BuilderPrivate::addTemplateInstantiations(const CXType &type,
// Finally, remove the list "<>" from the type name.
const bool parsed = addTemplateInstantiationsRecursion(type, t)
&& !t->instantiations().isEmpty();
+ if (!parsed)
+ t->setInstantiations({});
const QPair<int, int> pos = parsed
? parseTemplateArgumentList(*typeName, dummyTemplateArgumentHandler)
: t->parseTemplateArgumentList(*typeName);
@@ -550,6 +558,26 @@ void BuilderPrivate::addTypeDef(const CXCursor &cursor, const CXType &cxType)
m_cursorTypedefHash.insert(cursor, item);
}
+void BuilderPrivate::startTemplateTypeAlias(const CXCursor &cursor)
+{
+ const QString target = getCursorSpelling(cursor);
+ m_currentTemplateTypeAlias.reset(new _TemplateTypeAliasModelItem(m_model, target));
+ setFileName(cursor, m_currentTemplateTypeAlias.data());
+ m_currentTemplateTypeAlias->setScope(m_scope);
+}
+
+void BuilderPrivate::endTemplateTypeAlias(const CXCursor &typeAliasCursor)
+{
+ CXType type = clang_getTypedefDeclUnderlyingType(typeAliasCursor);
+ // Usually "<elaborated>std::list<T>" or "<unexposed>Container1<T>",
+ // as obtained with parser of PYSIDE-323
+ if (type.kind == CXType_Unexposed || type.kind == CXType_Elaborated) {
+ m_currentTemplateTypeAlias->setType(createTypeInfo(type));
+ m_scopeStack.back()->addTemplateTypeAlias(m_currentTemplateTypeAlias);
+ }
+ m_currentTemplateTypeAlias.reset();
+}
+
// extract an expression from the cursor via source
// CXCursor_EnumConstantDecl, ParmDecl (a = Flag1 | Flag2)
QString BuilderPrivate::cursorValueExpression(BaseVisitor *bv, const CXCursor &cursor) const
@@ -592,13 +620,52 @@ long clang_EnumDecl_isScoped4(BaseVisitor *bv, const CXCursor &cursor)
}
#endif // CLANG_NO_ENUMDECL_ISSCOPED
+// Resolve declaration and type of a base class
+
+struct TypeDeclaration
+{
+ CXType type;
+ CXCursor declaration;
+};
+
+static TypeDeclaration resolveBaseSpecifier(const CXCursor &cursor)
+{
+ Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier);
+ CXType inheritedType = clang_getCursorType(cursor);
+ CXCursor decl = clang_getTypeDeclaration(inheritedType);
+ if (inheritedType.kind != CXType_Unexposed) {
+ while (true) {
+ auto kind = clang_getCursorKind(decl);
+ if (kind != CXCursor_TypeAliasDecl && kind != CXCursor_TypedefDecl)
+ break;
+ inheritedType = clang_getTypedefDeclUnderlyingType(decl);
+ decl = clang_getTypeDeclaration(inheritedType);
+ }
+ }
+ return {inheritedType, decl};
+}
+
// Add a base class to the current class from CXCursor_CXXBaseSpecifier
void BuilderPrivate::addBaseClass(const CXCursor &cursor)
{
- const CXType inheritedType = clang_getCursorType(cursor); // Note spelling has "struct baseClass",
- QString baseClassName = getTypeName(inheritedType); // use type.
- const CXCursor declCursor = clang_getTypeDeclaration(inheritedType);
- const CursorClassHash::const_iterator it = m_cursorClassHash.constFind(declCursor);
+ Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier);
+ // Note: spelling has "struct baseClass", use type
+ QString baseClassName;
+ const auto decl = resolveBaseSpecifier(cursor);
+ if (decl.type.kind == CXType_Unexposed) {
+ // The type is unexposed when the base class is a template type alias:
+ // "class QItemSelection : public QList<X>" where QList is aliased to QVector.
+ // Try to resolve via code model.
+ TypeInfo info = createTypeInfo(decl.type);
+ auto parentScope = m_scopeStack.at(m_scopeStack.size() - 2); // Current is class.
+ auto resolved = TypeInfo::resolveType(info, parentScope);
+ if (resolved != info)
+ baseClassName = resolved.toString();
+ }
+ if (baseClassName.isEmpty())
+ baseClassName = getTypeName(decl.type);
+
+ auto it = m_cursorClassHash.constFind(decl.declaration);
const CodeModel::AccessPolicy access = accessPolicy(clang_getCXXAccessSpecifier(cursor));
if (it == m_cursorClassHash.constEnd()) {
// Set unqualified name. This happens in cases like "class X : public std::list<...>"
@@ -695,6 +762,11 @@ static bool cStringStartsWith(const char *str, const char (&prefix)[N])
}
#endif
+static bool cStringStartsWith(const char *str, const QByteArray &prefix)
+{
+ return std::strncmp(prefix.constData(), str, int(prefix.size())) == 0;
+}
+
bool BuilderPrivate::visitHeader(const char *cFileName) const
{
// Resolve OpenGL typedefs although the header is considered a system header.
@@ -721,6 +793,16 @@ bool BuilderPrivate::visitHeader(const char *cFileName) const
return true;
}
#endif // Q_OS_MACOS
+ if (baseName) {
+ for (const auto &systemInclude : m_systemIncludes) {
+ if (systemInclude == baseName)
+ return true;
+ }
+ }
+ for (const auto &systemIncludePath : m_systemIncludePaths) {
+ if (cStringStartsWith(cFileName, systemIncludePath))
+ return true;
+ }
return false;
}
@@ -743,6 +825,16 @@ bool Builder::visitLocation(const CXSourceLocation &location) const
return result;
}
+void Builder::setSystemIncludes(const QByteArrayList &systemIncludes)
+{
+ for (const auto &i : systemIncludes) {
+ if (i.endsWith('/'))
+ d->m_systemIncludePaths.append(i);
+ else
+ d->m_systemIncludes.append(i);
+ }
+}
+
FileModelItem Builder::dom() const
{
Q_ASSERT(!d->m_scopeStack.isEmpty());
@@ -766,6 +858,17 @@ static CodeModel::ClassType codeModelClassTypeFromCursor(CXCursorKind kind)
return result;
}
+static NamespaceType namespaceType(const CXCursor &cursor)
+{
+ if (clang_Cursor_isAnonymous(cursor))
+ return NamespaceType::Anonymous;
+#if CINDEX_VERSION_MAJOR > 0 || CINDEX_VERSION_MINOR >= 59
+ if (clang_Cursor_isInlineNamespace(cursor))
+ return NamespaceType::Inline;
+#endif
+ return NamespaceType::Default;
+}
+
static QString enumType(const CXCursor &cursor)
{
QString name = getCursorSpelling(cursor); // "enum Foo { v1, v2 };"
@@ -904,6 +1007,9 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
d->m_scopeStack.back()->addFunction(d->m_currentFunction);
break;
case CXCursor_Namespace: {
+ const auto type = namespaceType(cursor);
+ if (type == NamespaceType::Anonymous)
+ return Skip;
const QString name = getCursorSpelling(cursor);
const NamespaceModelItem parentNamespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(d->m_scopeStack.back());
if (parentNamespaceItem.isNull()) {
@@ -920,6 +1026,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
namespaceItem.reset(new _NamespaceModelItem(d->m_model, name));
setFileName(cursor, namespaceItem.data());
namespaceItem->setScope(d->m_scope);
+ namespaceItem->setType(type);
parentNamespaceItem->addNamespace(namespaceItem);
d->pushScope(namespaceItem);
}
@@ -948,6 +1055,8 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
// Apply to function/member template?
if (!d->m_currentFunction.isNull()) {
d->m_currentFunction->setTemplateParameters(d->m_currentFunction->templateParameters() << tItem);
+ } else if (!d->m_currentTemplateTypeAlias.isNull()) {
+ d->m_currentTemplateTypeAlias->addTemplateParameter(tItem);
} else if (!d->m_currentClass.isNull()) { // Apply to class
const QString &tplParmName = tItem->name();
if (Q_UNLIKELY(!insertTemplateParameterIntoClassName(tplParmName, d->m_currentClass)
@@ -963,13 +1072,19 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
}
}
break;
- case CXCursor_TypeAliasDecl:
- case CXCursor_TypeAliasTemplateDecl: { // May contain nested CXCursor_TemplateTypeParameter
- const CXType type = clang_getCanonicalType(clang_getCursorType(cursor));
- if (type.kind > CXType_Unexposed)
- d->addTypeDef(cursor, type);
- }
- return Skip;
+ case CXCursor_TypeAliasTemplateDecl:
+ d->startTemplateTypeAlias(cursor);
+ break;
+ case CXCursor_TypeAliasDecl: // May contain nested CXCursor_TemplateTypeParameter
+ if (d->m_currentTemplateTypeAlias.isNull()) {
+ const CXType type = clang_getCanonicalType(clang_getCursorType(cursor));
+ if (type.kind > CXType_Unexposed)
+ d->addTypeDef(cursor, type);
+ return Skip;
+ } else {
+ d->endTemplateTypeAlias(cursor);
+ }
+ break;
case CXCursor_TypedefDecl: {
auto underlyingType = clang_getTypedefDeclUnderlyingType(cursor);
d->addTypeDef(cursor, underlyingType);
@@ -1048,6 +1163,9 @@ bool Builder::endToken(const CXCursor &cursor)
case CXCursor_ParmDecl:
d->m_currentArgument.clear();
break;
+ case CXCursor_TypeAliasTemplateDecl:
+ d->m_currentTemplateTypeAlias.reset();
+ break;
default:
break;
}
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h
index fa79acb2a..dc37dff0f 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h
@@ -44,6 +44,8 @@ public:
Builder();
~Builder();
+ void setSystemIncludes(const QByteArrayList &systemIncludes);
+
bool visitLocation(const CXSourceLocation &location) const override;
StartTokenResult startToken(const CXCursor &cursor) override;
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
index 8bee28cdf..df2476100 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
@@ -40,7 +40,7 @@ bool operator==(const CXCursor &c1, const CXCursor &c2)
&& std::equal(c1.data, c1.data + sizeof(c1.data) / sizeof(c1.data[0]), c2.data);
}
-uint qHash(const CXCursor &c, uint seed)
+QtCompatHashFunctionType qHash(const CXCursor &c, QtCompatHashFunctionType seed)
{
return qHash(c.kind) ^ qHash(c.xdata) ^ qHash(c.data[0])
^ qHash(c.data[1]) ^ qHash(c.data[2]) ^ seed;
@@ -52,10 +52,10 @@ bool operator==(const CXType &t1, const CXType &t2)
&& t1.data[1] == t2.data[1];
}
-uint qHash(const CXType &ct, uint seed)
+QtCompatHashFunctionType qHash(const CXType &ct, QtCompatHashFunctionType seed)
{
- return uint(ct.kind) ^ uint(0xFFFFFFFF & quintptr(ct.data[0]))
- ^ uint(0xFFFFFFFF & quintptr(ct.data[1])) ^ seed;
+ return QtCompatHashFunctionType(ct.kind) ^ QtCompatHashFunctionType(0xFFFFFFFF & quintptr(ct.data[0]))
+ ^ QtCompatHashFunctionType(0xFFFFFFFF & quintptr(ct.data[1])) ^ seed;
}
namespace clang {
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
index 738b51bb4..5f005bd5d 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
@@ -30,6 +30,7 @@
#define CLANGUTILS_H
#include <clang-c/Index.h>
+#include <qtcompat.h>
#include <QtCore/QPair>
#include <QtCore/QString>
#include <QtCore/QStringList>
@@ -40,10 +41,10 @@
QT_FORWARD_DECLARE_CLASS(QDebug)
bool operator==(const CXCursor &c1, const CXCursor &c2);
-uint qHash(const CXCursor &c, uint seed = 0);
+QtCompatHashFunctionType qHash(const CXCursor &c, QtCompatHashFunctionType seed = 0);
bool operator==(const CXType &t1, const CXType &t2);
-uint qHash(const CXType &ct, uint seed);
+QtCompatHashFunctionType qHash(const CXType &ct, QtCompatHashFunctionType seed);
namespace clang {
diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
index 188725da9..dac511003 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
@@ -356,12 +356,16 @@ QByteArrayList emulatedCompilerOptions()
LanguageLevel emulatedCompilerLanguageLevel()
{
-#if defined(Q_CC_MSVC) && _MSC_VER > 1900
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ return LanguageLevel::Cpp17;
+#else
+# if defined(Q_CC_MSVC) && _MSC_VER > 1900
// Fixes constexpr errors in MSVC2017 library headers with Clang 4.1..5.X (0.45 == Clang 6).
if (libClangVersion() < QVersionNumber(0, 45))
return LanguageLevel::Cpp1Z;
-#endif // Q_CC_MSVC && _MSC_VER > 1900
+# endif // Q_CC_MSVC && _MSC_VER > 1900
return LanguageLevel::Cpp14; // otherwise, t.h is parsed as "C"
+#endif // Qt 5
}
struct LanguageLevelMapping
diff --git a/sources/shiboken2/ApiExtractor/docparser.cpp b/sources/shiboken2/ApiExtractor/docparser.cpp
index 532956d1a..cb5d85074 100644
--- a/sources/shiboken2/ApiExtractor/docparser.cpp
+++ b/sources/shiboken2/ApiExtractor/docparser.cpp
@@ -65,7 +65,7 @@ QString DocParser::execXQuery(const XQueryPtr &xquery, const QString& query) con
QString errorMessage;
const QString result = xquery->evaluate(query, &errorMessage);
if (!errorMessage.isEmpty())
- qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return result;
}
@@ -138,12 +138,12 @@ R"(<xsl:template match="/">
QString errorMessage;
const QString result = xsl_transform(xml, xsl, &errorMessage);
if (!errorMessage.isEmpty())
- qCWarning(lcShiboken, "%s",
+ qCWarning(lcShibokenDoc, "%s",
qPrintable(msgXpathDocModificationError(mods, errorMessage)));
if (result == xml) {
const QString message = QLatin1String("Query did not result in any modifications to \"")
+ xml + QLatin1Char('"');
- qCWarning(lcShiboken, "%s",
+ qCWarning(lcShibokenDoc, "%s",
qPrintable(msgXpathDocModificationError(mods, message)));
}
return result;
diff --git a/sources/shiboken2/ApiExtractor/doxygenparser.cpp b/sources/shiboken2/ApiExtractor/doxygenparser.cpp
index 94c9ec7e0..7c15db1ca 100644
--- a/sources/shiboken2/ApiExtractor/doxygenparser.cpp
+++ b/sources/shiboken2/ApiExtractor/doxygenparser.cpp
@@ -80,7 +80,7 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
}
if (doxyFilePath.isEmpty()) {
- qCWarning(lcShiboken).noquote().nospace()
+ qCWarning(lcShibokenDoc).noquote().nospace()
<< "Can't find doxygen file for class " << metaClass->name() << ", tried: "
<< QDir::toNativeSeparators(documentationDataDirectory())
<< "/{struct|class|namespace}"<< doxyFileSuffix;
@@ -90,7 +90,7 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
QString errorMessage;
XQueryPtr xquery = XQuery::create(doxyFilePath, &errorMessage);
if (xquery.isNull()) {
- qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return;
}
@@ -99,7 +99,7 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
QString classDoc = getDocumentation(xquery, classQuery,
metaClass->typeEntry()->docModifications());
if (classDoc.isEmpty())
- qCWarning(lcShiboken(), "%s", qPrintable(msgCannotFindDocumentation(doxyFilePath, "class", metaClass->name(), classQuery)));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotFindDocumentation(doxyFilePath, "class", metaClass->name(), classQuery)));
metaClass->setDocumentation(classDoc);
//Functions Documentation
@@ -146,7 +146,7 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
}
QString doc = getDocumentation(xquery, query, DocModificationList());
if (doc.isEmpty()) {
- qCWarning(lcShiboken(), "%s",
+ qCWarning(lcShibokenDoc, "%s",
qPrintable(msgCannotFindDocumentation(doxyFilePath, metaClass, func, query)));
}
func->setDocumentation(doc);
@@ -163,7 +163,7 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
+ field->name() + QLatin1String("\"]/../detaileddescription");
QString doc = getDocumentation(xquery, query, DocModificationList());
if (doc.isEmpty()) {
- qCWarning(lcShiboken(), "%s",
+ qCWarning(lcShibokenDoc, "%s",
qPrintable(msgCannotFindDocumentation(doxyFilePath, metaClass, field, query)));
}
field->setDocumentation(doc);
@@ -176,7 +176,7 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
+ meta_enum->name() + QLatin1String("\"]/..");
QString doc = getDocumentation(xquery, query, DocModificationList());
if (doc.isEmpty()) {
- qCWarning(lcShiboken(), "%s",
+ qCWarning(lcShibokenDoc, "%s",
qPrintable(msgCannotFindDocumentation(doxyFilePath, metaClass, meta_enum, query)));
}
meta_enum->setDocumentation(doc);
@@ -189,7 +189,7 @@ Documentation DoxygenParser::retrieveModuleDocumentation(const QString& name){
QString sourceFile = documentationDataDirectory() + QLatin1String("/indexpage.xml");
if (!QFile::exists(sourceFile)) {
- qCWarning(lcShiboken).noquote().nospace()
+ qCWarning(lcShibokenDoc).noquote().nospace()
<< "Can't find doxygen XML file for module " << name << ", tried: "
<< QDir::toNativeSeparators(sourceFile);
return Documentation();
@@ -198,7 +198,7 @@ Documentation DoxygenParser::retrieveModuleDocumentation(const QString& name){
QString errorMessage;
XQueryPtr xquery = XQuery::create(sourceFile, &errorMessage);
if (xquery.isNull()) {
- qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return {};
}
diff --git a/sources/shiboken2/ApiExtractor/graph.cpp b/sources/shiboken2/ApiExtractor/graph.cpp
index 95a80197e..53e20ebba 100644
--- a/sources/shiboken2/ApiExtractor/graph.cpp
+++ b/sources/shiboken2/ApiExtractor/graph.cpp
@@ -101,7 +101,7 @@ bool Graph::containsEdge(int from, int to)
void Graph::addEdge(int from, int to)
{
- Q_ASSERT(to < (int)m_d->edges.size());
+ Q_ASSERT(to < m_d->edges.size());
m_d->edges[from].insert(to);
}
diff --git a/sources/shiboken2/ApiExtractor/include.cpp b/sources/shiboken2/ApiExtractor/include.cpp
index d6a451992..6c2cce3a9 100644
--- a/sources/shiboken2/ApiExtractor/include.cpp
+++ b/sources/shiboken2/ApiExtractor/include.cpp
@@ -41,7 +41,7 @@ QString Include::toString() const
return QLatin1String("import ") + m_name + QLatin1Char(';');
}
-uint qHash(const Include& inc)
+QtCompatHashFunctionType qHash(const Include& inc)
{
return qHash(inc.m_name);
}
@@ -49,7 +49,7 @@ uint qHash(const Include& inc)
QTextStream& operator<<(QTextStream& out, const Include& include)
{
if (include.isValid())
- out << include.toString() << endl;
+ out << include.toString() << Qt::endl;
return out;
}
diff --git a/sources/shiboken2/ApiExtractor/include.h b/sources/shiboken2/ApiExtractor/include.h
index f7dfea5a7..2219fba55 100644
--- a/sources/shiboken2/ApiExtractor/include.h
+++ b/sources/shiboken2/ApiExtractor/include.h
@@ -29,6 +29,8 @@
#ifndef INCLUDE_H
#define INCLUDE_H
+#include <qtcompat.h>
+
#include <QString>
#include <QVector>
@@ -76,13 +78,13 @@ public:
return m_type == other.m_type && m_name == other.m_name;
}
- friend uint qHash(const Include&);
+ friend QtCompatHashFunctionType qHash(const Include&);
private:
IncludeType m_type = IncludePath;
QString m_name;
};
-uint qHash(const Include& inc);
+QtCompatHashFunctionType qHash(const Include& inc);
QTextStream& operator<<(QTextStream& out, const Include& include);
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const Include &i);
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
index 0eb3c607f..0e905c9a0 100644
--- a/sources/shiboken2/ApiExtractor/messages.cpp
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -28,6 +28,7 @@
#include "messages.h"
#include "abstractmetalang.h"
+#include "typedatabase.h"
#include "typesystem.h"
#include <codemodel.h>
@@ -152,6 +153,22 @@ QString msgNoEnumTypeConflict(const EnumModelItem &enumItem,
return result;
}
+QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntries &te)
+{
+ QString result = QLatin1String("Ambiguous types of varying types found for \"") + qualifiedName
+ + QLatin1String("\": ");
+ QDebug(&result) << te;
+ return result;
+}
+
+QString msgAmbiguousTypesFound(const QString &qualifiedName, const TypeEntries &te)
+{
+ QString result = QLatin1String("Ambiguous types found for \"") + qualifiedName
+ + QLatin1String("\": ");
+ QDebug(&result) << te;
+ return result;
+}
+
QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n,
const QString &why)
{
@@ -218,6 +235,23 @@ QString msgCannotFindTypeEntry(const QString &t)
return QLatin1String("Cannot find type entry for \"") + t + QLatin1String("\".");
}
+QString msgCannotFindTypeEntryForSmartPointer(const QString &t, const QString &smartPointerType)
+{
+ return QLatin1String("Cannot find type entry \"") + t
+ + QLatin1String("\" for instantiation of \"") + smartPointerType + QLatin1String("\".");
+}
+
+QString msgInvalidSmartPointerType(const TypeInfo &i)
+{
+ return QLatin1String("Invalid smart pointer type \"") + i.toString() + QLatin1String("\".");
+}
+
+QString msgCannotFindSmartPointerInstantion(const TypeInfo &i)
+{
+ return QLatin1String("Cannot find instantiation of smart pointer type for \"")
+ + i.toString() + QLatin1String("\".");
+}
+
QString msgCannotTranslateTemplateArgument(int i,
const TypeInfo &typeInfo,
const QString &why)
@@ -356,8 +390,10 @@ QString msgCannotFindSmartPointer(const QString &instantiationType,
QString result;
QTextStream str(&result);
str << "Unable to find smart pointer type for " << instantiationType << " (known types:";
- for (auto t : pointers)
- str << ' ' << t->fullName();
+ for (auto t : pointers) {
+ auto typeEntry = t->typeEntry();
+ str << ' ' << typeEntry->targetLangName() << '/' << typeEntry->qualifiedCppName();
+ }
str << ").";
return result;
}
diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h
index ad0553fbc..3934c35b3 100644
--- a/sources/shiboken2/ApiExtractor/messages.h
+++ b/sources/shiboken2/ApiExtractor/messages.h
@@ -66,6 +66,9 @@ QString msgNoEnumTypeConflict(const EnumModelItem &enumItem,
const QString &className,
const TypeEntry *t);
+QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntries &te);
+QString msgAmbiguousTypesFound(const QString &qualifiedName, const TypeEntries &te);
+
QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n,
const QString &why);
@@ -86,6 +89,10 @@ QString msgUnableToTranslateType(const TypeInfo &typeInfo,
QString msgCannotFindTypeEntry(const QString &t);
+QString msgCannotFindTypeEntryForSmartPointer(const QString &t, const QString &smartPointerType);
+QString msgInvalidSmartPointerType(const TypeInfo &i);
+QString msgCannotFindSmartPointerInstantion(const TypeInfo &i);
+
QString msgCannotTranslateTemplateArgument(int i,
const TypeInfo &typeInfo,
const QString &why);
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
index fdf2af872..e381ba083 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
@@ -40,7 +40,7 @@
#include <QtCore/QStack>
// Predicate to find an item by name in a list of QSharedPointer<Item>
-template <class T> class ModelItemNamePredicate : public std::unary_function<bool, QSharedPointer<T> >
+template <class T> class ModelItemNamePredicate
{
public:
explicit ModelItemNamePredicate(const QString &name) : m_name(name) {}
@@ -91,6 +91,8 @@ static CodeModelItem findRecursion(const ScopeModelItem &scope,
return es;
if (TypeDefModelItem tp = scope->findTypeDef(nameSegment))
return tp;
+ if (TemplateTypeAliasModelItem tta = scope->findTemplateTypeAlias(nameSegment))
+ return tta;
return CodeModelItem();
}
if (auto nestedClass = scope->findClass(nameSegment))
@@ -191,13 +193,29 @@ TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, con
return resolveType(nextItem, combined, __scope);
}
+ if (TemplateTypeAliasModelItem templateTypeAlias = qSharedPointerDynamicCast<_TemplateTypeAliasModelItem>(__item)) {
+
+ TypeInfo combined = TypeInfo::combine(templateTypeAlias->type(), otherType);
+ // For the alias "template<typename T> using QList = QVector<T>" with
+ // other="QList<int>", replace the instantiations to obtain "QVector<int>".
+ auto aliasInstantiations = templateTypeAlias->type().instantiations();
+ auto concreteInstantiations = otherType.instantiations();
+ const int count = qMin(aliasInstantiations.size(), concreteInstantiations.size());
+ for (int i = 0; i < count; ++i)
+ aliasInstantiations[i] = concreteInstantiations[i];
+ combined.setInstantiations(aliasInstantiations);
+ const CodeModelItem nextItem = __scope->model()->findItem(combined.qualifiedName(), __scope);
+ if (!nextItem)
+ return combined;
+ return resolveType(nextItem, combined, __scope);
+ }
+
return otherType;
}
// Handler for clang::parseTemplateArgumentList() that populates
// TypeInfo::m_instantiations
-class TypeInfoTemplateArgumentHandler :
- public std::binary_function<void, int, const QStringRef &>
+class TypeInfoTemplateArgumentHandler
{
public:
explicit TypeInfoTemplateArgumentHandler(TypeInfo *t)
@@ -640,6 +658,9 @@ void _CodeModelItem::formatKind(QDebug &d, int k)
case Kind_TypeDef:
d << "TypeDefModelItem";
break;
+ case Kind_TemplateTypeAlias:
+ d << "TemplateTypeAliasModelItem";
+ break;
default:
d << "CodeModelItem";
break;
@@ -803,6 +824,11 @@ void _ScopeModelItem::addTypeDef(const TypeDefModelItem &item)
m_typeDefs.append(item);
}
+void _ScopeModelItem::addTemplateTypeAlias(const TemplateTypeAliasModelItem &item)
+{
+ m_templateTypeAliases.append(item);
+}
+
void _ScopeModelItem::addEnum(const EnumModelItem &item)
{
m_enums.append(item);
@@ -813,6 +839,7 @@ void _ScopeModelItem::appendScope(const _ScopeModelItem &other)
m_classes += other.m_classes;
m_enums += other.m_enums;
m_typeDefs += other.m_typeDefs;
+ m_templateTypeAliases += other.m_templateTypeAliases;
m_variables += other.m_variables;
m_functions += other.m_functions;
m_enumsDeclarations += other.m_enumsDeclarations;
@@ -857,6 +884,7 @@ void _ScopeModelItem::formatScopeItemsDebug(QDebug &d) const
formatScopeList(d, ", classes=", m_classes, "\n", true);
formatScopeList(d, ", enums=", m_enums, "\n", true);
formatScopeList(d, ", aliases=", m_typeDefs, "\n", true);
+ formatScopeList(d, ", template type aliases=", m_templateTypeAliases, "\n", true);
formatScopeList(d, ", functions=", m_functions, "\n", true);
formatScopeList(d, ", variables=", m_variables);
}
@@ -872,7 +900,7 @@ namespace {
// Predicate to match a non-template class name against the class list.
// "Vector" should match "Vector" as well as "Vector<T>" (as seen for methods
// from within the class "Vector").
-class ClassNamePredicate : public std::unary_function<bool, ClassModelItem>
+class ClassNamePredicate
{
public:
explicit ClassNamePredicate(const QString &name) : m_name(name) {}
@@ -908,6 +936,11 @@ TypeDefModelItem _ScopeModelItem::findTypeDef(const QString &name) const
return findModelItem(m_typeDefs, name);
}
+TemplateTypeAliasModelItem _ScopeModelItem::findTemplateTypeAlias(const QString &name) const
+{
+ return findModelItem(m_templateTypeAliases, name);
+}
+
EnumModelItem _ScopeModelItem::findEnum(const QString &name) const
{
return findModelItem(m_enums, name);
@@ -950,6 +983,16 @@ void _NamespaceModelItem::appendNamespace(const _NamespaceModelItem &other)
void _NamespaceModelItem::formatDebug(QDebug &d) const
{
_ScopeModelItem::formatDebug(d);
+ switch (m_type) {
+ case NamespaceType::Default:
+ break;
+ case NamespaceType::Anonymous:
+ d << ", anonymous";
+ break;
+ case NamespaceType::Inline:
+ d << ", inline";
+ break;
+ }
formatScopeList(d, ", namespaces=", m_namespaces);
}
#endif // !QT_NO_DEBUG_STREAM
@@ -1217,6 +1260,48 @@ void _TypeDefModelItem::formatDebug(QDebug &d) const
#endif // !QT_NO_DEBUG_STREAM
// ---------------------------------------------------------------------------
+
+_TemplateTypeAliasModelItem::_TemplateTypeAliasModelItem(CodeModel *model, int kind)
+ : _CodeModelItem(model, kind) {}
+
+_TemplateTypeAliasModelItem::_TemplateTypeAliasModelItem(CodeModel *model, const QString &name, int kind)
+ : _CodeModelItem(model, name, kind) {}
+
+TemplateParameterList _TemplateTypeAliasModelItem::templateParameters() const
+{
+ return m_templateParameters;
+}
+
+void _TemplateTypeAliasModelItem::addTemplateParameter(const TemplateParameterModelItem &templateParameter)
+{
+ m_templateParameters.append(templateParameter);
+}
+
+TypeInfo _TemplateTypeAliasModelItem::type() const
+{
+ return m_type;
+}
+
+void _TemplateTypeAliasModelItem::setType(const TypeInfo &type)
+{
+ m_type = type;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void _TemplateTypeAliasModelItem::formatDebug(QDebug &d) const
+{
+ _CodeModelItem::formatDebug(d);
+ d << ", <";
+ for (int i = 0, count = m_templateParameters.size(); i < count; ++i) {
+ if (i)
+ d << ", ";
+ d << m_templateParameters.at(i)->name();
+ }
+ d << ">, type=" << m_type;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
CodeModel::AccessPolicy _EnumModelItem::accessPolicy() const
{
return m_accessPolicy;
@@ -1464,4 +1549,3 @@ void _MemberModelItem::formatDebug(QDebug &d) const
#endif // !QT_NO_DEBUG_STREAM
// kate: space-indent on; indent-width 2; replace-tabs on;
-
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index 57b393f91..5bbd9ed3e 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -267,7 +267,8 @@ public:
Kind_File = 5 << FirstKind | Kind_Namespace,
Kind_TemplateParameter = 7 << FirstKind,
Kind_TypeDef = 8 << FirstKind,
- Kind_Variable = 9 << FirstKind | Kind_Member
+ Kind_TemplateTypeAlias = 9 << FirstKind,
+ Kind_Variable = 10 << FirstKind | Kind_Member
};
public:
@@ -333,18 +334,21 @@ public:
EnumList enums() const { return m_enums; }
inline FunctionList functions() const { return m_functions; }
TypeDefList typeDefs() const { return m_typeDefs; }
+ TemplateTypeAliasList templateTypeAliases() const { return m_templateTypeAliases; }
VariableList variables() const { return m_variables; }
void addClass(const ClassModelItem &item);
void addEnum(const EnumModelItem &item);
void addFunction(const FunctionModelItem &item);
void addTypeDef(const TypeDefModelItem &item);
+ void addTemplateTypeAlias(const TemplateTypeAliasModelItem &item);
void addVariable(const VariableModelItem &item);
ClassModelItem findClass(const QString &name) const;
EnumModelItem findEnum(const QString &name) const;
FunctionList findFunctions(const QString &name) const;
TypeDefModelItem findTypeDef(const QString &name) const;
+ TemplateTypeAliasModelItem findTemplateTypeAlias(const QString &name) const;
VariableModelItem findVariable(const QString &name) const;
void addEnumsDeclaration(const QString &enumsDeclaration);
@@ -372,6 +376,7 @@ private:
ClassList m_classes;
EnumList m_enums;
TypeDefList m_typeDefs;
+ TemplateTypeAliasList m_templateTypeAliases;
VariableList m_variables;
FunctionList m_functions;
@@ -440,6 +445,9 @@ public:
const NamespaceList &namespaces() const { return m_namespaces; }
+ NamespaceType type() const { return m_type; }
+ void setType(NamespaceType t) { m_type = t; }
+
void addNamespace(NamespaceModelItem item);
NamespaceModelItem findNamespace(const QString &name) const;
@@ -452,6 +460,7 @@ public:
private:
NamespaceList m_namespaces;
+ NamespaceType m_type = NamespaceType::Default;
};
class _FileModelItem: public _NamespaceModelItem
@@ -679,6 +688,30 @@ private:
TypeInfo m_type;
};
+class _TemplateTypeAliasModelItem : public _CodeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(TemplateTypeAlias)
+
+ explicit _TemplateTypeAliasModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _TemplateTypeAliasModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
+
+ TemplateParameterList templateParameters() const;
+ void addTemplateParameter(const TemplateParameterModelItem &templateParameter);
+
+ TypeInfo type() const;
+ void setType(const TypeInfo &type);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ TemplateParameterList m_templateParameters;
+ TypeInfo m_type;
+};
+
class _EnumModelItem: public _CodeModelItem
{
public:
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h b/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
index 1713ba42f..aebd59879 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
@@ -54,4 +54,11 @@ enum class ExceptionSpecification
Throws
};
+enum class NamespaceType
+{
+ Default,
+ Anonymous,
+ Inline
+};
+
#endif // CODEMODEL_ENUMS_H
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h b/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h
index 54dbe78dc..87fea5cde 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h
@@ -47,6 +47,7 @@ class _NamespaceModelItem;
class _ScopeModelItem;
class _TemplateParameterModelItem;
class _TypeDefModelItem;
+class _TemplateTypeAliasModelItem;
class _VariableModelItem;
class _MemberModelItem;
class TypeInfo;
@@ -62,6 +63,7 @@ using NamespaceModelItem = QSharedPointer<_NamespaceModelItem>;
using ScopeModelItem = QSharedPointer<_ScopeModelItem>;
using TemplateParameterModelItem = QSharedPointer<_TemplateParameterModelItem>;
using TypeDefModelItem = QSharedPointer<_TypeDefModelItem>;
+using TemplateTypeAliasModelItem = QSharedPointer<_TemplateTypeAliasModelItem>;
using VariableModelItem = QSharedPointer<_VariableModelItem>;
using MemberModelItem = QSharedPointer<_MemberModelItem>;
@@ -76,6 +78,7 @@ using NamespaceList = QVector<NamespaceModelItem>;
using ScopeList = QVector<ScopeModelItem>;
using TemplateParameterList = QVector<TemplateParameterModelItem>;
using TypeDefList = QVector<TypeDefModelItem>;
+using TemplateTypeAliasList = QVector<TemplateTypeAliasModelItem>;
using VariableList = QVector<VariableModelItem>;
using MemberList = QVector<MemberModelItem>;
diff --git a/sources/shiboken2/ApiExtractor/qtcompat.h b/sources/shiboken2/ApiExtractor/qtcompat.h
new file mode 100644
index 000000000..89a1db008
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/qtcompat.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCOMPAT_H
+#define QTCOMPAT_H
+
+#include <QtCore/QtGlobal>
+
+#if QT_VERSION >= 0x060000
+using QtCompatHashFunctionType = size_t;
+#else
+using QtCompatHashFunctionType = uint;
+#endif
+
+#endif // QTCOMPAT_H
diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
index 2e50470e4..512473131 100644
--- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp
+++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
@@ -225,7 +225,7 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
if (!sourceFile.exists())
sourceFile.setFile(sourceFileRoot + QStringLiteral(".xml"));
if (!sourceFile.exists()) {
- qCWarning(lcShiboken).noquote().nospace()
+ qCWarning(lcShibokenDoc).noquote().nospace()
<< "Can't find qdoc file for class " << metaClass->name() << ", tried: "
<< QDir::toNativeSeparators(sourceFile.absoluteFilePath());
return;
@@ -235,7 +235,7 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
QString errorMessage;
XQueryPtr xquery = XQuery::create(sourceFileName, &errorMessage);
if (xquery.isNull()) {
- qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return;
}
@@ -258,7 +258,7 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
Documentation doc(getDocumentation(xquery, query, classModifs));
if (doc.isEmpty())
- qCWarning(lcShiboken(), "%s", qPrintable(msgCannotFindDocumentation(sourceFileName, "class", className, query)));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotFindDocumentation(sourceFileName, "class", className, query)));
metaClass->setDocumentation(doc);
//Functions Documentation
@@ -268,7 +268,7 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
queryFunctionDocumentation(sourceFileName, metaClass, classQuery,
func, signedModifs, xquery, &errorMessage);
if (!errorMessage.isEmpty())
- qCWarning(lcShiboken(), "%s", qPrintable(errorMessage));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
func->setDocumentation(Documentation(documentation));
}
#if 0
@@ -291,7 +291,7 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
<< meta_enum->name() << "\"]/description";
doc.setValue(getDocumentation(xquery, query, DocModificationList()));
if (doc.isEmpty()) {
- qCWarning(lcShiboken(), "%s",
+ qCWarning(lcShibokenDoc, "%s",
qPrintable(msgCannotFindDocumentation(sourceFileName, metaClass, meta_enum, query)));
}
meta_enum->setDocumentation(doc);
@@ -321,7 +321,7 @@ Documentation QtDocParser::retrieveModuleDocumentation(const QString& name)
if (!QFile::exists(sourceFile))
sourceFile = prefix + QLatin1String("-module.webxml");
if (!QFile::exists(sourceFile)) {
- qCWarning(lcShiboken).noquote().nospace()
+ qCWarning(lcShibokenDoc).noquote().nospace()
<< "Can't find qdoc file for module " << name << ", tried: "
<< QDir::toNativeSeparators(sourceFile);
return Documentation();
@@ -330,7 +330,7 @@ Documentation QtDocParser::retrieveModuleDocumentation(const QString& name)
QString errorMessage;
XQueryPtr xquery = XQuery::create(sourceFile, &errorMessage);
if (xquery.isNull()) {
- qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return {};
}
@@ -339,7 +339,7 @@ Documentation QtDocParser::retrieveModuleDocumentation(const QString& name)
+ moduleName + QLatin1String("\"]/description");
Documentation doc = getDocumentation(xquery, query, DocModificationList());
if (doc.isEmpty()) {
- qCWarning(lcShiboken(), "%s", qPrintable(msgCannotFindDocumentation(sourceFile, "module", name, query)));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotFindDocumentation(sourceFile, "module", name, query)));
return doc;
}
diff --git a/sources/shiboken2/ApiExtractor/reporthandler.cpp b/sources/shiboken2/ApiExtractor/reporthandler.cpp
index ee70a8e9b..a489f7548 100644
--- a/sources/shiboken2/ApiExtractor/reporthandler.cpp
+++ b/sources/shiboken2/ApiExtractor/reporthandler.cpp
@@ -35,7 +35,7 @@
#include <cstdarg>
#include <cstdio>
-#if _WINDOWS || NOCOLOR
+#if defined(_WINDOWS) || defined(NOCOLOR)
#define COLOR_END ""
#define COLOR_WHITE ""
#define COLOR_YELLOW ""
@@ -58,6 +58,7 @@ static int m_step_warning = 0;
static QElapsedTimer m_timer;
Q_LOGGING_CATEGORY(lcShiboken, "qt.shiboken")
+Q_LOGGING_CATEGORY(lcShibokenDoc, "qt.shiboken.doc")
void ReportHandler::install()
{
@@ -80,6 +81,20 @@ void ReportHandler::setDebugLevel(ReportHandler::DebugLevel level)
m_debugLevel = level;
}
+bool ReportHandler::setDebugLevelFromArg(const QString &level)
+{
+ bool result = true;
+ if (level == QLatin1String("sparse"))
+ ReportHandler::setDebugLevel(ReportHandler::SparseDebug);
+ else if (level == QLatin1String("medium"))
+ ReportHandler::setDebugLevel(ReportHandler::MediumDebug);
+ else if (level == QLatin1String("full"))
+ ReportHandler::setDebugLevel(ReportHandler::FullDebug);
+ else
+ result = false;
+ return result;
+}
+
int ReportHandler::suppressedCount()
{
return m_suppressedCount;
diff --git a/sources/shiboken2/ApiExtractor/reporthandler.h b/sources/shiboken2/ApiExtractor/reporthandler.h
index 073586055..21f0e8933 100644
--- a/sources/shiboken2/ApiExtractor/reporthandler.h
+++ b/sources/shiboken2/ApiExtractor/reporthandler.h
@@ -33,6 +33,7 @@
#include <QString>
Q_DECLARE_LOGGING_CATEGORY(lcShiboken)
+Q_DECLARE_LOGGING_CATEGORY(lcShibokenDoc)
class ReportHandler
{
@@ -44,6 +45,7 @@ public:
static DebugLevel debugLevel();
static void setDebugLevel(DebugLevel level);
+ static bool setDebugLevelFromArg(const QString &);
static int warningCount();
diff --git a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
index a36cc17de..97ae0f850 100644
--- a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
@@ -15,7 +15,7 @@ macro(declare_test testname)
${CMAKE_CURRENT_BINARY_DIR}
${apiextractor_SOURCE_DIR}
)
- target_link_libraries(${testname} PRIVATE apiextractor Qt5::Test)
+ target_link_libraries(${testname} PRIVATE apiextractor Qt${QT_MAJOR_VERSION}::Test)
add_test(${testname} ${testname})
if (INSTALL_TESTS)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${testname}
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
index f2e15fdb0..f0aa4a318 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
@@ -588,4 +588,34 @@ void TestAbstractMetaClass::testIsPolymorphic()
QVERIFY(!a->isPolymorphic());
}
+void TestAbstractMetaClass::testClassTypedefedBaseClass()
+{
+ const char cppCode[] =R"CPP(
+class Base {
+};
+
+using BaseAlias1 = Base;
+using BaseAlias2 = BaseAlias1;
+
+class Derived : public BaseAlias2 {
+};
+)CPP";
+ const char xmlCode[] = R"XML(
+<typesystem package='Foo'>
+ <object-type name='Base'/>
+ <object-type name='Derived'/>
+</typesystem>
+)XML";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ auto base = AbstractMetaClass::findClass(classes, QLatin1String("Base"));
+ QVERIFY(base);
+ auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived"));
+ QVERIFY(derived);
+ QCOMPARE(derived->baseClasses().value(0), base);
+}
+
QTEST_APPLESS_MAIN(TestAbstractMetaClass)
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h
index e19973625..1d9f8d8f6 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h
@@ -51,6 +51,7 @@ private slots:
void testAbstractClassDefaultConstructors();
void testObjectTypesMustNotHaveCopyConstructors();
void testIsPolymorphic();
+ void testClassTypedefedBaseClass();
};
#endif // TESTABSTRACTMETACLASS_H
diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
index c50084b8e..ca4af9a10 100644
--- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
@@ -283,7 +283,7 @@ void TestAddFunction::testAddFunctionAtModuleLevel()
QCOMPARE(mods.size(), 1);
QVERIFY(mods.first().isCodeInjection());
CodeSnip snip = mods.first().snips.first();
- QCOMPARE(snip.code(), QLatin1String("custom_code();"));
+ QCOMPARE(snip.code().trimmed(), QLatin1String("custom_code();"));
}
void TestAddFunction::testAddFunctionWithVarargs()
diff --git a/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp b/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp
index 2234fb4c3..aaa72238c 100644
--- a/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp
@@ -57,8 +57,10 @@ void TestContainer::testContainerType()
//search for class A
AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
QVERIFY(classA);
- QVERIFY(classA->typeEntry()->baseContainerType());
- QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(classA->typeEntry()->baseContainerType())->type(), ContainerTypeEntry::ListContainer);
+ auto baseContainer = classA->typeEntry()->baseContainerType();
+ QVERIFY(baseContainer);
+ QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer)->containerKind(),
+ ContainerTypeEntry::ListContainer);
}
void TestContainer::testListOfValueType()
diff --git a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp
index 10194eb34..e61418467 100644
--- a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp
@@ -69,7 +69,7 @@ void TestNestedTypes::testNestedTypesModifications()
QCOMPARE(ins->functions().count(), 1);
QCOMPARE(ins->typeEntry()->codeSnips().count(), 1);
CodeSnip snip = ins->typeEntry()->codeSnips().first();
- QCOMPARE(snip.code(), QLatin1String("custom_code1();"));
+ QCOMPARE(snip.code().trimmed(), QLatin1String("custom_code1();"));
AbstractMetaFunction* addedFunc = ins->functions().first();
QVERIFY(addedFunc->isUserAdded());
@@ -80,7 +80,7 @@ void TestNestedTypes::testNestedTypesModifications()
QCOMPARE(addedFunc->modifications().size(), 1);
QVERIFY(addedFunc->modifications().first().isCodeInjection());
snip = addedFunc->modifications().first().snips.first();
- QCOMPARE(snip.code(), QLatin1String("custom_code2();"));
+ QCOMPARE(snip.code().trimmed(), QLatin1String("custom_code2();"));
const AbstractMetaClass *sc = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace::SomeClass"));
QVERIFY(ins);
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
index 5191cb38d..ec3ddb8b2 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
@@ -428,8 +428,10 @@ typedef Vector<int> IntVector;
AbstractMetaClass* vector = AbstractMetaClass::findClass(classes, QLatin1String("IntVector"));
QVERIFY(vector);
- QVERIFY(vector->typeEntry()->baseContainerType());
- QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(vector->typeEntry()->baseContainerType())->type(), ContainerTypeEntry::VectorContainer);
+ auto baseContainer = vector->typeEntry()->baseContainerType();
+ QVERIFY(baseContainer);
+ QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer)->containerKind(),
+ ContainerTypeEntry::VectorContainer);
QCOMPARE(vector->functions().count(), 4);
const AbstractMetaFunction* method = vector->findFunction(QLatin1String("method"));
@@ -443,6 +445,35 @@ typedef Vector<int> IntVector;
QCOMPARE(otherMethod->type()->cppSignature(), QLatin1String("Vector<int >"));
}
+void TestTemplates::testNonTypeTemplates()
+{
+ // PYSIDe-1296, functions with non type templates parameters.
+ const char cppCode[] = R"CPP(
+template <class T, int Size>
+class Array {
+ T array[Size];
+};
+
+Array<int, 2> foo();
+
+)CPP";
+
+ const char xmlCode[] = R"XML(
+<typesystem package='Foo'>
+ <primitive-type name='int'/>
+ <container-type name='Array' type='vector'/>
+ <function signature="foo()"/>
+</typesystem>)XML";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
+ QVERIFY(!builder.isNull());
+ auto functions = builder->globalFunctions();
+ QCOMPARE(functions.count(), 1);
+ auto foo = functions.constFirst();
+ QCOMPARE(foo->name(), QLatin1String("foo"));
+ QCOMPARE(foo->type()->name(), QLatin1String("Array"));
+}
+
// Perform checks on template inheritance; a typedef of a template class
// should result in rewritten types.
void TestTemplates::testTemplateTypeDefs_data()
@@ -561,4 +592,53 @@ void TestTemplates::testTemplateTypeDefs()
QCOMPARE(xmlValueField->type()->cppSignature(), QLatin1String("int"));
}
+void TestTemplates::testTemplateTypeAliases()
+{
+ // Model Qt 6's "template<typename T> using QList = QVector<T>"
+ const char cppCode[] = R"CPP(
+template<typename T>
+class Container1 { };
+
+template<typename T>
+using Container2 = Container1<T>;
+
+class Test
+{
+public:
+ Container2<int> m_intContainer;
+};
+
+class Derived : public Container2<int>
+{
+public:
+};
+)CPP";
+
+ const char xmlCode[] = R"XML(
+<typesystem package='Foo'>
+ <primitive-type name='int'/>
+ <value-type name='Container1'/>
+ <value-type name='Derived'/>
+ <object-type name='Test'/>
+</typesystem>)XML";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ auto testClass = AbstractMetaClass::findClass(classes, QLatin1String("Test"));
+ QVERIFY(testClass);
+
+ auto fields = testClass->fields();
+ QCOMPARE(fields.count(), 1);
+ auto fieldType = testClass->fields().at(0)->type();
+ QCOMPARE(fieldType->name(), QLatin1String("Container1"));
+ QCOMPARE(fieldType->instantiations().size(), 1);
+
+ auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived"));
+ QVERIFY(derived);
+ auto base = derived->templateBaseClass();
+ QCOMPARE(base->name(), QLatin1String("Container1"));
+}
+
QTEST_APPLESS_MAIN(TestTemplates)
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.h b/sources/shiboken2/ApiExtractor/tests/testtemplates.h
index df3de18b9..c96e7fe4a 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtemplates.h
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.h
@@ -46,8 +46,10 @@ private slots:
void testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration();
void testTypedefOfInstantiationOfTemplateClass();
void testContainerTypeIncompleteArgument();
+ void testNonTypeTemplates();
void testTemplateTypeDefs_data();
void testTemplateTypeDefs();
+ void testTemplateTypeAliases();
};
#endif
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index f393bf3bf..4a29a25c9 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -144,6 +144,25 @@ IncludeList TypeDatabase::extraIncludes(const QString& className) const
return typeEntry ? typeEntry->extraIncludes() : IncludeList();
}
+void TypeDatabase::addSystemInclude(const QString &name)
+{
+ m_systemIncludes.append(name.toUtf8());
+}
+
+// Add a lookup for the short name excluding inline namespaces
+// so that "std::shared_ptr" finds "std::__1::shared_ptr" as well.
+// Note: This inserts duplicate TypeEntry * into m_entries.
+void TypeDatabase::addInlineNamespaceLookups(const NamespaceTypeEntry *n)
+{
+ QVector<TypeEntry *> additionalEntries; // Store before modifying the hash
+ for (TypeEntry *entry : m_entries) {
+ if (entry->isChildOf(n))
+ additionalEntries.append(entry);
+ }
+ for (const auto &ae : additionalEntries)
+ m_entries.insert(ae->shortName(), ae);
+}
+
ContainerTypeEntry* TypeDatabase::findContainerType(const QString &name) const
{
QString template_name = name;
@@ -166,7 +185,7 @@ static bool inline useType(const TypeEntry *t)
FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->type() == TypeEntry::FunctionType && useType(entry))
return static_cast<FunctionTypeEntry*>(entry);
@@ -201,7 +220,7 @@ QString TypeDatabase::defaultPackageName() const
TypeEntry* TypeDatabase::findType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (useType(entry))
return entry;
@@ -209,7 +228,53 @@ TypeEntry* TypeDatabase::findType(const QString& name) const
return nullptr;
}
-TypeEntryMultiMapConstIteratorRange TypeDatabase::findTypes(const QString &name) const
+template <class Predicate>
+TypeEntries TypeDatabase::findTypesHelper(const QString &name, Predicate pred) const
+{
+ TypeEntries result;
+ const auto entries = findTypeRange(name);
+ for (TypeEntry *entry : entries) {
+ if (pred(entry))
+ result.append(entry);
+ }
+ return result;
+}
+
+TypeEntries TypeDatabase::findTypes(const QString &name) const
+{
+ return findTypesHelper(name, useType);
+}
+
+static bool useCppType(const TypeEntry *t)
+{
+ bool result = false;
+ switch (t->type()) {
+ case TypeEntry::PrimitiveType:
+ case TypeEntry::VoidType:
+ case TypeEntry::FlagsType:
+ case TypeEntry::EnumType:
+ case TypeEntry::TemplateArgumentType:
+ case TypeEntry::BasicValueType:
+ case TypeEntry::ContainerType:
+ case TypeEntry::ObjectType:
+ case TypeEntry::ArrayType:
+ case TypeEntry::CustomType:
+ case TypeEntry::SmartPointerType:
+ case TypeEntry::TypedefType:
+ result = useType(t);
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+
+TypeEntries TypeDatabase::findCppTypes(const QString &name) const
+{
+ return findTypesHelper(name, useCppType);
+}
+
+TypeEntryMultiMapConstIteratorRange TypeDatabase::findTypeRange(const QString &name) const
{
const auto range = m_entries.equal_range(name);
return {range.first, range.second};
@@ -322,11 +387,10 @@ TypeEntry *TypeDatabase::resolveTypeDefEntry(TypedefEntry *typedefEntry,
if (lessThanPos != -1)
sourceName.truncate(lessThanPos);
ComplexTypeEntry *source = nullptr;
- for (TypeEntry *e : findTypes(sourceName)) {
+ for (TypeEntry *e : findTypeRange(sourceName)) {
switch (e->type()) {
case TypeEntry::BasicValueType:
case TypeEntry::ContainerType:
- case TypeEntry::InterfaceType:
case TypeEntry::ObjectType:
case TypeEntry::SmartPointerType:
source = dynamic_cast<ComplexTypeEntry *>(e);
@@ -362,6 +426,17 @@ bool TypeDatabase::addType(TypeEntry *e, QString *errorMessage)
return true;
}
+// Add a dummy value entry for non-type template parameters
+ConstantValueTypeEntry *
+ TypeDatabase::addConstantValueTypeEntry(const QString &value,
+ const TypeEntry *parent)
+{
+ auto result = new ConstantValueTypeEntry(value, parent);
+ result->setCodeGeneration(0);
+ addType(result);
+ return result;
+}
+
bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName,
QString *reason) const
{
@@ -557,15 +632,8 @@ bool TypeDatabase::parseFile(const QString &filename, const QString &currentPath
return false;
}
- int count = m_entries.size();
bool ok = parseFile(&file, generate);
m_parsedTypesystemFiles[filepath] = ok;
- int newCount = m_entries.size();
-
- if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
- qCDebug(lcShiboken)
- << QStringLiteral("Parsed: '%1', %2 new entries").arg(filename).arg(newCount - count);
- }
return ok;
}
@@ -581,7 +649,7 @@ bool TypeDatabase::parseFile(QIODevice* device, bool generate)
PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->isPrimitive()) {
auto *pe = static_cast<PrimitiveTypeEntry *>(entry);
@@ -595,7 +663,7 @@ PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->isComplex() && useType(entry))
return static_cast<ComplexTypeEntry*>(entry);
@@ -605,7 +673,7 @@ ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry && entry->isObject() && useType(entry))
return static_cast<ObjectTypeEntry*>(entry);
@@ -616,7 +684,7 @@ ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
NamespaceTypeEntryList TypeDatabase::findNamespaceTypes(const QString& name) const
{
NamespaceTypeEntryList result;
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->isNamespace())
result.append(static_cast<NamespaceTypeEntry*>(entry));
@@ -698,6 +766,35 @@ static void _computeTypeIndexes()
computeTypeIndexes = false;
}
+// Build the C++ name excluding any inline namespaces
+// ("std::__1::shared_ptr" -> "std::shared_ptr"
+QString TypeEntry::shortName() const
+{
+ if (m_cachedShortName.isEmpty()) {
+ QVarLengthArray<const TypeEntry *> parents;
+ bool foundInlineNamespace = false;
+ for (auto p = m_parent; p != nullptr && p->type() != TypeEntry::TypeSystemType; p = p->parent()) {
+ if (p->type() == TypeEntry::NamespaceType
+ && static_cast<const NamespaceTypeEntry *>(p)->isInlineNamespace()) {
+ foundInlineNamespace = true;
+ } else {
+ parents.append(p);
+ }
+ }
+ if (foundInlineNamespace) {
+ m_cachedShortName.reserve(m_name.size());
+ for (int i = parents.size() - 1; i >= 0; --i) {
+ m_cachedShortName.append(parents.at(i)->entryName());
+ m_cachedShortName.append(QLatin1String("::"));
+ }
+ m_cachedShortName.append(m_entryName);
+ } else {
+ m_cachedShortName = m_name;
+ }
+ }
+ return m_cachedShortName;
+}
+
void TypeEntry::setRevision(int r)
{
if (m_revision != r) {
@@ -794,7 +891,7 @@ void TypeEntry::formatDebug(QDebug &d) const
if (m_name != cppName)
d << "\", cppName=\"" << cppName << '"';
d << ", type=" << m_type << ", codeGeneration=0x"
- << hex << m_codeGeneration << dec
+ << Qt::hex << m_codeGeneration << Qt::dec
<< ", target=\"" << targetLangName() << '"';
FORMAT_NONEMPTY_STRING("package", m_targetLangPackage)
FORMAT_BOOL("stream", m_stream)
@@ -849,12 +946,26 @@ void NamespaceTypeEntry::formatDebug(QDebug &d) const
ComplexTypeEntry::formatDebug(d);
auto pattern = m_filePattern.pattern();
FORMAT_NONEMPTY_STRING("pattern", pattern)
+ d << ",visibility=" << m_visibility;
+ if (m_inlineNamespace)
+ d << "[inline]";
}
void ContainerTypeEntry::formatDebug(QDebug &d) const
{
ComplexTypeEntry::formatDebug(d);
- d << ", type=" << m_type << ",\"" << typeName() << '"';
+ d << ", type=" << m_containerKind << ",\"" << typeName() << '"';
+}
+
+void SmartPointerTypeEntry::formatDebug(QDebug &d) const
+{
+ ComplexTypeEntry::formatDebug(d);
+ if (!m_instantiations.isEmpty()) {
+ d << ", instantiations[" << m_instantiations.size() << "]=(";
+ for (auto i : m_instantiations)
+ d << i->name() << ',';
+ d << ')';
+ }
}
QDebug operator<<(QDebug d, const TypeEntry *te)
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h
index f615b623d..7651d6b7b 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.h
+++ b/sources/shiboken2/ApiExtractor/typedatabase.h
@@ -96,6 +96,11 @@ public:
IncludeList extraIncludes(const QString &className) const;
+ const QByteArrayList &systemIncludes() const { return m_systemIncludes; }
+ void addSystemInclude(const QString &name);
+
+ void addInlineNamespaceLookups(const NamespaceTypeEntry *n);
+
PrimitiveTypeEntry *findPrimitiveType(const QString &name) const;
ComplexTypeEntry *findComplexType(const QString &name) const;
ObjectTypeEntry *findObjectType(const QString &name) const;
@@ -108,6 +113,8 @@ public:
QString defaultPackageName() const;
TypeEntry *findType(const QString &name) const;
+ TypeEntries findTypes(const QString &name) const;
+ TypeEntries findCppTypes(const QString &name) const;
const TypeEntryMultiMap &entries() const { return m_entries; }
const TypedefEntryMap &typedefEntries() const { return m_typedefEntries; }
@@ -130,6 +137,8 @@ public:
QString *reason = nullptr) const;
bool addType(TypeEntry *e, QString *errorMessage = nullptr);
+ ConstantValueTypeEntry *addConstantValueTypeEntry(const QString &value,
+ const TypeEntry *parent);
void addTypeSystemType(const TypeSystemTypeEntry *e);
FlagsTypeEntry *findFlagsType(const QString &name) const;
@@ -179,11 +188,13 @@ public:
void formatDebug(QDebug &d) const;
#endif
private:
- TypeEntryMultiMapConstIteratorRange findTypes(const QString &name) const;
+ TypeEntryMultiMapConstIteratorRange findTypeRange(const QString &name) const;
+ template <class Predicate>
+ TypeEntries findTypesHelper(const QString &name, Predicate pred) const;
TypeEntry *resolveTypeDefEntry(TypedefEntry *typedefEntry, QString *errorMessage);
bool m_suppressWarnings = true;
- TypeEntryMultiMap m_entries;
+ TypeEntryMultiMap m_entries; // Contains duplicate entries (cf addInlineNamespaceLookups).
TypeEntryMap m_flagsEntries;
TypedefEntryMap m_typedefEntries;
TemplateEntryMap m_templates;
@@ -201,6 +212,7 @@ private:
QVector<TypeRejection> m_rejections;
QStringList m_dropTypeEntries;
+ QByteArrayList m_systemIncludes;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h
index 0bb5cde1d..f9e6c669e 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h
+++ b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h
@@ -33,6 +33,7 @@
#include <QtCore/QString>
#include <QtCore/QVector>
+class ConstantValueTypeEntry;
class ContainerTypeEntry;
class NamespaceTypeEntry;
class PrimitiveTypeEntry;
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index abd2bfb07..729e6b32b 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -34,6 +34,7 @@
#include <QtCore/QSet>
#include <algorithm>
+#include <limits>
static QString strings_Object = QLatin1String("Object");
static QString strings_String = QLatin1String("String");
@@ -144,7 +145,7 @@ ComplexTypeEntry::ComplexTypeEntry(const ComplexTypeEntry &) = default;
QString ContainerTypeEntry::qualifiedCppName() const
{
- if (m_type == StringListContainer)
+ if (m_containerKind == StringListContainer)
return QLatin1String("QStringList");
return ComplexTypeEntry::qualifiedCppName();
}
@@ -212,7 +213,7 @@ QString TemplateInstance::expandCode() const
if (!code.startsWith(QLatin1Char('\n')))
result += QLatin1Char('\n');
result += code;
- result += QLatin1String("\n// TEMPLATE - ") + m_name + QLatin1String(" - END");
+ result += QLatin1String("\n// TEMPLATE - ") + m_name + QLatin1String(" - END\n");
return result;
}
@@ -226,6 +227,82 @@ QString CodeSnipAbstract::code() const
return res;
}
+void CodeSnipAbstract::addCode(const QString &code)
+{
+ codeList.append(CodeSnipFragment(fixSpaces(code)));
+}
+
+template <class String> // QString, QStringRef
+static inline int firstNonBlank(const String &s)
+{
+ const auto it = std::find_if(s.cbegin(), s.cend(),
+ [] (QChar c) { return !c.isSpace(); });
+ return int(it - s.cbegin());
+}
+
+template <class String> // QString, QStringRef
+static inline bool isEmpty(const String &s)
+{
+ return s.isEmpty()
+ || std::all_of(s.cbegin(), s.cend(),
+ [] (QChar c) { return c.isSpace(); });
+}
+
+QString CodeSnipAbstract::dedent(const QString &code)
+{
+ if (code.isEmpty())
+ return code;
+ // Right trim if indent=0, or trim if single line
+ if (!code.at(0).isSpace() || !code.contains(QLatin1Char('\n')))
+ return code.trimmed();
+ const auto lines = code.splitRef(QLatin1Char('\n'));
+ int spacesToRemove = std::numeric_limits<int>::max();
+ for (const auto &line : lines) {
+ if (!isEmpty(line)) {
+ const int nonSpacePos = firstNonBlank(line);
+ if (nonSpacePos < spacesToRemove)
+ spacesToRemove = nonSpacePos;
+ if (spacesToRemove == 0)
+ return code;
+ }
+ }
+ QString result;
+ for (const auto &line : lines) {
+ if (!isEmpty(line) && spacesToRemove < line.size())
+ result += line.mid(spacesToRemove).toString();
+ result += QLatin1Char('\n');
+ }
+ return result;
+}
+
+QString CodeSnipAbstract::fixSpaces(QString code)
+{
+ code.remove(QLatin1Char('\r'));
+ // Check for XML <tag>\n<space>bla...
+ if (code.startsWith(QLatin1String("\n ")))
+ code.remove(0, 1);
+ while (!code.isEmpty() && code.back().isSpace())
+ code.chop(1);
+ code = dedent(code);
+ if (!code.isEmpty() && !code.endsWith(QLatin1Char('\n')))
+ code.append(QLatin1Char('\n'));
+ return code;
+}
+
+// Prepend a line to the code, observing indentation
+void CodeSnipAbstract::prependCode(QString *code, QString firstLine)
+{
+ while (!code->isEmpty() && code->front() == QLatin1Char('\n'))
+ code->remove(0, 1);
+ if (!code->isEmpty() && code->front().isSpace()) {
+ const int indent = firstNonBlank(*code);
+ firstLine.prepend(QString(indent, QLatin1Char(' ')));
+ }
+ if (!firstLine.endsWith(QLatin1Char('\n')))
+ firstLine += QLatin1Char('\n');
+ code->prepend(firstLine);
+}
+
QString CodeSnipFragment::code() const
{
return m_instance ? m_instance->expandCode() : m_code;
@@ -433,7 +510,7 @@ QDebug operator<<(QDebug d, const CodeSnip &s)
void Modification::formatDebug(QDebug &d) const
{
- d << "modifiers=" << hex << showbase << modifiers << noshowbase << dec;
+ d << "modifiers=" << Qt::hex << Qt::showbase << modifiers << Qt::noshowbase << Qt::dec;
if (removal)
d << ", removal";
if (!renamedToName.isEmpty())
@@ -595,7 +672,7 @@ QString ComplexTypeEntry::targetLangApiName() const
QString ContainerTypeEntry::typeName() const
{
- switch(m_type) {
+ switch (m_containerKind) {
case LinkedListContainer:
return QLatin1String("linked-list");
case ListContainer:
@@ -684,6 +761,15 @@ TypeEntry::~TypeEntry()
delete m_customConversion;
}
+bool TypeEntry::isChildOf(const TypeEntry *p) const
+{
+ for (auto e = m_parent; e; e = e->parent()) {
+ if (e == p)
+ return true;
+ }
+ return false;
+}
+
const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const
{
for (auto e = this; e; e = e->parent()) {
@@ -693,6 +779,16 @@ const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const
return nullptr;
}
+const TypeEntry *TypeEntry::targetLangEnclosingEntry() const
+{
+ auto result = m_parent;
+ while (result && result->type() != TypeEntry::TypeSystemType
+ && !NamespaceTypeEntry::isVisibleScope(result)) {
+ result = result->parent();
+ }
+ return result;
+}
+
QString TypeEntry::targetLangName() const
{
if (m_cachedTargetLangName.isEmpty())
@@ -704,11 +800,13 @@ QString TypeEntry::buildTargetLangName() const
{
QString result = m_entryName;
for (auto p = parent(); p && p->type() != TypeEntry::TypeSystemType; p = p->parent()) {
- if (!result.isEmpty())
- result.prepend(QLatin1Char('.'));
- QString n = p->m_entryName;
- n.replace(QLatin1String("::"), QLatin1String(".")); // Primitive types may have "std::"
- result.prepend(n);
+ if (NamespaceTypeEntry::isVisibleScope(p)) {
+ if (!result.isEmpty())
+ result.prepend(QLatin1Char('.'));
+ QString n = p->m_entryName;
+ n.replace(QLatin1String("::"), QLatin1String(".")); // Primitive types may have "std::"
+ result.prepend(n);
+ }
}
return result;
}
@@ -752,6 +850,8 @@ TypeEntry *TypeEntry::clone() const
// Take over parameters relevant for typedefs
void TypeEntry::useAsTypedef(const TypeEntry *source)
{
+ // XML Typedefs are in the global namespace for now.
+ m_parent = source->typeSystemTypeEntry();
m_entryName = source->m_entryName;
m_name = source->m_name;
m_targetLangPackage = source->m_targetLangPackage;
@@ -905,11 +1005,11 @@ TypeEntry *TypedefEntry::clone() const
TypedefEntry::TypedefEntry(const TypedefEntry &) = default;
-ContainerTypeEntry::ContainerTypeEntry(const QString &entryName, Type type,
+ContainerTypeEntry::ContainerTypeEntry(const QString &entryName, ContainerKind containerKind,
const QVersionNumber &vr,
const TypeEntry *parent) :
ComplexTypeEntry(entryName, ContainerType, vr, parent),
- m_type(type)
+ m_containerKind(containerKind)
{
setCodeGeneration(GenerateForSubclass);
}
@@ -933,6 +1033,11 @@ TypeEntry *SmartPointerTypeEntry::clone() const
SmartPointerTypeEntry::SmartPointerTypeEntry(const SmartPointerTypeEntry &) = default;
+bool SmartPointerTypeEntry::matchesInstantiation(const TypeEntry *e) const
+{
+ return m_instantiations.isEmpty() || m_instantiations.contains(e);
+}
+
NamespaceTypeEntry::NamespaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
const TypeEntry *parent) :
ComplexTypeEntry(entryName, NamespaceType, vr, parent)
@@ -959,6 +1064,18 @@ bool NamespaceTypeEntry::matchesFile(const QString &needle) const
return m_filePattern.match(needle).hasMatch();
}
+bool NamespaceTypeEntry::isVisible() const
+{
+ return m_visibility == TypeSystem::Visibility::Visible
+ || (m_visibility == TypeSystem::Visibility::Auto && !m_inlineNamespace);
+}
+
+bool NamespaceTypeEntry::isVisibleScope(const TypeEntry *e)
+{
+ return e->type() != TypeEntry::NamespaceType
+ || static_cast<const NamespaceTypeEntry *>(e)->isVisible();
+}
+
ValueTypeEntry::ValueTypeEntry(const QString &entryName, const QVersionNumber &vr,
const TypeEntry *parent) :
ComplexTypeEntry(entryName, BasicValueType, vr, parent)
@@ -970,11 +1087,6 @@ bool ValueTypeEntry::isValue() const
return true;
}
-bool ValueTypeEntry::isNativeIdBased() const
-{
- return true;
-}
-
TypeEntry *ValueTypeEntry::clone() const
{
return new ValueTypeEntry(*this);
@@ -1122,30 +1234,6 @@ void CustomConversion::TargetToNativeConversion::setConversion(const QString& co
m_d->conversion = conversion;
}
-InterfaceTypeEntry::InterfaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent) :
- ComplexTypeEntry(entryName, InterfaceType, vr, parent)
-{
-}
-
-bool InterfaceTypeEntry::isNativeIdBased() const
-{
- return true;
-}
-
-QString InterfaceTypeEntry::qualifiedCppName() const
-{
- const int len = ComplexTypeEntry::qualifiedCppName().length() - interfaceName(QString()).length();
- return ComplexTypeEntry::qualifiedCppName().left(len);
-}
-
-TypeEntry *InterfaceTypeEntry::clone() const
-{
- return new InterfaceTypeEntry(*this);
-}
-
-InterfaceTypeEntry::InterfaceTypeEntry(const InterfaceTypeEntry &) = default;
-
FunctionTypeEntry::FunctionTypeEntry(const QString &entryName, const QString &signature,
const QVersionNumber &vr,
const TypeEntry *parent) :
@@ -1167,19 +1255,14 @@ ObjectTypeEntry::ObjectTypeEntry(const QString &entryName, const QVersionNumber
{
}
-InterfaceTypeEntry *ObjectTypeEntry::designatedInterface() const
-{
- return m_interface;
-}
-
-bool ObjectTypeEntry::isNativeIdBased() const
-{
- return true;
-}
-
TypeEntry *ObjectTypeEntry::clone() const
{
return new ObjectTypeEntry(*this);
}
ObjectTypeEntry::ObjectTypeEntry(const ObjectTypeEntry &) = default;
+
+void DocModification::setCode(const QString &code)
+{
+ m_code = CodeSnipAbstract::fixSpaces(code);
+}
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 4d0a23ca1..c6995b64d 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -115,7 +115,7 @@ class CodeSnipAbstract
public:
QString code() const;
- void addCode(const QString &code) { codeList.append(CodeSnipFragment(code)); }
+ void addCode(const QString &code);
void addCode(const QStringRef &code) { addCode(code.toString()); }
void addTemplateInstance(TemplateInstance *ti)
@@ -124,6 +124,10 @@ public:
}
QVector<CodeSnipFragment> codeList;
+
+ static QString fixSpaces(QString code);
+ static QString dedent(const QString &code);
+ static void prependCode(QString *code, QString firstLine);
};
class CustomFunction : public CodeSnipAbstract
@@ -228,7 +232,7 @@ struct ArgumentModification
struct Modification
{
- enum Modifiers {
+ enum Modifiers : uint {
InvalidModifier = 0x0000,
Private = 0x0001,
Protected = 0x0002,
@@ -499,7 +503,6 @@ QDebug operator<<(QDebug d, const AddedFunction::Argument &a);
QDebug operator<<(QDebug d, const AddedFunction &af);
#endif
-class InterfaceTypeEntry;
class ObjectTypeEntry;
class DocModification
@@ -511,8 +514,8 @@ public:
explicit DocModification(TypeSystem::DocModificationMode mode, const QString& signature) :
m_signature(signature), m_mode(mode) {}
- void setCode(const QString& code) { m_code = code; }
- void setCode(const QStringRef& code) { m_code = code.toString(); }
+ void setCode(const QString& code);
+ void setCode(const QStringRef& code) { setCode(code.toString()); }
QString code() const
{
@@ -562,20 +565,13 @@ public:
EnumValue,
ConstantValueType,
TemplateArgumentType,
- ThreadType,
BasicValueType,
- StringType,
ContainerType,
- InterfaceType,
ObjectType,
NamespaceType,
- VariantType,
- JObjectWrapperType,
- CharType,
ArrayType,
TypeSystemType,
CustomType,
- TargetLangType,
FunctionType,
SmartPointerType,
TypedefType
@@ -605,7 +601,10 @@ public:
const TypeEntry *parent() const { return m_parent; }
void setParent(const TypeEntry *p) { m_parent = p; }
+ bool isChildOf(const TypeEntry *p) const;
const TypeSystemTypeEntry *typeSystemTypeEntry() const;
+ // cf AbstractMetaClass::targetLangEnclosingClass()
+ const TypeEntry *targetLangEnclosingEntry() const;
bool isPrimitive() const
{
@@ -619,22 +618,10 @@ public:
{
return m_type == FlagsType;
}
- bool isInterface() const
- {
- return m_type == InterfaceType;
- }
bool isObject() const
{
return m_type == ObjectType;
}
- bool isString() const
- {
- return m_type == StringType;
- }
- bool isChar() const
- {
- return m_type == CharType;
- }
bool isNamespace() const
{
return m_type == NamespaceType;
@@ -647,14 +634,6 @@ public:
{
return m_type == SmartPointerType;
}
- bool isVariant() const
- {
- return m_type == VariantType;
- }
- bool isJObjectWrapper() const
- {
- return m_type == JObjectWrapperType;
- }
bool isArray() const
{
return m_type == ArrayType;
@@ -671,18 +650,10 @@ public:
{
return m_type == VarargsType;
}
- bool isThread() const
- {
- return m_type == ThreadType;
- }
bool isCustom() const
{
return m_type == CustomType;
}
- bool isBasicValue() const
- {
- return m_type == BasicValueType;
- }
bool isTypeSystem() const
{
return m_type == TypeSystemType;
@@ -708,6 +679,8 @@ public:
// The type's name in C++, fully qualified
QString name() const { return m_name; }
+ // C++ excluding inline namespaces
+ QString shortName() const;
// Name as specified in XML
QString entryName() const { return m_entryName; }
@@ -766,11 +739,6 @@ public:
QString qualifiedTargetLangName() const;
- virtual InterfaceTypeEntry *designatedInterface() const
- {
- return nullptr;
- }
-
void setCustomConstructor(const CustomFunction &func)
{
m_customConstructor = func;
@@ -798,11 +766,6 @@ public:
return false;
}
- virtual bool isNativeIdBased() const
- {
- return false;
- }
-
CodeSnipList codeSnips() const;
void setCodeSnips(const CodeSnipList &codeSnips)
{
@@ -896,7 +859,8 @@ protected:
private:
const TypeEntry *m_parent;
- QString m_name; // fully qualified
+ QString m_name; // C++ fully qualified
+ mutable QString m_cachedShortName; // C++ excluding inline namespaces
QString m_entryName;
QString m_targetLangPackage;
mutable QString m_cachedTargetLangName; // "Foo.Bar"
@@ -1446,7 +1410,7 @@ class ContainerTypeEntry : public ComplexTypeEntry
{
Q_GADGET
public:
- enum Type {
+ enum ContainerKind {
NoContainer,
ListContainer,
StringListContainer,
@@ -1461,14 +1425,14 @@ public:
MultiHashContainer,
PairContainer,
};
- Q_ENUM(Type)
+ Q_ENUM(ContainerKind)
- explicit ContainerTypeEntry(const QString &entryName, Type type, const QVersionNumber &vr,
- const TypeEntry *parent);
+ explicit ContainerTypeEntry(const QString &entryName, ContainerKind containerKind,
+ const QVersionNumber &vr, const TypeEntry *parent);
- Type type() const
+ ContainerKind containerKind() const
{
- return m_type;
+ return m_containerKind;
}
QString typeName() const;
@@ -1483,12 +1447,14 @@ protected:
ContainerTypeEntry(const ContainerTypeEntry &);
private:
- Type m_type;
+ ContainerKind m_containerKind;
};
class SmartPointerTypeEntry : public ComplexTypeEntry
{
public:
+ using Instantiations = QVector<const TypeEntry *>;
+
explicit SmartPointerTypeEntry(const QString &entryName,
const QString &getterName,
const QString &smartPointerType,
@@ -1508,6 +1474,13 @@ public:
TypeEntry *clone() const override;
+ Instantiations instantiations() const { return m_instantiations; }
+ void setInstantiations(const Instantiations &i) { m_instantiations = i; }
+ bool matchesInstantiation(const TypeEntry *e) const;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
protected:
SmartPointerTypeEntry(const SmartPointerTypeEntry &);
@@ -1515,6 +1488,7 @@ private:
QString m_getterName;
QString m_smartPointerType;
QString m_refCountMethodName;
+ Instantiations m_instantiations;
};
class NamespaceTypeEntry : public ComplexTypeEntry
@@ -1535,6 +1509,15 @@ public:
bool matchesFile(const QString &needle) const;
+ bool isVisible() const;
+ void setVisibility(TypeSystem::Visibility v) { m_visibility = v; }
+
+ // C++ 11 inline namespace, from code model
+ bool isInlineNamespace() const { return m_inlineNamespace; }
+ void setInlineNamespace(bool i) { m_inlineNamespace = i; }
+
+ static bool isVisibleScope(const TypeEntry *e);
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
@@ -1545,7 +1528,9 @@ protected:
private:
QRegularExpression m_filePattern;
const NamespaceTypeEntry *m_extends = nullptr;
+ TypeSystem::Visibility m_visibility = TypeSystem::Visibility::Auto;
bool m_hasPattern = false;
+ bool m_inlineNamespace = false;
};
class ValueTypeEntry : public ComplexTypeEntry
@@ -1556,8 +1541,6 @@ public:
bool isValue() const override;
- bool isNativeIdBased() const override;
-
TypeEntry *clone() const override;
protected:
@@ -1566,39 +1549,6 @@ protected:
ValueTypeEntry(const ValueTypeEntry &);
};
-class InterfaceTypeEntry : public ComplexTypeEntry
-{
-public:
- explicit InterfaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- static QString interfaceName(const QString &name)
- {
- return name + QLatin1String("Interface");
- }
-
- ObjectTypeEntry *origin() const
- {
- return m_origin;
- }
- void setOrigin(ObjectTypeEntry *origin)
- {
- m_origin = origin;
- }
-
- bool isNativeIdBased() const override;
- QString qualifiedCppName() const override;
-
- TypeEntry *clone() const override;
-
-protected:
- InterfaceTypeEntry(const InterfaceTypeEntry &);
-
-private:
- ObjectTypeEntry *m_origin = nullptr;
-};
-
-
class FunctionTypeEntry : public TypeEntry
{
public:
@@ -1635,21 +1585,10 @@ public:
explicit ObjectTypeEntry(const QString &entryName, const QVersionNumber &vr,
const TypeEntry *parent);
- InterfaceTypeEntry *designatedInterface() const override;
- void setDesignatedInterface(InterfaceTypeEntry *entry)
- {
- m_interface = entry;
- }
-
- bool isNativeIdBased() const override;
-
TypeEntry *clone() const override;
protected:
ObjectTypeEntry(const ObjectTypeEntry &);
-
-private:
- InterfaceTypeEntry *m_interface = nullptr;
};
struct TypeRejection
diff --git a/sources/shiboken2/ApiExtractor/typesystem_enums.h b/sources/shiboken2/ApiExtractor/typesystem_enums.h
index df83429d0..120c9417f 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_enums.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_enums.h
@@ -98,6 +98,13 @@ enum class ExceptionHandling {
On
};
+enum Visibility { // For namespaces
+ Unspecified,
+ Visible,
+ Invisible,
+ Auto
+};
+
} // namespace TypeSystem
#endif // TYPESYSTEM_ENUMS_H
diff --git a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
index fd702793e..73f92b294 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
@@ -40,6 +40,7 @@ class DocModification;
struct AddedFunction;
struct FieldModification;
struct FunctionModification;
+class TypeEntry;
using AddedFunctionPtr = QSharedPointer<AddedFunction>;
using AddedFunctionList = QVector<AddedFunctionPtr>;
@@ -47,5 +48,6 @@ using CodeSnipList = QVector<CodeSnip>;
using DocModificationList = QVector<DocModification>;
using FieldModificationList = QVector<FieldModification>;
using FunctionModificationList = QVector<FunctionModification>;
+using TypeEntries = QVector<const TypeEntry *>;
#endif // TYPESYSTEM_TYPEDEFS_H
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
index 98c729a32..0ba94d94e 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
@@ -62,6 +62,7 @@ static inline QString deleteInMainThreadAttribute() { return QStringLiteral("del
static inline QString deprecatedAttribute() { return QStringLiteral("deprecated"); }
static inline QString exceptionHandlingAttribute() { return QStringLiteral("exception-handling"); }
static inline QString extensibleAttribute() { return QStringLiteral("extensible"); }
+static inline QString fileNameAttribute() { return QStringLiteral("file-name"); }
static inline QString flagsAttribute() { return QStringLiteral("flags"); }
static inline QString forceAbstractAttribute() { return QStringLiteral("force-abstract"); }
static inline QString forceIntegerAttribute() { return QStringLiteral("force-integer"); }
@@ -94,6 +95,7 @@ static inline QString sourceAttribute() { return QStringLiteral("source"); }
static inline QString streamAttribute() { return QStringLiteral("stream"); }
static inline QString xPathAttribute() { return QStringLiteral("xpath"); }
static inline QString virtualSlotAttribute() { return QStringLiteral("virtual-slot"); }
+static inline QString visibleAttribute() { return QStringLiteral("visible"); }
static inline QString enumIdentifiedByValueAttribute() { return QStringLiteral("identified-by-value"); }
static inline QString noAttributeValue() { return QStringLiteral("no"); }
@@ -147,7 +149,7 @@ static QString extractSnippet(const QString &code, const QString &snippetLabel)
} else if (useLine)
result += line.toString() + QLatin1Char('\n');
}
- return result;
+ return CodeSnipAbstract::fixSpaces(result);
}
template <class EnumType, Qt::CaseSensitivity cs = Qt::CaseInsensitive>
@@ -295,7 +297,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::DocModificationMode, Qt::CaseInsensitive,
};
ENUM_LOOKUP_LINEAR_SEARCH()
-ENUM_LOOKUP_BEGIN(ContainerTypeEntry::Type, Qt::CaseSensitive,
+ENUM_LOOKUP_BEGIN(ContainerTypeEntry::ContainerKind, Qt::CaseSensitive,
containerTypeFromAttribute, ContainerTypeEntry::NoContainer)
{
{u"list", ContainerTypeEntry::ListContainer},
@@ -382,6 +384,7 @@ ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
{u"replace-type", StackElement::ReplaceType},
{u"smart-pointer-type", StackElement::SmartPointerTypeEntry},
{u"suppress-warning", StackElement::SuppressedWarning},
+ {u"system-include", StackElement::SystemInclude},
{u"target-to-native", StackElement::TargetToNative},
{u"template", StackElement::Template},
{u"typedef-type", StackElement::TypedefTypeEntry},
@@ -390,6 +393,17 @@ ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
};
ENUM_LOOKUP_BINARY_SEARCH()
+ENUM_LOOKUP_BEGIN(TypeSystem::Visibility, Qt::CaseSensitive,
+ visibilityFromAttribute, TypeSystem::Visibility::Unspecified)
+{
+ {u"no", TypeSystem::Visibility::Invisible},
+ {u"false", TypeSystem::Visibility::Invisible},
+ {u"auto", TypeSystem::Visibility::Auto},
+ {u"yes", TypeSystem::Visibility::Visible},
+ {u"true", TypeSystem::Visibility::Visible},
+};
+ENUM_LOOKUP_LINEAR_SEARCH()
+
static int indexOfAttribute(const QXmlStreamAttributes &atts,
QStringView name)
{
@@ -625,6 +639,14 @@ bool TypeSystemParser::parse(QXmlStreamReader &reader)
{
m_error.clear();
m_currentPath.clear();
+ m_smartPointerInstantiations.clear();
+ const bool result = parseXml(reader) && setupSmartPointerInstantiations();
+ m_smartPointerInstantiations.clear();
+ return result;
+}
+
+bool TypeSystemParser::parseXml(QXmlStreamReader &reader)
+{
const QString fileName = readerFileName(reader);
if (!fileName.isEmpty())
m_currentPath = QFileInfo(fileName).absolutePath();
@@ -668,6 +690,62 @@ bool TypeSystemParser::parse(QXmlStreamReader &reader)
return true;
}
+// Split a type list potentially with template types
+// "A<B,C>,D" -> ("A<B,C>", "D")
+static QStringList splitTypeList(const QString &s)
+{
+ QStringList result;
+ int templateDepth = 0;
+ int lastPos = 0;
+ const int size = s.size();
+ for (int i = 0; i < size; ++i) {
+ switch (s.at(i).toLatin1()) {
+ case '<':
+ ++templateDepth;
+ break;
+ case '>':
+ --templateDepth;
+ break;
+ case ',':
+ if (templateDepth == 0) {
+ result.append(s.mid(lastPos, i - lastPos).trimmed());
+ lastPos = i + 1;
+ }
+ break;
+ }
+ }
+ if (lastPos < size)
+ result.append(s.mid(lastPos, size - lastPos).trimmed());
+ return result;
+}
+
+bool TypeSystemParser::setupSmartPointerInstantiations()
+{
+ for (auto it = m_smartPointerInstantiations.cbegin(),
+ end = m_smartPointerInstantiations.cend(); it != end; ++it) {
+ auto smartPointerEntry = it.key();
+ const auto instantiationNames = splitTypeList(it.value());
+ SmartPointerTypeEntry::Instantiations instantiations;
+ instantiations.reserve(instantiationNames.size());
+ for (const auto &instantiationName : instantiationNames) {
+ const auto types = m_database->findCppTypes(instantiationName);
+ if (types.isEmpty()) {
+ m_error =
+ msgCannotFindTypeEntryForSmartPointer(instantiationName,
+ smartPointerEntry->name());
+ return false;
+ }
+ if (types.size() > 1) {
+ m_error = msgAmbiguousTypesFound(instantiationName, types);
+ return false;
+ }
+ instantiations.append(types.constFirst());
+ }
+ smartPointerEntry->setInstantiations(instantiations);
+ }
+ return true;
+}
+
bool TypeSystemParser::endElement(const QStringRef &localName)
{
if (m_ignoreDepth) {
@@ -715,11 +793,6 @@ bool TypeSystemParser::endElement(const QStringRef &localName)
centry->setFieldModifications(m_contextStack.top()->fieldMods);
centry->setCodeSnips(m_contextStack.top()->codeSnips);
centry->setDocModification(m_contextStack.top()->docModifications);
-
- if (centry->designatedInterface()) {
- centry->designatedInterface()->setCodeSnips(m_contextStack.top()->codeSnips);
- centry->designatedInterface()->setFunctionModifications(m_contextStack.top()->functionMods);
- }
}
break;
case StackElement::AddFunction: {
@@ -802,7 +875,7 @@ bool TypeSystemParser::endElement(const QStringRef &localName)
break;
default:
break; // nada
- };
+ }
break;
default:
break;
@@ -878,7 +951,7 @@ bool TypeSystemParser::characters(const String &ch)
break;
default:
Q_ASSERT(false);
- };
+ }
return true;
}
}
@@ -1110,6 +1183,7 @@ SmartPointerTypeEntry *
QString smartPointerType;
QString getter;
QString refCountMethodName;
+ QString instantiations;
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
if (name == QLatin1String("type")) {
@@ -1118,6 +1192,8 @@ SmartPointerTypeEntry *
getter = attributes->takeAt(i).value().toString();
} else if (name == QLatin1String("ref-count-method")) {
refCountMethodName = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("instantiations")) {
+ instantiations = attributes->takeAt(i).value().toString();
}
}
@@ -1152,6 +1228,7 @@ SmartPointerTypeEntry *
auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType,
refCountMethodName, since, currentParentTypeEntry());
applyCommonAttributes(type, attributes);
+ m_smartPointerInstantiations.insert(type, instantiations);
return type;
}
@@ -1201,7 +1278,7 @@ ContainerTypeEntry *
return nullptr;
}
const QStringRef typeName = attributes->takeAt(typeIndex).value();
- ContainerTypeEntry::Type containerType = containerTypeFromAttribute(typeName);
+ ContainerTypeEntry::ContainerKind containerType = containerTypeFromAttribute(typeName);
if (containerType == ContainerTypeEntry::NoContainer) {
m_error = QLatin1String("there is no container of type ") + typeName.toString();
return nullptr;
@@ -1251,40 +1328,6 @@ EnumTypeEntry *
return entry;
}
-ObjectTypeEntry *
- TypeSystemParser::parseInterfaceTypeEntry(const QXmlStreamReader &,
- const QString &name, const QVersionNumber &since,
- QXmlStreamAttributes *attributes)
-{
- if (!checkRootElement())
- return nullptr;
- auto *otype = new ObjectTypeEntry(name, since, currentParentTypeEntry());
- applyCommonAttributes(otype, attributes);
- QString targetLangName = name;
- bool generate = true;
- for (int i = attributes->size() - 1; i >= 0; --i) {
- const QStringRef name = attributes->at(i).qualifiedName();
- if (name == targetLangNameAttribute()) {
- targetLangName = attributes->takeAt(i).value().toString();
- } else if (name == generateAttribute()) {
- generate = convertBoolean(attributes->takeAt(i).value(),
- generateAttribute(), true);
- }
- }
-
- auto itype = new InterfaceTypeEntry(InterfaceTypeEntry::interfaceName(targetLangName),
- since, currentParentTypeEntry());
- itype->setTargetLangName(targetLangName);
-
- if (generate)
- itype->setCodeGeneration(m_generate);
- else
- itype->setCodeGeneration(TypeEntry::GenerateForSubclass);
-
- otype->setDesignatedInterface(itype);
- itype->setOrigin(otype);
- return otype;
-}
NamespaceTypeEntry *
TypeSystemParser::parseNamespaceTypeEntry(const QXmlStreamReader &reader,
@@ -1294,8 +1337,8 @@ NamespaceTypeEntry *
if (!checkRootElement())
return nullptr;
QScopedPointer<NamespaceTypeEntry> result(new NamespaceTypeEntry(name, since, currentParentTypeEntry()));
+ auto visibility = TypeSystem::Visibility::Unspecified;
applyCommonAttributes(result.data(), attributes);
- applyComplexTypeAttributes(reader, result.data(), attributes);
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef attributeName = attributes->at(i).qualifiedName();
if (attributeName == QLatin1String("files")) {
@@ -1318,9 +1361,24 @@ NamespaceTypeEntry *
return nullptr;
}
result->setExtends(*extendsIt);
+ } else if (attributeName == visibleAttribute()) {
+ const auto attribute = attributes->takeAt(i);
+ visibility = visibilityFromAttribute(attribute.value());
+ if (visibility == TypeSystem::Visibility::Unspecified) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgInvalidAttributeValue(attribute)));
+ }
+ } else if (attributeName == generateAttribute()) {
+ if (!convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true))
+ visibility = TypeSystem::Visibility::Invisible;
}
}
+ if (visibility != TypeSystem::Visibility::Unspecified)
+ result->setVisibility(visibility);
+ // Handle legacy "generate" before the common handling
+ applyComplexTypeAttributes(reader, result.data(), attributes);
+
if (result->extends() && !result->hasPattern()) {
m_error = msgExtendingNamespaceRequiresPattern(name);
return nullptr;
@@ -1482,9 +1540,6 @@ void TypeSystemParser::applyComplexTypeAttributes(const QXmlStreamReader &reader
if (ctype->type() != TypeEntry::ContainerType)
ctype->setTargetLangPackage(package);
- if (InterfaceTypeEntry *di = ctype->designatedInterface())
- di->setTargetLangPackage(package);
-
if (generate)
ctype->setCodeGeneration(m_generate);
else
@@ -2420,7 +2475,7 @@ bool TypeSystemParser::readFileSnippet(QXmlStreamAttributes *attributes, CodeSni
"// START of custom code block [file: "
<< source << "]\n"
<< extractSnippet(QString::fromUtf8(codeFile.readAll()), snippetLabel)
- << "\n// END of custom code block [file: " << source
+ << "// END of custom code block [file: " << source
<< "]\n// ========================================================================\n";
snip->addCode(content);
return true;
@@ -2499,7 +2554,7 @@ bool TypeSystemParser::parseInclude(const QXmlStreamReader &,
QString location;
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("file-name"))
+ if (name == fileNameAttribute())
fileName = attributes->takeAt(i).value().toString();
else if (name == locationAttribute())
location = attributes->takeAt(i).value().toString();
@@ -2520,10 +2575,18 @@ bool TypeSystemParser::parseInclude(const QXmlStreamReader &,
m_error = QLatin1String("Only supported parent tags are primitive-type, complex types or extra-includes");
return false;
}
- if (InterfaceTypeEntry *di = entry->designatedInterface()) {
- di->setInclude(entry->include());
- di->setExtraIncludes(entry->extraIncludes());
+ return true;
+}
+
+bool TypeSystemParser::parseSystemInclude(const QXmlStreamReader &,
+ QXmlStreamAttributes *attributes)
+{
+ const int index = indexOfAttribute(*attributes, fileNameAttribute());
+ if (index == -1) {
+ m_error = msgMissingAttribute(fileNameAttribute());
+ return false;
}
+ TypeDatabase::instance()->addSystemInclude(attributes->takeAt(index).value().toString());
return true;
}
@@ -2684,8 +2747,8 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
m_currentDroppedEntry = element;
m_currentDroppedEntryDepth = 1;
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
- qCDebug(lcShiboken)
- << QStringLiteral("Type system entry '%1' was intentionally dropped from generation.").arg(identifier);
+ qCInfo(lcShiboken, "Type system entry '%s' was intentionally dropped from generation.",
+ qPrintable(identifier));
}
return true;
}
@@ -2761,14 +2824,6 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
element->entry = m_currentEnum;
break;
- case StackElement::InterfaceTypeEntry:
- if (ObjectTypeEntry *oe = parseInterfaceTypeEntry(reader, name, versionRange.since, &attributes)) {
- applyComplexTypeAttributes(reader, oe, &attributes);
- element->entry = oe;
- } else {
- return false;
- }
- break;
case StackElement::ValueTypeEntry:
if (ValueTypeEntry *ve = parseValueTypeEntry(reader, name, versionRange.since, &attributes)) {
applyComplexTypeAttributes(reader, ve, &attributes);
@@ -2784,6 +2839,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
return false;
break;
case StackElement::ObjectTypeEntry:
+ case StackElement::InterfaceTypeEntry:
if (!checkRootElement())
return false;
element->entry = new ObjectTypeEntry(name, versionRange.since, currentParentTypeEntry());
@@ -2805,7 +2861,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
break;
default:
Q_ASSERT(false);
- };
+ }
if (element->entry) {
if (!m_database->addType(element->entry, &m_error))
@@ -2828,6 +2884,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
|| element->type == StackElement::LoadTypesystem
|| element->type == StackElement::InjectCode
|| element->type == StackElement::ExtraIncludes
+ || element->type == StackElement::SystemInclude
|| element->type == StackElement::ConversionRule
|| element->type == StackElement::AddFunction
|| element->type == StackElement::Template;
@@ -2980,6 +3037,10 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
if (!addRejection(m_database, &attributes, &m_error))
return false;
break;
+ case StackElement::SystemInclude:
+ if (!parseSystemInclude(reader, &attributes))
+ return false;
+ break;
case StackElement::Template: {
const int nameIndex = indexOfAttribute(attributes, nameAttribute());
if (nameIndex == -1) {
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.h b/sources/shiboken2/ApiExtractor/typesystemparser.h
index d3ea54fc6..b4be2765c 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.h
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.h
@@ -31,6 +31,7 @@
#include "typesystem.h"
#include <QtCore/QStack>
+#include <QtCore/QHash>
#include <QtCore/QScopedPointer>
QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes)
@@ -86,6 +87,7 @@ class StackElement
NativeToTarget = 0x1100,
TargetToNative = 0x1200,
AddConversion = 0x1300,
+ SystemInclude = 0x1400,
SimpleMask = 0x3f00,
// Code snip tags (0x1000, 0x2000, ... , 0xf000)
@@ -151,6 +153,8 @@ public:
QString errorString() const { return m_error; }
private:
+ bool parseXml(QXmlStreamReader &reader);
+ bool setupSmartPointerInstantiations();
bool startElement(const QXmlStreamReader &reader);
SmartPointerTypeEntry *parseSmartPointerEntry(const QXmlStreamReader &,
const QString &name,
@@ -184,9 +188,6 @@ private:
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes);
- ObjectTypeEntry *
- parseInterfaceTypeEntry(const QXmlStreamReader &, const QString &name,
- const QVersionNumber &since, QXmlStreamAttributes *);
ValueTypeEntry *
parseValueTypeEntry(const QXmlStreamReader &, const QString &name,
const QVersionNumber &since, QXmlStreamAttributes *);
@@ -247,6 +248,7 @@ private:
StackElement* element, QXmlStreamAttributes *);
bool parseInclude(const QXmlStreamReader &, const StackElement &topElement,
TypeEntry *entry, QXmlStreamAttributes *);
+ bool parseSystemInclude(const QXmlStreamReader &, QXmlStreamAttributes *);
TemplateInstance
*parseTemplateInstanceEnum(const QXmlStreamReader &, const StackElement &topElement,
QXmlStreamAttributes *);
@@ -271,6 +273,7 @@ private:
QString m_currentSignature;
QString m_currentPath;
QScopedPointer<TypeSystemEntityResolver> m_entityResolver;
+ QHash<SmartPointerTypeEntry *, QString> m_smartPointerInstantiations;
};
#endif // TYPESYSTEMPARSER_H
diff --git a/sources/shiboken2/CMakeLists.txt b/sources/shiboken2/CMakeLists.txt
index c1349cae6..3de5d3223 100644
--- a/sources/shiboken2/CMakeLists.txt
+++ b/sources/shiboken2/CMakeLists.txt
@@ -18,7 +18,9 @@ option(BUILD_TESTS "Build tests." TRUE)
option(USE_PYTHON_VERSION "Use specific python version to build shiboken2." "")
option(DISABLE_DOCSTRINGS "Disable documentation extraction." FALSE)
-find_package(Qt5 5.12 REQUIRED COMPONENTS Core)
+set (QT_MAJOR_VERSION 5)
+message(STATUS "Using Qt ${QT_MAJOR_VERSION}")
+find_package(Qt${QT_MAJOR_VERSION} 5.12 REQUIRED COMPONENTS Core)
if (QUIET_BUILD)
set_quiet_build()
@@ -64,13 +66,13 @@ set(shiboken2_library_so_version "${shiboken_MAJOR_VERSION}.${shiboken_MINOR_VER
compute_config_py_values(shiboken2_VERSION)
## For debugging the PYTHON* variables
-message("PYTHONLIBS_FOUND: " ${PYTHONLIBS_FOUND})
-message("PYTHON_LIBRARIES: " ${PYTHON_LIBRARIES})
-message("PYTHON_INCLUDE_DIRS: " ${PYTHON_INCLUDE_DIRS})
-message("PYTHON_DEBUG_LIBRARIES: " ${PYTHON_DEBUG_LIBRARIES})
-message("PYTHONINTERP_FOUND: " ${PYTHONINTERP_FOUND})
-message("PYTHON_EXECUTABLE: " ${PYTHON_EXECUTABLE})
-message("PYTHON_VERSION: " ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH})
+message(STATUS "PYTHONLIBS_FOUND: " ${PYTHONLIBS_FOUND})
+message(STATUS "PYTHON_LIBRARIES: " ${PYTHON_LIBRARIES})
+message(STATUS "PYTHON_INCLUDE_DIRS: " ${PYTHON_INCLUDE_DIRS})
+message(STATUS "PYTHON_DEBUG_LIBRARIES: " ${PYTHON_DEBUG_LIBRARIES})
+message(STATUS "PYTHONINTERP_FOUND: " ${PYTHONINTERP_FOUND})
+message(STATUS "PYTHON_EXECUTABLE: " ${PYTHON_EXECUTABLE})
+message(STATUS "PYTHON_VERSION: " ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH})
if (NOT PYTHON_EXTENSION_SUFFIX)
get_python_extension_suffix()
@@ -112,7 +114,11 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D QT_NO_CAST_FROM_ASCII -D QT_NO_CAST_T
# Force usage of the C++11 standard, without a silent fallback
# to C++98 if the compiler does not support C++11.
-set(CMAKE_CXX_STANDARD 11)
+if(${QT_MAJOR_VERSION} GREATER_EQUAL 6)
+ set(CMAKE_CXX_STANDARD 17)
+else()
+ set(CMAKE_CXX_STANDARD 11)
+endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
@@ -208,7 +214,7 @@ add_subdirectory(libshiboken)
add_subdirectory(doc)
# deps found, compile the generator.
-if (Qt5Core_FOUND AND PYTHONINTERP_FOUND)
+if (Qt${QT_MAJOR_VERSION}Core_FOUND AND PYTHONINTERP_FOUND)
add_subdirectory(generator)
add_subdirectory(shibokenmodule)
diff --git a/sources/shiboken2/data/shiboken_helpers.cmake b/sources/shiboken2/data/shiboken_helpers.cmake
index 6bd75d0ea..5e0c6ea72 100644
--- a/sources/shiboken2/data/shiboken_helpers.cmake
+++ b/sources/shiboken2/data/shiboken_helpers.cmake
@@ -244,7 +244,7 @@ macro(get_python_extension_suffix)
"
OUTPUT_VARIABLE PYTHON_EXTENSION_SUFFIX
OUTPUT_STRIP_TRAILING_WHITESPACE)
- message("PYTHON_EXTENSION_SUFFIX: " ${PYTHON_EXTENSION_SUFFIX})
+ message(STATUS "PYTHON_EXTENSION_SUFFIX: " ${PYTHON_EXTENSION_SUFFIX})
endmacro()
macro(get_llvm_config)
@@ -260,7 +260,7 @@ macro(get_llvm_config)
"
OUTPUT_VARIABLE LLVM_CONFIG
OUTPUT_STRIP_TRAILING_WHITESPACE)
- message("LLVM_CONFIG: " ${LLVM_CONFIG})
+ message(STATUS "LLVM_CONFIG: " ${LLVM_CONFIG})
endmacro()
macro(get_python_arch)
@@ -271,7 +271,7 @@ macro(get_python_arch)
"
OUTPUT_VARIABLE PYTHON_ARCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
- message("PYTHON_ARCH: " ${PYTHON_ARCH})
+ message(STATUS "PYTHON_ARCH: " ${PYTHON_ARCH})
endmacro()
macro(shiboken_parse_all_arguments prefix type flags options multiopts)
diff --git a/sources/shiboken2/doc/CMakeLists.txt b/sources/shiboken2/doc/CMakeLists.txt
index 5903e9dfc..9fee96298 100644
--- a/sources/shiboken2/doc/CMakeLists.txt
+++ b/sources/shiboken2/doc/CMakeLists.txt
@@ -1,11 +1,47 @@
+cmake_minimum_required(VERSION 3.1)
+
find_program(SPHINX sphinx-build DOC "Path to sphinx-build binary.")
if (SPHINX)
- message("-- sphinx-build - found")
+ message(STATUS "sphinx-build - found")
configure_file(conf.py.in conf.py @ONLY)
- add_custom_target(doc ${SPHINX} -b html -c . ${CMAKE_CURRENT_SOURCE_DIR} html )
+ # conditional tag for sphinx build
+ #string(JOIN "_" SPHINX_TAG ${DOC_OUTPUT_FORMAT} "format")
+ add_custom_target(doc
+ COMMAND ${SPHINX} -b ${DOC_OUTPUT_FORMAT} -c . ${CMAKE_CURRENT_SOURCE_DIR} html
+ COMMENT "Generating HTMLs..."
+ VERBATIM)
+ # Python script that will be called to update the QHP
+ set(py_cmd "from __future__ import print_function
+import fileinput
+import re
+try:
+\tfor line in fileinput.input('html/Shiboken.qhp',inplace=True,backup='.bak'):
+\t\tline_copy=line.strip()
+\t\tif not line_copy: # check for empty line
+\t\t\tcontinue
+\t\tmatch=re.match('(^.*virtualFolder.)doc(.*$)',line)
+\t\tif match:
+\t\t\trepl=''.join([match.group(1),'shiboken2',match.group(2)])
+\t\t\tprint(line.replace(match.group(0),repl),end=' ')
+\t\telse:
+\t\t\tprint(line)
+except:
+\tpass\n")
+ file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/py_script.py
+ CONTENT ${py_cmd})
+
+ # create a custom command to generate QCH
+ if(DOC_OUTPUT_FORMAT STREQUAL "qthelp")
+ file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/html/Shiboken.qhp QHP_FILE)
+ add_custom_command(TARGET doc POST_BUILD
+ COMMAND ${PYTHON_EXECUTABLE} py_script.py # ${CMAKE_CURRENT_BINARY_DIR}/html/Shiboken.qhp
+ COMMAND qhelpgenerator ${QHP_FILE}
+ COMMENT "Genereting QCH based on the QHP..."
+ VERBATIM)
+ endif()
else()
- message("-- sphinx-build - not found! doc target disabled")
+ message(WARNING "sphinx-build - not found! doc target disabled")
if (WIN32)
# if jom is used and we have no sphinx, then jom will crash.
# so for windows, we always create a doc target (until jom gets fixed...)
diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/domainindex.html b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/domainindex.html
new file mode 100644
index 000000000..c136cdd1c
--- /dev/null
+++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/domainindex.html
@@ -0,0 +1,57 @@
+{#
+ basic/domainindex.html
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ Template for domain indices (module index, ...).
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+#}
+{% extends "layout.html" %}
+{% set title = indextitle %}
+{% block extrahead %}
+{{ super() }}
+{% if not embedded and collapse_index %}
+ <script type="text/javascript">
+ DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true;
+ </script>
+{% endif %}
+{% endblock %}
+{% block body %}
+<div class="section">
+ {%- set curr_group = 0 %}
+
+ <h1>{{ indextitle }}</h1>
+
+ <div class="modindex-jumpbox">
+ {%- for (letter, entries) in content %}
+ <a href="#cap-{{ letter }}"><strong>{{ letter }}</strong></a>
+ {%- if not loop.last %} | {% endif %}
+ {%- endfor %}
+ </div>
+
+ <table class="indextable modindextable" cellspacing="0" cellpadding="2">
+ {%- for letter, entries in content %}
+ <tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
+ <tr class="cap"><td></td><td><a name="cap-{{ letter }}">
+ <strong>{{ letter }}</strong></a></td><td></td></tr>
+ {%- for (name, grouptype, page, anchor, extra, qualifier, description)
+ in entries %}
+ {%- if grouptype == 1 %}{% set curr_group = curr_group + 1 %}{% endif %}
+ <tr{% if grouptype == 2 %} class="cg-{{ curr_group }}"{% endif %}>
+ <td>{% if grouptype == 1 -%}
+ <img src="{{ pathto('_static/minus.png', 1) }}" id="toggle-{{ curr_group }}"
+ class="toggler" style="display: none" alt="-" />
+ {%- endif %}</td>
+ <td>{% if grouptype == 2 %}&nbsp;&nbsp;&nbsp;{% endif %}
+ {% if page %}<a href="{{ pathto(page) }}#{{ anchor }}">{% endif -%}
+ <tt class="xref">{{ name|e }}</tt>
+ {%- if page %}</a>{% endif %}
+ {%- if extra %} <em>({{ extra|e }})</em>{% endif -%}
+ </td><td>{% if qualifier %}<strong>{{ qualifier|e }}:</strong>{% endif %}
+ <em>{{ description|e }}</em></td></tr>
+ {%- endfor %}
+ {%- endfor %}
+ </table>
+</div>
+{% endblock %}
diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/fakebar.png b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/fakebar.png
new file mode 100644
index 000000000..b45830e00
--- /dev/null
+++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/fakebar.png
Binary files differ
diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg
new file mode 100644
index 000000000..cd474efba
--- /dev/null
+++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg
Binary files differ
diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png
new file mode 100644
index 000000000..3bc03b7c7
--- /dev/null
+++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png
Binary files differ
diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/minus.png b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/minus.png
new file mode 100644
index 000000000..da1c5620d
--- /dev/null
+++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/minus.png
Binary files differ
diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/plus.png b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/plus.png
new file mode 100644
index 000000000..b3cb37425
--- /dev/null
+++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/plus.png
Binary files differ
diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pyside.css b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pyside.css
new file mode 100644
index 000000000..aee5e4420
--- /dev/null
+++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pyside.css
@@ -0,0 +1,1943 @@
+@import url('cookie-confirm.css') screen;
+
+/* -- admonitions -- */
+
+div.admonition {
+ margin: 1.5em 0 1.5em;
+ padding: 0;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+div.admonition dl {
+ margin-bottom: 0;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.admonition code {
+ font-family: inherit;
+}
+
+p.admonition-title + p {
+ padding-left: 1em;
+}
+
+div.admonition a:after {
+ content: ', ';
+}
+
+div.admonition a:last-child:after {
+ content: '';
+}
+
+.body {
+ width: 100%
+}
+.bodywrapper .admonition p.admonition-title {
+ margin-bottom:5px
+}
+
+.bodywrapper .admonition p {
+ margin:0
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+div.warning, div.seealso, div.note {
+ padding: 6px 0px 6px 10px;
+ border: none;
+}
+
+div.warning {
+ background-color: #ffe4e4;
+}
+
+div.seealso {
+ background-color: #fff2d6;
+}
+
+div.note {
+ background-color: #f3f3f4;
+}
+
+table.docutils {
+ margin-right: auto;
+ margin-bottom: 10px;
+ border: none;
+ width: initial;
+}
+
+table.docutils.colwidths-given td {
+ float: none;
+}
+
+table.docutils th,
+table.docutils td {
+ padding-left:0;
+ border: none;
+}
+
+table.docutils td ul {
+ margin:0
+}
+
+table.docutils td ul > li {
+ margin: 0 0 0.5em;
+}
+h2 em {
+ float: right;
+ font-size: 10px;
+ position: relative;
+ top: -20px;
+}
+
+.document {
+ padding-bottom: 20px;
+}
+
+.documentwrapper {
+ margin-left: 20px;
+}
+
+.body blockquote {
+ border: none;
+ padding-left: 0;
+ margin-bottom: 1.5em;
+}
+
+.sphinxsidebar {
+ float: left;
+ width: 186px;
+ padding: 25px;
+ text-align: left;
+ background-color: #fff;
+}
+
+.sphinxsidebar ul {
+ padding: 0px;
+ margin: 0px;
+ list-style-position: inside;
+}
+
+.sphinxsidebar > ul {
+ padding: 0px;
+ margin: 0px;
+}
+
+.sphinxsidebar ul li li {
+ margin-left: 10px;
+ padding: 0px;
+ font-size: 0.95em;
+}
+
+.sphinxsidebar ul a,
+.sphinxsidebar p.topless a {
+ word-break: break-word;
+}
+
+.sphinxsidebar h3, .sphinxsidebar h3 a {
+ color: #333;
+}
+
+.sphinxsidebar p.topless {
+ margin: 1em 0 1em;
+}
+
+.pysidetoc ul {
+ list-style: none;
+ padding: 0px;
+ margin: 0px;
+}
+
+.pysidetoc em {
+ font-style: normal;
+}
+
+.pysidetoc strong {
+ display: block;
+ padding: 5px;
+ margin: 0 10px 10px 0;
+ border: none;
+ background-color: #e2e2e2;
+}
+
+.section .docutils.container td {
+ float:left;
+}
+
+.hide {
+ display: none;
+}
+
+/* copy-notice */
+.document + p {
+ margin-left: 255px;
+ width: 70%;
+ font-size: 0.75em;
+ margin: 0 35px 15px 280px;
+}
+
+#searchbox {
+ border-top: 1px solid #989898;
+ padding-top: 10px;
+ margin-left: -10px;
+ margin-right: -10px;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+#search_button {
+ border: 1px solid #3A393A;
+ background-color: #3A393A;
+ color: white;
+ cursor: pointer;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -khtml-border-radius: 5px;
+
+}
+
+form {
+ margin: 0px;
+ padding: 0px;
+}
+
+#searchbox h3 {
+ padding: 10px 0 0 0;
+ margin-bottom: 5px;
+}
+
+/* search field */
+form #q {
+ width: 136px;
+ /* height: 22px; */
+ /* border: none; */
+ margin: 0px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -khtml-border-radius: 5px;
+ margin-top: 2px;
+ padding: 4px;
+ line-height: 22px;
+}
+
+#search-results h2 {
+ display: none;
+}
+
+#search-results h2 {
+ display: none;
+}
+
+#search-results ul.search {
+ margin: 0px;
+ padding: 0px;
+}
+
+ul.search div.context {
+ padding-left: 40px;
+}
+
+#installation td {
+ text-align: center;
+ font-weight: bold;
+}
+
+em {
+ color: inherit;
+ font-style:italic;
+}
+
+/******** REL bar *********/
+
+.related {
+ display: inline;
+}
+
+.related h3 {
+ display: none;
+}
+
+.align-center {
+ text-align: center;
+}
+
+.contentstable {
+ width: 100%;
+}
+
+.contentstable td {
+ padding-left: 30px;
+ vertical-align: top;
+}
+
+p.biglink a {
+ font-size: 20px;
+}
+
+dt:target, .highlight {
+ background-color: #fbe54e;
+}
+
+p.highlight-link {
+ margin-top: 10px;
+ font-size: 0.8em;
+}
+
+#synopsis table, table.field-list {
+ margin: 1em 0 1em 0;
+}
+
+table.field-list tr {
+ text-align: left;
+}
+
+tt.descname {
+ font-size: 120%;
+ font-weight: bold;
+}
+
+#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul {
+ margin: 0;
+ padding: 6px;
+ border: 1px solid #ddd;
+ border-radius: 0;
+ background-color: #e2e2e2;
+}
+
+#functions p, #virtual-functions p, #slots p, #signals p, #static-functions p {
+ margin: 0;
+ padding: 0;
+}
+
+#functions li, #virtual-functions li, #slots li, #signals li, #static-functions li {
+ list-style: none;
+ margin: 5px;
+ padding: 0;
+ font-size: 90%;
+}
+
+#synopsis span.pre {
+ color: #009491;
+ font-weight: bolder;
+}
+
+#detailed-description .class dt,
+#detailed-description .method dt,
+#detailed-description .staticmethod dt,
+#detailed-description .attribute dt {
+ margin: 0px;
+ margin-bottom: 10px;
+ padding: 10px;
+ font-weight: bold;
+ background-color: #e2e2e2;
+ border: none;
+ border-radius: 0;
+}
+
+#detailed-description dd > blockquote,
+#detailed-description dd > .field-list {
+ font-family: monospace;
+ font-size: small;
+ border-left: 10px solid #e2e2e2;
+ padding-left: 10px;
+ margin-bottom: 1.5em;
+}
+
+#detailed-description dd > blockquote blockquote {
+ border: none;
+ padding: 0;
+}
+
+#detailed-description .class .field-odd,
+#detailed-description .method .field-odd,
+#detailed-description .staticmethod .field-odd,
+#detailed-description .attribute .field-odd {
+ margin: 0;
+ padding: 1px 0 0 0;
+ background-color: #ffffff;
+
+}
+
+#detailed-description .class .field-even,
+#detailed-description .method .field-even,
+#detailed-description .staticmethod .field-even,
+#detailed-description .attribute .field-even {
+ margin: 0;
+ padding: 1px 0 0 0;
+ background-color: #ffffff;
+}
+
+#detailed-description .class .field-odd li,
+#detailed-description .method .field-odd li,
+#detailed-description .staticmethod .field-odd li,
+#detailed-description .attribute .field-odd li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+
+}
+
+#detailed-description .class .field-even li,
+#detailed-description .method .field-even li,
+#detailed-description .staticmethod .field-even li,
+#detailed-description .attribute .field-even li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+#detailed-description .class .field-odd p,
+#detailed-description .method .field-odd p,
+#detailed-description .staticmethod .field-odd p,
+#detailed-description .attribute .field-odd p{
+ margin: 0;
+ margin-left: 20px;
+
+}
+
+#detailed-description .class .field-even p,
+#detailed-description .method .field-even p,
+#detailed-description .staticmethod .field-even p,
+#detailed-description .attribute .field-even p{
+ margin: 0;
+ margin-left: 20px;
+}
+
+#detailed-description .class .field-odd p:last-child,
+#detailed-description .method .field-odd p:last-child,
+#detailed-description .staticmethod .field-odd p:last-child,
+#detailed-description .attribute .field-odd p:last-child {
+ margin-bottom: 10px;
+
+}
+
+#detailed-description .class .field-even p:last-child,
+#detailed-description .method .field-even p:last-child,
+#detailed-description .staticmethod .field-even p:last-child,
+#detailed-description .attribute .field-even p:last-child{
+ margin-bottom: 10px;
+}
+
+.document dl.attribute,
+.document dl.class,
+.document dl.method,
+.document dl.staticmethod {
+ margin-top: 2em;
+}
+
+.document dl.attribute dd,
+.document dl.class dd,
+.document dl.method dd,
+.document dl.staticmethod dd {
+ padding-left: 1em;
+}
+
+#detailed-description .attribute td:nth-child(1) {
+ font-family: monospace;
+}
+
+/* Qt theme */
+#navbar {
+ position:fixed;
+ top:0;
+ left:0;
+ z-index:100;
+ background:#fff;
+ width:100%
+}
+#navbar .container, .fixed .container {
+ max-width:1280px;
+ margin:0 auto;
+ padding:0 3.9%; /* 0? */
+ position:relative;
+ overflow:visible
+}
+#navbar .navbar-header {
+ position:relative
+}
+#menuextras li a:hover span {
+ color: #41cd52;
+}
+/* new header */
+#mm-wrap, #mm-wrap #mm-helper,
+#mm-wrap #mm-helper li.mm-item,
+#mm-wrap #mm-helper a.mm-link {
+ -moz-transition: none;
+ -o-transition: none;
+ -webkit-transition: none;
+ transition: none;
+ -webkit-border-radius: 0 0 0 0;
+ -moz-border-radius: 0 0 0 0;
+ -ms-border-radius: 0 0 0 0;
+ -o-border-radius: 0 0 0 0;
+ border-radius: 0 0 0 0;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ -ms-box-shadow: none;
+ -o-box-shadow: none;
+ box-shadow: none;
+ background: none;
+ border: 0;
+ bottom: auto;
+ box-sizing: border-box;
+ clip: auto;
+ color: #090e21;
+ display: block;
+ float: none;
+ font-family: inherit;
+ font-size: 14px;
+ height: auto;
+ left: auto;
+ line-height: 1.7;
+ list-style-type: none;
+ margin: 0;
+ min-height: 0;
+ opacity: 1;
+ outline: none;
+ overflow: visible;
+ padding: 0;
+ position: relative;
+ right: auto;
+ text-align: left;
+ text-decoration: none;
+ text-transform: none;
+ top: auto;
+ vertical-align: baseline;
+ visibility: inherit;
+ width: auto;
+}
+#mm-wrap #mm-helper {
+ visibility:visible;
+ text-align:right;
+ padding:0 0px 0 0px
+}
+#navbar #mm-wrap #mm-helper li.mm-item {
+ border-right:solid #f3f3f4 1px;
+ padding-right:30px;
+ padding-left:30px
+}
+#navbar #mm-wrap #mm-helper li.mm-item > a:hover {
+ opacity: .5
+}
+#mm-wrap #mm-helper > li.mm-item {
+ margin:0 0 0 0;
+ display:inline-block;
+ height:auto;
+ vertical-align:middle
+}
+#navbar #mm-wrap #mm-helper li.mm-item:nth-child(3) {
+ border-right:0
+}
+#mm-wrap #mm-helper a.mm-link {
+ cursor: pointer
+}
+@media (max-width: 1279px) {
+ #navbar {
+ padding:0;
+ position:relative;
+ }
+ #navbar .container {
+ max-width:100%
+ }
+ .container {
+ padding:0 2%
+ }
+}
+#navbar .navbar-oneQt {
+ display:inline;
+ float:left;
+ width:31px;
+ color:#41cd52
+}
+#navbar .navbar-oneQt:before {
+ content:attr(data-icon);
+ position:absolute;
+ top:14px;
+ left:0;
+ color:#41cd52;
+ font-family:'Qt Icons';
+ line-height:1;
+ font-size:40px;
+ transition:all 0.3s ease-in-out;
+}
+#mm-wrap {
+ clear:both;
+ background:rgba(255, 255, 255, 0.1);
+ -webkit-border-radius:0px 0px 0px 0px;
+ -moz-border-radius:0px 0px 0px 0px;
+ -ms-border-radius:0px 0px 0px 0px;
+ -o-border-radius:0px 0px 0px 0px;
+ border-radius:0px 0px 0px 0px
+}
+#mm-wrap #mm-helper li.mm-item:last-child a {
+ background:transparent url("icon_avatar.png") 50% 50% no-repeat !important;
+ background-size:24px !important;
+ width:24px !important;
+ height:24px !important;
+}
+#navbar #mm-wrap #mm-helper li.mm-item > a {
+ opacity:1;
+ -webkit-transition:all 0.3s ease-in-out;
+ -moz-transition:all 0.3s ease-in-out;
+ -ms-transition:all 0.3s ease-in-out;
+ -o-transition:all 0.3s ease-in-out;
+ transition:all 0.3s ease-in-out;
+}
+#mm-wrap #mm-helper > li.mm-item > a.mm-link {
+ border-top:0px solid #fff;
+ border-left:0px solid #fff;
+ border-right:0px solid #fff;
+ border-bottom:0px solid #fff;
+ outline:none;
+ text-decoration:none;
+ padding:0 0 0 0;
+ line-height:70px;
+ font-weight:normal;
+ height:70px;
+ vertical-align:baseline;
+ text-align:left;
+ width:auto;
+ display:block;
+ color:#090e21;
+ text-transform:none;
+ text-decoration:none;
+ background:rgba(0, 0, 0, 0);
+ -webkit-border-radius:0px 0px 0px 0px;
+ -moz-border-radius:0px 0px 0px 0px;
+ -ms-border-radius:0px 0px 0px 0px;
+ -o-border-radius:0px 0px 0px 0px;
+ border-radius:0px 0px 0px 0px;
+ font-family:inherit;
+ font-size:14px;
+}
+/* end new header */
+@media (min-width: 1320px) {
+ .body .flowListDiv dl.flowList {
+ -webkit-column-count:3;
+ -moz-column-count:3;
+ column-count:3
+ }
+}
+@media (min-width: 1120px) {
+ #navbar.fixed {
+ -moz-box-shadow:0px 0px 8px rgba(0,0,0,0.23);
+ -webkit-box-shadow:0px 0px 8px rgba(0,0,0,0.23);
+ box-shadow:0px 0px 8px rgba(0,0,0,0.23)
+ }
+ #navbar.fixed #mm-wrap #mm-helper > li.mm-item > a.mm-link {
+ height:50px;
+ line-height:50px
+ }
+ #navbar.fixed .navbar-oneQt:before {
+ font-size:35px;
+ top:7px
+ }
+
+ .flowListDiv dl.flowList {
+ -webkit-column-count:2;
+ -moz-column-count:2;
+ column-count:2
+ }
+}
+@media (max-width: 1120px) {
+ #navbar {
+ padding:0;
+ position:relative
+ }
+ #navbar .navbar-oneQt:before {
+ left:10px
+ }
+ #navbar .container {
+ max-width:100%;
+ padding:0
+ }
+ #footerbar .container {
+ padding:0
+ }
+ body .main {
+ margin-top:0px
+ }
+ #footerbar .footer-main .footer-nav {
+ padding:3.9% 0 3.9% 3%;
+ border-bottom:1px solid #413d3b;
+ float:none;
+ display:block;
+ width:auto
+ }
+ #footerbar .footer-main .theqtcompany {
+ clear:both;
+ float:left;
+ margin:30px 0 8px 3%
+ }
+ #footerbar .footer-main .footer-social {
+ float:left;
+ padding:50px 0px 0px 3%
+ }
+ #footerbar #menu-footer-submenu {
+ clear:both;
+ float:none;
+ display:block;
+ padding:0px 0px 3.9% 3%
+ }
+ ul#menu-footer-submenu {
+ margin-left: 0
+ }
+}
+.cookies_yum {
+ background-color:#cecfd5;
+ display:none;
+ width:100%
+}
+.cookies_yum img {
+ width:25px;
+ top:6px;
+ display:inline-block;
+ position:absolute;
+ left:13px
+}
+.cookies_yum div {
+ margin:0 auto;
+ max-width:1280px;
+ min-height:30px;
+ padding:6px 0px 6px 0px;
+ position:relative
+}
+.cookies_yum p {
+ color:#09102b;
+ margin:0px;
+ font-size:0.79em;
+ display:inline-block;
+ line-height:1.2;
+ padding:0 30px 0 50px
+}
+.cookies_yum p a {
+ white-space:nowrap
+}
+.cookies_yum a:hover {
+ color:#46a2da
+}
+.cookies_yum .close {
+ width:15px;
+ height:15px;
+ background-image:url("cookiebar-x.png");
+ background-size:15px 30px;
+ background-position:top left;
+ cursor:pointer;
+ top:13px;
+ right:13px;
+ position:absolute;
+ transition:none
+}
+.cookies_yum .close:hover {
+ background-position:bottom left
+}
+#sidebar-toggle,#toc-toggle {
+ width:24px;
+ height:14px;
+ background-size:24px 28px;
+ cursor:pointer;
+ background-image:url("list_expand.png");
+ float:right
+}
+#sidebar-toggle.collapsed,
+#toc-toggle.collapsed {
+ background-position:bottom left
+}
+#sidebar-content > h2 {
+ display:none
+}
+#footerbar {
+ background:#222840;
+ color:#fff;
+ font-size: 0.9em;
+}
+#footerbar.fixed {
+ bottom:0;
+ left:0;
+ width:100%
+}
+#footerbar .footer-nav {
+ display:inline;
+ float:left
+}
+#footerbar .footer-main .footer-nav li {
+ float:left;
+ margin-right:1em
+}
+#footerbar .footer-main .footer-nav li a {
+ display:block;
+ padding:30px 0 10px 0;
+ line-height:20px;
+ height:20px;
+ color:#fff;
+ font-weight: 600;
+}
+#footerbar .footer-main .footer-nav li a:hover,#footerbar .footer-main .footer-nav li.current-menu-item a {
+ color:#eee
+}
+#footerbar .footer-main .footer-nav .sub-menu {
+ margin-left:0;
+ margin-bottom:0
+}
+#footerbar .footer-main .footer-nav .sub-menu li {
+ float:none;
+ width: 100%;
+}
+#footerbar .footer-main .footer-nav .sub-menu ul {
+ padding:1px 1em;
+ font-size:0.786em;
+ line-height:8px;
+ float:none;
+ color:#5d5b59;
+ margin-bottom:0
+}
+#footerbar .footer-main .footer-nav .sub-menu li a {
+ padding:2px 0;
+ font-size:1em;
+ float:none;
+ color:#cecfd5;
+ font-weight: 400;
+}
+#footerbar .footer-main .footer-nav .sub-menu li a:hover,#footerbar .footer-main .footer-nav .sub-menu li.current-menu-item a {
+ color:#eee
+}
+#footerbar .theqtcompany {
+ background:url("theqtcompany.png") no-repeat;
+ background-size:100%;
+ width:215px;
+ height:68px;
+ display:inline;
+ float:right;
+ margin:29px 0 28px 30px
+}
+#footerbar .footer-social {
+ display:inline;
+ float:right;
+ width:164px
+}
+#footerbar .footer-main .footer-social>div {
+ margin-left:0.1em;
+ margin-bottom:10px
+}
+#footerbar .disclaimer {
+ font-size:0.786em;
+ line-height:2.73;
+ color:#868584;
+ padding-top:20px;
+ padding-bottom:0.5%
+}
+#footerbar .disclaimer a {
+ color:#bdbebf
+}
+#footerbar .disclaimer a:hover {
+ color:#d6d6d6
+}
+#footerbar .disclaimer ul li {
+ float:left;
+ vertical-align:middle;
+ margin-left:1.18em
+}
+#footerbar .disclaimer ul li:first-child {
+ margin-left:0
+}
+#footerbar .disclaimer ul.lang-selector a {
+ color:#506a34;
+ color:rgba(128,195,66,0.3)
+}
+#footerbar .disclaimer ul.lang-selector a:hover {
+ color:#80c342;
+ color:rgba(128,195,66,0.7)
+}
+#menu-footer-menu, #menu-footer-menu ul {
+ margin-left:0;
+ margin-bottom:0
+}
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: normal;
+ font-weight: 400;
+ src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot");
+ /* IE9 Compat Modes */
+ src: local("Titillium Web"), local("TitilliumWeb-Regular"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.svg#TitilliumWeb") format("svg");
+ /* Legacy iOS */
+}
+/* titillium-web-italic - latin_latin-ext */
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: italic;
+ font-weight: 400;
+ src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot");
+ /* IE9 Compat Modes */
+ src: local("Titillium WebItalic"), local("TitilliumWeb-Italic"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.svg#TitilliumWeb") format("svg");
+ /* Legacy iOS */
+}
+/* titillium-web-600 - latin_latin-ext */
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: normal;
+ font-weight: 600;
+ src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot");
+ /* IE9 Compat Modes */
+ src: local("Titillium WebSemiBold"), local("TitilliumWeb-SemiBold"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.svg#TitilliumWeb") format("svg");
+ /* Legacy iOS */
+}
+@font-face {
+ font-family:monospace;
+ font-style:normal;
+ font-weight:400;
+ src:local("Droid Sans Mono"),local("DroidSansMono"),url(//fonts.gstatic.com/s/droidsansmono/v7/ns-m2xQYezAtqh7ai59hJUYuTAAIFFn5GTWtryCmBQ4.woff) format("woff")
+}
+@font-face {
+ font-family:'Qt Icons';
+ src:url("../style/icomoon.eot?-tgjuoj");
+ src:url("../style/icomoon.eot?#iefix-tgjuoj") format("embedded-opentype"),url("../style/icomoon.woff?-tgjuoj") format("woff"),url("../style/icomoon.ttf?-tgjuoj") format("truetype"),url("../style/icomoon.svg?-tgjuoj#icomoon") format("svg");
+ font-weight:normal;
+ font-style:normal
+}
+@font-face {
+ font-family:'social-icons';
+ src:url("../style/social-icons.eot?54625607");
+ src:url("../style/social-icons.eot?54625607#iefix") format("embedded-opentype"),
+ url("../style/social-icons.woff?54625607") format("woff");
+ font-weight:normal;
+ font-style:normal
+}
+.clearfix:before,.clearfix:after {
+ content:" ";
+ display:table
+}
+.clearfix:after {
+ clear:both
+}
+.clearfix {
+ *zoom:1
+}
+.clearfix .right {
+ float:right
+}
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
+ margin:0;
+ padding:0;
+ border:0;
+ font-size:100%;
+ line-height: 1.4;
+}
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
+ vertical-align:baseline
+}
+h1,h2,h3,h4,h5,h6 {
+ font-weight:300
+}
+.body h2,.body h3,.body h4,.body h5,.body h6 {
+ margin:1.5em 0 0.75em
+}
+.body h1 {
+ margin-bottom:0.75em;
+ font-size:2.25em;
+}
+.body h3.fn,.body h3.flags {
+ color:#26282a;
+ font-size:1.46em;
+ padding:15px 0 15px 0;
+ border-bottom:2px #eee solid;
+ word-wrap:break-word
+}
+.body .fngroup {
+ border-bottom:2px #eee solid;
+ padding-bottom:15px;
+ margin-bottom:1.5em
+}
+.body .fngroup h3.fngroupitem {
+ margin:0;
+ padding-bottom:0;
+ border:none
+}
+.body h3.fn .name,
+.body h3 span.type,
+.qmlname span.name {
+ font-weight: 400
+}
+.qmlname {
+ font-size:1.46em
+}
+.qmlproto table {
+ border:none;
+ border-bottom:2px #eee solid
+}
+.qmlproto table p {
+ max-width:100%
+}
+.qmlproto table tr {
+ background-color:#fff
+}
+.qmlname td, .qmlname th {
+ border:none;
+ text-align:left;
+ padding:5px 0 0 0
+}
+.qmlreadonly,.qmldefault {
+ padding:0 5px 0 5px;
+ font-size:0.75em;
+ background-color:#eee;
+ float:right
+}
+.qmlreadonly {
+ color:#414141
+}
+.qmldefault {
+ color:#D14141
+}
+.rightAlign {
+ padding:3px 5px 3px 10px;
+ text-align:right
+}
+.centerAlign.functionIndex {
+ text-align:center;
+ font-size:150%;
+ margin-bottom: 1em
+}
+article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section {
+ display:block
+}
+body {
+ line-height:1.25em;
+ font-family: Arial, Helvitica;
+ font-weight:400;
+ transition-duration:1s;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ font-size: 16px;
+ background-color:#f3f3f4;
+ color:#404244;
+}
+ol,ul {
+ list-style-type: square;
+ #color: #17a81a;
+}
+.body ol,.body ul {
+ margin-top:0.75em;
+ margin-left:20px
+}
+.bodywrapper ol>li {
+ list-style-type:decimal;
+ margin-left:15px
+}
+.bodywrapper ol.a >li {
+ list-style-type:lower-alpha;
+}
+.bodywrapper ol.A >li {
+ list-style-type:upper-alpha;
+}
+.bodywrapper ol.i >li {
+ list-style-type:lower-roman;
+}
+.bodywrapper ol.I >li {
+ list-style-type:upper-roman;
+}
+.body li p {
+ margin-top:1em
+}
+blockquote,q {
+ quotes:none;
+ border-left:10px solid #ddd;
+ padding-left:10px
+}
+blockquote:before,blockquote:after,q:before,q:after {
+ content:'';
+ content:none;
+ width:100%
+}
+table {
+ border-collapse:collapse;
+ border-spacing:0;
+ margin-bottom:5px;
+ width:100%
+}
+a {
+ color:#17a81a;
+ text-decoration:none;
+ transition-duration:0.3s
+}
+a:hover {
+ color:#17a81a
+}
+.main,#footerbar>div {
+ max-width:1280px;
+ width:95%;
+ margin:0 auto
+}
+.main {
+ margin-top:80px
+}
+@media (max-width: 1120px) {
+ .main,.navbar-header,#footerbar>div {
+ width: 100%;
+ margin: 0;
+ }
+ .main .main-rounded {
+ padding: 0 15px;
+ }
+}
+.main_index {
+ background-color:#fff
+}
+.sectionlist {
+ margin-bottom:2em
+}
+[class*="col-"] {
+ letter-spacing:normal
+}
+.landing,.main_index .row {
+ letter-spacing:-0.31em
+}
+.main_index .row>div {
+ letter-spacing:normal
+}
+.col-1,.body {
+ display:inline-block;
+ background-color:#fff;
+ padding: 25px 35px 20px 30px;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+}
+.col-1 h2 {
+ font-size:1.8em;
+ font-weight:300;
+ line-height:1.1;
+ margin-bottom:0.83em;
+ margin-top:1em
+}
+.icons1of3 img {
+ display:inline-block;
+ float:left;
+ margin-right:0.75em;
+ margin-top:-5px;
+ width:2.75em
+}
+div.multi-column {
+ position:relative
+}
+div.multi-column div {
+ display:-moz-inline-box;
+ display:inline-block;
+ vertical-align:top;
+ margin-top:1em;
+ margin-right:2em;
+ width:16em
+}
+.sidebar {
+ display:block;
+ position:relative;
+ position:sticky;
+ float:left;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ width:20%;
+ padding-right:20px
+}
+.sidebar li {
+ text-overflow:ellipsis;
+ overflow:hidden
+}
+.toc,.sectionlist {
+ padding:25px;
+ background-color:#fff;
+ margin-bottom:1.25em
+}
+.sidebar .sectionlist p {
+ margin-bottom:0
+}
+.sectionlist.promo {
+ padding:0;
+ background-color:#f3f3f4
+}
+.sidebar-content:empty {
+ display:none;
+ visibility:hidden
+}
+.col-2 h2,.toc h3,.sidebar-content h2,
+.sidebar-content h3,.sectionlist h2,
+.sphinxsidebar {
+ position: fixed;
+ overflow: scroll;
+ overflow-x: hidden;
+ overflow-y: hidden;
+}
+.sphinxsidebar h3 {
+ font-weight: bold;
+ margin-bottom:1em;
+}
+.toc h3 a {
+ color:#404244
+}
+.title {
+ font-size:2.25em;
+ font-weight:300;
+ letter-spacing:-1px;
+ line-height:1.15em;
+ margin-bottom:0.5em;
+ word-wrap:break-word
+}
+.navigationbar,col-1 h2 {
+ font-size:0.85em
+}
+.navigationbar h1 {
+ font-size:2.5em;
+ margin-bottom:0.85em;
+ margin-top:0.85em
+}
+.navigationbar li {
+ display:inline-block;
+ margin-right:5px;
+ position:relative;
+ padding-right:10px;
+ color:#585a5c
+}
+.navigationbar ul:last-of-type li a {
+ color:#404244
+}
+.sectionlist li, .sphinxsidebar li {
+ padding-bottom: 10px;
+ line-height: 1.75em;
+}
+.col-1 ul {
+ margin-bottom:1.56em
+}
+.bodywrapper li {
+ margin-top:0.5em;
+ line-height:1.25em
+}
+.bodywrapper li.level2 {
+ margin-left:10px;
+ margin-top:0.4em;
+ font-size:0.9375em;
+}
+.bodywrapper p,
+.bodywrapper dd {
+ line-height:1.25em;
+ margin:1em 0 1em;
+ color:#404244
+}
+.bodywrapper b {
+ font-weight:600
+}
+.body ul,.body ol {
+ /* margin-bottom:1.5em */
+}
+.bodywrapper ul ul {
+ margin-top:0.5em
+}
+.bodywrapper .naviNextPrevious {
+ margin-top:25px;
+ max-width:100%
+}
+.naviNextPrevious.headerNavi,
+p.naviNextPrevious + p {
+ display:none
+}
+.nextPage {
+ float:right
+}
+.prevPage:before {
+ content:"< "
+}
+.nextPage:after {
+ content:" >"
+}
+.navigationbar li a {
+ color:#404244
+}
+.navigationbar li:after {
+ color:#404244;
+ content:"›";
+ display:inline-block;
+ font-size:1.5em;
+ line-height:1;
+ position:absolute;
+ right:-2px;
+ top:-4px
+}
+.sub-navigation {
+ margin-top:10px
+}
+.navigationbar li:last-child:after,.sub-navigation li:after {
+ content:none
+}
+.navigationbar {
+ margin-bottom:10px;
+ line-height:1em
+}
+#buildversion {
+ margin-bottom:10px;
+ font-style:italic;
+ font-size:small;
+ float:right
+}
+.copy-notice {
+ width:75%;
+ font-size:0.75em;
+ margin:20px 35px 0 10px;
+ line-height:1.75em;
+ float:right;
+ color:#585a5c
+}
+.copy-notice.index {
+ margin-top:10px;
+ float:none
+}
+li a.active {
+ color:#585a5c
+}
+.flowList {
+ padding:25px
+}
+.flowListDiv dl {
+ -webkit-column-count:1;
+ -moz-column-count:1;
+ column-count:1
+}
+.flowList dd {
+ display:inline-block;
+ margin-left:10px;
+ width:90%;
+ line-height:1.15em;
+ overflow-x:hidden;
+ text-overflow:ellipsis
+}
+.alphaChar {
+ font-size:2em;
+ position:absolute
+}
+.flowList.odd {
+ background-color:#f9f9f9
+}
+.body ul>li,.doc-column ul>li {
+ list-style-image:url("list_arrow.png");
+ margin-left:15px;
+ color:#404244;
+ margin-top:0.65em;
+ line-height:1em
+}
+.bodywrapper table p {
+ margin:0px;
+ padding:0px
+}
+.bodywrapper table p {
+ margin:0px;
+ padding:0px;
+ min-height:1.25em
+}
+.bodywrapper .qmldoc {
+ margin-top:0.75em
+}
+.body h2 {
+ margin-top: 1.5em;
+ font-size:1.75em
+}
+.body h3 {
+ font-size:1.35em
+}
+.body h4 {
+ font-size:1.15em
+}
+.body p img {
+ margin-top:0.75em;
+ max-width:100%
+}
+.body .border img {
+ box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5)
+}
+.body .border .player {
+ box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5)
+}
+.body p.figCaption {
+ transform:translateY(-30px);
+ color:#606366;
+ font-size:95%;
+ margin-left:3px;
+ font-style:italic
+}
+.body table {
+ width:initial;
+ vertical-align:initial
+}
+table .odd {
+ background-color:#f9f9f9
+}
+table thead {
+ text-align:left;
+ padding-left:20px
+}
+table,table td,table th {
+ border:1px solid #eee
+}
+table td,table th {
+ padding:5px 20px;
+ line-height:1.3
+}
+.body .fixed table td {
+ min-width:50%;
+ width:50%
+}
+table.alignedsummary,table.propsummary {
+ width:initial
+}
+table.valuelist td.tblval {
+ font-size:0.75em
+}
+div.main_index .row {
+ border-bottom:10px solid #f3f3f4
+}
+div.main_index .row {
+ position:relative
+}
+div.main_index .row>div {
+ display:inline-block;
+ width:50%;
+ vertical-align:top;
+ padding:2em 3em;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box
+}
+div.main_index h2 {
+ font-size:2.1875em;
+ margin-bottom:1em
+}
+#search_bar {
+ width:40%;
+ float:right
+}
+div.main_index .row:after {
+ content:"";
+ position:absolute;
+ top:0;
+ right:50%;
+ height:100%;
+ width:10px;
+ background-color:#f3f3f4
+}
+div.table {
+ overflow-x:auto
+}
+.body tr > td > pre {
+ font-size:0.75em
+}
+p.qt_commercial {
+ border:3px solid #5caa15;
+ margin:0 auto;
+ padding:15px;
+ width:28%;
+ text-align:center;
+ clear:both
+}
+h1.qt_commercial {
+ padding:20px;
+ background-color:#5caa15;
+ display:inline;
+ float:right;
+ font-size:1.25em;
+ line-height:1.25em;
+ height:1.25em;
+ color:#fff
+}
+div.qt_commercial {
+ border-top:5px solid #5caa15;
+ margin-bottom:50px
+}
+div.pre {
+ position:relative;
+ height:auto
+}
+pre, .LegaleseLeft {
+ background-color:#222840;
+ color:#fff;
+ display:block;
+ font-family:monospace;
+ line-height:1.5;
+ overflow-x:auto;
+ margin-bottom:25px;
+ padding:25px;
+ margin-top:0.75em;
+ font-size: .8em;
+}
+.bodywrapper .LegaleseLeft p {
+ color:#fff;
+ white-space: pre-wrap
+}
+pre .str,code .str {
+ color:#aaaaaa
+}
+pre .kwd,code .kwd {
+ color:#ffff55
+}
+pre .com,code .com {
+ color:#55ffff
+}
+pre .typ,code .typ {
+ color:#4f9d08
+}
+pre a .typ,code a .typ {
+ color:#21be2b
+}
+pre .lit,code .lit {
+ color:#ff55ff
+}
+pre .pun,code .pun {
+ color:#fff
+}
+pre .pln,code .pln {
+ color:#fff
+}
+@media print {
+ pre {
+ background-color:#eee !important
+ }
+ pre .str,code .str {
+ color:#060
+ }
+ pre .kwd,code .kwd{
+ color:#006;
+ font-weight:bold
+ }
+ pre .com,code .com {
+ color:#600
+ }
+ pre .typ,code .typ {
+ color:#404;
+ font-weight:bold
+ }
+ pre .lit,code .lit {
+ color:#044
+ }
+ pre .pun,code .pun {
+ color:#440
+ }
+ pre .pln,code .pln {
+ color:#000
+ }
+}
+pre.wrap {
+ white-space:pre-wrap
+}
+pre span.wrap {
+ display:none;
+ background:url("wrap.png") no-repeat;
+ right:0;
+ top:2px;
+ position:absolute;
+ width:20px;
+ height:14px;
+ margin:4px;
+ opacity:0.65
+}
+
+span.pre {
+ color: #09102d;
+}
+
+span.wrap:hover {
+ opacity:1
+}
+span.wrap:active {
+ opacity:0.75
+}
+.copy_text {
+ background-color:#46a2da;
+ color:#fff;
+ border:2px solid #46a2da;
+ padding:10px 16px;
+ margin-left:-10px;
+ margin-top:-50px;
+ position:absolute;
+ opacity:0;
+ cursor:pointer;
+ float:right
+}
+.copy_text:hover {
+ background-color:#fff;
+ color:#46a2da
+}
+code,.codelike {
+ font-family:monospace;
+}
+#detailed-description .function dt > code,
+#detailed-description .function dt > em {
+ font-weight:bold
+}
+h3.fn code {
+ font-size:0.75em;
+ float:right;
+ background-color:#eee;
+ padding:3px;
+ margin: 3px 0 0 20px
+}
+pre:hover>.copy_text {
+ display:inline-block;
+ opacity:1;
+ transition:0.5s ease
+}
+#main_title_bar {
+ background:url("pyside-logo.png") no-repeat;
+ background-size:100%;
+ width:366px;
+ height:86px;
+ margin:15px 0 15px 0
+}
+#main_title_bar h1 {
+ visibility:hidden
+}
+#main_title_bar .search_bar {
+ letter-spacing:normal;
+ width:50%;
+ display:inline-block;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ vertical-align:middle
+}
+#main_title_bar h1 {
+ letter-spacing:normal;
+ display:inline-block;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ vertical-align:middle
+}
+#main_title_bar .search_bar * {
+ letter-spacing:normal;
+ padding:0;
+ margin:0;
+ border:none
+}
+#sidebar-toggle,#toc-toggle {
+ display:none
+}
+@media (max-width: 980px) {
+ body {
+ font-size:calc-em(14px)
+ }
+ #main_title_bar>h1,#main_title_bar .search_bar {
+ width:100%
+ }
+ #main_title_bar .search_bar {
+ margin-bottom:15px
+ }
+ .main {
+ margin-top:0px
+ }
+ .main_index .row {
+ border:none !important
+ }
+ .title {
+ font-size:1.5em;
+ font-weight:400;
+ word-wrap:break-word
+ }
+ .col-1,.body,.naviNextPrevious,.sidebar {
+ padding:10px
+ }
+ .sidebar {
+ position:relative;
+ padding-top:0
+ }
+ .search .sidebar {
+ display:none;
+ visibility:hidden
+ }
+ .col-2 h2,.toc h3,.sidebar-content h2,.sidebar-content h3,.sectionlist h2 {
+ text-align:center;
+ margin-bottom:5px
+ }
+ div.main_index .row:after {
+ content:none
+ }
+ div.main_index .row>div {
+ display:block !important;
+ width:100%;
+ padding:15px;
+ margin:0
+ }
+ .body,.sidebar,.col-1 {
+ width:100%
+ }
+ .sidebar-content,.col-2,.toc {
+ background-color:#fff;
+ margin-bottom:1em;
+ padding:20px
+ }
+ #sidebar-toggle,#toc-toggle {
+ display:block
+ }
+ #sidebar-toggle.collapsed + h2 {
+ display:block
+ }
+ .bodywrapper p {
+ margin-bottom:1em;
+ max-width:100%
+ }
+ table td,table th {
+ padding:5px 5px
+ }
+ .sectionlist {
+ padding:0
+ }
+ .sidebar > .sectionlist {
+ padding:20px
+ }
+ .sectionlist.promo {
+ max-width:46%;
+ margin:0 auto 1em auto;
+ float:left;
+ padding:0 2%
+ }
+ .sidebar .sidebar-content {
+ clear:both
+ }
+ .copy-notice {
+ float:none;
+ width:initial
+ }
+}
+[id]:target > *:first-child,
+dt[id]:target {
+ -webkit-animation:highlighter 3s;
+ animation:highlighter 3s
+}
+@-webkit-keyframes highlighter {
+ 25% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+ 75% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+}
+@keyframes highlighter {
+ 25% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+ 75% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+}
+@-webkit-keyframes copypaste {
+ 25% {
+ opacity:1
+ }
+ 100% {
+ border-radius:10px;
+ margin-top:-50px;
+ opacity:1
+ }
+}
+@keyframes copypaste {
+ 25% {
+ opacity:1
+ }
+ 100% {
+ border-radius:10px;
+ margin-top:-50px;
+ opacity:1
+ }
+}
+#footer {
+ clear:both
+}
+.footer-social i {
+ font-family: "social-icons";
+ font-style: normal;
+ font-size:150%;
+ margin: .55em;
+ color: #cecfd5
+}
+.footer-social i:hover {
+ color: #eee
+}
+.footer-social .icon-twitter:before {
+ content: '\f099'
+}
+.footer-social .icon-facebook:before {
+ content: '\f09a'
+}
+.footer-social .icon-youtube:before {
+ content: '\f16a'
+}
+.menuextraslanguages {
+ display:none;
+ visibility:hidden
+}
+
+input:focus {
+ border-color: #46a2da;
+ box-shadow: 0 0 5px #46a2da;
+ color: #000;
+}
+
+.animation {
+ width: 100%;
+ border-style: none;
+ border-width: 0
+}
+
+.player {
+ width: auto;
+ position: relative;
+ display: table;
+ margin-bottom:1.5em;
+}
+
+.playcontrol {
+ display: none;
+ background: url("play_icon.svg") no-repeat center,
+ linear-gradient(
+ rgba(0,0,0,0.15), rgba(0,0,0,0.15)
+ );
+ background-size: 25%;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ left: 0%;
+ right: 0%;
+ top: 0%;
+ bottom: 0%;
+ margin: auto
+}
+
+/* expand/collapse code sections */
+pre input {
+ display:none;
+ visibility:hidden
+}
+pre label {
+ display:block;
+ margin:-3px 3px 0 -16px;
+ text-align:center;
+ color:#21be2b;
+ float:left;
+}
+pre label:hover {
+ color:#fff
+}
+pre label::before {
+ font-weight:600;
+ font-size:16px;
+ content:"+";
+ display:inline-block;
+ width:16px;
+ height:16px
+}
+#ec_expand {
+ height:16px;
+ overflow:hidden;
+ transition:height 0.35s;
+}
+#ec_expand::before {
+ content:"...*/";
+ color:#aaa;
+ background-color:#3a4055;
+ z-index:99 !important;
+ right:25px;
+ position:absolute
+}
+#ec_toggle:checked ~ #ec_expand {
+ height:initial
+}
+#ec_toggle:checked ~ #ec_expand::before {
+ content:""
+}
+#ec_toggle:checked ~ label::before {
+ content:"-"
+}
+
+/* permalinks */
+h1:hover > .headerlink,
+h2:hover > .plink,
+h2:hover > .headerlink,
+h3:hover > .plink,
+h3:hover > .headerlink,
+h4:hover > .plink,
+h4:hover > .headerlink,
+h5:hover > .plink,
+h5:hover > .headerlink {
+ opacity:1
+}
+a.plink, a.headerlink {
+ opacity: 0;
+ padding-left: 8px;
+ font-size: 0.8em;
+ font-weight: 600;
+ transition: opacity 180ms ease-in-out
+}
+a.plink::before {
+ content:'\00B6'
+}
+
+table.special {
+ border: 3px;
+ padding: 0px;
+ border-collapse: separate;
+ border-spacing: 20px;
+ line-height: 1.5em;
+}
+
+.special p {
+ text-align: center;
+ color: #3a4055;
+}
+
+.special a {
+ display: block;
+ border-bottom: 0;
+ text-decoration: none;
+}
+
+.special a:hover {
+ border-bottom: 0;
+ text-decoration: none;
+}
+
+.special strong {
+ color: #17a81a;
+ font-size: 110%;
+ font-weight: normal;
+}
+
+table.special th,
+table.special td {
+ border: 1px solid #888;
+ padding-top: 14px;
+ padding-bottom: 14px;
+ padding-left: 6px;
+ padding-right: 5px;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -khtml-border-radius: 5px;
+}
+
+.special td:hover {
+ padding-top: 2px;
+ padding-bottom: 2px;
+ border-bottom: 4px solid #41cd52;
+}
diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png
new file mode 100644
index 000000000..3a2f2bd17
--- /dev/null
+++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png
Binary files differ
diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png
new file mode 100644
index 000000000..4036733a7
--- /dev/null
+++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png
Binary files differ
diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/theme.conf b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/theme.conf
new file mode 100644
index 000000000..4384b459c
--- /dev/null
+++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/theme.conf
@@ -0,0 +1,7 @@
+[theme]
+inherit = default
+stylesheet = pyside.css
+pygments_style = none
+
+[options]
+nosidebar = true
diff --git a/sources/shiboken2/doc/conf.py.in b/sources/shiboken2/doc/conf.py.in
index e158abbbe..f99af0fff 100644
--- a/sources/shiboken2/doc/conf.py.in
+++ b/sources/shiboken2/doc/conf.py.in
@@ -25,7 +25,12 @@ import sys, os
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.ifconfig',
'sphinx.ext.coverage']
+output_format='@DOC_OUTPUT_FORMAT@'
+
+def setup(app):
+ app.add_config_value('output_format','qthelp','env')
rst_epilog = """
+
.. |project| replace:: Shiboken
"""
@@ -158,3 +163,6 @@ html_show_sourcelink = False
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
+
+# -- Options for qthelp output --------------------------------------------------
+qthelp_theme = 'pysidedocs_qthelp'
diff --git a/sources/shiboken2/doc/index.rst b/sources/shiboken2/doc/index.rst
index ca452b9ca..a6e1bccd4 100644
--- a/sources/shiboken2/doc/index.rst
+++ b/sources/shiboken2/doc/index.rst
@@ -1,7 +1,14 @@
Shiboken
********
-Shiboken is a fundamental piece on the `Qt for Python`_ project that serves two purposes:
+.. ifconfig:: output_format == 'html'
+
+ Shiboken is a fundamental piece on the `Qt for Python <../index.html>`_ project that serves two purposes:
+
+.. ifconfig:: output_format == 'qthelp'
+
+ Shiboken is a fundamental piece on the `Qt for Python <../pyside2/index.html>`_ project that serves two purposes:
+
* Generator_: Extract information from C or C++ headers and generate CPython_ code that allow
to bring C or C++ projects to Python. This process uses a library called ApiExtractor_ which
@@ -9,7 +16,6 @@ Shiboken is a fundamental piece on the `Qt for Python`_ project that serves two
* Module_: An utility Python module that exposed new Python types, functions to handle pointers,
among other things, that is written in CPython_ and can use independently of the generator.
-.. _`Qt for Python`: ../index.html
.. _Generator: shibokengenerator.html
.. _Module: shibokenmodule.html
.. _CPython: https://github.com/python/cpython
diff --git a/sources/shiboken2/doc/shibokengenerator.rst b/sources/shiboken2/doc/shibokengenerator.rst
index 1a7152fbb..b15ad5ada 100644
--- a/sources/shiboken2/doc/shibokengenerator.rst
+++ b/sources/shiboken2/doc/shibokengenerator.rst
@@ -69,7 +69,7 @@ Usage
::
- shiboken [options] header-file typesystem-file
+ shiboken [options] header-file(s) typesystem-file
Options
diff --git a/sources/shiboken2/doc/typesystem_specifying_types.rst b/sources/shiboken2/doc/typesystem_specifying_types.rst
index bca1e0774..27267faab 100644
--- a/sources/shiboken2/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken2/doc/typesystem_specifying_types.rst
@@ -153,6 +153,7 @@ namespace-type
<typesystem>
<namespace-type name="..."
+ visible="true | auto | false"
generate="yes | no"
package="..."
since="..."
@@ -161,8 +162,16 @@ namespace-type
The **name** attribute is the name of the namespace, e.g., "Qt".
- The *optional* **generate** attribute is used to inform if you need to prepend
- the given namespace into each generated class. Its default value is **yes**.
+ The *optional* **visible** attribute is used specify whether the
+ namespace is visible in the target language name. Its default value is
+ **auto**. It means that normal namespaces are visible, but inline namespaces
+ (as introduced in C++ 11) will not be visible.
+
+ The detection of inline namespaces requires shiboken to be built
+ using LLVM 9.0.
+
+ The *optional* **generate** is a legacy attribute. Specifying
+ **no** is equivalent to **visible="false"**.
The **package** attribute can be used to override the package of the type system.
@@ -326,30 +335,7 @@ object-type
interface-type
^^^^^^^^^^^^^^
- The interface-type node indicates that the given class is replaced by an
- interface pattern when mapping from C++ to the target language. Using the
- interface-type node implicitly makes the given type an :ref:`object-type`.
-
- .. code-block:: xml
-
- <typesystem>
- <interface-type name="..."
- since="..."
- package ="..."
- default-superclass ="..."
- revision="..." />
- </typesystem>
-
- The **name** attribute is the fully qualified C++ class name. The *optional*
- **package** attribute can be used to override the package of the type system.
- If there is no C++ base class, the *optional* **default-superclass** attribute
- can be used to specify a superclass in the generated target language API, for
- the given class.
-
- The *optional* **since** value is used to specify the API version of this interface.
-
- The **revision** attribute can be used to specify a revision for each type, easing the
- production of ABI compatible bindings.
+ This type is deprecated and no longer has any effect. Use object-type instead.
.. _container-type:
@@ -436,6 +422,14 @@ smart-pointer-type
to function return values.
**ref-count-method** specifies the name of the method used to do reference counting.
+ The *optional* attribute **instantiations** specifies for which instantiations
+ of the smart pointer wrappers will be generated (comma-separated list).
+ By default, this will happen for all instantiations found by code parsing.
+ This might be a problem when linking different modules, since wrappers for the
+ same instantiation might be generated into different modules, which then clash.
+ Providing an instantiations list makes it possible to specify which wrappers
+ will be generated into specific modules.
+
.. code-block:: xml
<typesystem>
@@ -443,7 +437,8 @@ smart-pointer-type
since="..."
type="..."
getter="..."
- ref-count-method="..."/>
+ ref-count-method="..."
+ instantiations="..."/>
</typesystem>
.. _function:
@@ -467,3 +462,20 @@ function
The function tag has two *optional* attributes: **since**, whose value is used to specify
the API version of this function, and **rename**, to modify the function name.
+.. _system_include:
+
+system-include
+^^^^^^^^^^^^^^
+
+ The optional **system-include** specifies the name of a system include
+ file or a system include path (indicated by a trailing slash) to be
+ parsed. Normally, include files considered to be system include
+ files are skipped by the C++ code parser. Its primary use case
+ is exposing classes from the STL library.
+
+ .. code-block:: xml
+
+ <typesystem>
+ <system-include file-name="memory"/>
+ <system-include file-name="/usr/include/Qt/"/>
+ </typesystem>
diff --git a/sources/shiboken2/generator/CMakeLists.txt b/sources/shiboken2/generator/CMakeLists.txt
index 51623414b..1a3f4e5c4 100644
--- a/sources/shiboken2/generator/CMakeLists.txt
+++ b/sources/shiboken2/generator/CMakeLists.txt
@@ -20,7 +20,7 @@ target_include_directories(shiboken2 PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
${apiextractor_SOURCE_DIR}
)
-target_link_libraries(shiboken2 apiextractor Qt5::Core)
+target_link_libraries(shiboken2 apiextractor Qt${QT_MAJOR_VERSION}::Core)
if (NOT DISABLE_DOCSTRINGS)
target_sources(shiboken2 PRIVATE qtdoc/qtdocgenerator.cpp)
target_compile_definitions(shiboken2 PUBLIC DOCSTRINGS_ENABLED)
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index 484b1f641..4eabb3d2c 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -151,6 +151,12 @@ QString DefaultValue::constructorParameter() const
return m_value + QLatin1String("()");
}
+QString GeneratorContext::smartPointerWrapperName() const
+{
+ Q_ASSERT(m_type == SmartPointer);
+ return m_preciseClassType->cppSignature();
+}
+
struct Generator::GeneratorPrivate
{
const ApiExtractor *apiextractor = nullptr;
@@ -159,7 +165,6 @@ struct Generator::GeneratorPrivate
QString licenseComment;
QString moduleName;
QStringList instantiatedContainersNames;
- QStringList instantiatedSmartPointerNames;
QVector<const AbstractMetaType *> instantiatedContainers;
QVector<const AbstractMetaType *> instantiatedSmartPointers;
@@ -211,6 +216,31 @@ QString Generator::getSimplifiedContainerTypeName(const AbstractMetaType *type)
return typeName;
}
+// Strip a "const QSharedPtr<const Foo> &" or similar to "QSharedPtr<Foo>" (PYSIDE-1016/454)
+const AbstractMetaType *canonicalSmartPtrInstantiation(const AbstractMetaType *type)
+{
+ AbstractMetaTypeList instantiations = type->instantiations();
+ Q_ASSERT(instantiations.size() == 1);
+ const bool needsFix = type->isConstant() || type->referenceType() != NoReference;
+ const bool pointeeNeedsFix = instantiations.constFirst()->isConstant();
+ if (!needsFix && !pointeeNeedsFix)
+ return type;
+ auto fixedType = type->copy();
+ fixedType->setReferenceType(NoReference);
+ fixedType->setConstant(false);
+ if (pointeeNeedsFix) {
+ auto fixedPointeeType = instantiations.constFirst()->copy();
+ fixedPointeeType->setConstant(false);
+ fixedType->setInstantiations(AbstractMetaTypeList(1, fixedPointeeType));
+ }
+ return fixedType;
+}
+
+static inline const TypeEntry *pointeeTypeEntry(const AbstractMetaType *smartPtrType)
+{
+ return smartPtrType->instantiations().constFirst()->typeEntry();
+}
+
void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType *type,
const QString &context)
{
@@ -244,18 +274,15 @@ void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType
m_d->instantiatedContainers.append(type);
}
} else {
- // Is smart pointer.
- if (!m_d->instantiatedSmartPointerNames.contains(typeName)) {
- m_d->instantiatedSmartPointerNames.append(typeName);
- if (type->isConstant() || type->referenceType() != NoReference) {
- // Strip a "const QSharedPtr<Foo> &" or similar to "QSharedPtr<Foo>" (PYSIDE-1016)
- auto fixedType = type->copy();
- fixedType->setReferenceType(NoReference);
- fixedType->setConstant(false);
- type = fixedType;
- }
- m_d->instantiatedSmartPointers.append(type);
- }
+ // Is smart pointer. Check if the (const?) pointee is already known
+ auto pt = pointeeTypeEntry(type);
+ const bool present =
+ std::any_of(m_d->instantiatedSmartPointers.cbegin(), m_d->instantiatedSmartPointers.cend(),
+ [pt] (const AbstractMetaType *t) {
+ return pointeeTypeEntry(t) == pt;
+ });
+ if (!present)
+ m_d->instantiatedSmartPointers.append(canonicalSmartPtrInstantiation(type));
}
}
@@ -387,9 +414,9 @@ void Generator::setOutputDirectory(const QString &outDir)
m_d->outDir = outDir;
}
-bool Generator::generateFileForContext(GeneratorContext &context)
+bool Generator::generateFileForContext(const GeneratorContext &context)
{
- AbstractMetaClass *cls = context.metaClass();
+ const AbstractMetaClass *cls = context.metaClass();
if (!shouldGenerate(cls))
return true;
@@ -397,8 +424,6 @@ bool Generator::generateFileForContext(GeneratorContext &context)
const QString fileName = fileNameForContext(context);
if (fileName.isEmpty())
return true;
- if (ReportHandler::isDebug(ReportHandler::SparseDebug))
- qCDebug(lcShiboken) << "generating: " << fileName;
QString filePath = outputDirectory() + QLatin1Char('/') + subDirectoryForClass(cls)
+ QLatin1Char('/') + fileName;
@@ -421,12 +446,28 @@ QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType *smartP
return fileName;
}
+GeneratorContext Generator::contextForClass(const AbstractMetaClass *c) const
+{
+ GeneratorContext result;
+ result.m_metaClass = c;
+ return result;
+}
+
+GeneratorContext Generator::contextForSmartPointer(const AbstractMetaClass *c,
+ const AbstractMetaType *t) const
+{
+ GeneratorContext result;
+ result.m_metaClass = c;
+ result.m_preciseClassType = t;
+ result.m_type = GeneratorContext::SmartPointer;
+ return result;
+}
+
bool Generator::generate()
{
const AbstractMetaClassList &classList = m_d->apiextractor->classes();
for (AbstractMetaClass *cls : classList) {
- GeneratorContext context(cls);
- if (!generateFileForContext(context))
+ if (!generateFileForContext(contextForClass(cls)))
return false;
}
@@ -440,8 +481,7 @@ bool Generator::generate()
smartPointers)));
return false;
}
- GeneratorContext context(smartPointerClass, type, true);
- if (!generateFileForContext(context))
+ if (!generateFileForContext(contextForSmartPointer(smartPointerClass, type)))
return false;
}
return finishGeneration();
@@ -449,7 +489,8 @@ bool Generator::generate()
bool Generator::shouldGenerateTypeEntry(const TypeEntry *type) const
{
- return type->codeGeneration() & TypeEntry::GenerateTargetLang;
+ return (type->codeGeneration() & TypeEntry::GenerateTargetLang)
+ && NamespaceTypeEntry::isVisibleScope(type);
}
bool Generator::shouldGenerate(const AbstractMetaClass *metaClass) const
@@ -517,7 +558,9 @@ QTextStream &formatCode(QTextStream &s, const QString &code, Indentor &indentor)
Q_ASSERT(emptyLine.isValid());
for (QString line : lst) {
- if (!line.isEmpty() && !emptyLine.match(line).hasMatch()) {
+ if (line.startsWith(QLatin1Char('#'))) {
+ s << line; // Do not indent preprocessor lines
+ } else if (!line.isEmpty() && !emptyLine.match(line).hasMatch()) {
while (line.constEnd()->isSpace())
line.chop(1);
int limit = 0;
@@ -529,7 +572,7 @@ QTextStream &formatCode(QTextStream &s, const QString &code, Indentor &indentor)
s << indentor << line.remove(0, limit);
}
- s << endl;
+ s << Qt::endl;
}
return s;
}
@@ -670,6 +713,9 @@ DefaultValue Generator::minimalConstructor(const AbstractMetaType *type) const
if (Generator::isPointer(type))
return DefaultValue(DefaultValue::Pointer, QLatin1String("::") + type->typeEntry()->qualifiedCppName());
+ if (type->typeEntry()->isSmartPointer())
+ return minimalConstructor(type->typeEntry());
+
if (type->typeEntry()->isComplex()) {
auto cType = static_cast<const ComplexTypeEntry *>(type->typeEntry());
if (cType->hasDefaultConstructor())
@@ -724,6 +770,9 @@ DefaultValue Generator::minimalConstructor(const TypeEntry *type) const
: DefaultValue(DefaultValue::Custom, ctor);
}
+ if (type->isSmartPointer())
+ return DefaultValue(DefaultValue::DefaultConstructor, type->qualifiedCppName());
+
if (type->isComplex())
return minimalConstructor(AbstractMetaClass::findClass(classes(), type));
@@ -893,8 +942,12 @@ static QString getClassTargetFullName_(const T *t, bool includePackageName)
QString name = t->name();
const AbstractMetaClass *context = t->enclosingClass();
while (context) {
- name.prepend(QLatin1Char('.'));
- name.prepend(context->name());
+ // If the type was marked as 'visible=false' we should not use it in
+ // the type name
+ if (NamespaceTypeEntry::isVisibleScope(context->typeEntry())) {
+ name.prepend(QLatin1Char('.'));
+ name.prepend(context->name());
+ }
context = context->enclosingClass();
}
if (includePackageName) {
diff --git a/sources/shiboken2/generator/generator.h b/sources/shiboken2/generator/generator.h
index dde281f0e..5a55422a1 100644
--- a/sources/shiboken2/generator/generator.h
+++ b/sources/shiboken2/generator/generator.h
@@ -146,24 +146,32 @@ private:
* In the future the second case might be generalized for all template type instantiations.
*/
class GeneratorContext {
+ friend class ShibokenGenerator;
+ friend class Generator;
public:
- GeneratorContext() = default;
- GeneratorContext(AbstractMetaClass *metaClass,
- const AbstractMetaType *preciseType = nullptr,
- bool forSmartPointer = false)
- : m_metaClass(metaClass),
- m_preciseClassType(preciseType),
- m_forSmartPointer(forSmartPointer) {}
+ enum Type { Class, WrappedClass, SmartPointer };
+ GeneratorContext() = default;
- AbstractMetaClass *metaClass() const { return m_metaClass; }
- bool forSmartPointer() const { return m_forSmartPointer; }
+ const AbstractMetaClass *metaClass() const { return m_metaClass; }
const AbstractMetaType *preciseType() const { return m_preciseClassType; }
+ bool forSmartPointer() const { return m_type == SmartPointer; }
+ bool useWrapper() const { return m_type == WrappedClass; }
+
+ QString wrapperName() const
+ {
+ Q_ASSERT(m_type == WrappedClass);
+ return m_wrappername;
+ }
+
+ QString smartPointerWrapperName() const;
+
private:
- AbstractMetaClass *m_metaClass = nullptr;
+ const AbstractMetaClass *m_metaClass = nullptr;
const AbstractMetaType *m_preciseClassType = nullptr;
- bool m_forSmartPointer = false;
+ QString m_wrappername;
+ Type m_type = Class;
};
/**
@@ -294,8 +302,12 @@ protected:
/// Returns an AbstractMetaEnum for a given AbstractMetaType that holds an EnumTypeEntry, or nullptr if not found.
const AbstractMetaEnum *findAbstractMetaEnum(const AbstractMetaType *metaType) const;
+ virtual GeneratorContext contextForClass(const AbstractMetaClass *c) const;
+ GeneratorContext contextForSmartPointer(const AbstractMetaClass *c,
+ const AbstractMetaType *t) const;
+
/// Generates a file for given AbstractMetaClass or AbstractMetaType (smart pointer case).
- bool generateFileForContext(GeneratorContext &context);
+ bool generateFileForContext(const GeneratorContext &context);
/// Returns the file base name for a smart pointer.
QString getFileNameBaseForSmartPointer(const AbstractMetaType *smartPointerType,
@@ -371,7 +383,7 @@ protected:
* \return the file name used to write the binding code for the class
*/
virtual QString fileNameSuffix() const = 0;
- virtual QString fileNameForContext(GeneratorContext &context) const = 0;
+ virtual QString fileNameForContext(const GeneratorContext &context) const = 0;
virtual bool doSetup() = 0;
@@ -382,7 +394,7 @@ protected:
* \param s text stream to write the generated output
* \param metaClass the class that should be generated
*/
- virtual void generateClass(QTextStream &s, GeneratorContext &classContext) = 0;
+ virtual void generateClass(QTextStream &s, const GeneratorContext &classContext) = 0;
virtual bool finishGeneration() = 0;
/**
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 7c9ce4fb2..3c9d13b48 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -33,6 +33,7 @@
#include <iostream>
#include <apiextractor.h>
#include <fileout.h>
+#include <reporthandler.h>
#include <typedatabase.h>
#include <messages.h>
#include "generator.h"
@@ -59,10 +60,14 @@ static inline QString skipDeprecatedOption() { return QStringLiteral("skip-depre
static const char helpHint[] = "Note: use --help or -h for more information.\n";
-using CommandArgumentMap = QMap<QString, QString>;
-
using OptionDescriptions = Generator::OptionDescriptions;
+struct CommandLineArguments
+{
+ QMap<QString, QString> options;
+ QStringList positionalArguments;
+};
+
static void printOptions(QTextStream &s, const OptionDescriptions &options)
{
s.setFieldAlignment(QTextStream::AlignLeft);
@@ -73,16 +78,16 @@ static void printOptions(QTextStream &s, const OptionDescriptions &options)
if (od.second.isEmpty()) {
s << ", ";
} else {
- s << endl;
+ s << Qt::endl;
const auto lines = od.second.splitRef(QLatin1Char('\n'));
for (const auto &line : lines)
- s << " " << line << endl;
- s << endl;
+ s << " " << line << Qt::endl;
+ s << Qt::endl;
}
}
}
-static bool processProjectFile(QFile &projectFile, QMap<QString, QString> &args)
+static bool processProjectFile(QFile &projectFile, CommandLineArguments &args)
{
QByteArray line = projectFile.readLine().trimmed();
if (line.isEmpty() || line != "[generator-project]")
@@ -123,36 +128,36 @@ static bool processProjectFile(QFile &projectFile, QMap<QString, QString> &args)
else if (key == "api-version")
apiVersions << value;
else if (key == "header-file")
- args.insert(QLatin1String("arg-1"), value);
+ args.positionalArguments.prepend(value);
else if (key == "typesystem-file")
- args.insert(QLatin1String("arg-2"), value);
+ args.positionalArguments.append(value);
else
- args.insert(QString::fromUtf8(key), value);
+ args.options.insert(QString::fromUtf8(key), value);
}
if (!includePaths.isEmpty())
- args.insert(includePathOption(), includePaths.join(pathSplitter));
+ args.options.insert(includePathOption(), includePaths.join(pathSplitter));
if (!frameworkIncludePaths.isEmpty())
- args.insert(frameworkIncludePathOption(),
- frameworkIncludePaths.join(pathSplitter));
+ args.options.insert(frameworkIncludePathOption(),
+ frameworkIncludePaths.join(pathSplitter));
if (!systemIncludePaths.isEmpty()) {
- args.insert(systemIncludePathOption(),
- systemIncludePaths.join(pathSplitter));
+ args.options.insert(systemIncludePathOption(),
+ systemIncludePaths.join(pathSplitter));
}
if (!typesystemPaths.isEmpty())
- args.insert(typesystemPathOption(), typesystemPaths.join(pathSplitter));
+ args.options.insert(typesystemPathOption(), typesystemPaths.join(pathSplitter));
if (!apiVersions.isEmpty())
- args.insert(QLatin1String("api-version"), apiVersions.join(QLatin1Char('|')));
+ args.options.insert(QLatin1String("api-version"), apiVersions.join(QLatin1Char('|')));
if (!languageLevel.isEmpty())
- args.insert(languageLevelOption(), languageLevel);
+ args.options.insert(languageLevelOption(), languageLevel);
return true;
}
-static CommandArgumentMap getInitializedArguments()
+static CommandLineArguments getProjectFileArguments()
{
- CommandArgumentMap args;
+ CommandLineArguments args;
QStringList arguments = QCoreApplication::arguments();
QString appName = arguments.constFirst();
arguments.removeFirst();
@@ -194,22 +199,22 @@ static CommandArgumentMap getInitializedArguments()
// Concatenate values of path arguments that can occur multiple times on the
// command line.
static void addPathOptionValue(const QString &option, const QString &value,
- CommandArgumentMap &args)
+ CommandLineArguments &args)
{
- const CommandArgumentMap::iterator it = args.find(option);
- if (it != args.end())
+ auto it = args.options.find(option);
+ if (it != args.options.end())
it.value().append(pathSplitter + value);
else
- args.insert(option, value);
+ args.options.insert(option, value);
}
-static void getCommandLineArg(QString arg, int &argNum, QMap<QString, QString> &args)
+static void getCommandLineArg(QString arg, int &argNum, CommandLineArguments &args)
{
if (arg.startsWith(QLatin1String("--"))) {
arg.remove(0, 2);
const int split = arg.indexOf(QLatin1Char('='));
if (split < 0) {
- args.insert(arg, QString());
+ args.options.insert(arg, QString());
return;
}
const QString option = arg.left(split);
@@ -218,7 +223,7 @@ static void getCommandLineArg(QString arg, int &argNum, QMap<QString, QString> &
|| option == systemIncludePathOption() || option == typesystemPathOption()) {
addPathOptionValue(option, value, args);
} else {
- args.insert(option, value);
+ args.options.insert(option, value);
}
return;
}
@@ -233,28 +238,26 @@ static void getCommandLineArg(QString arg, int &argNum, QMap<QString, QString> &
else if (arg.startsWith(QLatin1Char('T')))
addPathOptionValue(typesystemPathOption(), arg.mid(1), args);
else if (arg == QLatin1String("h"))
- args.insert(helpOption(), QString());
+ args.options.insert(helpOption(), QString());
else if (arg.startsWith(QLatin1String("std=")))
- args.insert(languageLevelOption(), arg.mid(4));
+ args.options.insert(languageLevelOption(), arg.mid(4));
else
- args.insert(arg, QString());
+ args.options.insert(arg, QString());
return;
}
- argNum++;
- args.insert(QStringLiteral("arg-") + QString::number(argNum), arg);
+ if (argNum < args.positionalArguments.size())
+ args.positionalArguments[argNum] = arg;
+ else
+ args.positionalArguments.append(arg);
+ ++argNum;
}
-static QMap<QString, QString> getCommandLineArgs()
+static void getCommandLineArgs(CommandLineArguments &args)
{
- QMap<QString, QString> args = getInitializedArguments();
- QStringList arguments = QCoreApplication::arguments();
- arguments.removeFirst();
-
+ const QStringList arguments = QCoreApplication::arguments();
int argNum = 0;
- for (const QString &carg : qAsConst(arguments))
- getCommandLineArg(carg.trimmed(), argNum, args);
-
- return args;
+ for (int i = 1, size = arguments.size(); i < size; ++i)
+ getCommandLineArg(arguments.at(i).trimmed(), argNum, args);
}
static inline Generators docGenerators()
@@ -284,7 +287,7 @@ void printUsage()
{
QTextStream s(stdout);
s << "Usage:\n "
- << "shiboken [options] header-file typesystem-file\n\n"
+ << "shiboken [options] header-file(s) typesystem-file\n\n"
<< "General options:\n";
QString pathSyntax;
QTextStream(&pathSyntax) << "<path>[" << pathSplitter << "<path>"
@@ -343,7 +346,7 @@ void printUsage()
for (const GeneratorPtr &generator : generators) {
const OptionDescriptions options = generator->options();
if (!options.isEmpty()) {
- s << endl << generator->name() << " options:\n\n";
+ s << Qt::endl << generator->name() << " options:\n\n";
printOptions(s, generator->options());
}
}
@@ -364,14 +367,14 @@ static inline void errorPrint(const QString &s)
}
static void parseIncludePathOption(const QString &option, HeaderType headerType,
- CommandArgumentMap &args,
+ CommandLineArguments &args,
ApiExtractor &extractor)
{
- const CommandArgumentMap::iterator it = args.find(option);
- if (it != args.end()) {
+ const auto it = args.options.find(option);
+ if (it != args.options.end()) {
const QStringList includePathListList =
- it.value().split(pathSplitter, QString::SkipEmptyParts);
- args.erase(it);
+ it.value().split(pathSplitter, Qt::SkipEmptyParts);
+ args.options.erase(it);
for (const QString &s : includePathListList) {
auto path = QFile::encodeName(QDir::cleanPath(s));
extractor.addIncludePath(HeaderPath{path, headerType});
@@ -387,26 +390,29 @@ int main(int argc, char *argv[])
// needed by qxmlpatterns
QCoreApplication app(argc, argv);
ReportHandler::install();
- qCDebug(lcShiboken()).noquote().nospace() << QCoreApplication::arguments().join(QLatin1Char(' '));
+ if (ReportHandler::isDebug(ReportHandler::SparseDebug))
+ qCInfo(lcShiboken()).noquote().nospace() << QCoreApplication::arguments().join(QLatin1Char(' '));
// Store command arguments in a map
- CommandArgumentMap args = getCommandLineArgs();
+ const CommandLineArguments projectFileArguments = getProjectFileArguments();
+ CommandLineArguments args = projectFileArguments;
+ getCommandLineArgs(args);
Generators generators;
- CommandArgumentMap::iterator ait = args.find(QLatin1String("version"));
- if (ait != args.end()) {
- args.erase(ait);
+ auto ait = args.options.find(QLatin1String("version"));
+ if (ait != args.options.end()) {
+ args.options.erase(ait);
printVerAndBanner();
return EXIT_SUCCESS;
}
QString generatorSet;
- ait = args.find(QLatin1String("generator-set"));
- if (ait == args.end()) // Also check QLatin1String("generatorSet") command line argument for backward compatibility.
- ait = args.find(QLatin1String("generatorSet"));
- if (ait != args.end()) {
+ ait = args.options.find(QLatin1String("generator-set"));
+ if (ait == args.options.end()) // Also check QLatin1String("generatorSet") command line argument for backward compatibility.
+ ait = args.options.find(QLatin1String("generatorSet"));
+ if (ait != args.options.end()) {
generatorSet = ait.value();
- args.erase(ait);
+ args.options.erase(ait);
}
// Pre-defined generator sets.
@@ -423,30 +429,30 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
- ait = args.find(QLatin1String("help"));
- if (ait != args.end()) {
- args.erase(ait);
+ ait = args.options.find(QLatin1String("help"));
+ if (ait != args.options.end()) {
+ args.options.erase(ait);
printUsage();
return EXIT_SUCCESS;
}
- ait = args.find(diffOption());
- if (ait != args.end()) {
- args.erase(ait);
+ ait = args.options.find(diffOption());
+ if (ait != args.options.end()) {
+ args.options.erase(ait);
FileOut::diff = true;
}
- ait = args.find(dryrunOption());
- if (ait != args.end()) {
- args.erase(ait);
+ ait = args.options.find(dryrunOption());
+ if (ait != args.options.end()) {
+ args.options.erase(ait);
FileOut::dummy = true;
}
QString licenseComment;
- ait = args.find(QLatin1String("license-file"));
- if (ait != args.end()) {
+ ait = args.options.find(QLatin1String("license-file"));
+ if (ait != args.options.end()) {
QFile licenseFile(ait.value());
- args.erase(ait);
+ args.options.erase(ait);
if (licenseFile.open(QIODevice::ReadOnly)) {
licenseComment = QString::fromUtf8(licenseFile.readAll());
} else {
@@ -457,10 +463,10 @@ int main(int argc, char *argv[])
}
QString outputDirectory = QLatin1String("out");
- ait = args.find(QLatin1String("output-directory"));
- if (ait != args.end()) {
+ ait = args.options.find(QLatin1String("output-directory"));
+ if (ait != args.options.end()) {
outputDirectory = ait.value();
- args.erase(ait);
+ args.options.erase(ait);
}
if (!QDir(outputDirectory).exists()) {
@@ -474,38 +480,35 @@ int main(int argc, char *argv[])
// Create and set-up API Extractor
ApiExtractor extractor;
extractor.setLogDirectory(outputDirectory);
- ait = args.find(skipDeprecatedOption());
- if (ait != args.end()) {
+ ait = args.options.find(skipDeprecatedOption());
+ if (ait != args.options.end()) {
extractor.setSkipDeprecated(true);
- args.erase(ait);
+ args.options.erase(ait);
}
- ait = args.find(QLatin1String("silent"));
- if (ait != args.end()) {
+ ait = args.options.find(QLatin1String("silent"));
+ if (ait != args.options.end()) {
extractor.setSilent(true);
- args.erase(ait);
+ args.options.erase(ait);
} else {
- ait = args.find(QLatin1String("debug-level"));
- if (ait != args.end()) {
- const QString level = ait.value();
- args.erase(ait);
- if (level == QLatin1String("sparse"))
- extractor.setDebugLevel(ReportHandler::SparseDebug);
- else if (level == QLatin1String("medium"))
- extractor.setDebugLevel(ReportHandler::MediumDebug);
- else if (level == QLatin1String("full"))
- extractor.setDebugLevel(ReportHandler::FullDebug);
+ ait = args.options.find(QLatin1String("debug-level"));
+ if (ait != args.options.end()) {
+ if (!ReportHandler::setDebugLevelFromArg(ait.value())) {
+ errorPrint(QLatin1String("Invalid debug level: ") + ait.value());
+ return EXIT_FAILURE;
+ }
+ args.options.erase(ait);
}
}
- ait = args.find(QLatin1String("no-suppress-warnings"));
- if (ait != args.end()) {
- args.erase(ait);
+ ait = args.options.find(QLatin1String("no-suppress-warnings"));
+ if (ait != args.options.end()) {
+ args.options.erase(ait);
extractor.setSuppressWarnings(false);
}
- ait = args.find(QLatin1String("api-version"));
- if (ait != args.end()) {
+ ait = args.options.find(QLatin1String("api-version"));
+ if (ait != args.options.end()) {
const QStringList &versions = ait.value().split(QLatin1Char('|'));
- args.erase(ait);
+ args.options.erase(ait);
for (const QString &fullVersion : versions) {
QStringList parts = fullVersion.split(QLatin1Char(','));
QString package;
@@ -519,16 +522,16 @@ int main(int argc, char *argv[])
}
}
- ait = args.find(QLatin1String("drop-type-entries"));
- if (ait != args.end()) {
+ ait = args.options.find(QLatin1String("drop-type-entries"));
+ if (ait != args.options.end()) {
extractor.setDropTypeEntries(ait.value());
- args.erase(ait);
+ args.options.erase(ait);
}
- ait = args.find(QLatin1String("typesystem-paths"));
- if (ait != args.end()) {
+ ait = args.options.find(QLatin1String("typesystem-paths"));
+ if (ait != args.options.end()) {
extractor.addTypesystemSearchPath(ait.value().split(pathSplitter));
- args.erase(ait);
+ args.options.erase(ait);
}
parseIncludePathOption(includePathOption(), HeaderType::Standard,
@@ -538,46 +541,44 @@ int main(int argc, char *argv[])
parseIncludePathOption(systemIncludePathOption(), HeaderType::System,
args, extractor);
- ait = args.find(QLatin1String("arg-1"));
- if (ait == args.end()) {
- errorPrint(QLatin1String("Required argument header-file is missing."));
- return EXIT_FAILURE;
- }
- const QString cppFileName = ait.value();
- args.erase(ait);
- const QFileInfo cppFileNameFi(cppFileName);
- if (!cppFileNameFi.isFile() && !cppFileNameFi.isSymLink()) {
- errorPrint(QLatin1Char('"') + cppFileName + QLatin1String("\" does not exist."));
+ if (args.positionalArguments.size() < 2) {
+ errorPrint(QLatin1String("Insufficient positional arguments, specify header-file and typesystem-file."));
+ std::cout << '\n';
+ printUsage();
return EXIT_FAILURE;
}
- ait = args.find(QLatin1String("arg-2"));
- if (ait == args.end()) {
- errorPrint(QLatin1String("Required argument typesystem-file is missing."));
- return EXIT_FAILURE;
- }
- const QString typeSystemFileName = ait.value();
- args.erase(ait);
+ const QString typeSystemFileName = args.positionalArguments.takeLast();
QString messagePrefix = QFileInfo(typeSystemFileName).baseName();
if (messagePrefix.startsWith(QLatin1String("typesystem_")))
messagePrefix.remove(0, 11);
ReportHandler::setPrefix(QLatin1Char('(') + messagePrefix + QLatin1Char(')'));
+ QFileInfoList cppFileNames;
+ for (const QString &cppFileName : qAsConst(args.positionalArguments)) {
+ const QFileInfo cppFileNameFi(cppFileName);
+ if (!cppFileNameFi.isFile() && !cppFileNameFi.isSymLink()) {
+ errorPrint(QLatin1Char('"') + cppFileName + QLatin1String("\" does not exist."));
+ return EXIT_FAILURE;
+ }
+ cppFileNames.append(cppFileNameFi);
+ }
+
// Pass option to all generators (Cpp/Header generator have the same options)
- for (ait = args.begin(); ait != args.end(); ) {
+ for (ait = args.options.begin(); ait != args.options.end(); ) {
bool found = false;
for (const GeneratorPtr &generator : qAsConst(generators))
found |= generator->handleOption(ait.key(), ait.value());
if (found)
- ait = args.erase(ait);
+ ait = args.options.erase(ait);
else
++ait;
}
- ait = args.find(languageLevelOption());
- if (ait != args.end()) {
+ ait = args.options.find(languageLevelOption());
+ if (ait != args.options.end()) {
const QByteArray languageLevelBA = ait.value().toLatin1();
- args.erase(ait);
+ args.options.erase(ait);
const LanguageLevel level = clang::languageLevelFromOption(languageLevelBA.constData());
if (level == LanguageLevel::Default) {
std::cout << "Invalid argument for language level: \""
@@ -591,13 +592,14 @@ int main(int argc, char *argv[])
* --project-file, also the arguments of each generator before
* checking if there isn't any existing arguments in argsHandler.
*/
- args.remove(QLatin1String("project-file"));
- CommandArgumentMap projectFileArgs = getInitializedArguments();
- for (auto it = projectFileArgs.cbegin(), end = projectFileArgs.cend(); it != end; ++it)
- args.remove(it.key());
+ args.options.remove(QLatin1String("project-file"));
+ for (auto it = projectFileArguments.options.cbegin(), end = projectFileArguments.options.cend();
+ it != end; ++it) {
+ args.options.remove(it.key());
+ }
- if (!args.isEmpty()) {
- errorPrint(msgLeftOverArguments(args));
+ if (!args.options.isEmpty()) {
+ errorPrint(msgLeftOverArguments(args.options));
std::cout << helpHint;
return EXIT_FAILURE;
}
@@ -607,7 +609,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
- extractor.setCppFileName(cppFileNameFi.absoluteFilePath());
+ extractor.setCppFileNames(cppFileNames);
extractor.setTypeSystem(typeSystemFileName);
if (!extractor.run()) {
@@ -618,8 +620,11 @@ int main(int argc, char *argv[])
if (!extractor.classCount())
qCWarning(lcShiboken) << "No C++ classes found!";
- qCDebug(lcShiboken) << extractor << '\n'
- << *TypeDatabase::instance();
+ if (ReportHandler::isDebug(ReportHandler::FullDebug)
+ || qEnvironmentVariableIsSet("SHIBOKEN_DUMP_CODEMODEL")) {
+ qCInfo(lcShiboken) << "API Extractor:\n" << extractor
+ << "\n\nType datase:\n" << *TypeDatabase::instance();
+ }
for (const GeneratorPtr &g : qAsConst(generators)) {
g->setOutputDirectory(outputDirectory);
@@ -635,7 +640,6 @@ int main(int argc, char *argv[])
}
const QByteArray doneMessage = ReportHandler::doneMessage();
- qCDebug(lcShiboken, "%s", doneMessage.constData());
std::cout << doneMessage.constData() << std::endl;
return EXIT_SUCCESS;
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index f4efc293f..014cc948e 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -172,7 +172,7 @@ static QChar lastChar(const QTextStream &str)
static QTextStream &ensureEndl(QTextStream &s)
{
if (lastChar(s) != QLatin1Char('\n'))
- s << endl;
+ s << Qt::endl;
return s;
}
@@ -478,7 +478,7 @@ QString QtXmlToSphinx::transform(const QString& doc)
<< reader.errorString() << " at " << reader.lineNumber()
<< ':' << reader.columnNumber() << '\n' << doc;
m_output << INDENT << message;
- qCWarning(lcShiboken).noquote().nospace() << message;
+ qCWarning(lcShibokenDoc).noquote().nospace() << message;
break;
}
@@ -502,10 +502,10 @@ QString QtXmlToSphinx::transform(const QString& doc)
if (!m_inlineImages.isEmpty()) {
// Write out inline image definitions stored in handleInlineImageTag().
- m_output << endl;
+ m_output << Qt::endl;
for (const InlineImage &img : qAsConst(m_inlineImages))
- m_output << ".. |" << img.tag << "| image:: " << img.href << endl;
- m_output << endl;
+ m_output << ".. |" << img.tag << "| image:: " << img.href << Qt::endl;
+ m_output << Qt::endl;
m_inlineImages.clear();
}
@@ -541,7 +541,7 @@ QString QtXmlToSphinx::readFromLocations(const QStringList &locations, const QSt
<< locations.join(QLatin1String("\", \""));
return QString(); // null
}
- qCDebug(lcShiboken).noquote().nospace() << "snippet file " << path
+ qCDebug(lcShibokenDoc).noquote().nospace() << "snippet file " << path
<< " [" << identifier << ']' << " resolved to " << resolvedPath;
return readFromLocation(resolvedPath, identifier, errorMessage);
}
@@ -608,11 +608,11 @@ void QtXmlToSphinx::handleHeadingTag(QXmlStreamReader& reader)
else
type = types[typeIdx];
} else if (token == QXmlStreamReader::EndElement) {
- m_output << Pad(type, headingSize) << endl << endl;
+ m_output << Pad(type, headingSize) << Qt::endl << Qt::endl;
} else if (token == QXmlStreamReader::Characters) {
- m_output << endl << endl;
+ m_output << Qt::endl << Qt::endl;
headingSize = writeEscapedRstText(m_output, reader.text().trimmed());
- m_output << endl;
+ m_output << Qt::endl;
}
}
@@ -628,7 +628,7 @@ void QtXmlToSphinx::handleParaTag(QXmlStreamReader& reader)
else if (result.startsWith(QLatin1String("**Note:**")))
result.replace(0, 9, QLatin1String(".. note:: "));
- m_output << INDENT << result << endl << endl;
+ m_output << INDENT << result << Qt::endl << Qt::endl;
} else if (token == QXmlStreamReader::Characters) {
const QStringRef text = reader.text();
const QChar end = lastChar(m_output);
@@ -726,7 +726,7 @@ void QtXmlToSphinx::handleSeeAlsoTag(QXmlStreamReader& reader)
handleLinkEnd(m_seeAlsoContext.data());
m_seeAlsoContext.reset();
}
- m_output << endl << endl;
+ m_output << Qt::endl << Qt::endl;
break;
default:
break;
@@ -747,7 +747,7 @@ void formatSnippet(QTextStream &str, Indent indent, const QString &snippet)
for (const QStringRef &line : lines) {
if (!line.trimmed().isEmpty())
str << indent << line;
- str << endl;
+ str << Qt::endl;
}
}
@@ -783,7 +783,7 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
const QString pythonCode =
readFromLocations(m_generator->codeSnippetDirs(), location, identifier, &errorMessage);
if (!errorMessage.isEmpty())
- qCWarning(lcShiboken, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
// Fall back to C++ snippet when "path" attribute is present.
// Also read fallback snippet when comparison is desired.
QString fallbackCode;
@@ -792,15 +792,15 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
const QString fallback = reader.attributes().value(fallbackPathAttribute()).toString();
if (QFileInfo::exists(fallback)) {
if (pythonCode.isEmpty())
- qCWarning(lcShiboken, "%s", qPrintable(msgFallbackWarning(reader, m_context, m_lastTagName, location, identifier, fallback)));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(msgFallbackWarning(reader, m_context, m_lastTagName, location, identifier, fallback)));
fallbackCode = readFromLocation(fallback, identifier, &errorMessage);
if (!errorMessage.isEmpty())
- qCWarning(lcShiboken, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
}
}
if (!pythonCode.isEmpty() && !fallbackCode.isEmpty() && snippetComparison())
- qCDebug(lcShiboken, "%s", qPrintable(msgSnippetComparison(location, identifier, pythonCode, fallbackCode)));
+ qCDebug(lcShibokenDoc, "%s", qPrintable(msgSnippetComparison(location, identifier, pythonCode, fallbackCode)));
if (!consecutiveSnippet)
m_output << INDENT << "::\n\n";
@@ -811,7 +811,7 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
m_output << INDENT << "<Code snippet \"" << location << ':' << identifier << "\" not found>\n";
else
formatSnippet(m_output, INDENT, code);
- m_output << endl;
+ m_output << Qt::endl;
}
}
void QtXmlToSphinx::handleDotsTag(QXmlStreamReader& reader)
@@ -930,16 +930,16 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
switch (listType) {
case BulletList:
case OrderedList: {
- m_output << endl;
+ m_output << Qt::endl;
const char *separator = listType == BulletList ? "* " : "#. ";
const char *indent = listType == BulletList ? " " : " ";
for (const TableCell &cell : m_currentTable.constFirst()) {
const QVector<QStringRef> itemLines = cell.data.splitRef(QLatin1Char('\n'));
- m_output << INDENT << separator << itemLines.constFirst() << endl;
+ m_output << INDENT << separator << itemLines.constFirst() << Qt::endl;
for (int i = 1, max = itemLines.count(); i < max; ++i)
- m_output << INDENT << indent << itemLines[i] << endl;
+ m_output << INDENT << indent << itemLines[i] << Qt::endl;
}
- m_output << endl;
+ m_output << Qt::endl;
}
break;
case EnumeratedList:
@@ -1120,7 +1120,7 @@ static bool copyImage(const QString &href, const QString &docDataDir,
<< source.errorString();
return false;
}
- qCDebug(lcShiboken()).noquote().nospace() << __FUNCTION__ << " href=\""
+ qCDebug(lcShibokenDoc()).noquote().nospace() << __FUNCTION__ << " href=\""
<< href << "\", context=\"" << context << "\", docDataDir=\""
<< docDataDir << "\", outputDir=\"" << outputDir << "\", copied \""
<< source.fileName() << "\"->\"" << targetFileName << '"';
@@ -1134,7 +1134,7 @@ bool QtXmlToSphinx::copyImage(const QString &href) const
::copyImage(href, m_generator->docDataDir(), m_context,
m_generator->outputDirectory(), &errorMessage);
if (!result)
- qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return result;
}
@@ -1144,7 +1144,7 @@ void QtXmlToSphinx::handleImageTag(QXmlStreamReader& reader)
return;
const QString href = reader.attributes().value(QLatin1String("href")).toString();
if (copyImage(href))
- m_output << INDENT << ".. image:: " << href << endl << endl;
+ m_output << INDENT << ".. image:: " << href << Qt::endl << Qt::endl;
}
void QtXmlToSphinx::handleInlineImageTag(QXmlStreamReader& reader)
@@ -1174,13 +1174,13 @@ void QtXmlToSphinx::handleRawTag(QXmlStreamReader& reader)
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
QString format = reader.attributes().value(QLatin1String("format")).toString();
- m_output << INDENT << ".. raw:: " << format.toLower() << endl << endl;
+ m_output << INDENT << ".. raw:: " << format.toLower() << Qt::endl << Qt::endl;
} else if (token == QXmlStreamReader::Characters) {
const QVector<QStringRef> lst(reader.text().split(QLatin1Char('\n')));
for (const QStringRef &row : lst)
- m_output << INDENT << INDENT << row << endl;
+ m_output << INDENT << INDENT << row << Qt::endl;
} else if (token == QXmlStreamReader::EndElement) {
- m_output << endl << endl;
+ m_output << Qt::endl << Qt::endl;
}
}
@@ -1193,9 +1193,9 @@ void QtXmlToSphinx::handleCodeTag(QXmlStreamReader& reader)
} else if (token == QXmlStreamReader::Characters) {
const QVector<QStringRef> lst(reader.text().split(QLatin1Char('\n')));
for (const QStringRef &row : lst)
- m_output << INDENT << INDENT << row << endl;
+ m_output << INDENT << INDENT << row << Qt::endl;
} else if (token == QXmlStreamReader::EndElement) {
- m_output << endl << endl;
+ m_output << Qt::endl << Qt::endl;
INDENT.indent--;
}
}
@@ -1204,7 +1204,7 @@ void QtXmlToSphinx::handleUnknownTag(QXmlStreamReader& reader)
{
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement)
- qCDebug(lcShiboken).noquote().nospace() << "Unknown QtDoc tag: \"" << reader.name().toString() << "\".";
+ qCDebug(lcShibokenDoc).noquote().nospace() << "Unknown QtDoc tag: \"" << reader.name().toString() << "\".";
}
void QtXmlToSphinx::handleSuperScriptTag(QXmlStreamReader& reader)
@@ -1235,7 +1235,7 @@ void QtXmlToSphinx::handlePageTag(QXmlStreamReader &reader)
? writeEscapedRstText(m_output, title)
: writeEscapedRstText(m_output, fullTitle);
- m_output << endl << Pad('*', size) << endl << endl;
+ m_output << Qt::endl << Pad('*', size) << Qt::endl << Qt::endl;
}
void QtXmlToSphinx::handleTargetTag(QXmlStreamReader &reader)
@@ -1292,14 +1292,14 @@ void QtXmlToSphinx::handleQuoteFileTag(QXmlStreamReader& reader)
QString errorMessage;
QString code = readFromLocation(location, QString(), &errorMessage);
if (!errorMessage.isEmpty())
- qCWarning(lcShiboken(), "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(msgTagWarning(reader, m_context, m_lastTagName, errorMessage)));
m_output << INDENT << "::\n\n";
Indentation indentation(INDENT);
if (code.isEmpty())
m_output << INDENT << "<Code snippet \"" << location << "\" not found>\n";
else
formatCode(m_output, code, INDENT);
- m_output << endl;
+ m_output << Qt::endl;
}
}
@@ -1391,7 +1391,7 @@ void QtXmlToSphinx::Table::format (QTextStream& s) const
return;
if (!isNormalized()) {
- qCDebug(lcShiboken) << "Attempt to print an unnormalized table!";
+ qCDebug(lcShibokenDoc) << "Attempt to print an unnormalized table!";
return;
}
@@ -1435,7 +1435,7 @@ void QtXmlToSphinx::Table::format (QTextStream& s) const
c = '-';
s << Pad(c, colWidths.at(col)) << '+';
}
- s << endl;
+ s << Qt::endl;
// Print the table cells
@@ -1452,7 +1452,7 @@ void QtXmlToSphinx::Table::format (QTextStream& s) const
else
s << ' ';
if (rowLine < rowLines.count())
- s << qSetFieldWidth(colWidths[j]) << left << rowLines.at(rowLine) << qSetFieldWidth(0);
+ s << qSetFieldWidth(colWidths[j]) << Qt::left << rowLines.at(rowLine) << qSetFieldWidth(0);
else
s << Pad(' ', colWidths.at(j));
}
@@ -1461,7 +1461,7 @@ void QtXmlToSphinx::Table::format (QTextStream& s) const
s << "|\n";
}
}
- s << INDENT << horizontalLine << endl << endl;
+ s << INDENT << horizontalLine << Qt::endl << Qt::endl;
}
static QString getFuncName(const AbstractMetaFunction* cppFunc) {
@@ -1523,7 +1523,7 @@ bool QtDocGenerator::shouldGenerate(const AbstractMetaClass *cls) const
&& cls->typeEntry()->type() != TypeEntry::SmartPointerType;
}
-QString QtDocGenerator::fileNameForContext(GeneratorContext &context) const
+QString QtDocGenerator::fileNameForContext(const GeneratorContext &context) const
{
const AbstractMetaClass *metaClass = context.metaClass();
if (!context.forSmartPointer()) {
@@ -1562,11 +1562,11 @@ void QtDocGenerator::writeFormattedText(QTextStream &s, const Documentation &doc
s << INDENT
<< (typesystemIndentation > 0 && typesystemIndentation < line.size()
? line.right(line.size() - typesystemIndentation) : line)
- << endl;
+ << Qt::endl;
}
}
- s << endl;
+ s << Qt::endl;
}
static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaClass, const AbstractMetaClassList& allClasses)
@@ -1584,7 +1584,7 @@ static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaCl
QStringList classes;
for (AbstractMetaClass *c : qAsConst(res))
classes << QLatin1String(":ref:`") + getClassTargetFullName(c, false) + QLatin1Char('`');
- s << classes.join(QLatin1String(", ")) << endl << endl;
+ s << classes.join(QLatin1String(", ")) << Qt::endl << Qt::endl;
}
// Extract the <brief> section from a WebXML (class) documentation and remove it
@@ -1611,10 +1611,10 @@ static bool extractBrief(Documentation *sourceDoc, Documentation *brief)
return true;
}
-void QtDocGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
+void QtDocGenerator::generateClass(QTextStream &s, const GeneratorContext &classContext)
{
- AbstractMetaClass *metaClass = classContext.metaClass();
- qCDebug(lcShiboken).noquote().nospace() << "Generating Documentation for " << metaClass->fullName();
+ const AbstractMetaClass *metaClass = classContext.metaClass();
+ qCDebug(lcShibokenDoc).noquote().nospace() << "Generating Documentation for " << metaClass->fullName();
m_packages[metaClass->package()] << fileNameForContext(classContext);
@@ -1625,15 +1625,15 @@ void QtDocGenerator::generateClass(QTextStream &s, GeneratorContext &classContex
s << ".. _" << className << ":" << "\n\n";
s << ".. currentmodule:: " << metaClass->package() << "\n\n\n";
- s << className << endl;
- s << Pad('*', className.count()) << endl << endl;
+ s << className << Qt::endl;
+ s << Pad('*', className.count()) << Qt::endl << Qt::endl;
auto documentation = metaClass->documentation();
Documentation brief;
if (extractBrief(&documentation, &brief))
writeFormattedText(s, brief, metaClass);
- s << ".. inheritance-diagram:: " << getClassTargetFullName(metaClass, true) << endl
+ s << ".. inheritance-diagram:: " << getClassTargetFullName(metaClass, true) << Qt::endl
<< " :parts: 2\n\n"; // TODO: This would be a parameter in the future...
@@ -1740,17 +1740,17 @@ void QtDocGenerator::writeFunctionList(QTextStream& s, const AbstractMetaClass*
void QtDocGenerator::writeFunctionBlock(QTextStream& s, const QString& title, QStringList& functions)
{
if (!functions.isEmpty()) {
- s << title << endl
- << QString(title.size(), QLatin1Char('^')) << endl;
+ s << title << Qt::endl
+ << QString(title.size(), QLatin1Char('^')) << Qt::endl;
std::sort(functions.begin(), functions.end());
s << ".. container:: function_list\n\n";
Indentation indentation(INDENT);
for (const QString &func : qAsConst(functions))
- s << INDENT << '*' << ' ' << func << endl;
+ s << INDENT << '*' << ' ' << func << Qt::endl;
- s << endl << endl;
+ s << Qt::endl << Qt::endl;
}
}
@@ -1760,7 +1760,7 @@ void QtDocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClas
const AbstractMetaEnumList &enums = cppClass->enums();
for (AbstractMetaEnum *en : enums) {
- s << section_title << getClassTargetFullName(cppClass) << '.' << en->name() << endl << endl;
+ s << section_title << getClassTargetFullName(cppClass) << '.' << en->name() << Qt::endl << Qt::endl;
writeFormattedText(s, en->documentation(), cppClass);
const auto version = versionOf(en->typeEntry());
if (!version.isNull())
@@ -1775,7 +1775,7 @@ void QtDocGenerator::writeFields(QTextStream& s, const AbstractMetaClass* cppCla
const AbstractMetaFieldList &fields = cppClass->fields();
for (AbstractMetaField *field : fields) {
- s << section_title << getClassTargetFullName(cppClass) << "." << field->name() << endl << endl;
+ s << section_title << getClassTargetFullName(cppClass) << "." << field->name() << Qt::endl << Qt::endl;
//TODO: request for member ‘documentation’ is ambiguous
writeFormattedText(s, field->AbstractMetaAttributes::documentation(), cppClass);
}
@@ -1819,14 +1819,14 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass*
}
}
- s << endl;
+ s << Qt::endl;
for (QHash<QString, AbstractMetaArgument*>::const_iterator it = arg_map.cbegin(), end = arg_map.cend(); it != end; ++it) {
Indentation indentation(INDENT, 2);
writeParameterType(s, cppClass, it.value());
}
- s << endl;
+ s << Qt::endl;
for (AbstractMetaFunction *func : qAsConst(lst))
writeFormattedText(s, func->documentation(), cppClass);
@@ -1917,7 +1917,7 @@ void QtDocGenerator::writeDocSnips(QTextStream &s,
if (row.trimmed().size() == 0) {
if (currentRow == 0)
continue;
- s << endl;
+ s << Qt::endl;
}
if (currentRow == 0) {
@@ -1931,7 +1931,7 @@ void QtDocGenerator::writeDocSnips(QTextStream &s,
break;
}
}
- s << row.midRef(offset) << endl;
+ s << row.midRef(offset) << Qt::endl;
currentRow++;
}
@@ -1971,7 +1971,7 @@ bool QtDocGenerator::writeInjectDocumentation(QTextStream& s,
}
}
- s << endl;
+ s << Qt::endl;
// TODO: Deprecate the use of doc string on glue code.
// This is pre "add-function" and "inject-documentation" tags.
@@ -2046,13 +2046,13 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType* type, cons
void QtDocGenerator::writeParameterType(QTextStream& s, const AbstractMetaClass* cppClass, const AbstractMetaArgument* arg)
{
s << INDENT << ":param " << arg->name() << ": "
- << translateToPythonType(arg->type(), cppClass) << endl;
+ << translateToPythonType(arg->type(), cppClass) << Qt::endl;
}
void QtDocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass,
const AbstractMetaFunction *func)
{
- s << endl;
+ s << Qt::endl;
const AbstractMetaArgumentList &funcArgs = func->arguments();
for (AbstractMetaArgument *arg : funcArgs) {
@@ -2078,9 +2078,9 @@ void QtDocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractM
if (retType.isEmpty())
retType = translateToPythonType(func->type(), cppClass);
- s << INDENT << ":rtype: " << retType << endl;
+ s << INDENT << ":rtype: " << retType << Qt::endl;
}
- s << endl;
+ s << Qt::endl;
}
void QtDocGenerator::writeFunction(QTextStream& s, const AbstractMetaClass* cppClass,
@@ -2134,7 +2134,7 @@ static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 4
std::sort(it.value().begin(), it.value().end());
if (i)
- ss << endl;
+ ss << Qt::endl;
ss << "**" << it.key() << "**\n\n";
i += 2; // a letter title is equivalent to two entries in space
@@ -2184,11 +2184,11 @@ void QtDocGenerator::writeModuleDocumentation()
FileOut output(outputDir + QLatin1String("/index.rst"));
QTextStream& s = output.stream;
- s << ".. module:: " << it.key() << endl << endl;
+ s << ".. module:: " << it.key() << Qt::endl << Qt::endl;
const QString &title = it.key();
- s << title << endl;
- s << Pad('*', title.length()) << endl << endl;
+ s << title << Qt::endl;
+ s << Pad('*', title.length()) << Qt::endl << Qt::endl;
/* Avoid showing "Detailed Description for *every* class in toc tree */
Indentation indentation(INDENT);
@@ -2202,7 +2202,7 @@ void QtDocGenerator::writeModuleDocumentation()
if (!m_extraSectionDir.isEmpty()) {
QDir extraSectionDir(m_extraSectionDir);
if (!extraSectionDir.exists())
- qCWarning(lcShiboken) << m_extraSectionDir << "doesn't exist";
+ qCWarning(lcShibokenDoc) << m_extraSectionDir << "doesn't exist";
QStringList fileList = extraSectionDir.entryList(QStringList() << (moduleName.mid(lastIndex + 1) + QLatin1String("?*.rst")), QDir::Files);
QStringList::iterator it2 = fileList.begin();
@@ -2213,7 +2213,7 @@ void QtDocGenerator::writeModuleDocumentation()
if (QFile::exists(newFilePath))
QFile::remove(newFilePath);
if (!QFile::copy(m_extraSectionDir + QLatin1Char('/') + origFileName, newFilePath)) {
- qCDebug(lcShiboken).noquote().nospace() << "Error copying extra doc "
+ qCDebug(lcShibokenDoc).noquote().nospace() << "Error copying extra doc "
<< QDir::toNativeSeparators(m_extraSectionDir + QLatin1Char('/') + origFileName)
<< " to " << QDir::toNativeSeparators(newFilePath);
}
@@ -2230,8 +2230,8 @@ void QtDocGenerator::writeModuleDocumentation()
Indentation deeperIndentation(INDENT);
s << INDENT << ":maxdepth: 1\n\n";
for (const QString &className : qAsConst(it.value()))
- s << INDENT << className << endl;
- s << endl << endl;
+ s << INDENT << className << Qt::endl;
+ s << Qt::endl << Qt::endl;
}
s << "Detailed Description\n--------------------\n\n";
@@ -2269,7 +2269,7 @@ void QtDocGenerator::writeAdditionalDocumentation()
{
QFile additionalDocumentationFile(m_additionalDocumentationList);
if (!additionalDocumentationFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qCWarning(lcShiboken, "%s",
+ qCWarning(lcShibokenDoc, "%s",
qPrintable(msgCannotOpenForReading(additionalDocumentationFile)));
return;
}
@@ -2295,7 +2295,7 @@ void QtDocGenerator::writeAdditionalDocumentation()
targetDir = outDir.absolutePath();
} else {
if (!outDir.exists(dir) && !outDir.mkdir(dir)) {
- qCWarning(lcShiboken, "Cannot create directory %s under %s",
+ qCWarning(lcShibokenDoc, "Cannot create directory %s under %s",
qPrintable(dir),
qPrintable(QDir::toNativeSeparators(outputDirectory())));
break;
@@ -2312,14 +2312,14 @@ void QtDocGenerator::writeAdditionalDocumentation()
if (QtXmlToSphinx::convertToRst(this, fi.absoluteFilePath(),
rstFile, context, &errorMessage)) {
++successCount;
- qCDebug(lcShiboken).nospace().noquote() << __FUNCTION__
+ qCDebug(lcShibokenDoc).nospace().noquote() << __FUNCTION__
<< " converted " << fi.fileName()
<< ' ' << rstFileName;
} else {
- qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
}
} else {
- qCWarning(lcShiboken, "%s",
+ qCWarning(lcShibokenDoc, "%s",
qPrintable(msgNonExistentAdditionalDocFile(m_docDataDir, line)));
}
++count;
@@ -2327,7 +2327,7 @@ void QtDocGenerator::writeAdditionalDocumentation()
}
additionalDocumentationFile.close();
- qCInfo(lcShiboken, "Created %d/%d additional documentation files.",
+ qCInfo(lcShibokenDoc, "Created %d/%d additional documentation files.",
successCount, count);
}
@@ -2346,7 +2346,7 @@ bool QtDocGenerator::doSetup()
m_docParser = new QtDocParser;
if (m_libSourceDir.isEmpty() || m_docDataDir.isEmpty()) {
- qCWarning(lcShiboken) << "Documentation data dir and/or Qt source dir not informed, "
+ qCWarning(lcShibokenDoc) << "Documentation data dir and/or Qt source dir not informed, "
"documentation will not be extracted from Qt sources.";
return false;
}
@@ -2395,7 +2395,7 @@ bool QtDocGenerator::handleOption(const QString &key, const QString &value)
return true;
}
if (key == QLatin1String("doc-parser")) {
- qCDebug(lcShiboken).noquote().nospace() << "doc-parser: " << value;
+ qCDebug(lcShibokenDoc).noquote().nospace() << "doc-parser: " << value;
if (value == QLatin1String("doxygen"))
m_docParser = new DoxygenParser;
return true;
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
index 56cb9c4bb..e4067cc6f 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
@@ -238,8 +238,8 @@ public:
protected:
bool shouldGenerate(const AbstractMetaClass *) const override;
QString fileNameSuffix() const override;
- QString fileNameForContext(GeneratorContext &context) const override;
- void generateClass(QTextStream &s, GeneratorContext &classContext) override;
+ QString fileNameForContext(const GeneratorContext &context) const override;
+ void generateClass(QTextStream &s, const GeneratorContext &classContext) override;
bool finishGeneration() override;
void writeFunctionArguments(QTextStream&, const AbstractMetaFunction*, Options) const override {}
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 64467e3d1..7b74c90d1 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -44,8 +44,7 @@
#include <QMetaType>
#include <algorithm>
-
-#include <algorithm>
+#include <cstring>
static const char CPP_ARG0[] = "cppArg0";
@@ -196,7 +195,7 @@ QString CppGenerator::fileNameSuffix() const
return QLatin1String("_wrapper.cpp");
}
-QString CppGenerator::fileNameForContext(GeneratorContext &context) const
+QString CppGenerator::fileNameForContext(const GeneratorContext &context) const
{
const AbstractMetaClass *metaClass = context.metaClass();
if (!context.forSmartPointer()) {
@@ -293,14 +292,12 @@ static inline bool canGenerateFieldSetter(const AbstractMetaField *field)
\param s the output buffer
\param metaClass the pointer to metaclass information
*/
-void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
+void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classContext)
{
- AbstractMetaClass *metaClass = classContext.metaClass();
- if (ReportHandler::isDebug(ReportHandler::SparseDebug))
- qCDebug(lcShiboken) << "Generating wrapper implementation for " << metaClass->fullName();
+ const AbstractMetaClass *metaClass = classContext.metaClass();
// write license comment
- s << licenseComment() << endl;
+ s << licenseComment() << Qt::endl;
if (!avoidProtectedHack() && !metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
s << "//workaround to access protected functions\n";
@@ -315,7 +312,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << "#include <pysidesignal.h>\n"
<< "#include <pysideproperty.h>\n"
<< "#include <pyside.h>\n"
- << "#include <destroylistener.h>\n"
+ << "#include <pysideqenum.h>\n"
<< "#include <qapp_macro.h>\n\n"
<< "QT_WARNING_DISABLE_DEPRECATED\n\n";
}
@@ -332,6 +329,10 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << "#include <algorithm>\n#include <set>\n";
if (metaClass->generateExceptionHandling())
s << "#include <exception>\n";
+ s << "#include <iterator>\n"; // For containers
+
+ if (wrapperDiagnostics())
+ s << "#include <helper.h>\n#include <iostream>\n";
s << "\n// module include\n" << "#include \"" << getModuleHeaderFileName() << "\"\n";
@@ -339,11 +340,11 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
headerfile.replace(QLatin1String(".cpp"), QLatin1String(".h"));
s << "\n// main header\n" << "#include \"" << headerfile << "\"\n";
- s << endl << "// inner classes\n";
+ s << Qt::endl << "// inner classes\n";
const AbstractMetaClassList &innerClasses = metaClass->innerClasses();
for (AbstractMetaClass *innerClass : innerClasses) {
- GeneratorContext innerClassContext(innerClass);
- if (shouldGenerate(innerClass)) {
+ GeneratorContext innerClassContext = contextForClass(innerClass);
+ if (shouldGenerate(innerClass) && !innerClass->typeEntry()->isSmartPointer()) {
QString headerfile = fileNameForContext(innerClassContext);
headerfile.replace(QLatin1String(".cpp"), QLatin1String(".h"));
s << "#include \"" << headerfile << "\"\n";
@@ -361,8 +362,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
includes.append(cppEnum->typeEntry()->extraIncludes());
std::sort(includes.begin(), includes.end());
for (const Include &inc : qAsConst(includes))
- s << inc.toString() << endl;
- s << endl;
+ s << inc.toString() << Qt::endl;
+ s << Qt::endl;
s << "\n#include <cctype>\n#include <cstring>\n";
@@ -381,7 +382,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
}
}
- s << endl << endl << typeNameFunc << endl;
+ s << Qt::endl << Qt::endl << typeNameFunc << Qt::endl;
// Create string literal for smart pointer getter method.
if (classContext.forSmartPointer()) {
@@ -394,21 +395,23 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
// class inject-code native/beginning
if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
- writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode, metaClass);
- s << endl;
+ writeClassCodeSnips(s, metaClass->typeEntry()->codeSnips(),
+ TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode,
+ classContext);
+ s << Qt::endl;
}
// python conversion rules
if (metaClass->typeEntry()->hasTargetConversionRule()) {
s << "// Python Conversion\n";
- s << metaClass->typeEntry()->conversionRule() << endl;
+ s << metaClass->typeEntry()->conversionRule() << Qt::endl;
}
- if (shouldGenerateCppWrapper(metaClass)) {
+ if (classContext.useWrapper()) {
s << "// Native ---------------------------------------------------------\n\n";
if (avoidProtectedHack() && usePySideExtensions()) {
- s << "void " << wrapperName(metaClass) << "::pysideInitQtMetaTypes()\n{\n";
+ s << "void " << classContext.wrapperName() << "::pysideInitQtMetaTypes()\n{\n";
Indentation indent(INDENT);
writeInitQtMetaTypeFunctionBody(s, classContext);
s << "}\n\n";
@@ -416,22 +419,22 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
const AbstractMetaFunctionList &funcs = filterFunctions(metaClass);
int maxOverrides = 0;
- writeCacheResetNative(s, metaClass);
+ writeCacheResetNative(s, classContext);
for (const AbstractMetaFunction *func : funcs) {
const bool notAbstract = !func->isAbstract();
if ((func->isPrivate() && notAbstract && !visibilityModifiedToPrivate(func))
|| (func->isModifiedRemoved() && notAbstract))
continue;
if (func->functionType() == AbstractMetaFunction::ConstructorFunction && !func->isUserAdded())
- writeConstructorNative(s, func);
+ writeConstructorNative(s, classContext, func);
else if (shouldWriteVirtualMethodNative(func))
writeVirtualMethodNative(s, func, maxOverrides++);
}
if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor()) {
if (usePySideExtensions() && metaClass->isQObject())
- writeMetaObjectMethod(s, metaClass);
- writeDestructorNative(s, metaClass);
+ writeMetaObjectMethod(s, classContext);
+ writeDestructorNative(s, classContext);
}
}
@@ -553,7 +556,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
// Write methods definition
s << "static PyMethodDef " << className << "_methods[] = {\n";
- s << methodsDefinitions << endl;
+ s << methodsDefinitions << Qt::endl;
if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
s << INDENT << "{\"__copy__\", reinterpret_cast<PyCFunction>(" << className << "___copy__)"
<< ", METH_NOARGS},\n";
@@ -580,9 +583,9 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
writeCppSelfDefinition(s, classContext);
if (f->allowThread()) {
s << INDENT << "int result;\n";
- s << INDENT << BEGIN_ALLOW_THREADS << endl;
+ s << INDENT << BEGIN_ALLOW_THREADS << Qt::endl;
s << INDENT << "result = !" << CPP_SELF_VAR << "->isNull();\n";
- s << INDENT << END_ALLOW_THREADS << endl;
+ s << INDENT << END_ALLOW_THREADS << Qt::endl;
s << INDENT << "return result;\n";
} else {
s << INDENT << "return !" << CPP_SELF_VAR << "->isNull();\n";
@@ -635,10 +638,10 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
writeGetterFunction(s, metaField, classContext);
if (canGenerateFieldSetter(metaField))
writeSetterFunction(s, metaField, classContext);
- s << endl;
+ s << Qt::endl;
}
- s << "// Getters and Setters for " << metaClass->name() << endl;
+ s << "// Getters and Setters for " << metaClass->name() << Qt::endl;
s << "static PyGetSetDef " << cpythonGettersSettersDefinitionName(metaClass) << "[] = {\n";
for (const AbstractMetaField *metaField : fields) {
if (metaField->isStatic())
@@ -666,7 +669,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
writeTpClearFunction(s, metaClass);
writeClassDefinition(s, metaClass, classContext);
- s << endl;
+ s << Qt::endl;
if (metaClass->isPolymorphic() && metaClass->baseClass())
writeTypeDiscoveryFunction(s, metaClass);
@@ -680,37 +683,44 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
if (hasFlags) {
writeFlagsMethods(s, cppEnum);
writeFlagsNumberMethodsDefinition(s, cppEnum);
- s << endl;
+ s << Qt::endl;
}
}
- s << endl;
+ s << Qt::endl;
writeConverterFunctions(s, metaClass, classContext);
writeClassRegister(s, metaClass, classContext, signatureStream);
// class inject-code native/end
if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
- writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode, metaClass);
- s << endl;
+ writeClassCodeSnips(s, metaClass->typeEntry()->codeSnips(),
+ TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode,
+ classContext);
+ s << Qt::endl;
}
}
-void CppGenerator::writeCacheResetNative(QTextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeCacheResetNative(QTextStream &s, const GeneratorContext &classContext)
{
Indentation indentation(INDENT);
- s << "void " << wrapperName(metaClass) << "::resetPyMethodCache()\n{\n";
+ s << "void " << classContext.wrapperName()
+ << "::resetPyMethodCache()\n{\n";
s << INDENT << "std::fill_n(m_PyMethodCache, sizeof(m_PyMethodCache) / sizeof(m_PyMethodCache[0]), false);\n";
s << "}\n\n";
}
-void CppGenerator::writeConstructorNative(QTextStream &s, const AbstractMetaFunction *func)
+void CppGenerator::writeConstructorNative(QTextStream &s, const GeneratorContext &classContext,
+ const AbstractMetaFunction *func)
{
Indentation indentation(INDENT);
- s << functionSignature(func, wrapperName(func->ownerClass()) + QLatin1String("::"), QString(),
+ const QString qualifiedName = classContext.wrapperName() + QLatin1String("::");
+ s << functionSignature(func, qualifiedName, QString(),
OriginalTypeDescription | SkipDefaultValues);
s << " : ";
writeFunctionCall(s, func);
s << "\n{\n";
+ if (wrapperDiagnostics())
+ s << INDENT << R"(std::cerr << __FUNCTION__ << ' ' << this << '\n';)" << '\n';
const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
s << INDENT << "resetPyMethodCache();\n";
writeCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode, func, lastArg);
@@ -719,10 +729,13 @@ void CppGenerator::writeConstructorNative(QTextStream &s, const AbstractMetaFunc
s << "}\n\n";
}
-void CppGenerator::writeDestructorNative(QTextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeDestructorNative(QTextStream &s, const GeneratorContext &classContext)
{
Indentation indentation(INDENT);
- s << wrapperName(metaClass) << "::~" << wrapperName(metaClass) << "()\n{\n";
+ s << classContext.wrapperName() << "::~"
+ << classContext.wrapperName() << "()\n{\n";
+ if (wrapperDiagnostics())
+ s << INDENT << R"(std::cerr << __FUNCTION__ << ' ' << this << '\n';)" << '\n';
// kill pyobject
s << INDENT << "SbkObject *wrapper = Shiboken::BindingManager::instance().retrieveWrapper(this);\n";
s << INDENT << "Shiboken::Object::destroy(wrapper, this);\n";
@@ -750,11 +763,14 @@ QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctio
return QLatin1Char('"') + func->typeReplaced(0) + QLatin1Char('"');
// SbkType would return null when the type is a container.
- if (func->type()->typeEntry()->isContainer()) {
+ auto typeEntry = func->type()->typeEntry();
+ if (typeEntry->isContainer()) {
return QLatin1Char('"')
- + reinterpret_cast<const ContainerTypeEntry *>(func->type()->typeEntry())->typeName()
+ + reinterpret_cast<const ContainerTypeEntry *>(typeEntry)->typeName()
+ QLatin1Char('"');
}
+ if (typeEntry->isSmartPointer())
+ return QLatin1Char('"') + typeEntry->qualifiedCppName() + QLatin1Char('"');
if (avoidProtectedHack()) {
const AbstractMetaEnum *metaEnum = findAbstractMetaEnum(func->type());
@@ -765,7 +781,8 @@ QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctio
if (func->type()->isPrimitive())
return QLatin1Char('"') + func->type()->name() + QLatin1Char('"');
- return QString::fromLatin1("reinterpret_cast<PyTypeObject *>(Shiboken::SbkType< %1 >())->tp_name").arg(func->type()->typeEntry()->qualifiedCppName());
+ return QLatin1String("reinterpret_cast<PyTypeObject *>(Shiboken::SbkType< ")
+ + typeEntry->qualifiedCppName() + QLatin1String(" >())->tp_name");
}
void CppGenerator::writeVirtualMethodNative(QTextStream &s,
@@ -821,7 +838,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
errorMsg += func->signature();
errorMsg = msgCouldNotFindMinimalConstructor(errorMsg, func->type()->cppSignature());
qCWarning(lcShiboken).noquote().nospace() << errorMsg;
- s << endl << INDENT << "#error " << errorMsg << endl;
+ s << Qt::endl << INDENT << "#error " << errorMsg << Qt::endl;
}
} else {
defaultReturnExpr.setType(DefaultValue::Void);
@@ -832,7 +849,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
<< QString::fromLatin1("Pure virtual method '%1::%2' must be implement but was "\
"completely removed on type system.")
.arg(func->ownerClass()->name(), func->minimalSignature());
- s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl;
s << "}\n\n";
return;
}
@@ -842,11 +859,19 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
CodeSnipList snips = func->injectedCodeSnips();
const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode, func, lastArg);
- s << endl;
}
// PYSIDE-803: Build a boolean cache for unused overrides.
bool multi_line = retType == nullptr; // set to true when using instrumentation
+ if (wrapperDiagnostics()) {
+ s << INDENT << "std::cerr << ";
+#ifndef Q_CC_MSVC // g++ outputs __FUNCTION__ unqualified
+ s << '"' << prefix << R"(" << )";
+#endif
+ s << R"(__FUNCTION__ << ' ' << this << " m_PyMethodCache[" << )"
+ << cacheIndex << R"( << "]=" << m_PyMethodCache[)" << cacheIndex
+ << R"(] << '\n';)" << '\n';
+ }
s << INDENT << "if (m_PyMethodCache[" << cacheIndex << "])" << (multi_line ? " {\n" : "\n");
{
Indentation indentation(INDENT);
@@ -873,7 +898,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
s << INDENT << "if (PyErr_Occurred())\n";
{
Indentation indentation(INDENT);
- s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl;
}
s << INDENT << "Shiboken::AutoDecRef " << PYTHON_OVERRIDE_VAR << "(Shiboken::BindingManager::instance().getOverride(this, \"";
@@ -887,7 +912,6 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
snips = func->injectedCodeSnips();
const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::ShellCode, func, lastArg);
- s << endl;
}
if (func->isAbstract()) {
@@ -962,7 +986,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
}
s << "Py_BuildValue(\"(" << getFormatUnitString(func, false) << ")\",\n";
- s << argConversions.join(QLatin1String(",\n")) << endl;
+ s << argConversions.join(QLatin1String(",\n")) << Qt::endl;
s << INDENT << "));\n";
}
@@ -980,7 +1004,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
}
}
}
- s << endl;
+ s << Qt::endl;
CodeSnipList snips;
if (func->hasInjectedCode()) {
@@ -991,7 +1015,6 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode, func, lastArg);
- s << endl;
}
if (!injectedCodeCallsPythonOverride(func)) {
@@ -1004,7 +1027,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
{
Indentation indent(INDENT);
s << INDENT << "PyErr_Print();\n";
- s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl;
}
s << INDENT << "}\n";
@@ -1026,7 +1049,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
"\"Invalid return value in function %s, expected %s, got %s.\", \"";
s << func->ownerClass()->name() << '.' << funcName << "\", " << getVirtualFunctionReturnTypeName(func);
s << ", Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);\n";
- s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl;
}
s << INDENT << "}\n";
@@ -1047,7 +1070,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
"\"Invalid return value in function %s, expected %s, got %s.\", \"";
s << func->ownerClass()->name() << '.' << funcName << "\", " << getVirtualFunctionReturnTypeName(func);
s << ", Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);\n";
- s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << Qt::endl;
}
s << INDENT << "}\n";
@@ -1090,7 +1113,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
}
if (func->hasInjectedCode()) {
- s << endl;
+ s << Qt::endl;
const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode, func, lastArg);
}
@@ -1116,16 +1139,17 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
s<< "}\n\n";
}
-void CppGenerator::writeMetaObjectMethod(QTextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeMetaObjectMethod(QTextStream &s, const GeneratorContext &classContext)
{
Indentation indentation(INDENT);
- QString wrapperClassName = wrapperName(metaClass);
+ const QString wrapperClassName = classContext.wrapperName();
+ const QString qualifiedCppName = classContext.metaClass()->qualifiedCppName();
s << "const QMetaObject *" << wrapperClassName << "::metaObject() const\n{\n";
s << INDENT << "if (QObject::d_ptr->metaObject)\n"
<< INDENT << INDENT << "return QObject::d_ptr->dynamicMetaObject();\n";
s << INDENT << "SbkObject *pySelf = Shiboken::BindingManager::instance().retrieveWrapper(this);\n";
s << INDENT << "if (pySelf == nullptr)\n";
- s << INDENT << INDENT << "return " << metaClass->qualifiedCppName() << "::metaObject();\n";
+ s << INDENT << INDENT << "return " << qualifiedCppName << "::metaObject();\n";
s << INDENT << "return PySide::SignalManager::retrieveMetaObject(reinterpret_cast<PyObject *>(pySelf));\n";
s<< "}\n\n";
@@ -1134,7 +1158,8 @@ void CppGenerator::writeMetaObjectMethod(QTextStream &s, const AbstractMetaClass
s << "{\n";
AbstractMetaFunction *func = nullptr;
- AbstractMetaFunctionList list = metaClass->queryFunctionsByName(QLatin1String("qt_metacall"));
+ AbstractMetaFunctionList list =
+ classContext.metaClass()->queryFunctionsByName(QLatin1String("qt_metacall"));
if (list.size() == 1)
func = list[0];
@@ -1147,24 +1172,25 @@ void CppGenerator::writeMetaObjectMethod(QTextStream &s, const AbstractMetaClass
}
}
- s << INDENT << "int result = " << metaClass->qualifiedCppName() << "::qt_metacall(call, id, args);\n";
+ s << INDENT << "int result = " << qualifiedCppName << "::qt_metacall(call, id, args);\n";
s << INDENT << "return result < 0 ? result : PySide::SignalManager::qt_metacall(this, call, id, args);\n";
s << "}\n\n";
// qt_metacast function
- writeMetaCast(s, metaClass);
+ writeMetaCast(s, classContext);
}
-void CppGenerator::writeMetaCast(QTextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeMetaCast(QTextStream &s, const GeneratorContext &classContext)
{
Indentation indentation(INDENT);
- QString wrapperClassName = wrapperName(metaClass);
+ const QString wrapperClassName = classContext.wrapperName();
+ const QString qualifiedCppName = classContext.metaClass()->qualifiedCppName();
s << "void *" << wrapperClassName << "::qt_metacast(const char *_clname)\n{\n";
s << INDENT << "if (!_clname) return {};\n";
s << INDENT << "SbkObject *pySelf = Shiboken::BindingManager::instance().retrieveWrapper(this);\n";
s << INDENT << "if (pySelf && PySide::inherits(Py_TYPE(pySelf), _clname))\n";
s << INDENT << INDENT << "return static_cast<void *>(const_cast< " << wrapperClassName << " *>(this));\n";
- s << INDENT << "return " << metaClass->qualifiedCppName() << "::qt_metacast(_clname);\n";
+ s << INDENT << "return " << qualifiedCppName << "::qt_metacast(_clname);\n";
s << "}\n\n";
}
@@ -1215,7 +1241,7 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream &s, const TypeEntry *
}
c << ";\n";
writeCppToPythonFunction(s, code, typeName, typeName);
- s << endl;
+ s << Qt::endl;
if (enumType->isFlags())
return;
@@ -1257,7 +1283,7 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream &s, const TypeEntry *
}
void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaClass *metaClass,
- GeneratorContext &classContext)
+ const GeneratorContext &classContext)
{
s << "// Type conversion functions.\n\n";
@@ -1295,7 +1321,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
const QString pyTypeCheck = QLatin1String("PyObject_TypeCheck(pyIn, reinterpret_cast<PyTypeObject *>(")
+ cpythonType + QLatin1String("))");
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, pyTypeCheck, QString(), true);
- s << endl;
+ s << Qt::endl;
// C++ pointer to a Python wrapper, keeping identity.
s << "// C++ to Python pointer conversion - tries to find the Python wrapper for the C++ object (keeps object identity).\n";
@@ -1320,7 +1346,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
<< INDENT << "if (sbkType && Shiboken::ObjectType::hasSpecialCastFunction(sbkType)) {\n"
<< INDENT << " typeName = typeNameOf(tCppIn);\n"
<< INDENT << " changedTypeName = true;\n"
- << INDENT << " }\n"
+ << INDENT << "}\n"
<< INDENT << "PyObject *result = Shiboken::Object::newObject(" << cpythonType
<< ", const_cast<void *>(cppIn), false, /* exactType */ changedTypeName, typeName);\n"
<< INDENT << "if (changedTypeName)\n"
@@ -1332,12 +1358,12 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
// The conversions for an Object Type end here.
if (!metaClass->typeEntry()->isValue() && !metaClass->typeEntry()->isSmartPointer()) {
- s << endl;
+ s << Qt::endl;
return;
}
// Always copies C++ value (not pointer, and not reference) to a new Python wrapper.
- s << endl << "// C++ to Python copy conversion.\n";
+ s << Qt::endl << "// C++ to Python copy conversion.\n";
if (!classContext.forSmartPointer())
targetTypeName = metaClass->name();
else
@@ -1348,16 +1374,18 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
code.clear();
QString computedWrapperName;
- if (!classContext.forSmartPointer())
- computedWrapperName = wrapperName(metaClass);
- else
- computedWrapperName = wrapperName(classContext.preciseType());
+ if (!classContext.forSmartPointer()) {
+ computedWrapperName = classContext.useWrapper()
+ ? classContext.wrapperName() : metaClass->qualifiedCppName();
+ } else {
+ computedWrapperName = classContext.smartPointerWrapperName();
+ }
c << INDENT << "return Shiboken::Object::newObject(" << cpythonType
<< ", new ::" << computedWrapperName << "(*reinterpret_cast<const "
<< typeName << " *>(cppIn)), true, true);";
writeCppToPythonFunction(s, code, sourceTypeName, targetTypeName);
- s << endl;
+ s << Qt::endl;
// Python to C++ copy conversion.
s << "// Python to C++ copy conversion.\n";
@@ -1382,7 +1410,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
// "Is convertible" function for the Python object to C++ value copy conversion.
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, pyTypeCheck);
- s << endl;
+ s << Qt::endl;
// User provided implicit conversions.
CustomConversion *customConversion = metaClass->typeEntry()->customConversion();
@@ -1477,42 +1505,42 @@ void CppGenerator::writeCustomConverterFunctions(QTextStream &s, const CustomCon
s << "// Python to C++ conversions for type '" << customConversion->ownerType()->qualifiedCppName() << "'.\n";
for (CustomConversion::TargetToNativeConversion *toNative : toCppConversions)
writePythonToCppConversionFunctions(s, toNative, customConversion->ownerType());
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClass *metaClass,
- GeneratorContext &classContext)
+ const GeneratorContext &classContext)
{
if (metaClass->isNamespace())
return;
s << INDENT << "// Register Converter\n";
s << INDENT << "SbkConverter *converter = Shiboken::Conversions::createConverter(";
- s << cpythonTypeName(metaClass) << ',' << endl;
+ s << cpythonTypeName(metaClass) << ',' << Qt::endl;
{
Indentation indent(INDENT);
QString sourceTypeName = metaClass->name();
QString targetTypeName = sourceTypeName + QLatin1String("_PTR");
- s << INDENT << pythonToCppFunctionName(sourceTypeName, targetTypeName) << ',' << endl;
- s << INDENT << convertibleToCppFunctionName(sourceTypeName, targetTypeName) << ',' << endl;
+ s << INDENT << pythonToCppFunctionName(sourceTypeName, targetTypeName) << ',' << Qt::endl;
+ s << INDENT << convertibleToCppFunctionName(sourceTypeName, targetTypeName) << ',' << Qt::endl;
std::swap(targetTypeName, sourceTypeName);
s << INDENT << cppToPythonFunctionName(sourceTypeName, targetTypeName);
if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
- s << ',' << endl;
+ s << ',' << Qt::endl;
sourceTypeName = metaClass->name() + QLatin1String("_COPY");
s << INDENT << cppToPythonFunctionName(sourceTypeName, targetTypeName);
}
}
s << ");\n";
- s << endl;
+ s << Qt::endl;
QStringList cppSignature;
if (!classContext.forSmartPointer()) {
cppSignature = metaClass->qualifiedCppName().split(QLatin1String("::"),
- QString::SkipEmptyParts);
+ Qt::SkipEmptyParts);
} else {
cppSignature = classContext.preciseType()->cppSignature().split(QLatin1String("::"),
- QString::SkipEmptyParts);
+ Qt::SkipEmptyParts);
}
while (!cppSignature.isEmpty()) {
QString signature = cppSignature.join(QLatin1String("::"));
@@ -1531,12 +1559,12 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas
s << qualifiedCppNameInvocation << ").name());\n";
- if (shouldGenerateCppWrapper(metaClass)) {
+ if (classContext.useWrapper()) {
s << INDENT << "Shiboken::Conversions::registerConverterName(converter, typeid(::";
- s << wrapperName(metaClass) << ").name());\n";
+ s << classContext.wrapperName() << ").name());\n";
}
- s << endl;
+ s << Qt::endl;
if (!metaClass->typeEntry()->isValue() && !metaClass->typeEntry()->isSmartPointer())
return;
@@ -1608,10 +1636,11 @@ void CppGenerator::writeContainerConverterFunctions(QTextStream &s, const Abstra
}
void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &overloadData,
- GeneratorContext &context)
+ const GeneratorContext &context)
{
const AbstractMetaFunction *rfunc = overloadData.referenceFunction();
const AbstractMetaClass *ownerClass = rfunc->ownerClass();
+ Q_ASSERT(ownerClass == context.metaClass());
int minArgs = overloadData.minArgs();
int maxArgs = overloadData.maxArgs();
bool initPythonArguments;
@@ -1631,15 +1660,14 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
s << qualifiedCppName << " >()))\n";
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl << Qt::endl;
}
// Declare pointer for the underlying C++ object.
s << INDENT << "::";
if (!context.forSmartPointer()) {
- s << (shouldGenerateCppWrapper(ownerClass) ? wrapperName(ownerClass)
- : ownerClass->qualifiedCppName());
+ s << (context.useWrapper() ? context.wrapperName() : ownerClass->qualifiedCppName());
} else {
- s << context.preciseType()->cppSignature();
+ s << context.smartPointerWrapperName();
}
s << " *cptr{};\n";
@@ -1673,10 +1701,10 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
}
if (usesNamedArguments && !rfunc->isCallOperator())
- s << INDENT << "int numNamedArgs = (kwds ? PyDict_Size(kwds) : 0);\n";
+ s << INDENT << "const Py_ssize_t numNamedArgs = (kwds ? PyDict_Size(kwds) : 0);\n";
if (initPythonArguments) {
- s << INDENT << "int numArgs = ";
+ s << INDENT << "const Py_ssize_t numArgs = ";
if (minArgs == 0 && maxArgs == 1 && !rfunc->isConstructor() && !pythonFunctionWrapperUsesListOfArguments(overloadData))
s << "(" << PYTHON_ARG << " == 0 ? 0 : 1);\n";
else
@@ -1685,7 +1713,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
}
void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFunctionList &overloads,
- GeneratorContext &classContext)
+ const GeneratorContext &classContext)
{
ErrorCode errorCode(-1);
OverloadData overloadData(overloads, this);
@@ -1736,7 +1764,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
s << INDENT << "\"'" << metaClass->qualifiedCppName();
}
s << "' represents a C++ abstract class and cannot be instantiated\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT<< "}\n\n";
}
@@ -1755,24 +1783,24 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
writeMethodWrapperPreamble(s, overloadData, classContext);
- s << endl;
+ s << Qt::endl;
if (overloadData.maxArgs() > 0)
writeOverloadedFunctionDecisor(s, overloadData);
writeFunctionCalls(s, overloadData, classContext);
- s << endl;
+ s << Qt::endl;
s << INDENT << "if (PyErr_Occurred() || !Shiboken::Object::setCppPointer(sbkSelf, Shiboken::SbkType< ::" << metaClass->qualifiedCppName() << " >(), cptr)) {\n";
{
Indentation indent(INDENT);
s << INDENT << "delete cptr;\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "}\n";
if (overloadData.maxArgs() > 0) {
s << INDENT << "if (!cptr) goto " << cpythonFunctionName(rfunc) << "_TypeError;\n";
- s << endl;
+ s << Qt::endl;
}
s << INDENT << "Shiboken::Object::setValidCpp(sbkSelf, true);\n";
@@ -1794,13 +1822,13 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
// Create metaObject and register signal/slot
if (metaClass->isQObject() && usePySideExtensions()) {
- s << endl << INDENT << "// QObject setup\n";
+ s << Qt::endl << INDENT << "// QObject setup\n";
s << INDENT << "PySide::Signal::updateSourceObject(self);\n";
s << INDENT << "metaObject = cptr->metaObject(); // <- init python qt properties\n";
s << INDENT << "if (kwds && !PySide::fillQtProperties(self, metaObject, kwds, argNames, " << argNamesSet.count() << "))\n";
{
Indentation indentation(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
}
@@ -1823,7 +1851,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
const CodeSnipList &injectedCodeSnips = func->injectedCodeSnips();
for (const CodeSnip &cs : injectedCodeSnips) {
if (cs.position == TypeSystem::CodeSnipPositionEnd) {
- s << INDENT << "case " << metaClass->functions().indexOf(func) << ':' << endl;
+ s << INDENT << "case " << metaClass->functions().indexOf(func) << ':' << Qt::endl;
s << INDENT << "{\n";
{
Indentation indent(INDENT);
@@ -1837,15 +1865,15 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
s << "}\n";
}
- s << endl;
- s << endl << INDENT << "return 1;\n";
+ s << Qt::endl;
+ s << Qt::endl << INDENT << "return 1;\n";
if (overloadData.maxArgs() > 0)
writeErrorSection(s, overloadData);
s<< "}\n\n";
}
void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunctionList &overloads,
- GeneratorContext &classContext)
+ const GeneratorContext &classContext)
{
OverloadData overloadData(overloads, this);
const AbstractMetaFunction *rfunc = overloadData.referenceFunction();
@@ -1863,7 +1891,7 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
writeMethodWrapperPreamble(s, overloadData, classContext);
- s << endl;
+ s << Qt::endl;
/*
* This code is intended for shift operations only:
@@ -1926,9 +1954,9 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
writeFunctionCalls(s, overloadData, classContext);
if (callExtendedReverseOperator)
- s << endl << INDENT << "} // End of \"if (!" << PYTHON_RETURN_VAR << ")\"\n";
+ s << Qt::endl << INDENT << "} // End of \"if (!" << PYTHON_RETURN_VAR << ")\"\n";
- s << endl;
+ s << Qt::endl;
writeFunctionReturnErrorCheckSection(s, hasReturnValue && !rfunc->isInplaceOperator());
@@ -1960,9 +1988,9 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
s << INDENT << "PyObject *";
s << PYTHON_ARGS << "[] = {"
- << QString(maxArgs, QLatin1Char('0')).split(QLatin1String(""), QString::SkipEmptyParts).join(QLatin1String(", "))
+ << QString(maxArgs, QLatin1Char('0')).split(QLatin1String(""), Qt::SkipEmptyParts).join(QLatin1String(", "))
<< "};\n";
- s << endl;
+ s << Qt::endl;
if (overloadData.hasVarargs()) {
maxArgs--;
@@ -1973,7 +2001,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
s << INDENT << "Shiboken::AutoDecRef auto_nonvarargs(nonvarargs);\n";
s << INDENT << PYTHON_ARGS << '[' << maxArgs << "] = PyTuple_GetSlice(args, " << maxArgs << ", numArgs);\n";
s << INDENT << "Shiboken::AutoDecRef auto_varargs(" << PYTHON_ARGS << "[" << maxArgs << "]);\n";
- s << endl;
+ s << Qt::endl;
}
bool usesNamedArguments = overloadData.hasArgumentWithDefaultValue();
@@ -1986,7 +2014,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_TypeError, \"" << fullPythonFunctionName(rfunc) << "(): too many arguments\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << '}';
}
@@ -1999,7 +2027,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_TypeError, \"" << fullPythonFunctionName(rfunc) << "(): not enough arguments\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << '}';
}
@@ -2017,7 +2045,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
Indentation indent(INDENT);
s << INDENT << "goto " << cpythonFunctionName(rfunc) << "_TypeError;";
}
- s << endl << endl;
+ s << Qt::endl << Qt::endl;
QString funcName;
if (rfunc->isOperatorOverload())
@@ -2036,21 +2064,15 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
s << "))\n";
{
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
- s << endl;
+ s << Qt::endl;
}
-void CppGenerator::writeCppSelfAssigment(QTextStream &s, const GeneratorContext &context,
- const QString &className, bool cppSelfAsReference,
- bool useWrapperClass)
+void CppGenerator::writeCppSelfConversion(QTextStream &s, const GeneratorContext &context,
+ const QString &className, bool useWrapperClass)
{
static const QString pythonSelfVar = QLatin1String("self");
- if (cppSelfAsReference)
- s << className << " &";
- s << CPP_SELF_VAR << " = ";
- if (cppSelfAsReference)
- s << " *";
if (useWrapperClass)
s << "static_cast<" << className << " *>(";
if (!context.forSmartPointer())
@@ -2062,49 +2084,57 @@ void CppGenerator::writeCppSelfAssigment(QTextStream &s, const GeneratorContext
}
void CppGenerator::writeCppSelfDefinition(QTextStream &s,
- GeneratorContext &context,
+ const GeneratorContext &context,
bool hasStaticOverload,
bool cppSelfAsReference)
{
+ Q_ASSERT(!(cppSelfAsReference && hasStaticOverload));
+
const AbstractMetaClass *metaClass = context.metaClass();
bool useWrapperClass = avoidProtectedHack() && metaClass->hasProtectedMembers();
+ Q_ASSERT(!useWrapperClass || context.useWrapper());
QString className;
if (!context.forSmartPointer()) {
className = useWrapperClass
- ? wrapperName(metaClass)
+ ? context.wrapperName()
: (QLatin1String("::") + metaClass->qualifiedCppName());
} else {
- className = context.preciseType()->cppSignature();
+ className = context.smartPointerWrapperName();
}
- if (!cppSelfAsReference) {
- s << INDENT << className << " *" << CPP_SELF_VAR << " = nullptr;\n";
- writeUnusedVariableCast(s, QLatin1String(CPP_SELF_VAR));
+ writeInvalidPyObjectCheck(s, QLatin1String("self"));
+
+ if (cppSelfAsReference) {
+ s << INDENT << "auto &" << CPP_SELF_VAR << " = *";
+ writeCppSelfConversion(s, context, className, useWrapperClass);
+ s << ";\n";
+ return;
}
- // Checks if the underlying C++ object is valid.
- if (hasStaticOverload && !cppSelfAsReference) {
- s << INDENT << "if (self) {\n";
- {
- Indentation indent(INDENT);
- writeInvalidPyObjectCheck(s, QLatin1String("self"));
- s << INDENT;
- writeCppSelfAssigment(s, context, className, cppSelfAsReference, useWrapperClass);
- s << ";\n";
- }
- s << INDENT << "}\n";
+ if (!hasStaticOverload) {
+ s << INDENT << "auto " << CPP_SELF_VAR << " = ";
+ writeCppSelfConversion(s, context, className, useWrapperClass);
+ s << ";\n";
+ writeUnusedVariableCast(s, QLatin1String(CPP_SELF_VAR));
return;
}
- writeInvalidPyObjectCheck(s, QLatin1String("self"));
- s << INDENT;
- writeCppSelfAssigment(s, context, className, cppSelfAsReference, useWrapperClass);
- s << ";\n";
+ s << INDENT << className << " *" << CPP_SELF_VAR << " = nullptr;\n";
+ writeUnusedVariableCast(s, QLatin1String(CPP_SELF_VAR));
+
+ // Checks if the underlying C++ object is valid.
+ s << INDENT << "if (self)\n";
+ {
+ Indentation indent(INDENT);
+ s << INDENT << CPP_SELF_VAR << " = ";
+ writeCppSelfConversion(s, context, className, useWrapperClass);
+ s << ";\n";
+ }
}
void CppGenerator::writeCppSelfDefinition(QTextStream &s,
const AbstractMetaFunction *func,
- GeneratorContext &context,
+ const GeneratorContext &context,
bool hasStaticOverload)
{
if (!func->ownerClass() || func->isConstructor())
@@ -2128,7 +2158,7 @@ void CppGenerator::writeCppSelfDefinition(QTextStream &s,
void CppGenerator::writeErrorSection(QTextStream &s, OverloadData &overloadData)
{
const AbstractMetaFunction *rfunc = overloadData.referenceFunction();
- s << endl << INDENT << cpythonFunctionName(rfunc) << "_TypeError:\n";
+ s << Qt::endl << INDENT << cpythonFunctionName(rfunc) << "_TypeError:\n";
Indentation indentation(INDENT);
QString funcName = fullPythonFunctionName(rfunc);
@@ -2148,7 +2178,7 @@ void CppGenerator::writeFunctionReturnErrorCheckSection(QTextStream &s, bool has
Indentation indent(INDENT);
if (hasReturnValue)
s << INDENT << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "}\n";
}
@@ -2157,7 +2187,7 @@ void CppGenerator::writeInvalidPyObjectCheck(QTextStream &s, const QString &pyOb
{
s << INDENT << "if (!Shiboken::Object::isValid(" << pyObj << "))\n";
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
static QString pythonToCppConverterForArgumentName(const QString &argumentName)
@@ -2423,7 +2453,7 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream &s,
if (!defaultValue.isEmpty())
s << INDENT << '}';
- s << endl;
+ s << Qt::endl;
}
static void addConversionRuleCodeSnippet(CodeSnipList &snippetList, QString &rule,
@@ -2486,10 +2516,10 @@ void CppGenerator::writeOverloadedFunctionDecisor(QTextStream &s, const Overload
s << "static ";
if (const auto *decl = func->declaringClass())
s << decl->name() << "::";
- s << func->minimalSignature() << endl;
+ s << func->minimalSignature() << Qt::endl;
}
writeOverloadedFunctionDecisorEngine(s, &overloadData);
- s << endl;
+ s << Qt::endl;
// Ensure that the direct overload that called this reverse
// is called.
@@ -2505,7 +2535,7 @@ void CppGenerator::writeOverloadedFunctionDecisor(QTextStream &s, const Overload
s << INDENT << "// Function signature not found.\n";
s << INDENT << "if (overloadId == -1) goto " << cpythonFunctionName(overloadData.referenceFunction()) << "_TypeError;\n";
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const OverloadData *parentOverloadData)
@@ -2536,7 +2566,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
// Functions without arguments are identified right away.
if (maxArgs == 0) {
s << INDENT << "overloadId = " << parentOverloadData->headOverloadData()->overloads().indexOf(referenceFunction);
- s << "; // " << referenceFunction->minimalSignature() << endl;
+ s << "; // " << referenceFunction->minimalSignature() << Qt::endl;
return;
}
@@ -2552,7 +2582,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
if (isLastArgument || (signatureFound && !hasDefaultCall)) {
const AbstractMetaFunction *func = parentOverloadData->referenceFunction();
s << INDENT << "overloadId = " << parentOverloadData->headOverloadData()->overloads().indexOf(func);
- s << "; // " << func->minimalSignature() << endl;
+ s << "; // " << func->minimalSignature() << Qt::endl;
return;
}
}
@@ -2578,7 +2608,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
}
}
s << INDENT << "overloadId = " << parentOverloadData->headOverloadData()->overloads().indexOf(func);
- s << "; // " << func->minimalSignature() << endl;
+ s << "; // " << func->minimalSignature() << Qt::endl;
}
s << INDENT << '}';
}
@@ -2635,9 +2665,11 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
if (usePyArgs && signatureFound) {
AbstractMetaArgumentList args = refFunc->arguments();
- int lastArgIsVarargs = (int) (args.size() > 1 && args.constLast()->type()->isVarargs());
- int numArgs = args.size() - OverloadData::numberOfRemovedArguments(refFunc) - lastArgIsVarargs;
- typeChecks.prepend(QString::fromLatin1("numArgs %1 %2").arg(lastArgIsVarargs ? QLatin1String(">=") : QLatin1String("==")).arg(numArgs));
+ const bool isVarargs = args.size() > 1 && args.constLast()->type()->isVarargs();
+ int numArgs = args.size() - OverloadData::numberOfRemovedArguments(refFunc);
+ if (isVarargs)
+ --numArgs;
+ typeChecks.prepend(QString::fromLatin1("numArgs %1 %2").arg(isVarargs ? QLatin1String(">=") : QLatin1String("==")).arg(numArgs));
} else if (sequenceArgCount > 1) {
typeChecks.prepend(QString::fromLatin1("numArgs >= %1").arg(startArg + sequenceArgCount));
} else if (refFunc->isOperatorOverload() && !refFunc->isCallOperator()) {
@@ -2657,7 +2689,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
Indentation indent(INDENT);
QString separator;
QTextStream sep(&separator);
- sep << endl << INDENT << "&& ";
+ sep << Qt::endl << INDENT << "&& ";
s << typeChecks.join(separator);
}
s << ") {\n";
@@ -2667,11 +2699,11 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
}
s << INDENT << "}";
}
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeFunctionCalls(QTextStream &s, const OverloadData &overloadData,
- GeneratorContext &context)
+ const GeneratorContext &context)
{
const OverloadData::MetaFunctionList &overloads = overloadData.overloadsWithoutRepetition();
s << INDENT << "// Call function/method\n";
@@ -2683,7 +2715,7 @@ void CppGenerator::writeFunctionCalls(QTextStream &s, const OverloadData &overlo
} else {
for (int i = 0; i < overloads.count(); i++) {
const AbstractMetaFunction *func = overloads.at(i);
- s << INDENT << "case " << i << ": // " << func->signature() << endl;
+ s << INDENT << "case " << i << ": // " << func->signature() << Qt::endl;
s << INDENT << "{\n";
{
Indentation indent(INDENT);
@@ -2706,7 +2738,7 @@ void CppGenerator::writeFunctionCalls(QTextStream &s, const OverloadData &overlo
void CppGenerator::writeSingleFunctionCall(QTextStream &s,
const OverloadData &overloadData,
const AbstractMetaFunction *func,
- GeneratorContext &context)
+ const GeneratorContext &context)
{
if (func->isDeprecated()) {
s << INDENT << "Shiboken::warning(PyExc_DeprecationWarning, 1, \"Function: '"
@@ -2718,7 +2750,7 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
s << INDENT << "PyErr_Format(PyExc_TypeError, \"%s is a private method.\", \""
<< func->signature().replace(QLatin1String("::"), QLatin1String("."))
<< "\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
return;
}
@@ -2727,7 +2759,7 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
// Handle named arguments.
writeNamedArgumentResolution(s, func, usePyArgs);
- bool injectCodeCallsFunc = injectedCodeCallsCppFunction(func);
+ bool injectCodeCallsFunc = injectedCodeCallsCppFunction(context, func);
bool mayHaveUnunsedArguments = !func->isUserAdded() && func->hasInjectedCode() && injectCodeCallsFunc;
int removedArgs = 0;
for (int argIdx = 0; argIdx < func->arguments().count(); ++argIdx) {
@@ -2761,7 +2793,7 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
writeArgumentConversion(s, argType, argName, pyArgName, func->implementingClass(), defaultValue, func->isUserAdded());
}
- s << endl;
+ s << Qt::endl;
int numRemovedArgs = OverloadData::numberOfRemovedArguments(func);
@@ -2825,8 +2857,9 @@ void CppGenerator::writeCppToPythonFunction(QTextStream &s, const QString &code,
static void replaceCppToPythonVariables(QString &code, const QString &typeName)
{
- code.prepend(QLatin1String("auto &cppInRef = *reinterpret_cast<")
- + typeName + QLatin1String(" *>(const_cast<void *>(cppIn));\n"));
+ const QString line = QLatin1String("auto &cppInRef = *reinterpret_cast<")
+ + typeName + QLatin1String(" *>(const_cast<void *>(cppIn));");
+ CodeSnipAbstract::prependCode(&code, line);
code.replace(QLatin1String("%INTYPE"), typeName);
code.replace(QLatin1String("%OUTTYPE"), QLatin1String("PyObject *"));
code.replace(QLatin1String("%in"), QLatin1String("cppInRef"));
@@ -2916,7 +2949,7 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s,
if (conversion.isEmpty())
conversion = QLatin1Char('*') + cpythonWrapperCPtr(sourceType->typeEntry(), QLatin1String("pyIn"));
if (!preConversion.isEmpty())
- c << INDENT << preConversion << endl;
+ c << INDENT << preConversion << Qt::endl;
const QString fullTypeName = getFullTypeName(targetType->typeEntry());
c << INDENT << "*reinterpret_cast<" << fullTypeName << " *>(cppOut) = "
<< fullTypeName << '(' << conversion << ");";
@@ -2928,7 +2961,7 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s,
if (typeCheck.isEmpty())
typeCheck = QString::fromLatin1("PyObject_TypeCheck(pyIn, %1)").arg(sourcePyType);
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, typeCheck);
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s,
@@ -3000,11 +3033,10 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s, const Abs
}
// Python to C++ conversion function.
QString cppTypeName = getFullTypeNameWithoutModifiers(containerType);
- QString code;
- QTextStream c(&code);
- c << INDENT << "auto &cppOutRef = *reinterpret_cast<"
- << cppTypeName << " *>(cppOut);\n";
- code.append(toCppConversions.constFirst()->conversion());
+ QString code = toCppConversions.constFirst()->conversion();
+ const QString line = QLatin1String("auto &cppOutRef = *reinterpret_cast<")
+ + cppTypeName + QLatin1String(" *>(cppOut);");
+ CodeSnipAbstract::prependCode(&code, line);
for (int i = 0; i < containerType->instantiations().count(); ++i) {
const AbstractMetaType *type = containerType->instantiations().at(i);
QString typeName = getFullTypeName(type);
@@ -3036,15 +3068,15 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s, const Abs
else
typeCheck = QString::fromLatin1("%1pyIn)").arg(typeCheck);
writeIsPythonConvertibleToCppFunction(s, typeName, typeName, typeCheck);
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeAddPythonToCppConversion(QTextStream &s, const QString &converterVar, const QString &pythonToCppFunc, const QString &isConvertibleFunc)
{
- s << INDENT << "Shiboken::Conversions::addPythonToCppValueConversion(" << converterVar << ',' << endl;
+ s << INDENT << "Shiboken::Conversions::addPythonToCppValueConversion(" << converterVar << ',' << Qt::endl;
{
Indentation indent(INDENT);
- s << INDENT << pythonToCppFunc << ',' << endl;
+ s << INDENT << pythonToCppFunc << ',' << Qt::endl;
s << INDENT << isConvertibleFunc;
}
s << ");\n";
@@ -3075,8 +3107,8 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe
s << INDENT << "if (value && " << pyArgName << ") {\n";
{
Indentation indent(INDENT);
- s << INDENT << pyErrString.arg(arg->name()) << endl;
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << pyErrString.arg(arg->name()) << Qt::endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "}\n";
s << INDENT << "if (value) {\n";
@@ -3149,9 +3181,9 @@ static QStringList defaultExceptionHandling()
}
void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *func,
- GeneratorContext &context, int maxArgs)
+ const GeneratorContext &context, int maxArgs)
{
- s << INDENT << "// " << func->minimalSignature() << (func->isReverseOperator() ? " [reverse operator]": "") << endl;
+ s << INDENT << "// " << func->minimalSignature() << (func->isReverseOperator() ? " [reverse operator]": "") << Qt::endl;
if (func->isConstructor()) {
const CodeSnipList &snips = func->injectedCodeSnips();
for (const CodeSnip &cs : snips) {
@@ -3171,7 +3203,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '";
s << func->ownerClass()->name() << '.' << func->name() << "()' not implemented.\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "}\n";
}
@@ -3198,7 +3230,6 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
}
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode, func, lastArg);
- s << endl;
}
writeConversionRule(s, func, TypeSystem::NativeCode);
@@ -3283,14 +3314,14 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
std::swap(firstArg, secondArg);
QString op = func->originalName();
- op = op.right(op.size() - (sizeof("operator")/sizeof(char)-1));
+ op.remove(0, int(std::strlen("operator")));
if (func->isBinaryOperator()) {
if (func->isReverseOperator())
std::swap(firstArg, secondArg);
if (((op == QLatin1String("++")) || (op == QLatin1String("--"))) && !func->isReverseOperator()) {
- s << endl << INDENT << "for (int i=0; i < " << secondArg << "; i++, " << firstArg << op << ");\n";
+ s << Qt::endl << INDENT << "for (int i=0; i < " << secondArg << "; i++, " << firstArg << op << ");\n";
mc << firstArg;
} else {
mc << firstArg << ' ' << op << ' ' << secondArg;
@@ -3298,16 +3329,19 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
} else {
mc << op << ' ' << secondArg;
}
- } else if (!injectedCodeCallsCppFunction(func)) {
+ } else if (!injectedCodeCallsCppFunction(context, func)) {
if (func->isConstructor()) {
isCtor = true;
- QString className = wrapperName(func->ownerClass());
+ const auto owner = func->ownerClass();
+ Q_ASSERT(owner == context.metaClass());
+ QString className = context.useWrapper()
+ ? context.wrapperName() : owner->qualifiedCppName();
if (func->functionType() == AbstractMetaFunction::CopyConstructorFunction && maxArgs == 1) {
mc << "new ::" << className << "(*" << CPP_ARG0 << ')';
} else {
QString ctorCall = className + QLatin1Char('(') + userArgs.join(QLatin1String(", ")) + QLatin1Char(')');
- if (usePySideExtensions() && func->ownerClass()->isQObject()) {
+ if (usePySideExtensions() && owner->isQObject()) {
s << INDENT << "void *addr = PySide::nextQObjectMemoryAddr();\n";
uva << "if (addr) {\n";
{
@@ -3317,7 +3351,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
<< ctorCall << ";\n"
<< INDENT
<< "PySide::setNextQObjectMemoryAddr(0);"
- << endl;
+ << Qt::endl;
}
uva << INDENT << "} else {\n";
{
@@ -3410,7 +3444,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
}
}
- if (!injectedCodeCallsCppFunction(func)) {
+ if (!injectedCodeCallsCppFunction(context, func)) {
const bool allowThread = func->allowThread();
const bool generateExceptionHandling = func->generateExceptionHandling();
if (generateExceptionHandling) {
@@ -3421,12 +3455,12 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
<< INDENT << "threadSaver.save();\n";
}
} else if (allowThread) {
- s << INDENT << BEGIN_ALLOW_THREADS << endl;
+ s << INDENT << BEGIN_ALLOW_THREADS << Qt::endl;
}
s << INDENT;
if (isCtor) {
s << (useVAddr.isEmpty() ?
- QString::fromLatin1("cptr = %1;").arg(methodCall) : useVAddr) << endl;
+ QString::fromLatin1("cptr = %1;").arg(methodCall) : useVAddr) << Qt::endl;
} else if (func->type() && !func->isInplaceOperator()) {
bool writeReturnType = true;
if (avoidProtectedHack()) {
@@ -3486,10 +3520,8 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
}
}
- if (func->hasInjectedCode() && !func->isConstructor()) {
- s << endl;
+ if (func->hasInjectedCode() && !func->isConstructor())
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode, func, lastArg);
- }
bool hasReturnPolicy = false;
@@ -3512,12 +3544,12 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
hasReturnPolicy = true;
if (!ownership_mods.isEmpty()) {
- s << endl << INDENT << "// Ownership transferences.\n";
+ s << Qt::endl << INDENT << "// Ownership transferences.\n";
for (const ArgumentModification &arg_mod : qAsConst(ownership_mods)) {
const AbstractMetaClass *wrappedClass = nullptr;
QString pyArgName = argumentNameFromIndex(func, arg_mod.index, &wrappedClass);
if (!wrappedClass) {
- s << "#error Invalid ownership modification for argument " << arg_mod.index << '(' << pyArgName << ")\n" << endl;
+ s << "#error Invalid ownership modification for argument " << arg_mod.index << '(' << pyArgName << ")\n" << Qt::endl;
break;
}
@@ -3540,7 +3572,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
} else {
s << "invalidate(" << pyArgName << ");";
}
- s << endl;
+ s << Qt::endl;
}
} else if (!refcount_mods.isEmpty()) {
@@ -3560,7 +3592,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
} else {
pyArgName = argumentNameFromIndex(func, arg_mod.index, &wrappedClass);
if (pyArgName.isEmpty()) {
- s << "#error Invalid reference count modification for argument " << arg_mod.index << endl << endl;
+ s << "#error Invalid reference count modification for argument " << arg_mod.index << Qt::endl << Qt::endl;
break;
}
}
@@ -3631,9 +3663,9 @@ void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream &s, c
for (const QString &ancestor : ancestors)
s << INDENT << "offsets.insert(int(" << ancestor << "));\n";
- s << endl;
+ s << Qt::endl;
s << INDENT << "offsets.erase(0);\n";
- s << endl;
+ s << Qt::endl;
s << INDENT << "std::copy(offsets.cbegin(), offsets.cend(), mi_offsets);\n";
}
@@ -3701,7 +3733,7 @@ void CppGenerator::writeEnumConverterInitialization(QTextStream &s, const TypeEn
{
Indentation indent(INDENT);
QString typeName = fixedCppTypeName(enumType);
- s << INDENT << "SbkConverter *converter = Shiboken::Conversions::createConverter(" << enumPythonType << ',' << endl;
+ s << INDENT << "SbkConverter *converter = Shiboken::Conversions::createConverter(" << enumPythonType << ',' << Qt::endl;
{
Indentation indent(INDENT);
s << INDENT << cppToPythonFunctionName(typeName, typeName) << ");\n";
@@ -3786,7 +3818,7 @@ void CppGenerator::writeContainerConverterInitialization(QTextStream &s, const A
void CppGenerator::writeExtendedConverterInitialization(QTextStream &s, const TypeEntry *externalType,
const QVector<const AbstractMetaClass *>& conversions)
{
- s << INDENT << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << endl;
+ s << INDENT << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << Qt::endl;
for (const AbstractMetaClass *sourceClass : conversions) {
const QString converterVar = QLatin1String("reinterpret_cast<SbkObjectType *>(")
+ cppApiVariableName(externalType->targetLangPackage()) + QLatin1Char('[')
@@ -3868,7 +3900,7 @@ QTextStream &operator<<(QTextStream &str, const pyTypeSlotEntry &e)
void CppGenerator::writeClassDefinition(QTextStream &s,
const AbstractMetaClass *metaClass,
- GeneratorContext &classContext)
+ const GeneratorContext &classContext)
{
QString tp_flags;
QString tp_init;
@@ -3901,11 +3933,8 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
QLatin1String("Sbk_object_dealloc /* PYSIDE-832: Prevent replacement of \"0\" with subtype_dealloc. */");
tp_init.clear();
} else {
- QString deallocClassName;
- if (shouldGenerateCppWrapper(metaClass))
- deallocClassName = wrapperName(metaClass);
- else
- deallocClassName = cppClassName;
+ QString deallocClassName = classContext.useWrapper()
+ ? classContext.wrapperName() : cppClassName;
if (isQApp)
tp_dealloc = QLatin1String("&SbkDeallocQAppWrapper");
else
@@ -3974,7 +4003,7 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
if (metaClass == miClass)
writeMultipleInheritanceInitializerFunction(s, metaClass);
writeSpecialCastFunction(s, metaClass);
- s << endl;
+ s << Qt::endl;
}
s << "// Class Definition -----------------------------------------------\n";
@@ -4003,7 +4032,7 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
s << "{\n";
s << INDENT << "return " << typePtr << ";\n";
s << "}\n";
- s << endl;
+ s << Qt::endl;
s << "static PyType_Slot " << className << "_slots[] = {\n";
s << INDENT << "{Py_tp_base, nullptr}, // inserted by introduceWrapperType\n";
s << INDENT << pyTypeSlotEntry("Py_tp_dealloc", tp_dealloc)
@@ -4046,13 +4075,13 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
s << INDENT << tp_flags << ",\n";
s << INDENT << className << "_slots\n";
s << "};\n";
- s << endl;
- s << "} //extern \"C\"" << endl;
+ s << Qt::endl;
+ s << "} //extern \"C\"" << Qt::endl;
}
void CppGenerator::writeMappingMethods(QTextStream &s,
const AbstractMetaClass *metaClass,
- GeneratorContext &context)
+ const GeneratorContext &context)
{
for (auto it = m_mappingProtocol.cbegin(), end = m_mappingProtocol.cend(); it != end; ++it) {
const AbstractMetaFunction *func = metaClass->findFunction(it.key());
@@ -4076,7 +4105,7 @@ void CppGenerator::writeMappingMethods(QTextStream &s,
void CppGenerator::writeSequenceMethods(QTextStream &s,
const AbstractMetaClass *metaClass,
- GeneratorContext &context)
+ const GeneratorContext &context)
{
bool injectedCode = false;
@@ -4095,13 +4124,13 @@ void CppGenerator::writeSequenceMethods(QTextStream &s,
writeCppSelfDefinition(s, func, context);
- const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast();
+ const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : func->arguments().constLast();
writeCodeSnips(s, snips,TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, lastArg);
s<< "}\n\n";
}
if (!injectedCode)
- writeStdListWrapperMethods(s, context);
+ writeDefaultSequenceMethods(s, context);
}
void CppGenerator::writeTypeAsSequenceDefinition(QTextStream &s, const AbstractMetaClass *metaClass)
@@ -4262,7 +4291,7 @@ void CppGenerator::writeTpClearFunction(QTextStream &s, const AbstractMetaClass
s << "}\n";
}
-void CppGenerator::writeCopyFunction(QTextStream &s, GeneratorContext &context)
+void CppGenerator::writeCopyFunction(QTextStream &s, const GeneratorContext &context)
{
const AbstractMetaClass *metaClass = context.metaClass();
const QString className = chopType(cpythonTypeName(metaClass));
@@ -4280,12 +4309,12 @@ void CppGenerator::writeCopyFunction(QTextStream &s, GeneratorContext &context)
writeFunctionReturnErrorCheckSection(s);
s << INDENT << "return " << PYTHON_RETURN_VAR << ";\n";
s << "}\n";
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeGetterFunction(QTextStream &s,
const AbstractMetaField *metaField,
- GeneratorContext &context)
+ const GeneratorContext &context)
{
ErrorCode errorCode(QString::fromLatin1(NULL_PTR));
s << "static PyObject *" << cpythonGetterFunctionName(metaField) << "(PyObject *self, void *)\n";
@@ -4300,7 +4329,7 @@ void CppGenerator::writeGetterFunction(QTextStream &s,
QString cppField;
if (avoidProtectedHack() && metaField->isProtected()) {
QTextStream(&cppField) << "static_cast<"
- << wrapperName(metaField->enclosingClass()) << " *>("
+ << context.wrapperName() << " *>("
<< CPP_SELF_VAR << ")->" << protectedFieldGetterName(metaField) << "()";
} else {
cppField = QLatin1String(CPP_SELF_VAR) + QLatin1String("->") + metaField->name();
@@ -4367,7 +4396,7 @@ void CppGenerator::writeGetterFunction(QTextStream &s,
void CppGenerator::writeSetterFunction(QTextStream &s,
const AbstractMetaField *metaField,
- GeneratorContext &context)
+ const GeneratorContext &context)
{
ErrorCode errorCode(0);
s << "static int " << cpythonSetterFunctionName(metaField) << "(PyObject *self, PyObject *pyIn, void *)\n";
@@ -4404,7 +4433,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s,
s << getFullTypeNameWithoutModifiers(fieldType);
s << (fieldType->indirections() == 1 ? " *" : "") << " cppOut;\n";
s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut);\n";
- s << INDENT << "static_cast<" << wrapperName(metaField->enclosingClass())
+ s << INDENT << "static_cast<" << context.wrapperName()
<< " *>(" << CPP_SELF_VAR << ")->" << protectedFieldSetterName(metaField)
<< "(cppOut)";
} else if (isCppIntegralPrimitive(fieldType) || fieldType->typeEntry()->isEnum() || fieldType->typeEntry()->isFlags()) {
@@ -4419,7 +4448,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s,
s << cppField << ";\n";
s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut_ptr)";
}
- s << ";\n" << endl;
+ s << ";\n" << Qt::endl;
if (isPointerToWrapperType(fieldType)) {
s << INDENT << "Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(self), \"";
@@ -4430,7 +4459,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s,
s << "}\n";
}
-void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &context)
+void CppGenerator::writeRichCompareFunction(QTextStream &s, const GeneratorContext &context)
{
const AbstractMetaClass *metaClass = context.metaClass();
QString baseName = cpythonBaseName(metaClass);
@@ -4442,7 +4471,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
s << INDENT << "PyObject *" << PYTHON_RETURN_VAR << "{};\n";
s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << ";\n";
writeUnusedVariableCast(s, QLatin1String(PYTHON_TO_CPP_VAR));
- s << endl;
+ s << Qt::endl;
s << INDENT << "switch (op) {\n";
{
@@ -4452,7 +4481,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
const AbstractMetaFunction *rfunc = overloads[0];
QString operatorId = ShibokenGenerator::pythonRichCompareOperatorId(rfunc);
- s << INDENT << "case " << operatorId << ':' << endl;
+ s << INDENT << "case " << operatorId << ':' << Qt::endl;
Indentation indent(INDENT);
@@ -4487,7 +4516,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
s << ") {\n";
{
Indentation indent(INDENT);
- s << INDENT << "// " << func->signature() << endl;
+ s << INDENT << "// " << func->signature() << Qt::endl;
writeArgumentConversion(s, argType, QLatin1String(CPP_ARG0),
QLatin1String(PYTHON_ARG), metaClass,
QString(), func->isUserAdded());
@@ -4547,7 +4576,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
}
s << INDENT << baseName << "_RichComparison_TypeError:\n";
s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"operator not implemented.\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl << Qt::endl;
s<< "}\n\n";
}
@@ -4591,7 +4620,7 @@ void CppGenerator::writeMethodDefinition(QTextStream &s, const AbstractMetaFunct
writeMethodDefinitionEntry(s, overloads);
s << '}';
}
- s << ',' << endl;
+ s << ',' << Qt::endl;
}
void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunctionList &overloads)
@@ -4612,8 +4641,6 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
strArg += QLatin1Char('=');
QString e = arg->defaultValueExpression();
e.replace(QLatin1String("::"), QLatin1String("."));
- // the tests insert stuff like Str("<unknown>"):
- e.replace(QLatin1Char('"'), QLatin1String("\\\""));
strArg += e;
}
args << arg->name() + QLatin1Char(':') + strArg;
@@ -4624,7 +4651,7 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
s << funcName << '(' << args.join(QLatin1Char(',')) << ')';
if (f->type())
s << "->" << f->type()->pythonSignature();
- s << endl;
+ s << Qt::endl;
}
}
@@ -4651,9 +4678,8 @@ static QString mangleName(QString name)
void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnum *cppEnum)
{
- const AbstractMetaClass *enclosingClass = getProperEnclosingClassForEnum(cppEnum);
- const AbstractMetaClass *upper = enclosingClass ? enclosingClass->enclosingClass() : nullptr;
- bool hasUpperEnclosingClass = upper && upper->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass;
+ const AbstractMetaClass *enclosingClass = cppEnum->targetLangEnclosingClass();
+ bool hasUpperEnclosingClass = enclosingClass && enclosingClass->targetLangEnclosingClass() != nullptr;
const EnumTypeEntry *enumTypeEntry = cppEnum->typeEntry();
QString enclosingObjectVariable;
if (enclosingClass)
@@ -4685,7 +4711,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << INDENT << enumVarTypeObj << " = Shiboken::Enum::";
s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnum" : "createGlobalEnum");
- s << '(' << enclosingObjectVariable << ',' << endl;
+ s << '(' << enclosingObjectVariable << ',' << Qt::endl;
{
Indentation indent(INDENT);
s << INDENT << '"' << cppEnum->name() << "\",\n";
@@ -4693,13 +4719,13 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << INDENT << '"' << (cppEnum->enclosingClass() ? (cppEnum->enclosingClass()->qualifiedCppName() + QLatin1String("::")) : QString());
s << cppEnum->name() << '"';
if (flags)
- s << ',' << endl << INDENT << cpythonTypeNameExt(flags);
+ s << ',' << Qt::endl << INDENT << cpythonTypeNameExt(flags);
s << ");\n";
}
s << INDENT << "if (!" << cpythonTypeNameExt(cppEnum->typeEntry()) << ")\n";
{
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl << Qt::endl;
}
}
@@ -4732,7 +4758,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
<< "))->tp_dict, \"" << mangleName(enumValue->name()) << "\", anonEnumItem) < 0)\n";
{
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "Py_DECREF(anonEnumItem);\n";
}
@@ -4742,27 +4768,27 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << enumValueText << ") < 0)\n";
{
Indentation indent(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
}
break;
case CEnum: {
s << INDENT << "if (!Shiboken::Enum::";
s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnumItem" : "createGlobalEnumItem");
- s << '(' << enumVarTypeObj << ',' << endl;
+ s << '(' << enumVarTypeObj << ',' << Qt::endl;
Indentation indent(INDENT);
s << INDENT << enclosingObjectVariable << ", \"" << mangleName(enumValue->name()) << "\", ";
s << enumValueText << "))\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
break;
case EnumClass: {
s << INDENT << "if (!Shiboken::Enum::createScopedEnumItem("
- << enumVarTypeObj << ',' << endl;
+ << enumVarTypeObj << ',' << Qt::endl;
Indentation indent(INDENT);
s << INDENT << enumVarTypeObj<< ", \"" << mangleName(enumValue->name()) << "\", "
<< enumValueText << "))\n"
- << INDENT << returnStatement(m_currentErrorCode) << endl;
+ << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
break;
}
@@ -4773,7 +4799,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << INDENT << "// End of '" << cppEnum->name() << "' enum";
if (cppEnum->typeEntry()->flags())
s << "/flags";
- s << '.' << endl << endl;
+ s << '.' << Qt::endl << Qt::endl;
}
void CppGenerator::writeSignalInitialization(QTextStream &s, const AbstractMetaClass *metaClass)
@@ -4841,7 +4867,7 @@ void CppGenerator::writeFlagsMethods(QTextStream &s, const AbstractMetaEnum *cpp
writeFlagsToLong(s, cppEnum);
writeFlagsNonZero(s, cppEnum);
- s << endl;
+ s << Qt::endl;
}
void CppGenerator::writeFlagsNumberMethodsDefinition(QTextStream &s, const AbstractMetaEnum *cppEnum)
@@ -4865,7 +4891,7 @@ void CppGenerator::writeFlagsNumberMethodsDefinition(QTextStream &s, const Abstr
s << INDENT << "{Py_nb_long, (void *)" << cpythonName << "_long},\n";
s << "#endif\n";
s << INDENT << "{0, " << NULL_PTR << "} // sentinel\n";
- s << "};" << endl << endl;
+ s << "};\n\n";
}
void CppGenerator::writeFlagsBinaryOperator(QTextStream &s, const AbstractMetaEnum *cppEnum,
@@ -4936,35 +4962,47 @@ QString CppGenerator::getSimpleClassInitFunctionName(const AbstractMetaClass *me
return initFunctionName;
}
-QString CppGenerator::getInitFunctionName(GeneratorContext &context) const
+QString CppGenerator::getInitFunctionName(const GeneratorContext &context) const
{
return !context.forSmartPointer()
? getSimpleClassInitFunctionName(context.metaClass())
: getFilteredCppSignatureString(context.preciseType()->cppSignature());
}
+void CppGenerator::writeSignatureStrings(QTextStream &s,
+ QTextStream &signatureStream,
+ const QString &arrayName,
+ const char *comment) const
+{
+ s << "// The signatures string for the " << comment << ".\n";
+ s << "// Multiple signatures have their index \"n:\" in front.\n";
+ s << "static const char *" << arrayName << "_SignatureStrings[] = {\n";
+ QString line;
+ while (signatureStream.readLineInto(&line)) {
+ // must anything be escaped?
+ if (line.contains(QLatin1Char('"')) || line.contains(QLatin1Char('\\')))
+ s << INDENT << "R\"CPP(" << line << ")CPP\",\n";
+ else
+ s << INDENT << '"' << line << "\",\n";
+ }
+ s << INDENT << NULL_PTR << "}; // Sentinel\n\n";
+}
+
void CppGenerator::writeClassRegister(QTextStream &s,
const AbstractMetaClass *metaClass,
- GeneratorContext &classContext,
+ const GeneratorContext &classContext,
QTextStream &signatureStream)
{
const ComplexTypeEntry *classTypeEntry = metaClass->typeEntry();
- const AbstractMetaClass *enc = metaClass->enclosingClass();
- bool hasEnclosingClass = enc && enc->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass;
- QString enclosingObjectVariable = hasEnclosingClass ? QLatin1String("enclosingClass") : QLatin1String("module");
+ const AbstractMetaClass *enc = metaClass->targetLangEnclosingClass();
+ QString enclosingObjectVariable = enc ? QLatin1String("enclosingClass") : QLatin1String("module");
QString pyTypeName = cpythonTypeName(metaClass);
QString initFunctionName = getInitFunctionName(classContext);
// PYSIDE-510: Create a signatures string for the introspection feature.
- s << "// The signatures string for the functions.\n";
- s << "// Multiple signatures have their index \"n:\" in front.\n";
- s << "static const char *" << initFunctionName << "_SignatureStrings[] = {\n";
- QString line;
- while (signatureStream.readLineInto(&line))
- s << INDENT << '"' << line << "\",\n";
- s << INDENT << NULL_PTR << "}; // Sentinel\n\n";
+ writeSignatureStrings(s, signatureStream, initFunctionName, "functions");
s << "void init_" << initFunctionName;
s << "(PyObject *" << enclosingObjectVariable << ")\n{\n";
@@ -4973,7 +5011,7 @@ void CppGenerator::writeClassRegister(QTextStream &s,
const AbstractMetaClassList baseClasses = getBaseClasses(metaClass);
if (metaClass->baseClassNames().size() > 1) {
s << INDENT << "PyObject *" << pyTypeBasesVariable
- << " = PyTuple_Pack(" << baseClasses.size() << ',' << endl;
+ << " = PyTuple_Pack(" << baseClasses.size() << ',' << Qt::endl;
Indentation indent(INDENT);
for (int i = 0, size = baseClasses.size(); i < size; ++i) {
if (i)
@@ -5023,10 +5061,12 @@ void CppGenerator::writeClassRegister(QTextStream &s,
s << INDENT;
if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
QString dtorClassName = metaClass->qualifiedCppName();
- if ((avoidProtectedHack() && metaClass->hasProtectedDestructor()) || classTypeEntry->isValue())
- dtorClassName = wrapperName(metaClass);
+ if (((avoidProtectedHack() && metaClass->hasProtectedDestructor()) || classTypeEntry->isValue())
+ && classContext.useWrapper()) {
+ dtorClassName = classContext.wrapperName();
+ }
if (classContext.forSmartPointer())
- dtorClassName = wrapperName(classContext.preciseType());
+ dtorClassName = classContext.smartPointerWrapperName();
s << "&Shiboken::callCppDestructor< ::" << dtorClassName << " >,\n";
} else {
@@ -5045,13 +5085,13 @@ void CppGenerator::writeClassRegister(QTextStream &s,
// 8:baseTypes
if (metaClass->baseClassNames().size() > 1)
- s << INDENT << pyTypeBasesVariable << ',' << endl;
+ s << INDENT << pyTypeBasesVariable << ',' << Qt::endl;
else
s << INDENT << "0,\n";
// 9:wrapperflags
QByteArrayList wrapperFlags;
- if (hasEnclosingClass)
+ if (enc)
wrapperFlags.append(QByteArrayLiteral("Shiboken::ObjectType::WrapperFlags::InnerClass"));
if (metaClass->deleteInMainThread())
wrapperFlags.append(QByteArrayLiteral("Shiboken::ObjectType::WrapperFlags::DeleteInMainThread"));
@@ -5061,23 +5101,25 @@ void CppGenerator::writeClassRegister(QTextStream &s,
s << INDENT << wrapperFlags.join(" | ");
}
s << INDENT << ");\n";
- s << INDENT << endl;
+ s << INDENT << Qt::endl;
if (!classContext.forSmartPointer())
- s << INDENT << cpythonTypeNameExt(classTypeEntry) << endl;
+ s << INDENT << cpythonTypeNameExt(classTypeEntry) << Qt::endl;
else
- s << INDENT << cpythonTypeNameExt(classContext.preciseType()) << endl;
+ s << INDENT << cpythonTypeNameExt(classContext.preciseType()) << Qt::endl;
s << INDENT << " = reinterpret_cast<PyTypeObject *>(" << pyTypeName << ");\n";
- s << endl;
+ s << Qt::endl;
// Register conversions for the type.
writeConverterRegister(s, metaClass, classContext);
- s << endl;
+ s << Qt::endl;
// class inject-code target/beginning
if (!classTypeEntry->codeSnips().isEmpty()) {
- writeCodeSnips(s, classTypeEntry->codeSnips(), TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode, metaClass);
- s << endl;
+ writeClassCodeSnips(s, classTypeEntry->codeSnips(),
+ TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode,
+ classContext);
+ s << Qt::endl;
}
// Fill multiple inheritance data, if needed.
@@ -5123,17 +5165,19 @@ void CppGenerator::writeClassRegister(QTextStream &s,
writeToPythonConversion(s, field->type(), metaClass, metaClass->qualifiedCppName() + QLatin1String("::") + field->name());
s << ");\n";
}
- s << endl;
+ s << Qt::endl;
// class inject-code target/end
if (!classTypeEntry->codeSnips().isEmpty()) {
- s << endl;
- writeCodeSnips(s, classTypeEntry->codeSnips(), TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode, metaClass);
+ s << Qt::endl;
+ writeClassCodeSnips(s, classTypeEntry->codeSnips(),
+ TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode,
+ classContext);
}
if (usePySideExtensions()) {
- if (avoidProtectedHack() && shouldGenerateCppWrapper(metaClass))
- s << INDENT << wrapperName(metaClass) << "::pysideInitQtMetaTypes();\n";
+ if (avoidProtectedHack() && classContext.useWrapper())
+ s << INDENT << classContext.wrapperName() << "::pysideInitQtMetaTypes();\n";
else
writeInitQtMetaTypeFunctionBody(s, classContext);
}
@@ -5152,7 +5196,7 @@ void CppGenerator::writeClassRegister(QTextStream &s,
s << "}\n";
}
-void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorContext &context) const
+void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, const GeneratorContext &context) const
{
const AbstractMetaClass *metaClass = context.metaClass();
// Gets all class name variants used on different possible scopes
@@ -5264,10 +5308,14 @@ QString CppGenerator::writeSmartPointerGetterCast()
+ QLatin1String(SMART_POINTER_GETTER) + QLatin1Char(')');
}
-void CppGenerator::writeSetattroDefinition(QTextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeSetattroDefinition(QTextStream &s, const AbstractMetaClass *metaClass) const
{
s << "static int " << ShibokenGenerator::cpythonSetattroFunctionName(metaClass)
<< "(PyObject *self, PyObject *name, PyObject *value)\n{\n";
+ if (wrapperDiagnostics()) {
+ s << INDENT << R"(std::cerr << __FUNCTION__ << ' ' << Shiboken::debugPyObject(name)
+ << ' ' << Shiboken::debugPyObject(value) << '\n';)" << '\n';
+ }
}
inline void CppGenerator::writeSetattroDefaultReturn(QTextStream &s) const
@@ -5276,17 +5324,17 @@ inline void CppGenerator::writeSetattroDefaultReturn(QTextStream &s) const
}
void CppGenerator::writeSetattroFunction(QTextStream &s, AttroCheck attroCheck,
- GeneratorContext &context)
+ const GeneratorContext &context)
{
Q_ASSERT(!context.forSmartPointer());
const AbstractMetaClass *metaClass = context.metaClass();
writeSetattroDefinition(s, metaClass);
// PYSIDE-803: Detect duck-punching; clear cache if a method is set.
if (attroCheck.testFlag(AttroCheckFlag::SetattroMethodOverride)
- && ShibokenGenerator::shouldGenerateCppWrapper(metaClass)) {
+ && context.useWrapper()) {
s << INDENT << "if (value && PyCallable_Check(value)) {\n";
s << INDENT << " auto plain_inst = " << cpythonWrapperCPtr(metaClass, QLatin1String("self")) << ";\n";
- s << INDENT << " auto inst = dynamic_cast<" << wrapperName(metaClass) << " *>(plain_inst);\n";
+ s << INDENT << " auto inst = dynamic_cast<" << context.wrapperName() << " *>(plain_inst);\n";
s << INDENT << " if (inst)\n";
s << INDENT << " inst->resetPyMethodCache();\n";
s << INDENT << "}\n";
@@ -5297,10 +5345,26 @@ void CppGenerator::writeSetattroFunction(QTextStream &s, AttroCheck attroCheck,
Indentation indent(INDENT);
s << INDENT << "return PySide::Property::setValue(reinterpret_cast<PySideProperty *>(pp.object()), self, value);\n";
}
+
+ if (attroCheck.testFlag(AttroCheckFlag::SetattroUser)) {
+ auto func = AbstractMetaClass::queryFirstFunction(metaClass->functions(),
+ AbstractMetaClass::SetAttroFunction);
+ Q_ASSERT(func);
+ s << INDENT << "{\n";
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "auto " << CPP_SELF_VAR << " = "
+ << cpythonWrapperCPtr(metaClass, QLatin1String("self")) << ";\n";
+ writeClassCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionAny,
+ TypeSystem::TargetLangCode, context);
+ }
+ s << INDENT << "}\n";
+ }
+
writeSetattroDefaultReturn(s);
}
-void CppGenerator::writeSmartPointerSetattroFunction(QTextStream &s, GeneratorContext &context)
+void CppGenerator::writeSmartPointerSetattroFunction(QTextStream &s, const GeneratorContext &context)
{
Q_ASSERT(context.forSmartPointer());
writeSetattroDefinition(s, context.metaClass());
@@ -5346,7 +5410,7 @@ QString CppGenerator::qObjectGetAttroFunction() const
}
void CppGenerator::writeGetattroFunction(QTextStream &s, AttroCheck attroCheck,
- GeneratorContext &context)
+ const GeneratorContext &context)
{
Q_ASSERT(!context.forSmartPointer());
const AbstractMetaClass *metaClass = context.metaClass();
@@ -5401,10 +5465,25 @@ void CppGenerator::writeGetattroFunction(QTextStream &s, AttroCheck attroCheck,
}
}
+ if (attroCheck.testFlag(AttroCheckFlag::GetattroUser)) {
+ auto func = AbstractMetaClass::queryFirstFunction(metaClass->functions(),
+ AbstractMetaClass::GetAttroFunction);
+ Q_ASSERT(func);
+ s << INDENT << "{\n";
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "auto " << CPP_SELF_VAR << " = "
+ << cpythonWrapperCPtr(metaClass, QLatin1String("self")) << ";\n";
+ writeClassCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionAny,
+ TypeSystem::TargetLangCode, context);
+ }
+ s << INDENT << "}\n";
+ }
+
s << INDENT << "return " << getattrFunc << ";\n}\n\n";
}
-void CppGenerator::writeSmartPointerGetattroFunction(QTextStream &s, GeneratorContext &context)
+void CppGenerator::writeSmartPointerGetattroFunction(QTextStream &s, const GeneratorContext &context)
{
Q_ASSERT(context.forSmartPointer());
const AbstractMetaClass *metaClass = context.metaClass();
@@ -5450,6 +5529,25 @@ void CppGenerator::writeSmartPointerGetattroFunction(QTextStream &s, GeneratorCo
s << INDENT << "return tmp;\n}\n\n";
}
+// Write declaration and invocation of the init function for the module init
+// function.
+void CppGenerator::writeInitFunc(QTextStream &declStr, QTextStream &callStr,
+ const Indentor &indent, const QString &initFunctionName,
+ const TypeEntry *enclosingEntry)
+{
+ const bool hasParent =
+ enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType;
+ declStr << "void init_" << initFunctionName << "(PyObject *"
+ << (hasParent ? "enclosingClass" : "module") << ");\n";
+ callStr << indent << "init_" << initFunctionName;
+ if (hasParent) {
+ callStr << "(reinterpret_cast<PyTypeObject *>("
+ << cpythonTypeNameExt(enclosingEntry) << ")->tp_dict);\n";
+ } else {
+ callStr << "(module);\n";
+ }
+}
+
bool CppGenerator::finishGeneration()
{
//Generate CPython wrapper file
@@ -5504,33 +5602,20 @@ bool CppGenerator::finishGeneration()
const AbstractMetaClassList lst = classesTopologicalSorted(additionalDependencies);
for (const AbstractMetaClass *cls : lst){
- if (!shouldGenerate(cls))
- continue;
-
- const QString initFunctionName = QLatin1String("init_") + getSimpleClassInitFunctionName(cls);
-
- s_classInitDecl << "void " << initFunctionName << "(PyObject *module);" << endl;
-
- s_classPythonDefines << INDENT << initFunctionName;
- if (cls->enclosingClass()
- && (cls->enclosingClass()->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass)) {
- s_classPythonDefines << "(reinterpret_cast<PyTypeObject *>("
- << cpythonTypeNameExt(cls->enclosingClass()->typeEntry()) << ")->tp_dict);";
- } else {
- s_classPythonDefines << "(module);";
+ if (shouldGenerate(cls)) {
+ writeInitFunc(s_classInitDecl, s_classPythonDefines, INDENT,
+ getSimpleClassInitFunctionName(cls),
+ cls->typeEntry()->targetLangEnclosingEntry());
}
- s_classPythonDefines << endl;
}
// Initialize smart pointer types.
const QVector<const AbstractMetaType *> &smartPtrs = instantiatedSmartPointers();
for (const AbstractMetaType *metaType : smartPtrs) {
- GeneratorContext context(nullptr, metaType, true);
- QString initFunctionName = getInitFunctionName(context);
- s_classInitDecl << "void init_" << initFunctionName << "(PyObject *module);" << endl;
- QString defineStr = QLatin1String("init_") + initFunctionName;
- defineStr += QLatin1String("(module);");
- s_classPythonDefines << INDENT << defineStr << endl;
+ GeneratorContext context = contextForSmartPointer(nullptr, metaType);
+ writeInitFunc(s_classInitDecl, s_classPythonDefines, INDENT,
+ getInitFunctionName(context),
+ metaType->typeEntry()->targetLangEnclosingEntry());
}
QString moduleFileName(outputDirectory() + QLatin1Char('/') + subDirectoryForPackage(packageName()));
@@ -5543,7 +5628,7 @@ bool CppGenerator::finishGeneration()
QTextStream &s = file.stream;
// write license comment
- s << licenseComment() << endl;
+ s << licenseComment() << Qt::endl;
s << "#include <sbkpython.h>\n";
s << "#include <shiboken.h>\n";
@@ -5552,22 +5637,22 @@ bool CppGenerator::finishGeneration()
if (usePySideExtensions()) {
s << includeQDebug;
s << "#include <pyside.h>\n";
+ s << "#include <pysideqenum.h>\n";
s << "#include <qapp_macro.h>\n";
}
- s << "#include \"" << getModuleHeaderFileName() << '"' << endl << endl;
+ s << "#include \"" << getModuleHeaderFileName() << '"' << Qt::endl << Qt::endl;
for (const Include &include : qAsConst(includes))
s << include;
- s << endl;
+ s << Qt::endl;
// Global enums
AbstractMetaEnumList globalEnums = this->globalEnums();
const AbstractMetaClassList &classList = classes();
for (const AbstractMetaClass *metaClass : classList) {
const AbstractMetaClass *encClass = metaClass->enclosingClass();
- if (encClass && encClass->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass)
- continue;
- lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass);
+ if (!encClass || !NamespaceTypeEntry::isVisibleScope(encClass->typeEntry()))
+ lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass);
}
TypeDatabase *typeDb = TypeDatabase::instance();
@@ -5575,14 +5660,14 @@ bool CppGenerator::finishGeneration()
Q_ASSERT(moduleEntry);
//Extra includes
- s << endl << "// Extra includes\n";
+ s << Qt::endl << "// Extra includes\n";
QVector<Include> extraIncludes = moduleEntry->extraIncludes();
for (AbstractMetaEnum *cppEnum : qAsConst(globalEnums))
extraIncludes.append(cppEnum->typeEntry()->extraIncludes());
std::sort(extraIncludes.begin(), extraIncludes.end());
for (const Include &inc : qAsConst(extraIncludes))
s << inc;
- s << endl;
+ s << Qt::endl;
s << "// Current module's type array.\n";
s << "PyTypeObject **" << cppApiVariableName() << " = nullptr;\n";
@@ -5596,10 +5681,8 @@ bool CppGenerator::finishGeneration()
const CodeSnipList snips = moduleEntry->codeSnips();
// module inject-code native/beginning
- if (!snips.isEmpty()) {
+ if (!snips.isEmpty())
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode);
- s << endl;
- }
// cleanup staticMetaObject attribute
if (usePySideExtensions()) {
@@ -5623,7 +5706,7 @@ bool CppGenerator::finishGeneration()
s << "// Global functions ";
s << "------------------------------------------------------------\n";
- s << globalFunctionImpl << endl;
+ s << globalFunctionImpl << Qt::endl;
s << "static PyMethodDef " << moduleName() << "_methods[] = {\n";
s << globalFunctionDecl;
@@ -5631,7 +5714,7 @@ bool CppGenerator::finishGeneration()
s << "// Classes initialization functions ";
s << "------------------------------------------------------------\n";
- s << classInitDecl << endl;
+ s << classInitDecl << Qt::endl;
if (!globalEnums.isEmpty()) {
QString converterImpl;
@@ -5643,14 +5726,14 @@ bool CppGenerator::finishGeneration()
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
writeEnumConverterFunctions(s, cppEnum);
- s << endl;
+ s << Qt::endl;
}
if (!converterImpl.isEmpty()) {
s << "// Enum converters ";
s << "------------------------------------------------------------\n";
s << "namespace Shiboken\n{\n";
- s << converterImpl << endl;
+ s << converterImpl << Qt::endl;
s << "} // namespace Shiboken\n\n";
}
}
@@ -5662,16 +5745,16 @@ bool CppGenerator::finishGeneration()
s << "PyTypeObject **" << cppApiVariableName(requiredModule) << ";\n";
s << "SbkConverter **" << convertersVariableName(requiredModule) << ";\n";
}
- s << endl;
+ s << Qt::endl;
s << "// Module initialization ";
s << "------------------------------------------------------------\n";
ExtendedConverterData extendedConverters = getExtendedConverters();
if (!extendedConverters.isEmpty()) {
- s << endl << "// Extended Converters.\n\n";
+ s << Qt::endl << "// Extended Converters.\n\n";
for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) {
const TypeEntry *externalType = it.key();
- s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << endl;
+ s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << Qt::endl;
for (const AbstractMetaClass *sourceClass : it.value()) {
AbstractMetaType *sourceType = buildAbstractMetaTypeFromAbstractMetaClass(sourceClass);
AbstractMetaType *targetType = buildAbstractMetaTypeFromTypeEntry(externalType);
@@ -5682,13 +5765,13 @@ bool CppGenerator::finishGeneration()
const QVector<const CustomConversion *> &typeConversions = getPrimitiveCustomConversions();
if (!typeConversions.isEmpty()) {
- s << endl << "// Primitive Type converters.\n\n";
+ s << Qt::endl << "// Primitive Type converters.\n\n";
for (const CustomConversion *conversion : typeConversions) {
s << "// C++ to Python conversion for type '" << conversion->ownerType()->qualifiedCppName() << "'.\n";
writeCppToPythonFunction(s, conversion);
writeCustomConverterFunctions(s, conversion);
}
- s << endl;
+ s << Qt::endl;
}
const QVector<const AbstractMetaType *> &containers = instantiatedContainers();
@@ -5698,7 +5781,7 @@ bool CppGenerator::finishGeneration()
s << "// C++ to Python conversion for type '" << container->cppSignature() << "'.\n";
writeContainerConverterFunctions(s, container);
}
- s << endl;
+ s << Qt::endl;
}
s << "#if defined _WIN32 || defined __CYGWIN__\n";
@@ -5724,22 +5807,14 @@ bool CppGenerator::finishGeneration()
s << "#endif\n\n";
// PYSIDE-510: Create a signatures string for the introspection feature.
- s << "// The signatures string for the global functions.\n";
- s << "// Multiple signatures have their index \"n:\" in front.\n";
- s << "static const char *" << moduleName() << "_SignatureStrings[] = {\n";
- QString line;
- while (signatureStream.readLineInto(&line))
- s << INDENT << '"' << line << "\",\n";
- s << INDENT << NULL_PTR << "}; // Sentinel\n\n";
+ writeSignatureStrings(s, signatureStream, moduleName(), "global functions");
s << "SBK_MODULE_INIT_FUNCTION_BEGIN(" << moduleName() << ")\n";
ErrorCode errorCode(QLatin1String("SBK_MODULE_INIT_ERROR"));
// module inject-code target/beginning
- if (!snips.isEmpty()) {
+ if (!snips.isEmpty())
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode);
- s << endl;
- }
for (const QString &requiredModule : requiredModules) {
s << INDENT << "{\n";
@@ -5785,26 +5860,26 @@ bool CppGenerator::finishGeneration()
s << classPythonDefines;
if (!typeConversions.isEmpty()) {
- s << endl;
+ s << Qt::endl;
for (const CustomConversion *conversion : typeConversions) {
writePrimitiveConverterInitialization(s, conversion);
- s << endl;
+ s << Qt::endl;
}
}
if (!containers.isEmpty()) {
- s << endl;
+ s << Qt::endl;
for (const AbstractMetaType *container : containers) {
writeContainerConverterInitialization(s, container);
- s << endl;
+ s << Qt::endl;
}
}
if (!extendedConverters.isEmpty()) {
- s << endl;
+ s << Qt::endl;
for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) {
writeExtendedConverterInitialization(s, it.key(), it.value());
- s << endl;
+ s << Qt::endl;
}
}
@@ -5819,7 +5894,7 @@ bool CppGenerator::finishGeneration()
if (!referencedType)
continue;
QString converter = converterObject(referencedType);
- QStringList cppSignature = pte->qualifiedCppName().split(QLatin1String("::"), QString::SkipEmptyParts);
+ QStringList cppSignature = pte->qualifiedCppName().split(QLatin1String("::"), Qt::SkipEmptyParts);
while (!cppSignature.isEmpty()) {
QString signature = cppSignature.join(QLatin1String("::"));
s << INDENT << "Shiboken::Conversions::registerConverterName(" << converter << ", \"" << signature << "\");\n";
@@ -5827,12 +5902,12 @@ bool CppGenerator::finishGeneration()
}
}
- s << endl;
+ s << Qt::endl;
if (maxTypeIndex)
s << INDENT << "Shiboken::Module::registerTypes(module, " << cppApiVariableName() << ");\n";
s << INDENT << "Shiboken::Module::registerTypeConverters(module, " << convertersVariableName() << ");\n";
- s << endl << INDENT << "if (PyErr_Occurred()) {\n";
+ s << Qt::endl << INDENT << "if (PyErr_Occurred()) {\n";
{
Indentation indentation(INDENT);
s << INDENT << "PyErr_Print();\n";
@@ -5841,16 +5916,12 @@ bool CppGenerator::finishGeneration()
s << INDENT << "}\n";
// module inject-code target/end
- if (!snips.isEmpty()) {
+ if (!snips.isEmpty())
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode);
- s << endl;
- }
// module inject-code native/end
- if (!snips.isEmpty()) {
+ if (!snips.isEmpty())
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode);
- s << endl;
- }
if (usePySideExtensions()) {
for (AbstractMetaEnum *metaEnum : qAsConst(globalEnums))
@@ -5866,7 +5937,7 @@ bool CppGenerator::finishGeneration()
s << INDENT << "FinishSignatureInitialization(module, " << moduleName()
<< "_SignatureStrings);\n";
- s << endl;
+ s << Qt::endl;
s << "SBK_MODULE_INIT_FUNCTION_END\n";
return file.done() != FileOut::Failure;
@@ -5972,17 +6043,20 @@ void CppGenerator::writeReturnValueHeuristics(QTextStream &s, const AbstractMeta
}
}
-void CppGenerator::writeHashFunction(QTextStream &s, GeneratorContext &context)
+void CppGenerator::writeHashFunction(QTextStream &s, const GeneratorContext &context)
{
const AbstractMetaClass *metaClass = context.metaClass();
- s << "static Py_hash_t " << cpythonBaseName(metaClass) << "_HashFunc(PyObject *self) {\n";
+ const char hashType[] = "Py_hash_t";
+ s << "static " << hashType << ' ' << cpythonBaseName(metaClass)
+ << "_HashFunc(PyObject *self) {\n";
writeCppSelfDefinition(s, context);
- s << INDENT << "return " << metaClass->typeEntry()->hashFunction() << '(';
- s << (isObjectType(metaClass) ? "" : "*") << CPP_SELF_VAR << ");\n";
+ s << INDENT << "return " << hashType << '('
+ << metaClass->typeEntry()->hashFunction() << '('
+ << (isObjectType(metaClass) ? "" : "*") << CPP_SELF_VAR << "));\n";
s<< "}\n\n";
}
-void CppGenerator::writeStdListWrapperMethods(QTextStream &s, GeneratorContext &context)
+void CppGenerator::writeDefaultSequenceMethods(QTextStream &s, const GeneratorContext &context)
{
const AbstractMetaClass *metaClass = context.metaClass();
ErrorCode errorCode(0);
@@ -6000,10 +6074,17 @@ void CppGenerator::writeStdListWrapperMethods(QTextStream &s, GeneratorContext &
writeCppSelfDefinition(s, context);
writeIndexError(s, QLatin1String("index out of bounds"));
- s << INDENT << metaClass->qualifiedCppName() << "::iterator _item = " << CPP_SELF_VAR << "->begin();\n";
- s << INDENT << "for (Py_ssize_t pos = 0; pos < _i; pos++) _item++;\n";
+ QString value;
+ s << INDENT << metaClass->qualifiedCppName() << "::const_iterator _item = "
+ << CPP_SELF_VAR << "->begin();\n"
+ << INDENT << "std::advance(_item, _i);\n";
- const AbstractMetaType *itemType = metaClass->templateBaseClassInstantiations().constFirst();
+ const AbstractMetaTypeList instantiations = metaClass->templateBaseClassInstantiations();
+ if (instantiations.isEmpty()) {
+ qFatal("shiboken: %s: Internal error, no instantiations of \"%s\" were found.",
+ __FUNCTION__, qPrintable(metaClass->qualifiedCppName()));
+ }
+ const AbstractMetaType *itemType = instantiations.constFirst();
s << INDENT << "return ";
writeToPythonConversion(s, itemType, metaClass, QLatin1String("*_item"));
@@ -6030,9 +6111,11 @@ void CppGenerator::writeStdListWrapperMethods(QTextStream &s, GeneratorContext &
s << INDENT << "}\n";
writeArgumentConversion(s, itemType, QLatin1String("cppValue"), QLatin1String("pyArg"), metaClass);
- s << INDENT << metaClass->qualifiedCppName() << "::iterator _item = " << CPP_SELF_VAR << "->begin();\n";
- s << INDENT << "for (Py_ssize_t pos = 0; pos < _i; pos++) _item++;\n";
- s << INDENT << "*_item = cppValue;\n";
+ s << INDENT << metaClass->qualifiedCppName() << "::iterator _item = "
+ << CPP_SELF_VAR << "->begin();\n"
+ << INDENT << "std::advance(_item, _i);\n"
+ << INDENT << "*_item = cppValue;\n";
+
s << INDENT << "return {};\n";
s << "}\n";
}
@@ -6042,13 +6125,13 @@ void CppGenerator::writeIndexError(QTextStream &s, const QString &errorMsg)
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_IndexError, \"" << errorMsg << "\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
}
s << INDENT << "}\n";
}
QString CppGenerator::writeReprFunction(QTextStream &s,
- GeneratorContext &context,
+ const GeneratorContext &context,
uint indirections)
{
const AbstractMetaClass *metaClass = context.metaClass();
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h
index aee1fb7d4..4e995d56f 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.h
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h
@@ -43,53 +43,53 @@ public:
protected:
QString fileNameSuffix() const override;
- QString fileNameForContext(GeneratorContext &context) const override;
+ QString fileNameForContext(const GeneratorContext &context) const override;
QVector<AbstractMetaFunctionList> filterGroupedOperatorFunctions(const AbstractMetaClass *metaClass,
uint query);
- void generateClass(QTextStream &s, GeneratorContext &classContext) override;
+ void generateClass(QTextStream &s, const GeneratorContext &classContext) override;
bool finishGeneration() override;
private:
void writeInitFunc(QTextStream &declStr, QTextStream &callStr,
const Indentor &indent, const QString &initFunctionName,
const TypeEntry *enclosingEntry = nullptr);
- void writeCacheResetNative(QTextStream &s, const AbstractMetaClass *metaClass);
- void writeConstructorNative(QTextStream &s, const AbstractMetaFunction *func);
- void writeDestructorNative(QTextStream &s, const AbstractMetaClass *metaClass);
+ void writeCacheResetNative(QTextStream &s, const GeneratorContext &classContext);
+ void writeConstructorNative(QTextStream &s, const GeneratorContext &classContext,
+ const AbstractMetaFunction *func);
+ void writeDestructorNative(QTextStream &s, const GeneratorContext &classContext);
QString getVirtualFunctionReturnTypeName(const AbstractMetaFunction *func);
void writeVirtualMethodNative(QTextStream &s, const AbstractMetaFunction *func, int cacheIndex);
- void writeMetaObjectMethod(QTextStream &s, const AbstractMetaClass *metaClass);
- void writeMetaCast(QTextStream &s, const AbstractMetaClass *metaClass);
+ void writeMetaObjectMethod(QTextStream &s, const GeneratorContext &classContext);
+ void writeMetaCast(QTextStream &s, const GeneratorContext &classContext);
void writeEnumConverterFunctions(QTextStream &s, const TypeEntry *enumType);
void writeEnumConverterFunctions(QTextStream &s, const AbstractMetaEnum *metaEnum);
void writeConverterFunctions(QTextStream &s, const AbstractMetaClass *metaClass,
- GeneratorContext &classContext);
+ const GeneratorContext &classContext);
void writeCustomConverterFunctions(QTextStream &s, const CustomConversion *customConversion);
void writeConverterRegister(QTextStream &s, const AbstractMetaClass *metaClass,
- GeneratorContext &classContext);
+ const GeneratorContext &classContext);
void writeCustomConverterRegister(QTextStream &s, const CustomConversion *customConversion, const QString &converterVar);
void writeContainerConverterFunctions(QTextStream &s, const AbstractMetaType *containerType);
void writeMethodWrapperPreamble(QTextStream &s, OverloadData &overloadData,
- GeneratorContext &context);
+ const GeneratorContext &context);
void writeConstructorWrapper(QTextStream &s, const AbstractMetaFunctionList &overloads,
- GeneratorContext &classContext);
+ const GeneratorContext &classContext);
void writeMethodWrapper(QTextStream &s, const AbstractMetaFunctionList &overloads,
- GeneratorContext &classContext);
+ const GeneratorContext &classContext);
void writeArgumentsInitializer(QTextStream &s, OverloadData &overloadData);
- void writeCppSelfAssigment(QTextStream &s, const GeneratorContext &context,
- const QString &className, bool cppSelfAsReference,
- bool useWrapperClass);
+ void writeCppSelfConversion(QTextStream &s, const GeneratorContext &context,
+ const QString &className, bool useWrapperClass);
void writeCppSelfDefinition(QTextStream &s,
const AbstractMetaFunction *func,
- GeneratorContext &context,
+ const GeneratorContext &context,
bool hasStaticOverload = false);
void writeCppSelfDefinition(QTextStream &s,
- GeneratorContext &context,
+ const GeneratorContext &context,
bool hasStaticOverload = false,
bool cppSelfAsReference = false);
@@ -106,13 +106,15 @@ private:
void writeTypeDiscoveryFunction(QTextStream &s, const AbstractMetaClass *metaClass);
- static void writeSetattroDefinition(QTextStream &s, const AbstractMetaClass *metaClass);
+ void writeSetattroDefinition(QTextStream &s, const AbstractMetaClass *metaClass) const;
void writeSetattroDefaultReturn(QTextStream &s) const;
- void writeSmartPointerSetattroFunction(QTextStream &s, GeneratorContext &context);
- void writeSetattroFunction(QTextStream &s, AttroCheck attroCheck, GeneratorContext &context);
+ void writeSmartPointerSetattroFunction(QTextStream &s, const GeneratorContext &context);
+ void writeSetattroFunction(QTextStream &s, AttroCheck attroCheck,
+ const GeneratorContext &context);
static void writeGetattroDefinition(QTextStream &s, const AbstractMetaClass *metaClass);
- void writeSmartPointerGetattroFunction(QTextStream &s, GeneratorContext &context);
- void writeGetattroFunction(QTextStream &s, AttroCheck attroCheck, GeneratorContext &context);
+ void writeSmartPointerGetattroFunction(QTextStream &s, const GeneratorContext &context);
+ void writeGetattroFunction(QTextStream &s, AttroCheck attroCheck,
+ const GeneratorContext &context);
QString writeSmartPointerGetterCast();
QString qObjectGetAttroFunction() const;
@@ -183,13 +185,13 @@ private:
/// Writes calls to all the possible method/function overloads.
void writeFunctionCalls(QTextStream &s,
const OverloadData &overloadData,
- GeneratorContext &context);
+ const GeneratorContext &context);
/// Writes the call to a single function usually from a collection of overloads.
void writeSingleFunctionCall(QTextStream &s,
const OverloadData &overloadData,
const AbstractMetaFunction *func,
- GeneratorContext &context);
+ const GeneratorContext &context);
/// Returns the name of a C++ to Python conversion function.
static QString cppToPythonFunctionName(const QString &sourceTypeName, QString targetTypeName = QString());
@@ -242,48 +244,51 @@ private:
/// Returns a string containing the name of an argument for the given function and argument index.
QString argumentNameFromIndex(const AbstractMetaFunction *func, int argIndex, const AbstractMetaClass **wrappedClass);
void writeMethodCall(QTextStream &s, const AbstractMetaFunction *func,
- GeneratorContext &context, int maxArgs = 0);
+ const GeneratorContext &context, int maxArgs = 0);
- QString getInitFunctionName(GeneratorContext &context) const;
+ QString getInitFunctionName(const GeneratorContext &context) const;
QString getSimpleClassInitFunctionName(const AbstractMetaClass *metaClass) const;
+ void writeSignatureStrings(QTextStream &s, QTextStream &signatureStream,
+ const QString &arrayName,
+ const char *comment) const;
void writeClassRegister(QTextStream &s,
const AbstractMetaClass *metaClass,
- GeneratorContext &classContext,
+ const GeneratorContext &classContext,
QTextStream &signatureStream);
void writeClassDefinition(QTextStream &s,
const AbstractMetaClass *metaClass,
- GeneratorContext &classContext);
+ const GeneratorContext &classContext);
void writeMethodDefinitionEntry(QTextStream &s, const AbstractMetaFunctionList &overloads);
void writeMethodDefinition(QTextStream &s, const AbstractMetaFunctionList &overloads);
void writeSignatureInfo(QTextStream &s, const AbstractMetaFunctionList &overloads);
/// Writes the implementation of all methods part of python sequence protocol
void writeSequenceMethods(QTextStream &s,
const AbstractMetaClass *metaClass,
- GeneratorContext &context);
+ const GeneratorContext &context);
void writeTypeAsSequenceDefinition(QTextStream &s, const AbstractMetaClass *metaClass);
/// Writes the PyMappingMethods structure for types that supports the python mapping protocol.
void writeTypeAsMappingDefinition(QTextStream &s, const AbstractMetaClass *metaClass);
void writeMappingMethods(QTextStream &s,
const AbstractMetaClass *metaClass,
- GeneratorContext &context);
+ const GeneratorContext &context);
void writeTypeAsNumberDefinition(QTextStream &s, const AbstractMetaClass *metaClass);
void writeTpTraverseFunction(QTextStream &s, const AbstractMetaClass *metaClass);
void writeTpClearFunction(QTextStream &s, const AbstractMetaClass *metaClass);
- void writeCopyFunction(QTextStream &s, GeneratorContext &context);
+ void writeCopyFunction(QTextStream &s, const GeneratorContext &context);
void writeGetterFunction(QTextStream &s,
const AbstractMetaField *metaField,
- GeneratorContext &context);
+ const GeneratorContext &context);
void writeSetterFunction(QTextStream &s,
const AbstractMetaField *metaField,
- GeneratorContext &context);
+ const GeneratorContext &context);
- void writeRichCompareFunction(QTextStream &s, GeneratorContext &context);
+ void writeRichCompareFunction(QTextStream &s, const GeneratorContext &context);
void writeEnumsInitialization(QTextStream &s, AbstractMetaEnumList &enums);
void writeEnumInitialization(QTextStream &s, const AbstractMetaEnum *metaEnum);
@@ -314,7 +319,7 @@ private:
void writeParentChildManagement(QTextStream &s, const AbstractMetaFunction *func, bool userHeuristicForReturn);
bool writeParentChildManagement(QTextStream &s, const AbstractMetaFunction *func, int argIndex, bool userHeuristicPolicy);
void writeReturnValueHeuristics(QTextStream &s, const AbstractMetaFunction *func);
- void writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorContext &context) const;
+ void writeInitQtMetaTypeFunctionBody(QTextStream &s, const GeneratorContext &context) const;
/**
* Returns the multiple inheritance initializer function for the given class.
@@ -339,14 +344,14 @@ private:
/// Returns true if generator should produce getters and setters for the given class.
bool shouldGenerateGetSetList(const AbstractMetaClass *metaClass);
- void writeHashFunction(QTextStream &s, GeneratorContext &context);
+ void writeHashFunction(QTextStream &s, const GeneratorContext &context);
/// Write default implementations for sequence protocol
- void writeStdListWrapperMethods(QTextStream &s, GeneratorContext &context);
+ void writeDefaultSequenceMethods(QTextStream &s, const GeneratorContext &context);
/// Helper function for writeStdListWrapperMethods.
void writeIndexError(QTextStream &s, const QString &errorMsg);
- QString writeReprFunction(QTextStream &s, GeneratorContext &context, uint indirections);
+ QString writeReprFunction(QTextStream &s, const GeneratorContext &context, uint indirections);
const AbstractMetaFunction *boolCast(const AbstractMetaClass *metaClass) const;
bool hasBoolCast(const AbstractMetaClass *metaClass) const
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
index 34bba408a..8b3fe1653 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
@@ -45,7 +45,7 @@ QString HeaderGenerator::fileNameSuffix() const
return QLatin1String("_wrapper.h");
}
-QString HeaderGenerator::fileNameForContext(GeneratorContext &context) const
+QString HeaderGenerator::fileNameForContext(const GeneratorContext &context) const
{
const AbstractMetaClass *metaClass = context.metaClass();
if (!context.forSmartPointer()) {
@@ -91,11 +91,10 @@ void HeaderGenerator::writeProtectedFieldAccessors(QTextStream &s, const Abstrac
<< " { " << fieldName << " = value; }\n";
}
-void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
+void HeaderGenerator::generateClass(QTextStream &s, const GeneratorContext &classContextIn)
{
- AbstractMetaClass *metaClass = classContext.metaClass();
- if (ReportHandler::isDebug(ReportHandler::SparseDebug))
- qCDebug(lcShiboken) << "Generating header for " << metaClass->fullName();
+ GeneratorContext classContext = classContextIn;
+ const AbstractMetaClass *metaClass = classContext.metaClass();
m_inheritedOverloads.clear();
Indentation indent(INDENT);
@@ -104,9 +103,10 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
QString wrapperName;
if (!classContext.forSmartPointer()) {
- wrapperName = HeaderGenerator::wrapperName(metaClass);
+ wrapperName = classContext.useWrapper()
+ ? classContext.wrapperName() : metaClass->qualifiedCppName();
} else {
- wrapperName = HeaderGenerator::wrapperName(classContext.preciseType());
+ wrapperName = classContext.smartPointerWrapperName();
}
QString outerHeaderGuard = getFilteredCppSignatureString(wrapperName).toUpper();
QString innerHeaderGuard;
@@ -119,13 +119,12 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
s << "#define protected public\n\n";
//Includes
- s << metaClass->typeEntry()->include() << endl;
+ s << metaClass->typeEntry()->include() << Qt::endl;
- if (shouldGenerateCppWrapper(metaClass) &&
- usePySideExtensions() && metaClass->isQObject())
+ if (classContext.useWrapper() && usePySideExtensions() && metaClass->isQObject())
s << "namespace PySide { class DynamicQMetaObject; }\n\n";
- while (shouldGenerateCppWrapper(metaClass)) {
+ while (classContext.useWrapper()) {
if (!innerHeaderGuard.isEmpty()) {
s << "# ifndef SBK_" << innerHeaderGuard << "_H\n";
s << "# define SBK_" << innerHeaderGuard << "_H\n\n";
@@ -171,7 +170,9 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
s << '~' << wrapperName << "();\n";
}
- writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode);
+ writeClassCodeSnips(s, metaClass->typeEntry()->codeSnips(),
+ TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode,
+ classContext);
if ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
&& usePySideExtensions() && metaClass->isQObject()) {
@@ -204,11 +205,12 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
metaClass = metaClass->baseClass();
if (!metaClass || !avoidProtectedHack())
break;
- classContext = GeneratorContext(metaClass);
+ classContext = contextForClass(metaClass);
if (!classContext.forSmartPointer()) {
- wrapperName = HeaderGenerator::wrapperName(metaClass);
+ wrapperName = classContext.useWrapper()
+ ? classContext.wrapperName() : metaClass->qualifiedCppName();
} else {
- wrapperName = HeaderGenerator::wrapperName(classContext.preciseType());
+ wrapperName = classContext.smartPointerWrapperName();
}
innerHeaderGuard = getFilteredCppSignatureString(wrapperName).toUpper();
}
@@ -337,7 +339,8 @@ void HeaderGenerator::writeTypeIndexValueLine(QTextStream &s, const TypeEntry *t
void HeaderGenerator::writeTypeIndexValueLines(QTextStream &s, const AbstractMetaClass *metaClass)
{
- if (!metaClass->typeEntry()->generateCode())
+ auto typeEntry = metaClass->typeEntry();
+ if (!typeEntry->generateCode() || !NamespaceTypeEntry::isVisibleScope(typeEntry))
return;
writeTypeIndexValueLine(s, metaClass->typeEntry());
const AbstractMetaEnumList &enums = metaClass->enums();
@@ -411,9 +414,17 @@ bool HeaderGenerator::finishGeneration()
int smartPointerCount = 0;
const QVector<const AbstractMetaType *> &instantiatedSmartPtrs = instantiatedSmartPointers();
for (const AbstractMetaType *metaType : instantiatedSmartPtrs) {
- _writeTypeIndexValue(macrosStream, getTypeIndexVariableName(metaType),
- smartPointerCountIndex);
- macrosStream << ", // " << metaType->cppSignature() << endl;
+ QString indexName = getTypeIndexVariableName(metaType);
+ _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
+ macrosStream << ", // " << metaType->cppSignature() << Qt::endl;
+ // Add a the same value for const pointees (shared_ptr<const Foo>).
+ const auto ptrName = metaType->typeEntry()->entryName();
+ int pos = indexName.indexOf(ptrName, 0, Qt::CaseInsensitive);
+ if (pos >= 0) {
+ indexName.insert(pos + ptrName.size() + 1, QLatin1String("CONST"));
+ _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
+ macrosStream << ", // (const)\n";
+ }
++smartPointerCountIndex;
++smartPointerCount;
}
@@ -449,7 +460,7 @@ bool HeaderGenerator::finishGeneration()
const QVector<const AbstractMetaType *> &containers = instantiatedContainers();
for (const AbstractMetaType *container : containers) {
_writeTypeIndexValue(macrosStream, getTypeIndexVariableName(container), pCount);
- macrosStream << ", // " << container->cppSignature() << endl;
+ macrosStream << ", // " << container->cppSignature() << Qt::endl;
pCount++;
}
@@ -517,10 +528,10 @@ bool HeaderGenerator::finishGeneration()
FileOut file(moduleHeaderFileName);
QTextStream &s = file.stream;
// write license comment
- s << licenseComment() << endl << endl;
+ s << licenseComment() << Qt::endl << Qt::endl;
- s << "#ifndef " << includeShield << endl;
- s << "#define " << includeShield << endl << endl;
+ s << "#ifndef " << includeShield << Qt::endl;
+ s << "#define " << includeShield << Qt::endl << Qt::endl;
if (!avoidProtectedHack()) {
s << "//workaround to access protected functions\n";
s << "#define protected public\n\n";
@@ -534,7 +545,7 @@ bool HeaderGenerator::finishGeneration()
s << "// Module Includes\n";
for (const QString &requiredModule : qAsConst(requiredTargetImports))
s << "#include <" << getModuleHeaderFileName(requiredModule) << ">\n";
- s << endl;
+ s << Qt::endl;
}
s << "// Bound library includes\n";
@@ -546,7 +557,7 @@ bool HeaderGenerator::finishGeneration()
const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
for (const PrimitiveTypeEntry *ptype : primitiveTypeList)
s << ptype->include();
- s << endl;
+ s << Qt::endl;
}
if (!containerTypes().isEmpty()) {
@@ -554,24 +565,24 @@ bool HeaderGenerator::finishGeneration()
const ContainerTypeEntryList &containerTypeList = containerTypes();
for (const ContainerTypeEntry *ctype : containerTypeList)
s << ctype->include();
- s << endl;
+ s << Qt::endl;
}
- s << macros << endl;
+ s << macros << Qt::endl;
if (!protectedEnumSurrogates.isEmpty()) {
s << "// Protected enum surrogates\n";
- s << protectedEnumSurrogates << endl;
+ s << protectedEnumSurrogates << Qt::endl;
}
s << "namespace Shiboken\n{\n\n";
s << "// PyType functions, to get the PyObjectType for a type T\n";
- s << sbkTypeFunctions << endl;
+ s << sbkTypeFunctions << Qt::endl;
s << "} // namespace Shiboken\n\n";
- s << "#endif // " << includeShield << endl << endl;
+ s << "#endif // " << includeShield << Qt::endl << Qt::endl;
return file.done() != FileOut::Failure;
}
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.h b/sources/shiboken2/generator/shiboken2/headergenerator.h
index 5f59dd13a..30ce06636 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.h
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.h
@@ -47,8 +47,8 @@ public:
protected:
QString fileNameSuffix() const override;
- QString fileNameForContext(GeneratorContext &context) const override;
- void generateClass(QTextStream &s, GeneratorContext &classContext) override;
+ QString fileNameForContext(const GeneratorContext &context) const override;
+ void generateClass(QTextStream &s, const GeneratorContext &classContext) override;
bool finishGeneration() override;
private:
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
index 56b64bbd5..bd39e9444 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
@@ -106,7 +106,7 @@ struct OverloadSortData
return;
map[typeName] = counter;
if (!reverseMap.contains(counter))
- reverseMap[counter] = 0;
+ reverseMap[counter] = nullptr;
counter++;
}
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index b6ab70d1f..6abaef698 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -47,6 +47,7 @@ static const char RETURN_VALUE_HEURISTIC[] = "enable-return-value-heuristic";
static const char ENABLE_PYSIDE_EXTENSIONS[] = "enable-pyside-extensions";
static const char DISABLE_VERBOSE_ERROR_MESSAGES[] = "disable-verbose-error-messages";
static const char USE_ISNULL_AS_NB_NONZERO[] = "use-isnull-as-nb_nonzero";
+static const char WRAPPER_DIAGNOSTICS[] = "wrapper-diagnostics";
const char *CPP_ARG = "cppArg";
const char *CPP_ARG_REMOVED = "removed_cppArg";
@@ -96,7 +97,7 @@ static QString resolveScopePrefix(const QStringList &scopeList, const QString &v
static inline QStringList splitClassScope(const AbstractMetaClass *scope)
{
- return scope->qualifiedCppName().split(QLatin1String("::"), QString::SkipEmptyParts);
+ return scope->qualifiedCppName().split(QLatin1String("::"), Qt::SkipEmptyParts);
}
static QString resolveScopePrefix(const AbstractMetaClass *scope, const QString &value)
@@ -335,7 +336,7 @@ void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumLi
{
Q_ASSERT(metaClass);
// if a scope is not to be generated, collect its enums into the parent scope
- if (metaClass->typeEntry()->codeGeneration() == TypeEntry::GenerateForSubclass) {
+ if (!NamespaceTypeEntry::isVisibleScope(metaClass->typeEntry())) {
const AbstractMetaEnumList &enums = metaClass->enums();
for (AbstractMetaEnum *metaEnum : enums) {
if (!metaEnum->isPrivate() && metaEnum->typeEntry()->generateCode()
@@ -346,47 +347,13 @@ void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumLi
}
}
-static const AbstractMetaClass *getProperEnclosingClass(const AbstractMetaClass *metaClass)
-{
- if (!metaClass)
- return nullptr;
-
- if (metaClass->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass)
- return metaClass;
-
- return getProperEnclosingClass(metaClass->enclosingClass());
-}
-
-const AbstractMetaClass *ShibokenGenerator::getProperEnclosingClassForEnum(const AbstractMetaEnum *metaEnum)
-{
- return getProperEnclosingClass(metaEnum->enclosingClass());
-}
-
QString ShibokenGenerator::wrapperName(const AbstractMetaClass *metaClass) const
{
- if (shouldGenerateCppWrapper(metaClass)) {
- QString result = metaClass->name();
- if (metaClass->enclosingClass()) // is a inner class
- result.replace(QLatin1String("::"), QLatin1String("_"));
-
- result += QLatin1String("Wrapper");
- return result;
- }
- return metaClass->qualifiedCppName();
-}
-
-QString ShibokenGenerator::wrapperName(const AbstractMetaType *metaType) const
-{
- return metaType->cppSignature();
-}
-
-QString ShibokenGenerator::wrapperName(const TypeEntry *type) const
-{
- QString name = type->name();
- int pos = name.lastIndexOf(QLatin1String("::"));
- if (pos >= 0)
- name = name.remove(0, pos + 2);
- return name + QLatin1String("Wrapper");
+ Q_ASSERT(shouldGenerateCppWrapper(metaClass));
+ QString result = metaClass->name();
+ if (metaClass->enclosingClass()) // is a inner class
+ result.replace(QLatin1String("::"), QLatin1String("_"));
+ return result + QLatin1String("Wrapper");
}
QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClass)
@@ -394,7 +361,8 @@ QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClas
QString fullClassName = metaClass->name();
const AbstractMetaClass *enclosing = metaClass->enclosingClass();
while (enclosing) {
- fullClassName.prepend(enclosing->name() + QLatin1Char('.'));
+ if (NamespaceTypeEntry::isVisibleScope(enclosing->typeEntry()))
+ fullClassName.prepend(enclosing->name() + QLatin1Char('.'));
enclosing = enclosing->enclosingClass();
}
fullClassName.prepend(packageName() + QLatin1Char('.'));
@@ -821,7 +789,7 @@ QString ShibokenGenerator::cpythonBaseName(const TypeEntry *type)
baseName = cpythonFlagsName(static_cast<const FlagsTypeEntry *>(type));
} else if (type->isContainer()) {
const auto *ctype = static_cast<const ContainerTypeEntry *>(type);
- switch (ctype->type()) {
+ switch (ctype->containerKind()) {
case ContainerTypeEntry::ListContainer:
case ContainerTypeEntry::StringListContainer:
case ContainerTypeEntry::LinkedListContainer:
@@ -1196,10 +1164,11 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType *metaType
return QLatin1String("PyObject_Check");
return cpythonCheckFunction(metaType->typeEntry(), genericNumberType);
}
- if (metaType->typeEntry()->isContainer()) {
+ auto typeEntry = metaType->typeEntry();
+ if (typeEntry->isContainer()) {
QString typeCheck = QLatin1String("Shiboken::Conversions::");
- ContainerTypeEntry::Type type =
- static_cast<const ContainerTypeEntry *>(metaType->typeEntry())->type();
+ ContainerTypeEntry::ContainerKind type =
+ static_cast<const ContainerTypeEntry *>(typeEntry)->containerKind();
if (type == ContainerTypeEntry::ListContainer
|| type == ContainerTypeEntry::StringListContainer
|| type == ContainerTypeEntry::LinkedListContainer
@@ -1238,7 +1207,7 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType *metaType
}
return typeCheck;
}
- return cpythonCheckFunction(metaType->typeEntry(), genericNumberType);
+ return cpythonCheckFunction(typeEntry, genericNumberType);
}
QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type, bool genericNumberType)
@@ -1486,6 +1455,16 @@ void ShibokenGenerator::writeFunctionArguments(QTextStream &s,
}
}
+GeneratorContext ShibokenGenerator::contextForClass(const AbstractMetaClass *c) const
+{
+ GeneratorContext result = Generator::contextForClass(c);
+ if (shouldGenerateCppWrapper(c)) {
+ result.m_type = GeneratorContext::WrappedClass;
+ result.m_wrappername = wrapperName(c);
+ }
+ return result;
+}
+
QString ShibokenGenerator::functionReturnType(const AbstractMetaFunction *func, Options options) const
{
QString modifiedReturnType = QString(func->typeReplaced(0));
@@ -1569,16 +1548,34 @@ void ShibokenGenerator::writeUnusedVariableCast(QTextStream &s, const QString &v
s << INDENT << "SBK_UNUSED(" << variableName<< ")\n";
}
+static bool filterFunction(const AbstractMetaFunction *func, bool avoidProtectedHack)
+{
+ switch (func->functionType()) {
+ case AbstractMetaFunction::DestructorFunction:
+ case AbstractMetaFunction::SignalFunction:
+ case AbstractMetaFunction::GetAttroFunction:
+ case AbstractMetaFunction::SetAttroFunction:
+ return false;
+ default:
+ break;
+ }
+ if (func->usesRValueReferences())
+ return false;
+ if (func->isModifiedRemoved() && !func->isAbstract()
+ && (!avoidProtectedHack || !func->isProtected())) {
+ return false;
+ }
+ return true;
+}
+
AbstractMetaFunctionList ShibokenGenerator::filterFunctions(const AbstractMetaClass *metaClass)
{
AbstractMetaFunctionList result;
const AbstractMetaFunctionList &funcs = metaClass->functions();
+ result.reserve(funcs.size());
for (AbstractMetaFunction *func : funcs) {
- if (func->isSignal() || func->isDestructor() || func->usesRValueReferences()
- || (func->isModifiedRemoved() && !func->isAbstract()
- && (!avoidProtectedHack() || !func->isProtected())))
- continue;
- result << func;
+ if (filterFunction(func, avoidProtectedHack()))
+ result.append(func);
}
return result;
}
@@ -1663,17 +1660,24 @@ QString ShibokenGenerator::getCodeSnippets(const CodeSnipList &codeSnips,
}
return code;
}
-void ShibokenGenerator::processCodeSnip(QString &code, const AbstractMetaClass *context)
+
+void ShibokenGenerator::processClassCodeSnip(QString &code, const GeneratorContext &context)
{
- if (context) {
- // Replace template variable by the Python Type object
- // for the class context in which the variable is used.
- code.replace(QLatin1String("%PYTHONTYPEOBJECT"),
- cpythonTypeName(context) + QLatin1String("->type"));
- code.replace(QLatin1String("%TYPE"), wrapperName(context));
- code.replace(QLatin1String("%CPPTYPE"), context->name());
- }
+ auto metaClass = context.metaClass();
+ // Replace template variable by the Python Type object
+ // for the class context in which the variable is used.
+ code.replace(QLatin1String("%PYTHONTYPEOBJECT"),
+ cpythonTypeName(metaClass) + QLatin1String("->type"));
+ const QString className = context.useWrapper()
+ ? context.wrapperName() : metaClass->qualifiedCppName();
+ code.replace(QLatin1String("%TYPE"), className);
+ code.replace(QLatin1String("%CPPTYPE"), metaClass->name());
+ processCodeSnip(code);
+}
+
+void ShibokenGenerator::processCodeSnip(QString &code)
+{
// replace "toPython" converters
replaceConvertToPythonTypeSystemVariable(code);
@@ -1739,19 +1743,33 @@ ShibokenGenerator::ArgumentVarReplacementList ShibokenGenerator::getArgumentRepl
return argReplacements;
}
-void ShibokenGenerator::writeCodeSnips(QTextStream &s,
+void ShibokenGenerator::writeClassCodeSnips(QTextStream &s,
const CodeSnipList &codeSnips,
TypeSystem::CodeSnipPosition position,
TypeSystem::Language language,
- const AbstractMetaClass *context)
+ const GeneratorContext &context)
+{
+ QString code = getCodeSnippets(codeSnips, position, language);
+ if (code.isEmpty())
+ return;
+ processClassCodeSnip(code, context);
+ s << INDENT << "// Begin code injection\n";
+ s << code;
+ s << INDENT << "// End of code injection\n\n";
+}
+
+void ShibokenGenerator::writeCodeSnips(QTextStream &s,
+ const CodeSnipList &codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language)
{
QString code = getCodeSnippets(codeSnips, position, language);
if (code.isEmpty())
return;
- processCodeSnip(code, context);
+ processCodeSnip(code);
s << INDENT << "// Begin code injection\n";
s << code;
- s << INDENT << "// End of code injection\n";
+ s << INDENT << "// End of code injection\n\n";
}
void ShibokenGenerator::writeCodeSnips(QTextStream &s,
@@ -1978,7 +1996,7 @@ void ShibokenGenerator::writeCodeSnips(QTextStream &s,
processCodeSnip(code);
s << INDENT << "// Begin code injection\n";
s << code;
- s << INDENT << "// End of code injection\n";
+ s << INDENT << "// End of code injection\n\n";
}
// Returns true if the string is an expression,
@@ -2137,13 +2155,17 @@ bool ShibokenGenerator::injectedCodeUsesPySelf(const AbstractMetaFunction *func)
return false;
}
-bool ShibokenGenerator::injectedCodeCallsCppFunction(const AbstractMetaFunction *func)
+bool ShibokenGenerator::injectedCodeCallsCppFunction(const GeneratorContext &context,
+ const AbstractMetaFunction *func)
{
QString funcCall = func->originalName() + QLatin1Char('(');
QString wrappedCtorCall;
if (func->isConstructor()) {
funcCall.prepend(QLatin1String("new "));
- wrappedCtorCall = QStringLiteral("new %1(").arg(wrapperName(func->ownerClass()));
+ const auto owner = func->ownerClass();
+ const QString className = context.useWrapper()
+ ? context.wrapperName() : owner->qualifiedCppName();
+ wrappedCtorCall = QLatin1String("new ") + className + QLatin1Char('(');
}
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode);
for (const CodeSnip &snip : qAsConst(snips)) {
@@ -2213,10 +2235,18 @@ ShibokenGenerator::AttroCheck ShibokenGenerator::checkAttroFunctionNeeds(const A
} else {
if (getGeneratorClassInfo(metaClass).needsGetattroFunction)
result |= AttroCheckFlag::GetattroOverloads;
+ if (metaClass->queryFirstFunction(metaClass->functions(),
+ AbstractMetaClass::GetAttroFunction)) {
+ result |= AttroCheckFlag::GetattroUser;
+ }
if (usePySideExtensions() && metaClass->qualifiedCppName() == QLatin1String("QObject"))
result |= AttroCheckFlag::SetattroQObject;
if (useOverrideCaching(metaClass))
result |= AttroCheckFlag::SetattroMethodOverride;
+ if (metaClass->queryFirstFunction(metaClass->functions(),
+ AbstractMetaClass::SetAttroFunction)) {
+ result |= AttroCheckFlag::SetattroUser;
+ }
// PYSIDE-1255: If setattro is generated for a class inheriting
// QObject, the property code needs to be generated, too.
if ((result & AttroCheckFlag::SetattroMask) != 0
@@ -2394,11 +2424,20 @@ static void dumpFunction(AbstractMetaFunctionList lst)
static bool isGroupable(const AbstractMetaFunction *func)
{
- if (func->isSignal() || func->isDestructor() || (func->isModifiedRemoved() && !func->isAbstract()))
+ switch (func->functionType()) {
+ case AbstractMetaFunction::DestructorFunction:
+ case AbstractMetaFunction::SignalFunction:
+ case AbstractMetaFunction::GetAttroFunction:
+ case AbstractMetaFunction::SetAttroFunction:
+ return false;
+ default:
+ break;
+ }
+ if (func->isModifiedRemoved() && !func->isAbstract())
return false;
// weird operator overloads
if (func->name() == QLatin1String("operator[]") || func->name() == QLatin1String("operator->")) // FIXME: what about cast operators?
- return false;;
+ return false;
return true;
}
@@ -2518,7 +2557,9 @@ Generator::OptionDescriptions ShibokenGenerator::options() const
"(USE WITH CAUTION!)"))
<< qMakePair(QLatin1String(USE_ISNULL_AS_NB_NONZERO),
QLatin1String("If a class have an isNull() const method, it will be used to compute\n"
- "the value of boolean casts"));
+ "the value of boolean casts"))
+ << qMakePair(QLatin1String(WRAPPER_DIAGNOSTICS),
+ QLatin1String("Generate diagnostic code around wrappers"));
}
bool ShibokenGenerator::handleOption(const QString &key, const QString & /* value */)
@@ -2535,6 +2576,8 @@ bool ShibokenGenerator::handleOption(const QString &key, const QString & /* valu
return (m_useIsNullAsNbNonZero = true);
if (key == QLatin1String(AVOID_PROTECTED_HACK))
return (m_avoidProtectedHack = true);
+ if (key == QLatin1String(WRAPPER_DIAGNOSTICS))
+ return (m_wrapperDiagnostics = true);
return false;
}
@@ -2599,13 +2642,19 @@ void ShibokenGenerator::collectContainerTypesFromConverterMacros(const QString &
QString convMacro = toPythonMacro ? QLatin1String("%CONVERTTOPYTHON[") : QLatin1String("%CONVERTTOCPP[");
int offset = toPythonMacro ? sizeof("%CONVERTTOPYTHON") : sizeof("%CONVERTTOCPP");
int start = 0;
+ QString errorMessage;
while ((start = code.indexOf(convMacro, start)) != -1) {
int end = code.indexOf(QLatin1Char(']'), start);
start += offset;
if (code.at(start) != QLatin1Char('%')) {
QString typeString = code.mid(start, end - start);
- AbstractMetaType *type = buildAbstractMetaTypeFromString(typeString);
- addInstantiatedContainersAndSmartPointers(type, type->originalTypeDescription());
+ if (AbstractMetaType *type =
+ buildAbstractMetaTypeFromString(typeString, &errorMessage)) {
+ addInstantiatedContainersAndSmartPointers(type, type->originalTypeDescription());
+ } else {
+ qFatal("%s: Cannot translate type \"%s\": %s", __FUNCTION__,
+ qPrintable(typeString), qPrintable(errorMessage));
+ }
}
start = end;
}
@@ -2778,7 +2827,7 @@ void ShibokenGenerator::writeMinimalConstructorExpression(QTextStream &s, const
} else {
const QString message = msgCouldNotFindMinimalConstructor(QLatin1String(__FUNCTION__), type->qualifiedCppName());
qCWarning(lcShiboken()).noquote() << message;
- s << ";\n#error " << message << endl;
+ s << ";\n#error " << message << Qt::endl;
}
}
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index 24c1374ae..d8259d245 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -69,10 +69,12 @@ public:
None = 0x0,
GetattroOverloads = 0x01,
GetattroSmartPointer = 0x02,
+ GetattroUser = 0x04, // Injected code
GetattroMask = 0x0F,
SetattroQObject = 0x10,
SetattroSmartPointer = 0x20,
SetattroMethodOverride = 0x40,
+ SetattroUser = 0x80, // Injected code
SetattroMask = 0xF0,
};
Q_DECLARE_FLAGS(AttroCheck, AttroCheckFlag);
@@ -105,6 +107,8 @@ protected:
const AbstractMetaFunction *func,
Options options = NoOption) const override;
+ GeneratorContext contextForClass(const AbstractMetaClass *c) const override;
+
/**
* Returns a map with all functions grouped, the function name is used as key.
* Example of return value: { "foo" -> ["foo(int)", "foo(int, long)], "bar" -> "bar(double)"}
@@ -122,11 +126,15 @@ protected:
AbstractMetaFunctionList getFunctionAndInheritedOverloads(const AbstractMetaFunction *func, QSet<QString> *seen);
/// Write user's custom code snippets at class or module level.
+ void writeClassCodeSnips(QTextStream &s,
+ const QVector<CodeSnip> & codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language,
+ const GeneratorContext &context);
void writeCodeSnips(QTextStream &s,
const QVector<CodeSnip> & codeSnips,
TypeSystem::CodeSnipPosition position,
- TypeSystem::Language language,
- const AbstractMetaClass *context = nullptr);
+ TypeSystem::Language language);
/// Write user's custom code snippets at function level.
void writeCodeSnips(QTextStream &s,
const QVector<CodeSnip> & codeSnips,
@@ -136,7 +144,8 @@ protected:
const AbstractMetaArgument *lastArg = nullptr);
/// Replaces variables for the user's custom code at global or class level.
- void processCodeSnip(QString &code, const AbstractMetaClass *context = nullptr);
+ void processCodeSnip(QString &code);
+ void processClassCodeSnip(QString &code, const GeneratorContext &context);
/**
* Verifies if any of the function's code injections of the "native"
@@ -153,7 +162,8 @@ protected:
* \param func the function to check
* \return true if the function's code snippets call the wrapped C++ function
*/
- bool injectedCodeCallsCppFunction(const AbstractMetaFunction *func);
+ bool injectedCodeCallsCppFunction(const GeneratorContext &context,
+ const AbstractMetaFunction *func);
/**
* Verifies if any of the function's code injections of the "native" class makes a
@@ -219,16 +229,14 @@ protected:
/// Adds enums eligible for generation from classes/namespaces marked not to be generated.
static void lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumList &enumList, const AbstractMetaClass *metaClass);
- /// Returns the enclosing class for an enum, or nullptr if it should be global.
- const AbstractMetaClass *getProperEnclosingClassForEnum(const AbstractMetaEnum *metaEnum);
QString wrapperName(const AbstractMetaClass *metaClass) const;
- QString wrapperName(const AbstractMetaType *metaType) const;
- QString wrapperName(const TypeEntry *type) const;
QString fullPythonClassName(const AbstractMetaClass *metaClass);
QString fullPythonFunctionName(const AbstractMetaFunction *func);
+ bool wrapperDiagnostics() const { return m_wrapperDiagnostics; }
+
static QString protectedEnumSurrogateName(const AbstractMetaEnum *metaEnum);
static QString protectedFieldGetterName(const AbstractMetaField *field);
static QString protectedFieldSetterName(const AbstractMetaField *field);
@@ -550,6 +558,7 @@ private:
bool m_verboseErrorMessagesDisabled = false;
bool m_useIsNullAsNbNonZero = false;
bool m_avoidProtectedHack = false;
+ bool m_wrapperDiagnostics = false;
using AbstractMetaTypeCache = QHash<QString, AbstractMetaType *>;
AbstractMetaTypeCache m_metaTypeFromStringCache;
diff --git a/sources/shiboken2/libshiboken/CMakeLists.txt b/sources/shiboken2/libshiboken/CMakeLists.txt
index a38da8d89..dee5dbd21 100644
--- a/sources/shiboken2/libshiboken/CMakeLists.txt
+++ b/sources/shiboken2/libshiboken/CMakeLists.txt
@@ -14,7 +14,7 @@ macro(get_numpy_location)
break"
OUTPUT_VARIABLE PYTHON_NUMPY_LOCATION
OUTPUT_STRIP_TRAILING_WHITESPACE)
- message("PYTHON_NUMPY_LOCATION: " ${PYTHON_NUMPY_LOCATION})
+ message(STATUS "PYTHON_NUMPY_LOCATION: " ${PYTHON_NUMPY_LOCATION})
endmacro()
option(ENABLE_VERSION_SUFFIX "Used to use current version in suffix to generated files. This is used to allow multiples versions installed simultaneous." FALSE)
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index 78f4cbe8b..d7184569b 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -59,6 +59,8 @@
#include "qapp_macro.h"
#include "voidptr.h"
+#include <iostream>
+
#if defined(__APPLE__)
#include <dlfcn.h>
#endif
@@ -484,7 +486,7 @@ void SbkObjectTypeDealloc(PyObject *pyObj)
}
}
-PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
+static PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
{
// Check if all bases are new style before calling type.tp_new
// Was causing gc assert errors in test_bug704.py when
@@ -511,7 +513,8 @@ PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *k
#ifndef IS_PY3K
if (PyClass_Check(baseType)) {
PyErr_Format(PyExc_TypeError, "Invalid base class used in type %s. "
- "PySide only support multiple inheritance from python new style class.", metatype->tp_name);
+ "PySide only supports multiple inheritance from Python new style classes.",
+ metatype->tp_name);
return 0;
}
#endif
@@ -577,7 +580,6 @@ PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *k
if (PepType_SOTP(base)->subtype_init)
PepType_SOTP(base)->subtype_init(newType, args, kwds);
}
-
return reinterpret_cast<PyObject *>(newType);
}
@@ -729,35 +731,6 @@ bool walkThroughClassHierarchy(PyTypeObject *currentType, HierarchyVisitor *visi
return result;
}
-bool importModule(const char *moduleName, PyTypeObject *** cppApiPtr)
-{
- PyObject *sysModules = PyImport_GetModuleDict();
- PyObject *module = PyDict_GetItemString(sysModules, moduleName);
- if (!module) {
- module = PyImport_ImportModule(moduleName);
- if (!module)
- return false;
- } else {
- Py_INCREF(module);
- }
-
- Shiboken::AutoDecRef cppApi(PyObject_GetAttrString(module, "_Cpp_Api"));
- Py_DECREF(module);
-
- if (cppApi.isNull())
- return false;
-
-#ifdef IS_PY3K
- if (PyCapsule_CheckExact(cppApi))
- *cppApiPtr = reinterpret_cast<PyTypeObject **>(PyCapsule_GetPointer(cppApi, nullptr));
-#else
- // Python 2.6 doesn't have PyCapsule API, so let's keep usign PyCObject on all Python 2.x
- if (PyCObject_Check(cppApi))
- *cppApiPtr = reinterpret_cast<PyTypeObject **>(PyCObject_AsVoidPtr(cppApi));
-#endif
- return true;
-}
-
// Wrapper metatype and base type ----------------------------------------------------------
HierarchyVisitor::HierarchyVisitor() = default;
@@ -984,8 +957,11 @@ introduceWrapperType(PyObject *enclosingObject,
}
}
// PYSIDE-510: Here is the single change to support signatures.
- if (SbkSpecial_Type_Ready(enclosingObject, reinterpret_cast<PyTypeObject *>(type), signatureStrings) < 0)
+ if (SbkSpecial_Type_Ready(enclosingObject, reinterpret_cast<PyTypeObject *>(type), signatureStrings) < 0) {
+ std::cerr << "Warning: " << __FUNCTION__ << " returns nullptr for "
+ << typeName << '/' << originalName << " due to SbkSpecial_Type_Ready() failing\n";
return nullptr;
+ }
initPrivateData(type);
auto sotp = PepType_SOTP(type);
@@ -1001,7 +977,13 @@ introduceWrapperType(PyObject *enclosingObject,
// PyModule_AddObject steals type's reference.
Py_INCREF(ob_type);
- return PyModule_AddObject(enclosingObject, typeName, ob_type) == 0 ? type : nullptr;
+ if (PyModule_AddObject(enclosingObject, typeName, ob_type) != 0) {
+ std::cerr << "Warning: " << __FUNCTION__ << " returns nullptr for "
+ << typeName << '/' << originalName << " due to PyModule_AddObject(enclosingObject="
+ << enclosingObject << ",ob_type=" << ob_type << ") failing\n";
+ return nullptr;
+ }
+ return type;
}
void setSubTypeInitHook(SbkObjectType *type, SubTypeInitHook func)
@@ -1456,11 +1438,6 @@ PyObject *newObject(SbkObjectType *instanceType,
return reinterpret_cast<PyObject *>(self);
}
-void destroy(SbkObject *self)
-{
- destroy(self, nullptr);
-}
-
void destroy(SbkObject *self, void *cppData)
{
// Skip if this is called with NULL pointer this can happen in derived classes
diff --git a/sources/shiboken2/libshiboken/basewrapper.h b/sources/shiboken2/libshiboken/basewrapper.h
index 4132b5cc5..7248103cc 100644
--- a/sources/shiboken2/libshiboken/basewrapper.h
+++ b/sources/shiboken2/libshiboken/basewrapper.h
@@ -86,9 +86,6 @@ typedef void *(*SpecialCastFunction)(void *, SbkObjectType *);
typedef SbkObjectType *(*TypeDiscoveryFunc)(void *, SbkObjectType *);
typedef void *(*TypeDiscoveryFuncV2)(void *, SbkObjectType *);
-typedef void *(*ExtendedToCppFunc)(PyObject *); // DEPRECATED.
-typedef bool (*ExtendedIsConvertibleFunc)(PyObject *); // DEPRECATED.
-
// Used in userdata dealloc function
typedef void (*DeleteUserDataFunc)(void *);
@@ -144,11 +141,6 @@ void callCppDestructor(void *cptr)
delete reinterpret_cast<T *>(cptr);
}
-/**
- * Shiboken::importModule is DEPRECATED. Use Shiboken::Module::import() instead.
- */
-SBK_DEPRECATED(LIBSHIBOKEN_API bool importModule(const char *moduleName, PyTypeObject *** cppApiPtr));
-
// setErrorAboutWrongArguments now gets overload info from the signature module.
LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject *args, const char *funcName);
@@ -426,9 +418,6 @@ LIBSHIBOKEN_API void invalidate(PyObject *pyobj);
*/
LIBSHIBOKEN_API void makeValid(SbkObject *self);
-/// \deprecated Use destroy(SbkObject *, void *)
-SBK_DEPRECATED(LIBSHIBOKEN_API void destroy(SbkObject *self));
-
/**
* Destroy any data in Shiboken structure and c++ pointer if the pyboject has the ownership
*/
diff --git a/sources/shiboken2/libshiboken/bindingmanager.cpp b/sources/shiboken2/libshiboken/bindingmanager.cpp
index 1f18ed60a..1ab8dd089 100644
--- a/sources/shiboken2/libshiboken/bindingmanager.cpp
+++ b/sources/shiboken2/libshiboken/bindingmanager.cpp
@@ -318,11 +318,6 @@ void BindingManager::addClassInheritance(SbkObjectType *parent, SbkObjectType *c
m_d->classHierarchy.addEdge(parent, child);
}
-SbkObjectType *BindingManager::resolveType(void *cptr, SbkObjectType *type)
-{
- return resolveType(&cptr, type);
-}
-
SbkObjectType *BindingManager::resolveType(void **cptr, SbkObjectType *type)
{
SbkObjectType *identifiedType = m_d->classHierarchy.identifyType(cptr, type, type);
diff --git a/sources/shiboken2/libshiboken/bindingmanager.h b/sources/shiboken2/libshiboken/bindingmanager.h
index bfcbdc79b..ba5535347 100644
--- a/sources/shiboken2/libshiboken/bindingmanager.h
+++ b/sources/shiboken2/libshiboken/bindingmanager.h
@@ -77,12 +77,6 @@ public:
void addClassInheritance(SbkObjectType *parent, SbkObjectType *child);
/**
- * \deprecated Use \fn resolveType(void **, SbkObjectType *), this version is broken when used with multiple inheritance
- * because the \p cptr pointer of the discovered type may be different of the given \p cptr in case
- * of multiple inheritance
- */
- SBK_DEPRECATED(SbkObjectType *resolveType(void *cptr, SbkObjectType *type));
- /**
* Try to find the correct type of *cptr knowing that it's at least of type \p type.
* In case of multiple inheritance this function may change the contents of cptr.
* \param cptr a pointer to a pointer to the instance of type \p type
diff --git a/sources/shiboken2/libshiboken/helper.cpp b/sources/shiboken2/libshiboken/helper.cpp
index 013080b6e..b0f909d39 100644
--- a/sources/shiboken2/libshiboken/helper.cpp
+++ b/sources/shiboken2/libshiboken/helper.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -40,17 +40,128 @@
#include "helper.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
+
+#include <iomanip>
+#include <iostream>
+
#include <stdarg.h>
#ifdef _WIN32
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
# include <windows.h>
#else
# include <pthread.h>
#endif
+#include <algorithm>
+
+static void formatPyTypeObject(const PyTypeObject *obj, std::ostream &str)
+{
+ if (obj) {
+ str << '"' << obj->tp_name << "\", 0x" << std::hex
+ << obj->tp_flags << std::dec;
+ if (obj->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ str << " [heaptype]";
+ if (obj->tp_flags & Py_TPFLAGS_BASETYPE)
+ str << " [base]";
+ if (obj->tp_flags & Py_TPFLAGS_HAVE_GC)
+ str << " [gc]";
+ if (obj->tp_flags & Py_TPFLAGS_LONG_SUBCLASS)
+ str << " [long]";
+ if (obj->tp_flags & Py_TPFLAGS_LIST_SUBCLASS)
+ str << " [list]";
+ if (obj->tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS)
+ str << " [tuple]";
+ if (obj->tp_flags & Py_TPFLAGS_BYTES_SUBCLASS)
+ str << " [bytes]";
+ if (obj->tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS)
+ str << " [unicode]";
+ if (obj->tp_flags & Py_TPFLAGS_DICT_SUBCLASS)
+ str << " [dict]";
+ if (obj->tp_flags & Py_TPFLAGS_TYPE_SUBCLASS)
+ str << " [type]";
+ if (obj->tp_flags & Py_TPFLAGS_IS_ABSTRACT)
+ str << " [abstract]";
+ } else {
+ str << '0';
+ }
+}
+
+static void formatPyObject(PyObject *obj, std::ostream &str);
+
+static void formatPySequence(PyObject *obj, std::ostream &str)
+{
+ const Py_ssize_t size = PySequence_Size(obj);
+ const Py_ssize_t printSize = std::min(size, Py_ssize_t(5));
+ str << size << " <";
+ for (Py_ssize_t i = 0; i < printSize; ++i) {
+ if (i)
+ str << ", ";
+ str << '(';
+ PyObject *item = PySequence_GetItem(obj, i);
+ formatPyObject(item, str);
+ str << ')';
+ Py_XDECREF(item);
+ }
+ if (printSize < size)
+ str << ",...";
+ str << '>';
+}
+
+static void formatPyObject(PyObject *obj, std::ostream &str)
+{
+ if (obj) {
+ formatPyTypeObject(obj->ob_type, str);
+ str << ", ";
+ if (PyLong_Check(obj))
+ str << PyLong_AsLong(obj);
+ else if (PyFloat_Check(obj))
+ str << PyFloat_AsDouble(obj);
+#ifdef IS_PY3K
+ else if (PyUnicode_Check(obj))
+ str << '"' << _PepUnicode_AsString(obj) << '"';
+#else
+ else if (PyString_Check(obj))
+ str << '"' << PyString_AsString(obj) << '"';
+#endif
+ else if (PySequence_Check(obj))
+ formatPySequence(obj, str);
+ else
+ str << "<unknown>";
+ } else {
+ str << '0';
+ }
+}
+
namespace Shiboken
{
+debugPyObject::debugPyObject(PyObject *o) : m_object(o)
+{
+}
+
+debugPyTypeObject::debugPyTypeObject(const PyTypeObject *o) : m_object(o)
+{
+}
+
+std::ostream &operator<<(std::ostream &str, const debugPyTypeObject &o)
+{
+ str << "PyTypeObject(";
+ formatPyTypeObject(o.m_object, str);
+ str << ')';
+ return str;
+}
+
+std::ostream &operator<<(std::ostream &str, const debugPyObject &o)
+{
+ str << "PyObject(";
+ formatPyObject(o.m_object, str);
+ str << ')';
+ return str;
+}
+
// PySide-510: Changed from PySequence to PyList, which is correct.
bool listToArgcArgv(PyObject *argList, int *argc, char ***argv, const char *defaultAppName)
{
@@ -125,7 +236,7 @@ int warning(PyObject *category, int stacklevel, const char *format, ...)
{
va_list args;
va_start(args, format);
-#if _WIN32
+#ifdef _WIN32
va_list args2 = args;
#else
va_list args2;
diff --git a/sources/shiboken2/libshiboken/helper.h b/sources/shiboken2/libshiboken/helper.h
index 14aae8028..7e46f3d93 100644
--- a/sources/shiboken2/libshiboken/helper.h
+++ b/sources/shiboken2/libshiboken/helper.h
@@ -44,6 +44,8 @@
#include "shibokenmacros.h"
#include "autodecref.h"
+#include <iosfwd>
+
#define SBK_UNUSED(x) (void)(x);
namespace Shiboken
@@ -99,6 +101,24 @@ LIBSHIBOKEN_API ThreadId mainThreadId();
*/
LIBSHIBOKEN_API int warning(PyObject *category, int stacklevel, const char *format, ...);
+struct LIBSHIBOKEN_API debugPyObject
+{
+ explicit debugPyObject(PyObject *o);
+
+ PyObject *m_object;
+};
+
+struct LIBSHIBOKEN_API debugPyTypeObject
+{
+ explicit debugPyTypeObject(const PyTypeObject *o);
+
+ const PyTypeObject *m_object;
+};
+
+LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &str, const debugPyObject &o);
+LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &str, const debugPyTypeObject &o);
+
} // namespace Shiboken
+
#endif // HELPER_H
diff --git a/sources/shiboken2/libshiboken/pep384impl.cpp b/sources/shiboken2/libshiboken/pep384impl.cpp
index f07cac613..5e0053e2e 100644
--- a/sources/shiboken2/libshiboken/pep384impl.cpp
+++ b/sources/shiboken2/libshiboken/pep384impl.cpp
@@ -668,6 +668,22 @@ PyImport_GetModule(PyObject *name)
}
#endif // PY_VERSION_HEX < 0x03070000 || defined(Py_LIMITED_API)
+
+/*****************************************************************************
+ *
+ * Python 2 incompatibilities
+ *
+ * This is incompatibly implemented as macro in Python 2.
+ */
+#if PY_VERSION_HEX < 0x03000000
+
+PyObject *PepMapping_Items(PyObject *o)
+{
+ return PyObject_CallMethod(o, const_cast<char *>("items"), NULL);
+}
+
+#endif
+
/*****************************************************************************
*
* Extra support for name mangling
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index 541b0e775..2bfe52254 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -533,6 +533,18 @@ LIBSHIBOKEN_API PyObject *PyImport_GetModule(PyObject *name);
/*****************************************************************************
*
+ * Python 2 incompatibilities
+ *
+ * This is incompatibly implemented as macro in Python 2.
+ */
+#if PY_VERSION_HEX < 0x03000000
+extern LIBSHIBOKEN_API PyObject *PepMapping_Items(PyObject *o);
+#else
+#define PepMapping_Items PyMapping_Items
+#endif
+
+/*****************************************************************************
+ *
* Runtime support for Python 3.8 incompatibilities
*
*/
diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp
index 36f2f48f9..369b264e7 100644
--- a/sources/shiboken2/libshiboken/sbkenum.cpp
+++ b/sources/shiboken2/libshiboken/sbkenum.cpp
@@ -608,11 +608,16 @@ newItem(PyTypeObject *enumType, long itemValue, const char *itemName)
enumObj->ob_value = itemValue;
if (newValue) {
- PyObject *values = PyDict_GetItem(enumType->tp_dict, Shiboken::PyName::values());
- if (!values) {
- values = PyDict_New();
- PyDict_SetItem(enumType->tp_dict, Shiboken::PyName::values(), values);
- Py_DECREF(values); // ^ values still alive, because setitem increfs it
+ auto dict = enumType->tp_dict; // Note: 'values' is borrowed
+ PyObject *values = PyDict_GetItemWithError(dict, Shiboken::PyName::values());
+ if (values == nullptr) {
+ if (PyErr_Occurred())
+ return nullptr;
+ Shiboken::AutoDecRef new_values(values = PyDict_New());
+ if (values == nullptr)
+ return nullptr;
+ if (PyDict_SetItem(dict, Shiboken::PyName::values(), values) < 0)
+ return nullptr;
}
PyDict_SetItemString(values, itemName, reinterpret_cast<PyObject *>(enumObj));
}
@@ -720,11 +725,11 @@ newTypeWithName(const char *name,
{
// Careful: SbkType_FromSpec does not allocate the string.
PyType_Slot newslots[99] = {}; // enough but not too big for the stack
- auto *newspec = new PyType_Spec;
- newspec->name = strdup(name);
- newspec->basicsize = SbkNewType_spec.basicsize;
- newspec->itemsize = SbkNewType_spec.itemsize;
- newspec->flags = SbkNewType_spec.flags;
+ PyType_Spec newspec;
+ newspec.name = strdup(name);
+ newspec.basicsize = SbkNewType_spec.basicsize;
+ newspec.itemsize = SbkNewType_spec.itemsize;
+ newspec.flags = SbkNewType_spec.flags;
// we must append all the number methods, so rebuild everything:
int idx = 0;
while (SbkNewType_slots[idx].slot) {
@@ -734,8 +739,8 @@ newTypeWithName(const char *name,
}
if (numbers_fromFlag)
copyNumberMethods(numbers_fromFlag, newslots, &idx);
- newspec->slots = newslots;
- auto *type = reinterpret_cast<PyTypeObject *>(SbkType_FromSpec(newspec));
+ newspec.slots = newslots;
+ auto *type = reinterpret_cast<PyTypeObject *>(SbkType_FromSpec(&newspec));
Py_TYPE(type) = SbkEnumType_TypeF();
auto *enumType = reinterpret_cast<SbkEnumType *>(type);
diff --git a/sources/shiboken2/libshiboken/sbkpython.h b/sources/shiboken2/libshiboken/sbkpython.h
index 9dd1e712e..6755e945d 100644
--- a/sources/shiboken2/libshiboken/sbkpython.h
+++ b/sources/shiboken2/libshiboken/sbkpython.h
@@ -41,6 +41,7 @@
#define SBKPYTHON_H
#include "sbkversion.h"
+#define PyEnumMeta_Check(x) (strcmp(Py_TYPE(x)->tp_name, "EnumMeta") == 0)
// Qt's "slots" macro collides with the "slots" member variables
// used in some Python structs. For compilers that support push_macro,
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.cpp b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
index c19665176..541d74918 100644
--- a/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
@@ -55,11 +55,15 @@ namespace PyName {
STATIC_STRING_IMPL(dumps, "dumps")
STATIC_STRING_IMPL(loads, "loads")
STATIC_STRING_IMPL(result, "result")
+STATIC_STRING_IMPL(value, "value")
STATIC_STRING_IMPL(values, "values")
// Internal:
STATIC_STRING_IMPL(classmethod, "classmethod")
+STATIC_STRING_IMPL(co_name, "co_name")
STATIC_STRING_IMPL(compile, "compile");
+STATIC_STRING_IMPL(f_code, "f_code")
+STATIC_STRING_IMPL(f_lineno, "f_lineno")
STATIC_STRING_IMPL(function, "function")
STATIC_STRING_IMPL(marshal, "marshal")
STATIC_STRING_IMPL(method, "method")
@@ -73,6 +77,7 @@ namespace PyMagicName {
STATIC_STRING_IMPL(class_, "__class__")
STATIC_STRING_IMPL(ecf, "__ecf__")
STATIC_STRING_IMPL(file, "__file__")
+STATIC_STRING_IMPL(members, "__members__")
STATIC_STRING_IMPL(module, "__module__")
STATIC_STRING_IMPL(name, "__name__")
STATIC_STRING_IMPL(qualname, "__qualname__")
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.h b/sources/shiboken2/libshiboken/sbkstaticstrings.h
index 07d6cc60a..4078d163c 100644
--- a/sources/shiboken2/libshiboken/sbkstaticstrings.h
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.h
@@ -48,9 +48,13 @@ namespace Shiboken
// Some often-used strings
namespace PyName
{
+LIBSHIBOKEN_API PyObject *co_name();
LIBSHIBOKEN_API PyObject *dumps();
+LIBSHIBOKEN_API PyObject *f_code();
+LIBSHIBOKEN_API PyObject *f_lineno();
LIBSHIBOKEN_API PyObject *loads();
LIBSHIBOKEN_API PyObject *result();
+LIBSHIBOKEN_API PyObject *value();
LIBSHIBOKEN_API PyObject *values();
} // namespace PyName
@@ -59,6 +63,7 @@ namespace PyMagicName
LIBSHIBOKEN_API PyObject *class_();
LIBSHIBOKEN_API PyObject *ecf();
LIBSHIBOKEN_API PyObject *file();
+LIBSHIBOKEN_API PyObject *members();
LIBSHIBOKEN_API PyObject *module();
LIBSHIBOKEN_API PyObject *name();
LIBSHIBOKEN_API PyObject *qualname();
diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py
index 0e0943143..f5ef03613 100644
--- a/sources/shiboken2/shiboken_version.py
+++ b/sources/shiboken2/shiboken_version.py
@@ -38,13 +38,13 @@
#############################################################################
major_version = "5"
-minor_version = "14"
-patch_version = "2"
+minor_version = "15"
+patch_version = "0"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
# An empty string means the generated package will be an official release.
-pre_release_version_type = "a"
+release_version_type = "a"
# For example: "1", "2" (which means "beta1", "beta2", if type is "b").
pre_release_version = "1"
@@ -52,4 +52,4 @@ pre_release_version = "1"
if __name__ == '__main__':
# Used by CMake.
print('{0};{1};{2};{3};{4}'.format(major_version, minor_version, patch_version,
- pre_release_version_type, pre_release_version))
+ release_version_type, pre_release_version))
diff --git a/sources/shiboken2/tests/CMakeLists.txt b/sources/shiboken2/tests/CMakeLists.txt
index 375215369..2ba951de1 100644
--- a/sources/shiboken2/tests/CMakeLists.txt
+++ b/sources/shiboken2/tests/CMakeLists.txt
@@ -1,5 +1,7 @@
+cmake_minimum_required(VERSION 3.1)
+
if(BUILD_TESTS)
- find_package(Qt5Test 5.12 REQUIRED)
+ find_package(Qt${QT_MAJOR_VERSION}Test 5.12 REQUIRED)
endif()
add_subdirectory(libminimal)
@@ -42,24 +44,20 @@ if(NOT CTEST_TESTING_TIMEOUT)
set(CTEST_TESTING_TIMEOUT 60)
endif()
-if(CMAKE_VERSION VERSION_LESS 2.8)
- message("CMake version greater than 2.8 necessary to run tests")
-else()
- get_filename_component(BUILD_DIR "${libminimal_BINARY_DIR}" DIRECTORY)
- get_filename_component(BUILD_DIR "${BUILD_DIR}" DIRECTORY)
- get_filename_component(BUILD_DIR "${BUILD_DIR}" DIRECTORY)
- foreach(test_file ${TEST_FILES})
- string(REGEX MATCH "/([^/]+)(binding|module)/([^/]+)_test.py" tmp ${test_file})
- set(test_name "${CMAKE_MATCH_1}_${CMAKE_MATCH_3}")
- list(FIND test_blacklist ${test_name} expect_fail)
- add_test(${test_name} ${PYTHON_EXECUTABLE} ${test_file})
- set_tests_properties(${test_name} PROPERTIES ENVIRONMENT "BUILD_DIR=${BUILD_DIR}")
- set_tests_properties(${test_name} PROPERTIES TIMEOUT ${CTEST_TESTING_TIMEOUT})
- if (${expect_fail} GREATER -1)
- set_tests_properties(${test_name} PROPERTIES WILL_FAIL TRUE)
- endif()
- endforeach()
-endif()
+get_filename_component(BUILD_DIR "${libminimal_BINARY_DIR}" DIRECTORY)
+get_filename_component(BUILD_DIR "${BUILD_DIR}" DIRECTORY)
+get_filename_component(BUILD_DIR "${BUILD_DIR}" DIRECTORY)
+foreach(test_file ${TEST_FILES})
+ string(REGEX MATCH "/([^/]+)(binding|module)/([^/]+)_test.py" tmp ${test_file})
+ set(test_name "${CMAKE_MATCH_1}_${CMAKE_MATCH_3}")
+ list(FIND test_blacklist ${test_name} expect_fail)
+ add_test(${test_name} ${PYTHON_EXECUTABLE} ${test_file})
+ set_tests_properties(${test_name} PROPERTIES ENVIRONMENT "BUILD_DIR=${BUILD_DIR}")
+ set_tests_properties(${test_name} PROPERTIES TIMEOUT ${CTEST_TESTING_TIMEOUT})
+ if (${expect_fail} GREATER -1)
+ set_tests_properties(${test_name} PROPERTIES WILL_FAIL TRUE)
+ endif()
+endforeach()
add_subdirectory(dumpcodemodel)
diff --git a/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt b/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt
index 7c6d60fe2..5c5e2c7b0 100644
--- a/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt
+++ b/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt
@@ -3,4 +3,4 @@ add_executable(dumpcodemodel main.cpp)
target_include_directories(dumpcodemodel
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${apiextractor_SOURCE_DIR})
-target_link_libraries(dumpcodemodel PUBLIC apiextractor Qt5::Core)
+target_link_libraries(dumpcodemodel PUBLIC apiextractor Qt${QT_MAJOR_VERSION}::Core)
diff --git a/sources/shiboken2/tests/dumpcodemodel/main.cpp b/sources/shiboken2/tests/dumpcodemodel/main.cpp
index 52d64be94..37c964fc0 100644
--- a/sources/shiboken2/tests/dumpcodemodel/main.cpp
+++ b/sources/shiboken2/tests/dumpcodemodel/main.cpp
@@ -43,6 +43,8 @@
#include <algorithm>
#include <iterator>
+static bool optJoinNamespaces = false;
+
static inline QString languageLevelDescription()
{
return QLatin1String("C++ Language level (c++11..c++17, default=")
@@ -69,7 +71,6 @@ static const char *primitiveTypes[] = {
static inline QString nameAttribute() { return QStringLiteral("name"); }
-static void formatXmlNamespace(QXmlStreamWriter &writer, const NamespaceModelItem &nsp);
static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass);
static void formatXmlEnum(QXmlStreamWriter &writer, const EnumModelItem &en)
@@ -79,10 +80,16 @@ static void formatXmlEnum(QXmlStreamWriter &writer, const EnumModelItem &en)
writer.writeEndElement();
}
+static bool useClass(const ClassModelItem &c)
+{
+ return c->classType() != CodeModel::Union && c->templateParameters().isEmpty()
+ && !c->name().isEmpty(); // No anonymous structs
+}
+
static void formatXmlScopeMembers(QXmlStreamWriter &writer, const ScopeModelItem &nsp)
{
for (const auto &klass : nsp->classes()) {
- if (klass->classType() != CodeModel::Union && klass->templateParameters().isEmpty())
+ if (useClass(klass))
formatXmlClass(writer, klass);
}
for (const auto &en : nsp->enums())
@@ -95,12 +102,20 @@ static bool isPublicCopyConstructor(const FunctionModelItem &f)
&& f->accessPolicy() == CodeModel::Public && !f->isDeleted();
}
+static void formatXmlLocationComment(QXmlStreamWriter &writer, const CodeModelItem &i)
+{
+ QString comment;
+ QTextStream(&comment) << ' ' << i->fileName() << ':' << i->startLine() << ' ';
+ writer.writeComment(comment);
+}
+
static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass)
{
// Heuristics for value types: check on public copy constructors.
const auto functions = klass->functions();
const bool isValueType = std::any_of(functions.cbegin(), functions.cend(),
isPublicCopyConstructor);
+ formatXmlLocationComment(writer, klass);
writer.writeStartElement(isValueType ? QStringLiteral("value-type")
: QStringLiteral("object-type"));
writer.writeAttribute(nameAttribute(), klass->name());
@@ -108,10 +123,51 @@ static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass
writer.writeEndElement();
}
+// Check whether a namespace is relevant for type system
+// output, that is, has non template classes, functions or enumerations.
+static bool hasMembers(const NamespaceModelItem &nsp)
+{
+ if (!nsp->namespaces().isEmpty() || !nsp->enums().isEmpty()
+ || !nsp->functions().isEmpty()) {
+ return true;
+ }
+ const auto classes = nsp->classes();
+ return std::any_of(classes.cbegin(), classes.cend(), useClass);
+}
+
+static void startXmlNamespace(QXmlStreamWriter &writer, const NamespaceModelItem &nsp)
+{
+ formatXmlLocationComment(writer, nsp);
+ writer.writeStartElement(QStringLiteral("namespace-type"));
+ writer.writeAttribute(nameAttribute(), nsp->name());
+}
+
static void formatXmlNamespaceMembers(QXmlStreamWriter &writer, const NamespaceModelItem &nsp)
{
- for (const auto &nested : nsp->namespaces())
- formatXmlNamespace(writer, nested);
+ auto nestedNamespaces = nsp->namespaces();
+ for (int i = nestedNamespaces.size() - 1; i >= 0; --i) {
+ if (!hasMembers(nestedNamespaces.at(i)))
+ nestedNamespaces.removeAt(i);
+ }
+ while (!nestedNamespaces.isEmpty()) {
+ auto current = nestedNamespaces.takeFirst();
+ startXmlNamespace(writer, current);
+ formatXmlNamespaceMembers(writer, current);
+ if (optJoinNamespaces) {
+ // Write out members of identical namespaces and remove
+ const QString name = current->name();
+ for (int i = 0; i < nestedNamespaces.size(); ) {
+ if (nestedNamespaces.at(i)->name() == name) {
+ formatXmlNamespaceMembers(writer, nestedNamespaces.at(i));
+ nestedNamespaces.removeAt(i);
+ } else {
+ ++i;
+ }
+ }
+ }
+ writer.writeEndElement();
+ }
+
for (auto func : nsp->functions()) {
const QString signature = func->typeSystemSignature();
if (!signature.contains(QLatin1String("operator"))) { // Skip free operators
@@ -123,14 +179,6 @@ static void formatXmlNamespaceMembers(QXmlStreamWriter &writer, const NamespaceM
formatXmlScopeMembers(writer, nsp);
}
-static void formatXmlNamespace(QXmlStreamWriter &writer, const NamespaceModelItem &nsp)
-{
- writer.writeStartElement(QStringLiteral("namespace-type"));
- writer.writeAttribute(nameAttribute(), nsp->name());
- formatXmlNamespaceMembers(writer, nsp);
- writer.writeEndElement();
-}
-
static void formatXmlOutput(const FileModelItem &dom)
{
QString output;
@@ -183,6 +231,10 @@ int main(int argc, char **argv)
QStringLiteral("Display debug output"));
parser.addOption(debugOption);
+ QCommandLineOption joinNamespacesOption({QStringLiteral("j"), QStringLiteral("join-namespaces")},
+ QStringLiteral("Join namespaces"));
+ parser.addOption(joinNamespacesOption);
+
QCommandLineOption languageLevelOption(QStringLiteral("std"),
languageLevelDescription(),
QStringLiteral("level"));
@@ -211,6 +263,8 @@ int main(int argc, char **argv)
}
}
+ optJoinNamespaces = parser.isSet(joinNamespacesOption);
+
const FileModelItem dom = AbstractMetaBuilderPrivate::buildDom(arguments, level, 0);
if (dom.isNull()) {
QString message = QLatin1String("Unable to parse ") + positionalArguments.join(QLatin1Char(' '));
diff --git a/sources/shiboken2/tests/libother/CMakeLists.txt b/sources/shiboken2/tests/libother/CMakeLists.txt
index 6aba91e13..d1e4c4354 100644
--- a/sources/shiboken2/tests/libother/CMakeLists.txt
+++ b/sources/shiboken2/tests/libother/CMakeLists.txt
@@ -5,12 +5,13 @@ number.cpp
otherderived.cpp
otherobjecttype.cpp
othermultiplederived.cpp
+smartptrtester.cpp
)
add_library(libother SHARED ${libother_SRC})
target_include_directories(libother PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(libother PRIVATE LIBOTHER_BUILD)
-target_link_libraries(libother PUBLIC libsample)
+target_link_libraries(libother PUBLIC libsample libsmart)
set_property(TARGET libother PROPERTY PREFIX "")
diff --git a/sources/shiboken2/tests/libother/otherobjecttype.cpp b/sources/shiboken2/tests/libother/otherobjecttype.cpp
index ca356ce94..1f782ecd8 100644
--- a/sources/shiboken2/tests/libother/otherobjecttype.cpp
+++ b/sources/shiboken2/tests/libother/otherobjecttype.cpp
@@ -34,3 +34,13 @@ operator<<(Collector& collector, const OtherObjectType& obj)
collector << obj.identifier()*2;
return collector;
}
+
+int OtherObjectType::enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value)
+{
+ return static_cast<int>(value);
+}
+
+int OtherObjectType::enumAsIntForInvisibleNamespace(Invisible::EnumOnNamespace value)
+{
+ return static_cast<int>(value);
+}
diff --git a/sources/shiboken2/tests/libother/otherobjecttype.h b/sources/shiboken2/tests/libother/otherobjecttype.h
index 22687c8bd..efd394347 100644
--- a/sources/shiboken2/tests/libother/otherobjecttype.h
+++ b/sources/shiboken2/tests/libother/otherobjecttype.h
@@ -35,11 +35,14 @@
#include "libothermacros.h"
#include "objecttype.h"
#include "collector.h"
+#include "samplenamespace.h"
-class OtherObjectType : public ObjectType
+
+class LIBOTHER_API OtherObjectType : public ObjectType
{
public:
-
+ static int enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value);
+ static int enumAsIntForInvisibleNamespace(Invisible::EnumOnNamespace value);
};
diff --git a/sources/shiboken2/tests/libother/smartptrtester.cpp b/sources/shiboken2/tests/libother/smartptrtester.cpp
new file mode 100644
index 000000000..9636c7521
--- /dev/null
+++ b/sources/shiboken2/tests/libother/smartptrtester.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "smartptrtester.h"
+
+SharedPtr<Str> SmartPtrTester::createSharedPtrStr(const char *what)
+{
+ return SharedPtr<Str>(new Str(what));
+}
+
+std::string SmartPtrTester::valueOfSharedPtrStr(const SharedPtr<Str> &str)
+{
+ return str->cstring();
+}
+
+SharedPtr<Integer> SmartPtrTester::createSharedPtrInteger(int v)
+{
+ auto i = SharedPtr<Integer>(new Integer);
+ i->m_int = v;
+ return i;
+}
+
+int SmartPtrTester::valueOfSharedPtrInteger(const SharedPtr<Integer> &v)
+{
+ return v->m_int;
+}
+
+void SmartPtrTester::fiddleInt(const SharedPtr<int> &) // no binding, should not cause errors
+{
+}
diff --git a/sources/shiboken2/tests/libother/smartptrtester.h b/sources/shiboken2/tests/libother/smartptrtester.h
new file mode 100644
index 000000000..a560bcf2f
--- /dev/null
+++ b/sources/shiboken2/tests/libother/smartptrtester.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SMARTPTRTESTER_H
+#define SMARTPTRTESTER_H
+
+#include "libothermacros.h"
+
+#include <smart.h>
+#include <str.h>
+
+class LIBOTHER_API SmartPtrTester
+{
+public:
+ SharedPtr<Str> createSharedPtrStr(const char *what);
+ std::string valueOfSharedPtrStr(const SharedPtr<Str> &);
+
+ SharedPtr<Integer> createSharedPtrInteger(int v);
+ int valueOfSharedPtrInteger(const SharedPtr<Integer> &);
+
+ void fiddleInt(const SharedPtr<int> &);
+};
+
+#endif // SMARTPTRTESTER_H
diff --git a/sources/shiboken2/tests/libsample/CMakeLists.txt b/sources/shiboken2/tests/libsample/CMakeLists.txt
index 170829fbc..ae13cd9f2 100644
--- a/sources/shiboken2/tests/libsample/CMakeLists.txt
+++ b/sources/shiboken2/tests/libsample/CMakeLists.txt
@@ -36,6 +36,7 @@ pointf.cpp
polygon.cpp
protected.cpp
reference.cpp
+renaming.cpp
sample.cpp
samplenamespace.cpp
sbkdate.cpp
diff --git a/sources/shiboken2/tests/libsample/modifications.cpp b/sources/shiboken2/tests/libsample/modifications.cpp
index 56ba81875..627d17b45 100644
--- a/sources/shiboken2/tests/libsample/modifications.cpp
+++ b/sources/shiboken2/tests/libsample/modifications.cpp
@@ -165,3 +165,22 @@ Modifications::TestEnum Modifications::defaultEnumValue() const
return TestEnumValue2;
}
+bool Modifications::wasGetAttroCalled() const
+{
+ return m_getAttroCalled;
+}
+
+void Modifications::notifyGetAttroCalled()
+{
+ m_getAttroCalled = true;
+}
+
+bool Modifications::wasSetAttroCalled() const
+{
+ return m_setAttroCalled;
+}
+
+void Modifications::notifySetAttroCalled()
+{
+ m_setAttroCalled = true;
+}
diff --git a/sources/shiboken2/tests/libsample/modifications.h b/sources/shiboken2/tests/libsample/modifications.h
index 674a05f27..888c66d18 100644
--- a/sources/shiboken2/tests/libsample/modifications.h
+++ b/sources/shiboken2/tests/libsample/modifications.h
@@ -132,9 +132,17 @@ public:
TestEnum enumValue() const;
TestEnum defaultEnumValue() const;
+ bool wasGetAttroCalled() const;
+ void notifyGetAttroCalled();
+
+ bool wasSetAttroCalled() const;
+ void notifySetAttroCalled();
+
private:
ObjectType* m_object;
TestEnum m_enumValue = TestEnumValue1;
+ bool m_getAttroCalled = false;
+ bool m_setAttroCalled = false;
};
class LIBSAMPLE_API AbstractModifications : public Modifications
diff --git a/sources/shiboken2/tests/libsample/renaming.cpp b/sources/shiboken2/tests/libsample/renaming.cpp
new file mode 100644
index 000000000..30586e1db
--- /dev/null
+++ b/sources/shiboken2/tests/libsample/renaming.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renaming.h"
+
+#include <iostream>
+
+int ToBeRenamedValue::value() const
+{
+ return m_value;
+}
+
+void ToBeRenamedValue::setValue(int v)
+{
+ m_value = v;
+}
+
+void RenamedUser::useRenamedValue(const ToBeRenamedValue &v)
+{
+ std::cout << __FUNCTION__ << ' ' << v.value() << '\n';
+}
diff --git a/sources/shiboken2/tests/libsample/renaming.h b/sources/shiboken2/tests/libsample/renaming.h
new file mode 100644
index 000000000..cd88b36bf
--- /dev/null
+++ b/sources/shiboken2/tests/libsample/renaming.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENAMING_H
+#define RENAMING_H
+
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API ToBeRenamedValue
+{
+public:
+ int value() const;
+ void setValue(int v);
+
+private:
+ int m_value = 42;
+};
+
+class LIBSAMPLE_API RenamedUser
+{
+public:
+ void useRenamedValue(const ToBeRenamedValue &v);
+};
+
+#endif // POINT_H
diff --git a/sources/shiboken2/tests/libsample/samplenamespace.h b/sources/shiboken2/tests/libsample/samplenamespace.h
index 6868b5f0a..9e46b2ad6 100644
--- a/sources/shiboken2/tests/libsample/samplenamespace.h
+++ b/sources/shiboken2/tests/libsample/samplenamespace.h
@@ -51,6 +51,13 @@ enum EnumOnNamespace {
Option3 = 3
};
+struct ObjectOnInvisibleNamespace
+{
+ bool exists() const { return true; }
+ static int toInt(EnumOnNamespace e) { return static_cast<int>(e); }
+ static ObjectOnInvisibleNamespace consume(const ObjectOnInvisibleNamespace &other) { return other; }
+};
+
};
namespace SampleNamespace
@@ -137,6 +144,8 @@ protected:
PublicScopedEnum protectedMethodReturningPublicScopedEnum() const;
};
+LIBSAMPLE_API inline int enumAsInt(SomeClass::PublicScopedEnum value) { return static_cast<int>(value); }
+
class DerivedFromNamespace : public SomeClass::SomeInnerClass::OkThisIsRecursiveEnough
{
public:
diff --git a/sources/shiboken2/tests/libsmart/smart.cpp b/sources/shiboken2/tests/libsmart/smart.cpp
index 6a4deb50a..81fa30c7e 100644
--- a/sources/shiboken2/tests/libsmart/smart.cpp
+++ b/sources/shiboken2/tests/libsmart/smart.cpp
@@ -93,7 +93,7 @@ Obj::~Obj()
void Obj::printObj() {
if (shouldPrint()) {
std::cout << "integer value: " << m_integer
- << " internal integer value: " << m_internalInteger->m_int << '\n';
+ << " internal integer value: " << m_internalInteger->value() << '\n';
}
}
@@ -134,6 +134,17 @@ int Obj::takeSharedPtrToObj(SharedPtr<Obj> pObj)
int Obj::takeSharedPtrToInteger(SharedPtr<Integer> pInt)
{
pInt->printInteger();
+ return pInt->value();
+}
+
+SharedPtr<const Integer> Obj::giveSharedPtrToConstInteger()
+{
+ SharedPtr<const Integer> co(new Integer);
+ return co;
+}
+
+int Obj::takeSharedPtrToConstInteger(SharedPtr<const Integer> pInt)
+{
return pInt->m_int;
}
@@ -173,7 +184,17 @@ Integer::~Integer()
std::cout << "Integer destructor " << this << '\n';
}
-void Integer::printInteger()
+int Integer::value() const
+{
+ return m_int;
+}
+
+void Integer::setValue(int v)
+{
+ m_int = v;
+}
+
+void Integer::printInteger() const
{
if (shouldPrint())
std::cout << "Integer value for object " << this << " is " << m_int << '\n';
diff --git a/sources/shiboken2/tests/libsmart/smart_integer.h b/sources/shiboken2/tests/libsmart/smart_integer.h
index 3756f68b0..126894120 100644
--- a/sources/shiboken2/tests/libsmart/smart_integer.h
+++ b/sources/shiboken2/tests/libsmart/smart_integer.h
@@ -37,8 +37,12 @@ public:
Integer(const Integer &other);
Integer &operator=(const Integer &other);
~Integer();
- void printInteger();
- int m_int;
+ void printInteger() const;
+
+ int value() const;
+ void setValue(int v);
+
+ int m_int; // public for testing member field access.
};
namespace Smart {
diff --git a/sources/shiboken2/tests/libsmart/smart_obj.h b/sources/shiboken2/tests/libsmart/smart_obj.h
index 12425366e..8fe45993f 100644
--- a/sources/shiboken2/tests/libsmart/smart_obj.h
+++ b/sources/shiboken2/tests/libsmart/smart_obj.h
@@ -48,12 +48,14 @@ public:
Integer takeInteger(Integer val);
SharedPtr<Obj> giveSharedPtrToObj();
std::vector<SharedPtr<Obj> > giveSharedPtrToObjList(int size);
- SharedPtr<Integer> giveSharedPtrToInteger();
+ virtual SharedPtr<Integer> giveSharedPtrToInteger(); // virtual for PYSIDE-1188
+ SharedPtr<const Integer> giveSharedPtrToConstInteger();
+ int takeSharedPtrToConstInteger(SharedPtr<const Integer> pInt);
SharedPtr<Smart::Integer2> giveSharedPtrToInteger2();
int takeSharedPtrToObj(SharedPtr<Obj> pObj);
int takeSharedPtrToInteger(SharedPtr<Integer> pInt);
- int m_integer;
+ int m_integer; // public for testing member field access.
Integer *m_internalInteger;
};
diff --git a/sources/shiboken2/tests/otherbinding/CMakeLists.txt b/sources/shiboken2/tests/otherbinding/CMakeLists.txt
index bc5c4bdad..05a282838 100644
--- a/sources/shiboken2/tests/otherbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/otherbinding/CMakeLists.txt
@@ -10,6 +10,8 @@ ${CMAKE_CURRENT_BINARY_DIR}/other/number_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/other/otherderived_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/other/othermultiplederived_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/other/otherobjecttype_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/other/sharedptr_str_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/other/smartptrtester_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/other/other_module_wrapper.cpp
)
@@ -28,8 +30,9 @@ COMMENT "Running generator for 'other' test binding..."
add_library(other MODULE ${other_SRC})
target_include_directories(other PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- ${sample_BINARY_DIR}/sample)
-target_link_libraries(other PUBLIC libother libsample libshiboken)
+ ${sample_BINARY_DIR}/sample
+ ${smart_BINARY_DIR}/smart)
+target_link_libraries(other PUBLIC libother libsample libsmart libshiboken)
set_property(TARGET other PROPERTY PREFIX "")
set_property(TARGET other PROPERTY OUTPUT_NAME "other${PYTHON_EXTENSION_SUFFIX}")
@@ -38,6 +41,6 @@ if(WIN32)
endif()
-add_dependencies(other sample)
+add_dependencies(other sample smart)
create_generator_target(other)
diff --git a/sources/shiboken2/tests/otherbinding/global.h b/sources/shiboken2/tests/otherbinding/global.h
index 0fccabb92..763566ae0 100644
--- a/sources/shiboken2/tests/otherbinding/global.h
+++ b/sources/shiboken2/tests/otherbinding/global.h
@@ -32,4 +32,5 @@
#include "otherderived.h"
#include "otherobjecttype.h"
#include "othermultiplederived.h"
+#include "smartptrtester.h"
diff --git a/sources/shiboken2/tests/otherbinding/other-binding.txt.in b/sources/shiboken2/tests/otherbinding/other-binding.txt.in
index a17b70fc1..dbe935a9f 100644
--- a/sources/shiboken2/tests/otherbinding/other-binding.txt.in
+++ b/sources/shiboken2/tests/otherbinding/other-binding.txt.in
@@ -8,11 +8,13 @@ typesystem-file = @other_TYPESYSTEM@
output-directory = @CMAKE_CURRENT_BINARY_DIR@
include-path = @libother_SOURCE_DIR@
+include-path = @libsmart_SOURCE_DIR@
include-path = @libsample_SOURCE_DIR@
include-path = @libsample_SOURCE_DIR@/..
typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@
typesystem-path = @sample_SOURCE_DIR@
+typesystem-path = @smart_SOURCE_DIR@
enable-parent-ctor-heuristic
diff --git a/sources/shiboken2/tests/otherbinding/signature_test.py b/sources/shiboken2/tests/otherbinding/signature_test.py
new file mode 100644
index 000000000..f3b712d04
--- /dev/null
+++ b/sources/shiboken2/tests/otherbinding/signature_test.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+'''Test cases for functions signature'''
+
+import os
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from shiboken_paths import init_paths
+init_paths()
+
+from other import OtherObjectType
+from shiboken_test_helper import objectFullname
+
+class SignatureTest(unittest.TestCase):
+
+ # Check if the argument of 'OtherObjectType::enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value)'
+ # has the correct representation
+ def testNamespaceFromOtherModule(self):
+ argType = OtherObjectType.enumAsInt.__signature__.parameters['value'].annotation
+ self.assertEqual(objectFullname(argType), 'sample.SampleNamespace.SomeClass.PublicScopedEnum')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken2/tests/otherbinding/smartptr_test.py b/sources/shiboken2/tests/otherbinding/smartptr_test.py
new file mode 100644
index 000000000..04f657757
--- /dev/null
+++ b/sources/shiboken2/tests/otherbinding/smartptr_test.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+'''Test cases for the SmartPtrTester class'''
+
+import os
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from shiboken_paths import init_paths
+init_paths()
+
+from smart import Integer
+from sample import Str
+from other import SmartPtrTester
+
+
+class SmartPtrTest(unittest.TestCase):
+ '''Test case for the SmartPtrTester class'''
+
+ def test(self):
+ tester = SmartPtrTester()
+
+ integerPtr = tester.createSharedPtrInteger(42)
+ self.assertEqual(tester.valueOfSharedPtrInteger(integerPtr), 42)
+
+ strPtr = tester.createSharedPtrStr('hello')
+ self.assertEqual(tester.valueOfSharedPtrStr(strPtr), 'hello')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken2/tests/otherbinding/typesystem_other.xml b/sources/shiboken2/tests/otherbinding/typesystem_other.xml
index 2932dafb3..78c4dd016 100644
--- a/sources/shiboken2/tests/otherbinding/typesystem_other.xml
+++ b/sources/shiboken2/tests/otherbinding/typesystem_other.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="other">
<load-typesystem name="typesystem_sample.xml" generate="no" />
+ <load-typesystem name="typesystem_smart.xml" generate="no" />
<object-type name="OtherObjectType" />
<object-type name="OtherDerived" />
@@ -9,6 +10,10 @@
<value-type name="ExtendsNoImplicitConversion" />
<value-type name="Number" />
+ <smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount"
+ instantiations="Str"/>
+ <value-type name="SmartPtrTester"/>
+
<suppress-warning text="signature 'operator!=(ByteArray,const char*)' for function modification in 'ByteArray' not found." />
<suppress-warning text="signature 'operator+(ByteArray,const char*)' for function modification in 'ByteArray' not found." />
<suppress-warning text="signature 'operator==(ByteArray,const char*)' for function modification in 'ByteArray' not found." />
diff --git a/sources/shiboken2/tests/samplebinding/CMakeLists.txt b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
index 61090d30e..b65068dc3 100644
--- a/sources/shiboken2/tests/samplebinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
@@ -94,6 +94,8 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/rect_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/rectf_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/reference_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/referentmodelindex_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/toberenamedvalue_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/renameduser_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sample_module_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sample_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sample_sample_wrapper.cpp
@@ -123,6 +125,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/filter_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/data_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/intersection_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/union_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/invisible_objectoninvisiblenamespace_wrapper.cpp
)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sample-binding.txt.in"
diff --git a/sources/shiboken2/tests/samplebinding/global.h b/sources/shiboken2/tests/samplebinding/global.h
index 3984102a8..f4e20b74f 100644
--- a/sources/shiboken2/tests/samplebinding/global.h
+++ b/sources/shiboken2/tests/samplebinding/global.h
@@ -75,6 +75,7 @@
#include "protected.h"
#include "rect.h"
#include "reference.h"
+#include "renaming.h"
#include "removednamespaces.h"
#include "sample.h"
#include "samplenamespace.h"
diff --git a/sources/shiboken2/tests/samplebinding/modifications_test.py b/sources/shiboken2/tests/samplebinding/modifications_test.py
index e6e9c5626..763ba04e5 100644
--- a/sources/shiboken2/tests/samplebinding/modifications_test.py
+++ b/sources/shiboken2/tests/samplebinding/modifications_test.py
@@ -235,6 +235,14 @@ class ModificationsTest(unittest.TestCase):
modifications.setEnumValue()
self.assertEqual(modifications.enumValue(), Modifications.TestEnumValue2)
+ def testSetGetAttro(self):
+ modifications = Modifications()
+ self.assertFalse(modifications.wasSetAttroCalled())
+ setattr(modifications, 'Foo', 'Bar')
+ self.assertTrue(modifications.wasSetAttroCalled())
+ self.assertEqual(getattr(modifications, 'Foo'), 'Bar')
+ self.assertTrue(modifications.wasGetAttroCalled())
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/namespace_test.py b/sources/shiboken2/tests/samplebinding/namespace_test.py
index aeaf81cff..23480d4c4 100644
--- a/sources/shiboken2/tests/samplebinding/namespace_test.py
+++ b/sources/shiboken2/tests/samplebinding/namespace_test.py
@@ -40,12 +40,17 @@ from shiboken_paths import init_paths
init_paths()
from sample import *
+from shiboken_test_helper import objectFullname
class TestEnumUnderNamespace(unittest.TestCase):
def testInvisibleNamespace(self):
o1 = EnumOnNamespace.Option1
self.assertEqual(o1, 1)
+ def testTpNames(self):
+ self.assertEqual(objectFullname(EnumOnNamespace), "sample.EnumOnNamespace")
+ self.assertEqual(str(EnumOnNamespace.Option1),
+ "sample.EnumOnNamespace.Option1")
class TestClassesUnderNamespace(unittest.TestCase):
def testIt(self):
@@ -72,5 +77,19 @@ class TestClassesUnderNamespace(unittest.TestCase):
self.assertEqual(str(SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum),
"<class 'sample.SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum'>")
+ # Test if enum inside of class is correct represented
+ self.assertEqual(objectFullname(SampleNamespace.enumInEnumOut.__signature__.parameters['in_'].annotation),
+ "sample.SampleNamespace.InValue")
+ self.assertEqual(objectFullname(SampleNamespace.enumAsInt.__signature__.parameters['value'].annotation),
+ "sample.SampleNamespace.SomeClass.PublicScopedEnum")
+ self.assertEqual(objectFullname(ObjectOnInvisibleNamespace.toInt.__signature__.parameters['e'].annotation),
+ "sample.EnumOnNamespace")
+
+ # Test if enum on namespace that was marked as not gerenated does not appear on type name
+ self.assertEqual(objectFullname(ObjectOnInvisibleNamespace),
+ "sample.ObjectOnInvisibleNamespace")
+ self.assertEqual(objectFullname(ObjectOnInvisibleNamespace.consume.__signature__.parameters['other'].annotation),
+ "sample.ObjectOnInvisibleNamespace")
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/renaming_test.py b/sources/shiboken2/tests/samplebinding/renaming_test.py
new file mode 100644
index 000000000..cb59dce3a
--- /dev/null
+++ b/sources/shiboken2/tests/samplebinding/renaming_test.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+'''Test cases for renaming using target-lang-name attribute.'''
+
+import os
+import re
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from shiboken_paths import init_paths
+init_paths()
+
+from sample import RenamedValue, RenamedUser
+
+class RenamingTest(unittest.TestCase):
+ def test(self):
+ '''Tests whether the C++ class ToBeRenamedValue renamed via attribute
+ target-lang-name to RenamedValue shows up in consuming function
+ signature strings correctly.
+ '''
+ renamed_value = RenamedValue()
+ self.assertEqual(str(type(renamed_value)),
+ "<class 'sample.RenamedValue'>")
+ rename_user = RenamedUser()
+ rename_user.useRenamedValue(renamed_value)
+ actual_signature = str(rename_user.useRenamedValue.__signature__)
+ self.assertTrue(re.match(r"^\(self,\s*v:\s*sample.RenamedValue\)$",
+ actual_signature))
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 3aaecf247..3cd318ceb 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -543,8 +543,9 @@
<enum-type identified-by-value="AnonymousGlobalEnum_Value0"/>
- <namespace-type name="Invisible" generate="no">
+ <namespace-type name="Invisible" visible="no">
<enum-type name="EnumOnNamespace" />
+ <value-type name="ObjectOnInvisibleNamespace" />
</namespace-type>
<namespace-type name="SampleNamespace">
@@ -1292,6 +1293,16 @@
<replace-default-expression with="cppSelf->defaultEnumValue()"/>
</modify-argument>
</modify-function>
+ <add-function signature="__getattro__" return-type="PyObject *">
+ <inject-code class="target" position="beginning">
+ cppSelf->notifyGetAttroCalled();
+ </inject-code>
+ </add-function>
+ <add-function signature="__setattro__" return-type="int">
+ <inject-code class="target" position="beginning">
+ cppSelf->notifySetAttroCalled();
+ </inject-code>
+ </add-function>
</object-type>
<object-type name="AbstractModifications">
@@ -2433,6 +2444,9 @@
<modify-function signature="dummy(std::list&lt;std::pair&lt;BlackBox *, BlackBox *&gt; &gt; &amp;)" rename="dummy_method" />
</object-type>
+ <value-type name="ToBeRenamedValue" target-lang-name="RenamedValue"/>
+ <value-type name="RenamedUser"/>
+
<suppress-warning text="horribly broken type '__off64_t'" />
<suppress-warning text="enum '__codecvt_result' does not have a type entry or is not an enum" />
<suppress-warning text="Pure virtual method &quot;Abstract::hideFunction(HideType*)&quot; must be implement but was completely removed on typesystem." />
diff --git a/sources/shiboken2/tests/shiboken_test_helper.py b/sources/shiboken2/tests/shiboken_test_helper.py
new file mode 100644
index 000000000..793baf4ad
--- /dev/null
+++ b/sources/shiboken2/tests/shiboken_test_helper.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+
+def objectFullname(t):
+ # '__qualname__' for Python 2 does exist for PySide types, only.
+ name = getattr(t, "__qualname__", t.__name__)
+ module = t.__module__
+ if module is None or module == str.__class__.__module__:
+ return name
+ else:
+ return module + '.' + name
diff --git a/sources/shiboken2/tests/smartbinding/smart_pointer_test.py b/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
index 6210916d3..50b2120a2 100644
--- a/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
+++ b/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
@@ -128,6 +128,10 @@ class SmartPointerTests(unittest.TestCase):
self.assertEqual(integer.m_int, 50)
# Set and get a member value via shared pointer (like operator->).
+ ptrToInteger.setValue(150)
+ self.assertEqual(ptrToInteger.value(), 150)
+
+ # Set and get a member field via shared pointer (like operator->).
ptrToInteger.m_int = 100
self.assertEqual(ptrToInteger.m_int, 100)
@@ -155,6 +159,18 @@ class SmartPointerTests(unittest.TestCase):
self.assertEqual(objCount(), 0)
self.assertEqual(integerCount(), 0)
+ def testConstIntegerSmartPointer(self):
+ # Uncomment to see more debug info about creation of objects and ref counts.
+ # Registry.getInstance().setShouldPrint(True)
+
+ # Create Obj.
+ o = Obj()
+ ptrToConstInteger = o.giveSharedPtrToConstInteger()
+ self.assertEqual(ptrToConstInteger.m_int, 456)
+ result = o.takeSharedPtrToConstInteger(ptrToConstInteger)
+ self.assertEqual(result, 456)
+ self.assertEqual(ptrToConstInteger.value(), 456)
+
def testSmartPointersWithNamespace(self):
# Create the main object
o = Obj()
diff --git a/sources/shiboken2/tests/smartbinding/typesystem_smart.xml b/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
index 0bb485957..8fb3082a0 100644
--- a/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
+++ b/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
@@ -43,7 +43,8 @@
possible to explicitly instantiate a new shared pointer in python e.g. o = SharedPtr_Foo()
won't work.
-->
- <smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount" />
+ <smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount"
+ instantiations="Integer,Smart::Integer2,Obj"/>
<object-type name="Obj" />
<value-type name="Integer" />
diff --git a/sources/shiboken2/tests/test_generator/CMakeLists.txt b/sources/shiboken2/tests/test_generator/CMakeLists.txt
index 5f5099897..07611e32c 100644
--- a/sources/shiboken2/tests/test_generator/CMakeLists.txt
+++ b/sources/shiboken2/tests/test_generator/CMakeLists.txt
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
project(test_generator)
set(dummy_generator_SRC dummygenerator.cpp)
@@ -8,7 +9,7 @@ set_property(TARGET dummy_generator PROPERTY PREFIX "")
add_executable(dummygenerator main.cpp)
set(DUMMYGENERATOR_EXECUTABLE dummygenerator${generator_SUFFIX})
set_target_properties(dummygenerator PROPERTIES OUTPUT_NAME ${DUMMYGENERATOR_EXECUTABLE})
-target_link_libraries(dummygenerator ${Qt5Core_LIBRARIES})
+target_link_libraries(dummygenerator ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES})
configure_file(dummygentestconfig.h.in "${CMAKE_CURRENT_BINARY_DIR}/dummygentestconfig.h" @ONLY)
@@ -32,15 +33,8 @@ if(WIN32)
endif()
macro(m_add_test testname)
- if(CMAKE_VERSION VERSION_LESS 2.8)
- add_test(${testname} ${CMAKE_COMMAND} -DTEST=${testname}
- -DWORKDIR=${CMAKE_CURRENT_BINARY_DIR}
- -DENV_PATH=${ENV_PATH} -DENV_QT_PLUGIN_PATH=${ENV_QT_PLUGIN_PATH}
- -P ${CMAKE_CURRENT_SOURCE_DIR}/run_test.cmake)
- else()
- add_test(${testname} ${testname})
- set_property(TEST ${testname} PROPERTY ENVIRONMENT "PATH=${ENV_PATH}" "QT_PLUGIN_PATH=${ENV_QT_PLUGIN_PATH}")
- endif()
+ add_test(${testname} ${testname})
+ set_property(TEST ${testname} PROPERTY ENVIRONMENT "PATH=${ENV_PATH}" "QT_PLUGIN_PATH=${ENV_QT_PLUGIN_PATH}")
endmacro()
macro(declare_test testname)
@@ -50,8 +44,8 @@ macro(declare_test testname)
target_link_libraries(${testname}
${QT_QTTEST_LIBRARY}
${QT_QTCORE_LIBRARY}
- ${Qt5Test_LIBRARIES}
- ${Qt5Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Test_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
)
m_add_test(${testname})
endmacro(declare_test testname)
diff --git a/tools/dump_metaobject.py b/tools/dump_metaobject.py
new file mode 100644
index 000000000..873d90e65
--- /dev/null
+++ b/tools/dump_metaobject.py
@@ -0,0 +1,155 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python project.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""Helper functions for formatting information on QMetaObject"""
+
+from PySide2.QtCore import (QMetaClassInfo, QMetaEnum, QMetaMethod,
+ QMetaProperty, QMetaObject, QObject)
+
+
+def _qbytearray_to_string(b):
+ return bytes(b.data()).decode('utf-8')
+
+
+def _dump_metaobject_helper(meta_obj, indent):
+ print('{}class {}:'.format(indent, meta_obj.className()))
+ indent += ' '
+
+ info_offset = meta_obj.classInfoOffset()
+ info_count = meta_obj.classInfoCount()
+ if info_offset < info_count:
+ print('{}Info:'.format(indent))
+ for i in range(info_offset, info_count):
+ name = meta_obj.classInfo(i).name()
+ value = meta_obj.classInfo(i).value()
+ print('{}{:4d} {}+{}'.format(indent, i, name, value))
+
+ enumerator_offset = meta_obj.enumeratorOffset()
+ enumerator_count = meta_obj.enumeratorCount()
+ if enumerator_offset < enumerator_count:
+ print('{}Enumerators:'.format(indent))
+ for e in range(enumerator_offset, enumerator_count):
+ meta_enum = meta_obj.enumerator(e)
+ name = meta_enum.name()
+ value_str = ''
+ descr = ''
+ if meta_enum.isFlag():
+ descr += ' flag'
+ if meta_enum.isScoped():
+ descr += ' scoped'
+ for k in range(0, meta_enum.keyCount()):
+ if k > 0:
+ value_str += ', '
+ value_str += '{} = {}'.format(meta_enum.key(k),
+ meta_enum.value(k))
+ print('{}{:4d} {}{} ({})'.format(indent, e, name, descr,
+ value_str))
+
+ property_offset = meta_obj.propertyOffset()
+ property_count = meta_obj.propertyCount()
+ if property_offset < property_count:
+ print('{}Properties:'.format(indent))
+ for p in range(property_offset, property_count):
+ meta_property = meta_obj.property(p)
+ name = meta_property.name()
+ desc = ''
+ if meta_property.isConstant():
+ desc += ', constant'
+ if meta_property.isDesignable:
+ desc += ', designable'
+ if meta_property.isFlagType:
+ desc += ', flag'
+ if meta_property.isEnumType():
+ desc += ', enum'
+ if meta_property.isStored():
+ desc += ', stored'
+ if meta_property.isWritable():
+ desc += ', writable'
+ if meta_property.isResettable:
+ desc += ', resettable'
+ if meta_property.hasNotifySignal():
+ notify_name = meta_property.notifySignal().name()
+ desc += ', notify={}'.format(_qbytearray_to_string(notify_name))
+ print('{}{:4d} {} {}{}'.format(indent, p, meta_property.typeName(),
+ name, desc))
+
+ method_offset = meta_obj.methodOffset()
+ method_count = meta_obj.methodCount()
+ if method_offset < method_count:
+ print('{}Methods:'.format(indent))
+ for m in range(method_offset, method_count):
+ method = meta_obj.method(m)
+ signature = _qbytearray_to_string(method.methodSignature())
+ access = ''
+ if method.access() == QMetaMethod.Protected:
+ access += 'protected '
+ elif method.access() == QMetaMethod.Private:
+ access += 'private '
+ type = method.methodType()
+ typeString = ''
+ if type == QMetaMethod.Signal:
+ typeString = ' (Signal)'
+ elif type == QMetaMethod.Slot:
+ typeString = ' (Slot)'
+ elif type == QMetaMethod.Constructor:
+ typeString = ' (Ct)'
+ desc = '{}{:4d} {}{} {}{}'.format(indent, m, access,
+ method.typeName(), signature,
+ typeString)
+ parameter_names = method.parameterNames()
+ if parameter_names:
+ parameter_types = method.parameterTypes()
+ desc += ' Parameters:'
+ for p, bname in enumerate(parameter_names):
+ name = _qbytearray_to_string(bname)
+ type = _qbytearray_to_string(parameter_types[p])
+ desc += ' {}: {}'.format(name if name else '<unnamed>', type)
+ print(desc)
+
+
+def dump_metaobject(meta_obj):
+ super_classes = [meta_obj]
+ super_class = meta_obj.superClass()
+ while super_class:
+ super_classes.append(super_class)
+ super_class = super_class.superClass()
+ indent = ''
+ for c in reversed(super_classes):
+ _dump_metaobject_helper(c, indent)
+ indent += ' '
diff --git a/tools/metaobject_dump.py b/tools/metaobject_dump.py
new file mode 100644
index 000000000..6c7a9f7df
--- /dev/null
+++ b/tools/metaobject_dump.py
@@ -0,0 +1,67 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python project.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+from dump_metaobject import dump_metaobject
+
+# Import all widget classes to enable instantiating them by type name
+from PySide2.QtWidgets import *
+
+
+DESC = """
+metaobject_dump.py <class_name>
+
+Dumps the QMetaObject of a class
+
+Example: metaobject_dump QLabel
+"""
+
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ print(DESC)
+ sys.exit(0)
+ app = QApplication(sys.argv)
+
+ type_name = sys.argv[1]
+ type_instance = eval(type_name)
+ if not type_instance:
+ print('Invalid type {}'.format(type_name))
+ sys.exit(1)
+ dump_metaobject(type_instance.staticMetaObject)
diff --git a/tools/metaobject_dump.pyproject b/tools/metaobject_dump.pyproject
new file mode 100644
index 000000000..f6d85b571
--- /dev/null
+++ b/tools/metaobject_dump.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["metaobject_dump.py", "dump_metaobject.py"]
+}
diff --git a/tools/missing_bindings-requirements.txt b/tools/missing_bindings-requirements.txt
new file mode 100644
index 000000000..4ddb60aa8
--- /dev/null
+++ b/tools/missing_bindings-requirements.txt
@@ -0,0 +1,7 @@
+pyside2
+pyqt5
+beautifulsoup4
+pyqt3d
+pyqtchart
+pyqtdatavisualization
+pyqtwebengine
diff --git a/tools/missing_bindings.py b/tools/missing_bindings.py
index a4a418a6e..33a296832 100644
--- a/tools/missing_bindings.py
+++ b/tools/missing_bindings.py
@@ -115,6 +115,7 @@ modules_to_test['QtPositioning'] = 'qtpositioning-module.html'
modules_to_test['QtRemoteObjects'] = 'qtremoteobjects-module.html'
modules_to_test['QtScriptTools'] = 'qtscripttools-module.html'
modules_to_test['QtSensors'] = 'qtsensors-module.html'
+modules_to_test['QtSerialPort'] = 'qtserialport-module.html'
types_to_ignore = set()
# QtCore
types_to_ignore.add('QFlag')
@@ -226,7 +227,8 @@ qt_documentation_website_prefixes['5.11'] = 'http://doc.qt.io/qt-5.11/'
qt_documentation_website_prefixes['5.11'] = 'http://doc.qt.io/qt-5.11/'
qt_documentation_website_prefixes['5.12'] = 'http://doc.qt.io/qt-5.12/'
qt_documentation_website_prefixes['5.13'] = 'http://doc.qt.io/qt-5.13/'
-qt_documentation_website_prefixes['5.14'] = 'http://doc.qt.io/qt-5/'
+qt_documentation_website_prefixes['5.14'] = 'http://doc.qt.io/qt-5.14/'
+qt_documentation_website_prefixes['5.15'] = 'http://doc.qt.io/qt-5/'
qt_documentation_website_prefixes['dev'] = 'http://doc-snapshots.qt.io/qt5-dev/'
@@ -249,8 +251,8 @@ parser.add_argument("module",
help="the Qt module for which to get the missing types")
parser.add_argument("--qt-version",
"-v",
- default='5.12',
- choices=['5.6', '5.9', '5.11', '5.12', '5.13', '5.14', 'dev'],
+ default='5.15',
+ choices=['5.6', '5.9', '5.11', '5.12', '5.13', '5.14', '5.15', 'dev'],
type=str,
dest='version',
help="the Qt version to use to check for types")