diff options
Diffstat (limited to 'sources')
247 files changed, 9290 insertions, 3120 deletions
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..0cdd5e2f7 100644 --- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml +++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml @@ -789,7 +789,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"/> @@ -1541,7 +1541,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<QAbstractProxyModel*>(%1)"> <extra-includes> @@ -2342,6 +2342,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*)"> 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.h b/sources/pyside2/PySide2/QtQuickControls2/typesystem_quickcontrols2.xml index dedcca662..51d42b46b 100644 --- a/sources/pyside2/libpyside/destroylistener.h +++ 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,37 +38,10 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +--> +<typesystem package="PySide2.QtQuickControls2"> + <load-typesystem name="QtQuick/typesystem_quick.xml" generate="no"/> -#ifndef PYSIDE_DESTROY_LISTENER -#define PYSIDE_DESTROY_LISTENER - -#include "pysidemacros.h" - -#include <QtCore/QObject> - -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); - - public Q_SLOTS: - void onObjectDestroyed(QObject *obj); - - private: - static DestroyListener *m_instance; - DestroyListenerPrivate *m_d; - DestroyListener(QObject *parent); - ~DestroyListener() override; -}; - -}//namespace - -#endif + <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/libpyside/destroylistener.cpp b/sources/pyside2/PySide2/QtSerialPort/typesystem_serialport.xml index 319a126cf..8548c543e 100644 --- a/sources/pyside2/libpyside/destroylistener.cpp +++ b/sources/pyside2/PySide2/QtSerialPort/typesystem_serialport.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,19 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - -#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 - +--> +<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& @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: - # (<class '__main__.Ui_ThemeWidgetForm'>, <class 'PySide2.QtWidgets.QWidget'>) - - - 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..1e9d9636e 100644 --- a/sources/pyside2/PySide2/glue/qtcore.cpp +++ b/sources/pyside2/PySide2/glue/qtcore.cpp @@ -1288,6 +1288,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 +1697,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> </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 %} {% 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 Binary files differnew file mode 100644 index 000000000..b45830e00 --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/fakebar.png diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg Binary files differnew file mode 100644 index 000000000..cd474efba --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png Binary files differnew file mode 100644 index 000000000..3bc03b7c7 --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/minus.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/minus.png Binary files differnew file mode 100644 index 000000000..da1c5620d --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/minus.png diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/plus.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/plus.png Binary files differnew file mode 100644 index 000000000..b3cb37425 --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/plus.png 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 Binary files differnew file mode 100644 index 000000000..3a2f2bd17 --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png Binary files differnew file mode 100644 index 000000000..4036733a7 --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png 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/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 Binary files differnew file mode 100644 index 000000000..0bcfd7d77 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/icons.png diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/forward.png b/sources/pyside2/doc/tutorials/basictutorial/icons/forward.png Binary files differnew file mode 100644 index 000000000..c7a532dfe --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/icons/forward.png diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/pause.png b/sources/pyside2/doc/tutorials/basictutorial/icons/pause.png Binary files differnew file mode 100644 index 000000000..d0beadb43 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/icons/pause.png diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/play.png b/sources/pyside2/doc/tutorials/basictutorial/icons/play.png Binary files differnew file mode 100644 index 000000000..345685337 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/icons/play.png diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/previous.png b/sources/pyside2/doc/tutorials/basictutorial/icons/previous.png Binary files differnew file mode 100644 index 000000000..979f18565 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/icons/previous.png diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/stop.png b/sources/pyside2/doc/tutorials/basictutorial/icons/stop.png Binary files differnew file mode 100644 index 000000000..1e88ded3a --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/icons/stop.png diff --git a/sources/pyside2/doc/tutorials/basictutorial/player-new.png b/sources/pyside2/doc/tutorials/basictutorial/player-new.png Binary files differnew file mode 100644 index 000000000..e1f660e5f --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/player-new.png diff --git a/sources/pyside2/doc/tutorials/basictutorial/player.png b/sources/pyside2/doc/tutorials/basictutorial/player.png Binary files differnew file mode 100644 index 000000000..3060a990d --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/player.png 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..11342ec71 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,11 +38,8 @@ 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 @@ -54,7 +51,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 +80,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 +92,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 +100,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,7 +123,6 @@ endif() # set(libpyside_HEADERS - destroylistener.h dynamicqmetaobject.h pysideclassinfo.h pysidemacros.h diff --git a/sources/pyside2/libpyside/pyside.cpp b/sources/pyside2/libpyside/pyside.cpp index e2b8708ce..4a554de58 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) @@ -271,11 +268,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/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..39ed1a6bc 100644 --- a/sources/pyside2/libpyside/pysidesignal.cpp +++ b/sources/pyside2/libpyside/pysidesignal.cpp @@ -805,32 +805,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 +888,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/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..310a751e0 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 @@ -595,8 +623,22 @@ long clang_EnumDecl_isScoped4(BaseVisitor *bv, const CXCursor &cursor) // 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. + // Note: spelling has "struct baseClass", use type + QString baseClassName; + const CXType inheritedType = clang_getCursorType(cursor); + if (inheritedType.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(inheritedType); + 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(inheritedType); + const CXCursor declCursor = clang_getTypeDeclaration(inheritedType); const CursorClassHash::const_iterator it = m_cursorClassHash.constFind(declCursor); const CodeModel::AccessPolicy access = accessPolicy(clang_getCXXAccessSpecifier(cursor)); @@ -695,6 +737,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 +768,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 +800,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 +833,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 +982,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 +1001,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 +1030,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 +1047,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 +1138,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/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/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 ¤tPath 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..920da9e10 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -144,7 +144,7 @@ ComplexTypeEntry::ComplexTypeEntry(const ComplexTypeEntry &) = default; QString ContainerTypeEntry::qualifiedCppName() const { - if (m_type == StringListContainer) + if (m_containerKind == StringListContainer) return QLatin1String("QStringList"); return ComplexTypeEntry::qualifiedCppName(); } @@ -433,7 +433,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 +595,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 +684,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 +702,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 +723,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 +773,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 +928,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 +956,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 +987,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 +1010,6 @@ bool ValueTypeEntry::isValue() const return true; } -bool ValueTypeEntry::isNativeIdBased() const -{ - return true; -} - TypeEntry *ValueTypeEntry::clone() const { return new ValueTypeEntry(*this); @@ -1122,30 +1157,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,16 +1178,6 @@ 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); diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index 4d0a23ca1..6d2d4bb44 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -228,7 +228,7 @@ struct ArgumentModification struct Modification { - enum Modifiers { + enum Modifiers : uint { InvalidModifier = 0x0000, Private = 0x0001, Protected = 0x0002, @@ -499,7 +499,6 @@ QDebug operator<<(QDebug d, const AddedFunction::Argument &a); QDebug operator<<(QDebug d, const AddedFunction &af); #endif -class InterfaceTypeEntry; class ObjectTypeEntry; class DocModification @@ -562,20 +561,13 @@ public: EnumValue, ConstantValueType, TemplateArgumentType, - ThreadType, BasicValueType, - StringType, ContainerType, - InterfaceType, ObjectType, NamespaceType, - VariantType, - JObjectWrapperType, - CharType, ArrayType, TypeSystemType, CustomType, - TargetLangType, FunctionType, SmartPointerType, TypedefType @@ -605,7 +597,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 +614,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 +630,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 +646,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 +675,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 +735,6 @@ public: QString qualifiedTargetLangName() const; - virtual InterfaceTypeEntry *designatedInterface() const - { - return nullptr; - } - void setCustomConstructor(const CustomFunction &func) { m_customConstructor = func; @@ -798,11 +762,6 @@ public: return false; } - virtual bool isNativeIdBased() const - { - return false; - } - CodeSnipList codeSnips() const; void setCodeSnips(const CodeSnipList &codeSnips) { @@ -896,7 +855,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 +1406,7 @@ class ContainerTypeEntry : public ComplexTypeEntry { Q_GADGET public: - enum Type { + enum ContainerKind { NoContainer, ListContainer, StringListContainer, @@ -1461,14 +1421,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 +1443,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 +1470,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 +1484,7 @@ private: QString m_getterName; QString m_smartPointerType; QString m_refCountMethodName; + Instantiations m_instantiations; }; class NamespaceTypeEntry : public ComplexTypeEntry @@ -1535,6 +1505,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 +1524,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 +1537,6 @@ public: bool isValue() const override; - bool isNativeIdBased() const override; - TypeEntry *clone() const override; protected: @@ -1566,39 +1545,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 +1581,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..9fdf81821 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"); } @@ -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 @@ -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> </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 %} {% 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 Binary files differnew file mode 100644 index 000000000..b45830e00 --- /dev/null +++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/fakebar.png diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg Binary files differnew file mode 100644 index 000000000..cd474efba --- /dev/null +++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png Binary files differnew file mode 100644 index 000000000..3bc03b7c7 --- /dev/null +++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/minus.png b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/minus.png Binary files differnew file mode 100644 index 000000000..da1c5620d --- /dev/null +++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/minus.png diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/plus.png b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/plus.png Binary files differnew file mode 100644 index 000000000..b3cb37425 --- /dev/null +++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/plus.png 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 Binary files differnew file mode 100644 index 000000000..3a2f2bd17 --- /dev/null +++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png diff --git a/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png Binary files differnew file mode 100644 index 000000000..4036733a7 --- /dev/null +++ b/sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png 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..88ba1f04f 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 @@ -529,7 +570,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 +711,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 +768,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 +940,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 25daea99e..476e176d3 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..4c637e701 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,6 @@ 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 <qapp_macro.h>\n\n" << "QT_WARNING_DISABLE_DEPRECATED\n\n"; } @@ -332,6 +328,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 +339,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 +361,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 +381,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 +394,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 +418,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 +555,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 +582,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 +637,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 +668,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 +682,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 +728,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 +762,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 +780,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 +837,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 +848,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 +858,20 @@ 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; + s << Qt::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,7 @@ 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; + s << Qt::endl; } if (func->isAbstract()) { @@ -962,7 +987,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 +1005,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, } } } - s << endl; + s << Qt::endl; CodeSnipList snips; if (func->hasInjectedCode()) { @@ -991,7 +1016,7 @@ 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; + s << Qt::endl; } if (!injectedCodeCallsPythonOverride(func)) { @@ -1004,7 +1029,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 +1051,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 +1072,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 +1115,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 +1141,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 +1160,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 +1174,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 +1243,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 +1285,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 +1323,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"; @@ -1332,12 +1360,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 +1376,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 +1412,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 +1507,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 +1561,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 +1638,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 +1662,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"; @@ -1685,7 +1715,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 +1766,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 +1785,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 +1824,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 +1853,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 +1867,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 +1893,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 +1956,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 +1990,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 +2003,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 +2016,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 +2029,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 +2047,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 +2066,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 +2086,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 +2160,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 +2180,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 +2189,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 +2455,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 +2518,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 +2537,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 +2568,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 +2584,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 +2610,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 +2667,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 +2691,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 +2701,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 +2717,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 +2740,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 +2752,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 +2761,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 +2795,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); @@ -2916,7 +2950,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 +2962,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, @@ -3036,15 +3070,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 +3109,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 +3183,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 +3205,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 +3232,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f } writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode, func, lastArg); - s << endl; + s << Qt::endl; } writeConversionRule(s, func, TypeSystem::NativeCode); @@ -3283,14 +3317,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 +3332,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 +3354,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f << ctorCall << ";\n" << INDENT << "PySide::setNextQObjectMemoryAddr(0);" - << endl; + << Qt::endl; } uva << INDENT << "} else {\n"; { @@ -3410,7 +3447,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 +3458,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()) { @@ -3487,7 +3524,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f } if (func->hasInjectedCode() && !func->isConstructor()) { - s << endl; + s << Qt::endl; writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode, func, lastArg); } @@ -3512,12 +3549,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 +3577,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 +3597,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 +3668,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 +3738,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 +3823,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 +3905,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 +3938,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 +4008,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 +4037,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 +4080,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 +4110,7 @@ void CppGenerator::writeMappingMethods(QTextStream &s, void CppGenerator::writeSequenceMethods(QTextStream &s, const AbstractMetaClass *metaClass, - GeneratorContext &context) + const GeneratorContext &context) { bool injectedCode = false; @@ -4095,13 +4129,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 +4296,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 +4314,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 +4334,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 +4401,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 +4438,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 +4453,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 +4464,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 +4476,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 +4486,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 +4521,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 +4581,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 +4625,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 +4646,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 +4656,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 +4683,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 +4716,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 +4724,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 +4763,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 +4773,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 +4804,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 +4872,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 +4896,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 +4967,42 @@ 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)) + s << INDENT << "R\"CPP(" << line << ")CPP\",\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"; @@ -5555,19 +5640,18 @@ bool CppGenerator::finishGeneration() 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 +5659,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"; @@ -5598,7 +5682,7 @@ bool CppGenerator::finishGeneration() // module inject-code native/beginning if (!snips.isEmpty()) { writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode); - s << endl; + s << Qt::endl; } // cleanup staticMetaObject attribute @@ -5623,7 +5707,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 +5715,7 @@ bool CppGenerator::finishGeneration() s << "// Classes initialization functions "; s << "------------------------------------------------------------\n"; - s << classInitDecl << endl; + s << classInitDecl << Qt::endl; if (!globalEnums.isEmpty()) { QString converterImpl; @@ -5643,14 +5727,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 +5746,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 +5766,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 +5782,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,13 +5808,7 @@ 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"; @@ -5738,7 +5816,7 @@ bool CppGenerator::finishGeneration() // module inject-code target/beginning if (!snips.isEmpty()) { writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode); - s << endl; + s << Qt::endl; } for (const QString &requiredModule : requiredModules) { @@ -5785,26 +5863,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 +5897,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 +5905,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"; @@ -5843,13 +5921,13 @@ bool CppGenerator::finishGeneration() // module inject-code target/end if (!snips.isEmpty()) { writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode); - s << endl; + s << Qt::endl; } // module inject-code native/end if (!snips.isEmpty()) { writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode); - s << endl; + s << Qt::endl; } if (usePySideExtensions()) { @@ -5866,7 +5944,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 +6050,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 +6081,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 +6118,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 +6132,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..fe0d2765c 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,16 +1743,30 @@ 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; - processCodeSnip(code, context); + processClassCodeSnip(code, context); + s << INDENT << "// Begin code injection\n"; + s << code; + s << INDENT << "// End of code injection\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); s << INDENT << "// Begin code injection\n"; s << code; s << INDENT << "// End of code injection\n"; @@ -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..443d25cdf 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 @@ -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/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp index 36f2f48f9..f9a43845a 100644 --- a/sources/shiboken2/libshiboken/sbkenum.cpp +++ b/sources/shiboken2/libshiboken/sbkenum.cpp @@ -720,11 +720,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 +734,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/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<std::pair<BlackBox *, BlackBox *> > &)" 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 "Abstract::hideFunction(HideType*)" 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) |