summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-12-04 01:00:23 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-12-04 01:00:23 +0100
commit0c29ebe374caad7e29c6a3d35c72c4eddaacc6af (patch)
treec6b228302ab37375a82f7bfb535e5bb39d36e624
parente5438e8ded27eb6f7f0e85704d6843069296c698 (diff)
parent2ed59f0d42d2817a5855be167f5e3ccf23563e39 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
-rw-r--r--examples/widgets/doc/src/styles.qdoc1
-rw-r--r--examples/widgets/widgets/styles/widgetgallery.cpp14
-rw-r--r--mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in34
-rw-r--r--mkspecs/features/qt_docs.prf3
-rw-r--r--mkspecs/features/testcase.prf3
-rw-r--r--src/corelib/Qt5CoreMacros.cmake111
-rw-r--r--src/corelib/codecs/qgb18030codec.cpp1
-rw-r--r--src/corelib/global/qfloat16.h1
-rw-r--r--src/corelib/global/qnamespace.qdoc16
-rw-r--r--src/corelib/io/qstandardpaths.cpp14
-rw-r--r--src/corelib/serialization/qcborvalue.cpp161
-rw-r--r--src/corelib/time/qdatetime.cpp8
-rw-r--r--src/corelib/time/qtimezoneprivate_android.cpp52
-rw-r--r--src/corelib/time/qtimezoneprivate_mac.mm11
-rw-r--r--src/corelib/tools/qhash.h5
-rw-r--r--src/corelib/tools/qpoint.h1
-rw-r--r--src/corelib/tools/qrect.h1
-rw-r--r--src/dbus/Qt5DBusMacros.cmake8
-rw-r--r--src/dbus/qdbusinterface.cpp4
-rw-r--r--src/gui/math3d/qmatrix4x4.h1
-rw-r--r--src/gui/math3d/qquaternion.h1
-rw-r--r--src/gui/math3d/qvector2d.h1
-rw-r--r--src/gui/math3d/qvector3d.h1
-rw-r--r--src/gui/math3d/qvector4d.h1
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp6
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp8
-rw-r--r--src/gui/painting/qtransform.h1
-rw-r--r--src/gui/rhi/qrhigles2.cpp3
-rw-r--r--src/gui/rhi/qrhivulkan.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp12
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm11
-rw-r--r--src/platformsupport/platformsupport.pro2
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm16
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm20
-rw-r--r--src/plugins/platforms/cocoa/qcocoasessionmanager.cpp88
-rw-r--r--src/plugins/platforms/cocoa/qcocoasessionmanager.h81
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm4
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm8
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp7
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp12
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm18
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac_p_p.h2
-rw-r--r--src/widgets/Qt5WidgetsMacros.cmake2
-rw-r--r--src/widgets/itemviews/qtreeview.cpp2
-rw-r--r--src/widgets/kernel/qwidget.cpp11
-rw-r--r--src/widgets/styles/qcommonstyle_p.h2
-rw-r--r--src/widgets/styles/qstylehelper.cpp9
-rw-r--r--src/widgets/widgets/qlineedit.cpp33
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp74
-rw-r--r--tests/auto/corelib/time/qdate/tst_qdate.cpp58
-rw-r--r--tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp65
-rw-r--r--tests/auto/corelib/time/qtime/tst_qtime.cpp52
-rw-r--r--tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp9
-rw-r--r--tests/auto/network/kernel/qnetworkinterface/BLACKLIST3
-rw-r--r--tests/auto/network/ssl/qsslcertificate/BLACKLIST13
-rw-r--r--tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp10
-rw-r--r--tests/auto/other/sessionmanagement_macos/sessionmanagement_macos.pro10
-rw-r--r--tests/auto/other/sessionmanagement_macos/tst_sessionmanagement_macos.mm61
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp18
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp34
-rw-r--r--tests/manual/highdpi/dragwidget.cpp15
-rw-r--r--tests/manual/highdpi/dragwidget.h5
-rw-r--r--tests/manual/highdpi/main.cpp331
67 files changed, 1113 insertions, 474 deletions
diff --git a/examples/widgets/doc/src/styles.qdoc b/examples/widgets/doc/src/styles.qdoc
index 4fea8f3bfc..a3a02768c6 100644
--- a/examples/widgets/doc/src/styles.qdoc
+++ b/examples/widgets/doc/src/styles.qdoc
@@ -27,6 +27,7 @@
/*!
\example widgets/styles
+ \meta {tag} {gallery}
\title Styles Example
\ingroup examples-widgets
\brief The Styles example illustrates how to create custom widget
diff --git a/examples/widgets/widgets/styles/widgetgallery.cpp b/examples/widgets/widgets/styles/widgetgallery.cpp
index fd8f0ec2d1..7e1616c6c0 100644
--- a/examples/widgets/widgets/styles/widgetgallery.cpp
+++ b/examples/widgets/widgets/styles/widgetgallery.cpp
@@ -65,6 +65,7 @@
#include <QRadioButton>
#include <QScrollBar>
#include <QSpinBox>
+#include <QStyle>
#include <QStyleFactory>
#include <QTableWidget>
#include <QTextEdit>
@@ -77,8 +78,16 @@ WidgetGallery::WidgetGallery(QWidget *parent)
originalPalette = QApplication::palette();
styleComboBox = new QComboBox;
- styleComboBox->addItem("NorwegianWood");
- styleComboBox->addItems(QStyleFactory::keys());
+ const QString defaultStyleName = QApplication::style()->objectName();
+ QStringList styleNames = QStyleFactory::keys();
+ styleNames.append("NorwegianWood");
+ for (int i = 1, size = styleNames.size(); i < size; ++i) {
+ if (defaultStyleName.compare(styleNames.at(i), Qt::CaseInsensitive) == 0) {
+ styleNames.swapItemsAt(0, i);
+ break;
+ }
+ }
+ styleComboBox->addItems(styleNames);
styleLabel = new QLabel(tr("&Style:"));
styleLabel->setBuddy(styleComboBox);
@@ -134,7 +143,6 @@ WidgetGallery::WidgetGallery(QWidget *parent)
setLayout(mainLayout);
setWindowTitle(tr("Styles"));
- changeStyle("NorwegianWood");
}
//! [4]
diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
index 364c23e750..5077b8d8b4 100644
--- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
+++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
@@ -173,11 +173,20 @@ macro(_populate_$${CMAKE_MODULE_NAME}_target_properties Configuration LIB_LOCATI
endif()
set(_static_link_flags \"${_Qt5$${CMAKE_MODULE_NAME}_STATIC_${Configuration}_LINK_FLAGS}\")
- if(NOT CMAKE_VERSION VERSION_LESS \"3.13\" AND _static_link_flags)
+ if(_static_link_flags)
set(_static_link_flags_genex \"$<${_genex_condition}:${_static_link_flags}>\")
- set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY INTERFACE_LINK_OPTIONS
- \"${_static_link_flags_genex}\"
- )
+ if(NOT CMAKE_VERSION VERSION_LESS \"3.13\")
+ set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY INTERFACE_LINK_OPTIONS
+ \"${_static_link_flags_genex}\"
+ )
+ else()
+ # Abuse INTERFACE_LINK_LIBRARIES to add link flags when CMake version is too low.
+ # Strip out SHELL:, because it is not supported in this property. And hope for the best.
+ string(REPLACE \"SHELL:\" \"\" _static_link_flags_genex \"${_static_link_flags_genex}\")
+ set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY INTERFACE_LINK_LIBRARIES
+ \"${_static_link_flags_genex}\"
+ )
+ endif()
endif()
!!ENDIF
@@ -546,11 +555,20 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
endif()
set(_static_link_flags \"${_Qt5${Plugin}_STATIC_${Configuration}_LINK_FLAGS}\")
- if(NOT CMAKE_VERSION VERSION_LESS \"3.13\" AND _static_link_flags)
+ if(_static_link_flags)
set(_static_link_flags_genex \"$<${_genex_condition}:${_static_link_flags}>\")
- set_property(TARGET Qt5::${Plugin} APPEND PROPERTY INTERFACE_LINK_OPTIONS
- \"${_static_link_flags_genex}\"
- )
+ if(NOT CMAKE_VERSION VERSION_LESS \"3.13\")
+ set_property(TARGET Qt5::${Plugin} APPEND PROPERTY INTERFACE_LINK_OPTIONS
+ \"${_static_link_flags_genex}\"
+ )
+ else()
+ # Abuse INTERFACE_LINK_LIBRARIES to add link flags when CMake version is too low.
+ # Strip out SHELL:, because it is not supported in this property. And hope for the best.
+ string(REPLACE \"SHELL:\" \"\" _static_link_flags_genex \"${_static_link_flags_genex}\")
+ set_property(TARGET Qt5::${Plugin} APPEND PROPERTY INTERFACE_LINK_LIBRARIES
+ \"${_static_link_flags_genex}\"
+ )
+ endif()
endif()
!!ENDIF
endmacro()
diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf
index deb4ac2829..095bf15dac 100644
--- a/mkspecs/features/qt_docs.prf
+++ b/mkspecs/features/qt_docs.prf
@@ -45,6 +45,8 @@ isEmpty(WIN_INCLUDETEMP) {
QDOC_INCLUDE_PATHS=@$$shell_quote($$WIN_INCLUDETEMP)
}
+macos: QDOC_INCLUDE_PATHS += $$join(QMAKE_DEFAULT_INCDIRS," -I","-I")
+
!build_online_docs: qtPrepareTool(QHELPGENERATOR, qhelpgenerator)
qtPrepareTool(QTATTRIBUTIONSSCANNER, qtattributionsscanner)
@@ -93,7 +95,6 @@ qtattributionsscanner.CONFIG += phony
QMAKE_EXTRA_TARGETS += qtattributionsscanner
doc_command = $$QDOC $$QMAKE_DOCS
-
prepare_docs {
prepare_docs.commands += $$doc_command -prepare $$PREP_DOC_INDEXES -no-link-errors $$QDOC_INCLUDE_PATHS
generate_docs.commands += $$doc_command -generate $$DOC_INDEXES $$QDOC_INCLUDE_PATHS
diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf
index d4f08835f1..7e9903d663 100644
--- a/mkspecs/features/testcase.prf
+++ b/mkspecs/features/testcase.prf
@@ -9,6 +9,9 @@ testcase_exceptions: CONFIG += exceptions
# Set in qt_build_config.prf
testcase_no_bundle: CONFIG -= app_bundle
+# cmdline may have been specified and not processed yet
+cmdline: CONFIG -= app_bundle
+
# Allow testcases to mark themselves as not supporting high-DPI
testcase_lowdpi {
macos {
diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake
index 17cc19fc4e..e298cf7de7 100644
--- a/src/corelib/Qt5CoreMacros.cmake
+++ b/src/corelib/Qt5CoreMacros.cmake
@@ -39,7 +39,7 @@
include(CMakeParseArguments)
# macro used to create the names of output files preserving relative dirs
-macro(QT5_MAKE_OUTPUT_FILE infile prefix ext outfile )
+macro(qt5_make_output_file infile prefix ext outfile )
string(LENGTH ${CMAKE_CURRENT_BINARY_DIR} _binlength)
string(LENGTH ${infile} _infileLength)
set(_checkinfile ${CMAKE_CURRENT_SOURCE_DIR})
@@ -65,7 +65,7 @@ macro(QT5_MAKE_OUTPUT_FILE infile prefix ext outfile )
endmacro()
-macro(QT5_GET_MOC_FLAGS _moc_flags)
+macro(qt5_get_moc_flags _moc_flags)
set(${_moc_flags})
get_directory_property(_inc_DIRS INCLUDE_DIRECTORIES)
@@ -97,7 +97,7 @@ endmacro()
# helper macro to set up a moc rule
-function(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target moc_depends)
+function(qt5_create_moc_command infile outfile moc_flags moc_options moc_target moc_depends)
# Pass the parameters in a file. Set the working directory to
# be that containing the parameters file and reference it by
# just the file name. This is necessary because the moc tool on
@@ -143,7 +143,7 @@ function(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target
endfunction()
-function(QT5_GENERATE_MOC infile outfile )
+function(qt5_generate_moc infile outfile )
# get include dirs and flags
qt5_get_moc_flags(moc_flags)
get_filename_component(abs_infile ${infile} ABSOLUTE)
@@ -160,7 +160,7 @@ endfunction()
# qt5_wrap_cpp(outfiles inputfile ... )
-function(QT5_WRAP_CPP outfiles )
+function(qt5_wrap_cpp outfiles )
# get include dirs
qt5_get_moc_flags(moc_flags)
@@ -189,7 +189,7 @@ endfunction()
# _qt5_parse_qrc_file(infile _out_depends _rc_depends)
# internal
-function(_QT5_PARSE_QRC_FILE infile _out_depends _rc_depends)
+function(_qt5_parse_qrc_file infile _out_depends _rc_depends)
get_filename_component(rc_path ${infile} PATH)
if(EXISTS "${infile}")
@@ -222,7 +222,7 @@ endfunction()
# qt5_add_binary_resources(target inputfiles ... )
-function(QT5_ADD_BINARY_RESOURCES target )
+function(qt5_add_binary_resources target )
set(options)
set(oneValueArgs DESTINATION)
@@ -241,7 +241,7 @@ function(QT5_ADD_BINARY_RESOURCES target )
foreach(it ${rcc_files})
get_filename_component(infile ${it} ABSOLUTE)
- _QT5_PARSE_QRC_FILE(${infile} _out_depends _rc_depends)
+ _qt5_parse_qrc_file(${infile} _out_depends _rc_depends)
set_source_files_properties(${infile} PROPERTIES SKIP_AUTORCC ON)
set(infiles ${infiles} ${infile})
set(out_depends ${out_depends} ${_out_depends})
@@ -258,7 +258,7 @@ endfunction()
# qt5_add_resources(outfiles inputfile ... )
-function(QT5_ADD_RESOURCES outfiles )
+function(qt5_add_resources outfiles )
set(options)
set(oneValueArgs)
@@ -278,7 +278,7 @@ function(QT5_ADD_RESOURCES outfiles )
get_filename_component(infile ${it} ABSOLUTE)
set(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.cpp)
- _QT5_PARSE_QRC_FILE(${infile} _out_depends _rc_depends)
+ _qt5_parse_qrc_file(${infile} _out_depends _rc_depends)
set_source_files_properties(${infile} PROPERTIES SKIP_AUTORCC ON)
add_custom_command(OUTPUT ${outfile}
@@ -295,7 +295,7 @@ endfunction()
# qt5_add_big_resources(outfiles inputfile ... )
-function(QT5_ADD_BIG_RESOURCES outfiles )
+function(qt5_add_big_resources outfiles )
if (CMAKE_VERSION VERSION_LESS 3.9)
message(FATAL_ERROR, "qt5_add_big_resources requires CMake 3.9 or newer")
endif()
@@ -319,7 +319,7 @@ function(QT5_ADD_BIG_RESOURCES outfiles )
set(tmpoutfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}tmp.cpp)
set(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.o)
- _QT5_PARSE_QRC_FILE(${infile} _out_depends _rc_depends)
+ _qt5_parse_qrc_file(${infile} _out_depends _rc_depends)
set_source_files_properties(${infile} PROPERTIES SKIP_AUTORCC ON)
add_custom_command(OUTPUT ${tmpoutfile}
COMMAND ${Qt5Core_RCC_EXECUTABLE} ${rcc_options} --name ${outfilename} --pass 1 --output ${tmpoutfile} ${infile}
@@ -343,58 +343,53 @@ endfunction()
set(_Qt5_COMPONENT_PATH "${CMAKE_CURRENT_LIST_DIR}/..")
-if (NOT CMAKE_VERSION VERSION_LESS 2.8.9)
- macro(qt5_use_modules _target _link_type)
- if(NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.11)
- if(CMAKE_WARN_DEPRECATED)
- set(messageType WARNING)
- endif()
- if(CMAKE_ERROR_DEPRECATED)
- set(messageType FATAL_ERROR)
- endif()
- if(messageType)
- message(${messageType} "The qt5_use_modules macro is obsolete. Use target_link_libraries with IMPORTED targets instead.")
- endif()
- endif()
+macro(qt5_use_modules _target _link_type)
+ if(CMAKE_WARN_DEPRECATED)
+ set(messageType WARNING)
+ endif()
+ if(CMAKE_ERROR_DEPRECATED)
+ set(messageType FATAL_ERROR)
+ endif()
+ if(messageType)
+ message(${messageType} "The qt5_use_modules macro is obsolete. Use target_link_libraries with IMPORTED targets instead.")
+ endif()
- if (NOT TARGET ${_target})
- message(FATAL_ERROR "The first argument to qt5_use_modules must be an existing target.")
- endif()
- if ("${_link_type}" STREQUAL "LINK_PUBLIC" OR "${_link_type}" STREQUAL "LINK_PRIVATE" )
- set(_qt5_modules ${ARGN})
- set(_qt5_link_type ${_link_type})
- else()
- set(_qt5_modules ${_link_type} ${ARGN})
- endif()
+ if (NOT TARGET ${_target})
+ message(FATAL_ERROR "The first argument to qt5_use_modules must be an existing target.")
+ endif()
+ if ("${_link_type}" STREQUAL "LINK_PUBLIC" OR "${_link_type}" STREQUAL "LINK_PRIVATE" )
+ set(_qt5_modules ${ARGN})
+ set(_qt5_link_type ${_link_type})
+ else()
+ set(_qt5_modules ${_link_type} ${ARGN})
+ endif()
- if ("${_qt5_modules}" STREQUAL "")
- message(FATAL_ERROR "qt5_use_modules requires at least one Qt module to use.")
- endif()
+ if ("${_qt5_modules}" STREQUAL "")
+ message(FATAL_ERROR "qt5_use_modules requires at least one Qt module to use.")
+ endif()
- foreach(_module ${_qt5_modules})
+ foreach(_module ${_qt5_modules})
+ if (NOT Qt5${_module}_FOUND)
+ find_package(Qt5${_module} PATHS "${_Qt5_COMPONENT_PATH}" NO_DEFAULT_PATH)
if (NOT Qt5${_module}_FOUND)
- find_package(Qt5${_module} PATHS "${_Qt5_COMPONENT_PATH}" NO_DEFAULT_PATH)
- if (NOT Qt5${_module}_FOUND)
- message(FATAL_ERROR "Cannot use \"${_module}\" module which has not yet been found.")
- endif()
- endif()
- target_link_libraries(${_target} ${_qt5_link_type} ${Qt5${_module}_LIBRARIES})
- set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES ${Qt5${_module}_INCLUDE_DIRS})
- set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS ${Qt5${_module}_COMPILE_DEFINITIONS})
- set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG)
- set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG)
- set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG)
- if (Qt5_POSITION_INDEPENDENT_CODE
- AND (CMAKE_VERSION VERSION_LESS 2.8.12
- AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
- OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)))
- set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE})
+ message(FATAL_ERROR "Cannot use \"${_module}\" module which has not yet been found.")
endif()
- endforeach()
- endmacro()
-endif()
+ endif()
+ target_link_libraries(${_target} ${_qt5_link_type} ${Qt5${_module}_LIBRARIES})
+ set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES ${Qt5${_module}_INCLUDE_DIRS})
+ set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS ${Qt5${_module}_COMPILE_DEFINITIONS})
+ set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG)
+ set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG)
+ set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG)
+ if (Qt5_POSITION_INDEPENDENT_CODE
+ AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
+ OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))
+ set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE})
+ endif()
+ endforeach()
+endmacro()
-function(QT5_IMPORT_PLUGINS TARGET_NAME)
+function(qt5_import_plugins TARGET_NAME)
set(_doing "")
foreach(_arg ${ARGN})
if(_arg STREQUAL "INCLUDE")
diff --git a/src/corelib/codecs/qgb18030codec.cpp b/src/corelib/codecs/qgb18030codec.cpp
index 4206eacb6f..ca15be1cea 100644
--- a/src/corelib/codecs/qgb18030codec.cpp
+++ b/src/corelib/codecs/qgb18030codec.cpp
@@ -107,7 +107,6 @@ QByteArray QGb18030Codec::convertFromUnicode(const QChar *uc, int len, Converter
if (high >= 0) {
if (uc[i].isLowSurrogate()) {
// valid surrogate pair
- ++i;
uint u = QChar::surrogateToUcs4(high, uc[i].unicode());
len = qt_UnicodeToGb18030(u, buf);
if (len >= 2) {
diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h
index 154b200475..f35eefd922 100644
--- a/src/corelib/global/qfloat16.h
+++ b/src/corelib/global/qfloat16.h
@@ -244,6 +244,7 @@ QF16_MAKE_ARITH_OP_INT(/)
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+QT_WARNING_DISABLE_INTEL(1572)
inline bool operator>(qfloat16 a, qfloat16 b) noexcept { return static_cast<float>(a) > static_cast<float>(b); }
inline bool operator<(qfloat16 a, qfloat16 b) noexcept { return static_cast<float>(a) < static_cast<float>(b); }
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 9896cf6e02..ef5f345e9c 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -724,9 +724,17 @@
\value LocalDate \e{This enum value is deprecated.} Use Qt::SystemLocaleShortDate
instead (or Qt::SystemLocaleLongDate if you want long dates).
- \value RFC2822Date \l{RFC 2822}, \l{RFC 850} and \l{RFC 1036} format: either
- \c{[ddd,] dd MMM yyyy hh:mm[:ss] +/-TZ} or \c{ddd MMM dd yyyy hh:mm[:ss] +/-TZ}
- for combined dates and times.
+ \value RFC2822Date \l{RFC 2822}, \l{RFC 850} and \l{RFC 1036} format:
+ either \c{[ddd,] dd MMM yyyy [hh:mm[:ss]][ ±tzoff]}
+ or \c{ddd MMM dd[ hh:mm:ss] yyyy[ ±tzoff]} are recognized for combined dates
+ and times, where \c{tzoff} is a timezone offset in \c{hhmm} format. For
+ dates and times separately, the same formats are matched and the unwanted
+ parts are ignored. In particular, note that a time is not recognized without
+ an accompanying date. When converting dates to string form,
+ format \c{dd MMM yyyy} is used, for times the format is \c{hh:mm:ss}. For
+ combined date and time, these are combined
+ as \c{dd MMM yyyy hh:mm:ss ±tzoff} (omitting the optional leading day of the
+ week from the first format recognized).
\note For \c ISODate formats, each \c Y, \c M and \c D represents a single digit
of the year, month and day used to specify the date. Each \c H, \c M and \c S
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 7306f19fc9..b62dc24b47 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -359,14 +359,14 @@ QT_BEGIN_NAMESPACE
/*!
\fn QString QStandardPaths::writableLocation(StandardLocation type)
- \include standardpath/functiondoc.qdocinc writableLocation
+ \include standardpath/functiondocs.qdocinc writableLocation
*/
/*!
\fn QStringList QStandardPaths::standardLocations(StandardLocation type)
- \include standardpath/functiondoc.qdocinc standardLocations
+ \include standardpath/functiondocs.qdocinc standardLocations
\sa writableLocation()
*/
@@ -390,7 +390,7 @@ static bool existsAsSpecified(const QString &path, QStandardPaths::LocateOptions
}
/*!
- \include standardpath/functiondoc.qdocinc locate
+ \include standardpath/functiondocs.qdocinc locate
*/
QString QStandardPaths::locate(StandardLocation type, const QString &fileName, LocateOptions options)
{
@@ -404,7 +404,7 @@ QString QStandardPaths::locate(StandardLocation type, const QString &fileName, L
}
/*!
- \include standardpath/functiondoc.qdocinc locateAll
+ \include standardpath/functiondocs.qdocinc locateAll
*/
QStringList QStandardPaths::locateAll(StandardLocation type, const QString &fileName, LocateOptions options)
{
@@ -477,7 +477,7 @@ static inline QString
#endif // Q_OS_WIN
/*!
- \include standardpath/functiondoc.qdocinc findExecutable
+ \include standardpath/functiondocs.qdocinc findExecutable
*/
QString QStandardPaths::findExecutable(const QString &executableName, const QStringList &paths)
{
@@ -535,7 +535,7 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr
}
/*!
- \include standardpath/functiondoc.qdocinc displayName
+ \include standardpath/functiondocs.qdocinc displayName
*/
#if !defined(Q_OS_MAC) && !defined(QT_BOOTSTRAPPED)
@@ -592,7 +592,7 @@ QString QStandardPaths::displayName(StandardLocation type)
/*!
\fn void QStandardPaths::setTestModeEnabled(bool testMode)
- \include standardpath/functiondoc.qdocinc setTestModeEnabled
+ \include standardpath/functiondocs.qdocinc setTestModeEnabled
*/
static bool qsp_testMode = false;
diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp
index c2f670de06..61d61dd9ae 100644
--- a/src/corelib/serialization/qcborvalue.cpp
+++ b/src/corelib/serialization/qcborvalue.cpp
@@ -761,6 +761,85 @@ QT_BEGIN_NAMESPACE
using namespace QtCbor;
+static QCborValue::Type convertToExtendedType(QCborContainerPrivate *d)
+{
+ qint64 tag = d->elements.at(0).value;
+ auto &e = d->elements[1];
+ const ByteData *b = d->byteData(e);
+
+ auto replaceByteData = [&](const char *buf, qsizetype len, Element::ValueFlags f) {
+ d->data.clear();
+ d->usedData = 0;
+ e.flags = Element::HasByteData | f;
+ e.value = d->addByteData(buf, len);
+ };
+
+ switch (tag) {
+ case qint64(QCborKnownTags::DateTimeString):
+ case qint64(QCborKnownTags::UnixTime_t): {
+ QDateTime dt;
+ if (tag == qint64(QCborKnownTags::DateTimeString) && b &&
+ e.type == QCborValue::String && (e.flags & Element::StringIsUtf16) == 0) {
+ // The data is supposed to be US-ASCII. If it isn't (contains UTF-8),
+ // QDateTime::fromString will fail anyway.
+ dt = QDateTime::fromString(b->asLatin1(), Qt::ISODateWithMs);
+ } else if (tag == qint64(QCborKnownTags::UnixTime_t) && e.type == QCborValue::Integer) {
+ dt = QDateTime::fromSecsSinceEpoch(e.value, Qt::UTC);
+ } else if (tag == qint64(QCborKnownTags::UnixTime_t) && e.type == QCborValue::Double) {
+ dt = QDateTime::fromMSecsSinceEpoch(qint64(e.fpvalue() * 1000), Qt::UTC);
+ }
+ if (dt.isValid()) {
+ QByteArray text = dt.toString(Qt::ISODateWithMs).toLatin1();
+ replaceByteData(text, text.size(), Element::StringIsAscii);
+ e.type = QCborValue::String;
+ d->elements[0].value = qint64(QCborKnownTags::DateTimeString);
+ return QCborValue::DateTime;
+ }
+ break;
+ }
+
+#ifndef QT_BOOTSTRAPPED
+ case qint64(QCborKnownTags::Url):
+ if (e.type == QCborValue::String) {
+ if (b) {
+ // normalize to a short (decoded) form, so as to save space
+ QUrl url(e.flags & Element::StringIsUtf16 ?
+ b->asQStringRaw() :
+ b->toUtf8String());
+ QByteArray encoded = url.toString(QUrl::DecodeReserved).toUtf8();
+ replaceByteData(encoded, encoded.size(), {});
+ }
+ return QCborValue::Url;
+ }
+ break;
+#endif // QT_BOOTSTRAPPED
+
+#if QT_CONFIG(regularexpression)
+ case quint64(QCborKnownTags::RegularExpression):
+ if (e.type == QCborValue::String) {
+ // no normalization is necessary
+ return QCborValue::RegularExpression;
+ }
+ break;
+#endif // QT_CONFIG(regularexpression)
+
+ case qint64(QCborKnownTags::Uuid):
+ if (e.type == QCborValue::ByteArray) {
+ // force the size to 16
+ char buf[sizeof(QUuid)] = {};
+ if (b)
+ memcpy(buf, b->byte(), qMin(sizeof(buf), size_t(b->len)));
+ replaceByteData(buf, sizeof(buf), {});
+
+ return QCborValue::Uuid;
+ }
+ break;
+ }
+
+ // no enriching happened
+ return QCborValue::Tag;
+}
+
#if QT_CONFIG(cborstream)
// in qcborstream.cpp
extern void qt_cbor_stream_set_error(QCborStreamReaderPrivate *d, QCborError error);
@@ -1390,77 +1469,10 @@ static QCborValue taggedValueFromCbor(QCborStreamReader &reader)
d->decodeValueFromCbor(reader);
}
- QCborValue::Type type = QCborValue::Tag;
+ QCborValue::Type type;
if (reader.lastError() == QCborError::NoError) {
// post-process to create our extended types
- qint64 tag = d->elements.at(0).value;
- auto &e = d->elements[1];
- const ByteData *b = d->byteData(e);
-
- auto replaceByteData = [&](const char *buf, qsizetype len) {
- d->data.clear();
- d->usedData = 0;
- e.flags = Element::HasByteData | Element::StringIsAscii;
- e.value = d->addByteData(buf, len);
- };
-
- switch (tag) {
- case qint64(QCborKnownTags::DateTimeString):
- case qint64(QCborKnownTags::UnixTime_t): {
- QDateTime dt;
- if (tag == qint64(QCborKnownTags::DateTimeString) && b &&
- e.type == QCborValue::String && (e.flags & Element::StringIsUtf16) == 0) {
- // The data is supposed to be US-ASCII. If it isn't,
- // QDateTime::fromString will fail anyway.
- dt = QDateTime::fromString(b->asLatin1(), Qt::ISODateWithMs);
- } else if (tag == qint64(QCborKnownTags::UnixTime_t) && e.type == QCborValue::Integer) {
- dt = QDateTime::fromSecsSinceEpoch(e.value, Qt::UTC);
- } else if (tag == qint64(QCborKnownTags::UnixTime_t) && e.type == QCborValue::Double) {
- dt = QDateTime::fromMSecsSinceEpoch(qint64(e.fpvalue() * 1000), Qt::UTC);
- }
- if (dt.isValid()) {
- QByteArray text = dt.toString(Qt::ISODateWithMs).toLatin1();
- replaceByteData(text, text.size());
- e.type = QCborValue::String;
- d->elements[0].value = qint64(QCborKnownTags::DateTimeString);
- type = QCborValue::DateTime;
- }
- break;
- }
-
- case qint64(QCborKnownTags::Url):
- if (e.type == QCborValue::String) {
- if (b) {
- // normalize to a short (decoded) form, so as to save space
- QUrl url(e.flags & Element::StringIsUtf16 ?
- b->asQStringRaw() :
- b->toUtf8String());
- QByteArray encoded = url.toString(QUrl::DecodeReserved).toUtf8();
- replaceByteData(encoded, encoded.size());
- }
- type = QCborValue::Url;
- }
- break;
-
- case quint64(QCborKnownTags::RegularExpression):
- if (e.type == QCborValue::String) {
- // no normalization is necessary
- type = QCborValue::RegularExpression;
- }
- break;
-
- case qint64(QCborKnownTags::Uuid):
- if (e.type == QCborValue::ByteArray) {
- // force the size to 16
- char buf[sizeof(QUuid)] = {};
- if (b)
- memcpy(buf, b->byte(), qMin(sizeof(buf), size_t(b->len)));
- replaceByteData(buf, sizeof(buf));
-
- type = QCborValue::Uuid;
- }
- break;
- }
+ type = convertToExtendedType(d);
} else {
// decoding error
type = QCborValue::Invalid;
@@ -1724,21 +1736,22 @@ QCborValue::QCborValue(const QCborMap &m)
}
/*!
- \fn QCborValue::QCborValue(QCborTag t, const QCborValue &tv)
- \fn QCborValue::QCborValue(QCborKnownTags t, const QCborValue &tv)
+ \fn QCborValue::QCborValue(QCborTag tag, const QCborValue &tv)
+ \fn QCborValue::QCborValue(QCborKnownTags tag, const QCborValue &tv)
Creates a QCborValue for the extended type represented by the tag value \a
- t, tagging value \a tv. The tag can later be retrieved using tag() and
+ tag, tagging value \a tv. The tag can later be retrieved using tag() and
the tagged value using taggedValue().
\sa isTag(), tag(), taggedValue(), QCborKnownTags
*/
-QCborValue::QCborValue(QCborTag t, const QCborValue &tv)
+QCborValue::QCborValue(QCborTag tag, const QCborValue &tv)
: n(-1), container(new QCborContainerPrivate), t(Tag)
{
container->ref.storeRelaxed(1);
- container->append(t);
+ container->append(tag);
container->append(tv);
+ t = convertToExtendedType(container);
}
/*!
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index accaea988e..c833c18809 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -164,8 +164,8 @@ static ParsedRfcDateTime rfcDateImpl(const QString &s)
{
ParsedRfcDateTime result;
- // Matches "Wdy, dd Mon yyyy HH:mm:ss ±hhmm" (Wdy, being optional)
- QRegExp rex(QStringLiteral("^(?:[A-Z][a-z]+,)?[ \\t]*(\\d{1,2})[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d)(?::(\\d\\d))?)?[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?"));
+ // Matches "[ddd,] dd MMM yyyy[ hh:mm[:ss]] [±hhmm]" - correct RFC 822, 2822, 5322 format
+ QRegExp rex(QStringLiteral("^[ \\t]*(?:[A-Z][a-z]+,)?[ \\t]*(\\d{1,2})[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d)(?::(\\d\\d))?)?[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?"));
if (s.indexOf(rex) == 0) {
const QStringList cap = rex.capturedTexts();
result.date = QDate(cap[3].toInt(), qt_monthNumberFromShortName(cap[2]), cap[1].toInt());
@@ -176,8 +176,8 @@ static ParsedRfcDateTime rfcDateImpl(const QString &s)
const int minOffset = cap[9].toInt();
result.utcOffset = ((hourOffset * 60 + minOffset) * (positiveOffset ? 60 : -60));
} else {
- // Matches "Wdy Mon dd HH:mm:ss yyyy"
- QRegExp rex(QStringLiteral("^[A-Z][a-z]+[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d):(\\d\\d))?[ \\t]+(\\d\\d\\d\\d)[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?"));
+ // Matches "ddd MMM dd[ hh:mm:ss] yyyy [±hhmm]" - permissive RFC 850, 1036 (read only)
+ QRegExp rex(QStringLiteral("^[ \\t]*[A-Z][a-z]+[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d):(\\d\\d))?[ \\t]+(\\d\\d\\d\\d)[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?"));
if (s.indexOf(rex) == 0) {
const QStringList cap = rex.capturedTexts();
result.date = QDate(cap[6].toInt(), qt_monthNumberFromShortName(cap[1]), cap[2].toInt());
diff --git a/src/corelib/time/qtimezoneprivate_android.cpp b/src/corelib/time/qtimezoneprivate_android.cpp
index be4f374fdd..5cb8155dcc 100644
--- a/src/corelib/time/qtimezoneprivate_android.cpp
+++ b/src/corelib/time/qtimezoneprivate_android.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2014 Drew Parsons <dparsons@emerall.com>
** Contact: https://www.qt.io/licensing/
**
@@ -53,9 +54,10 @@ QT_BEGIN_NAMESPACE
QAndroidTimeZonePrivate::QAndroidTimeZonePrivate()
: QTimeZonePrivate()
{
- // start with system time zone
- androidTimeZone = QJNIObjectPrivate::callStaticObjectMethod("java.util.TimeZone", "getDefault", "()Ljava/util/TimeZone;");
- init("UTC");
+ // Keep in sync with systemTimeZoneId():
+ androidTimeZone = QJNIObjectPrivate::callStaticObjectMethod(
+ "java.util.TimeZone", "getDefault", "()Ljava/util/TimeZone;");
+ m_id = androidTimeZone.callObjectMethod("getID", "()Ljava/lang/String;").toString().toUtf8();
}
// Create a named time zone
@@ -76,32 +78,33 @@ QAndroidTimeZonePrivate::~QAndroidTimeZonePrivate()
{
}
-
void QAndroidTimeZonePrivate::init(const QByteArray &ianaId)
{
- QJNIObjectPrivate jo_ianaId = QJNIObjectPrivate::fromString( QString::fromUtf8(ianaId) );
- androidTimeZone = QJNIObjectPrivate::callStaticObjectMethod( "java.util.TimeZone", "getTimeZone", "(Ljava/lang/String;)Ljava/util/TimeZone;", static_cast<jstring>(jo_ianaId.object()) );
+ const QString iana = QString::fromUtf8(ianaId);
+ androidTimeZone = QJNIObjectPrivate::callStaticObjectMethod(
+ "java.util.TimeZone", "getTimeZone", "(Ljava/lang/String;)Ljava/util/TimeZone;",
+ static_cast<jstring>(QJNIObjectPrivate::fromString(iana).object()));
+
+ // The ID or display name of the zone we've got, if it looks like what we asked for:
+ const auto match = [iana](const QJNIObjectPrivate &jname) -> QByteArray {
+ const QString name = jname.toString();
+ if (iana.compare(name, Qt::CaseInsensitive))
+ return name.toUtf8();
+
+ return QByteArray();
+ };
// Painfully, JNI gives us back a default zone object if it doesn't
// recognize the name; so check for whether ianaId is a recognized name of
// the zone object we got and ignore the zone if not.
// Try checking ianaId against getID(), getDisplayName():
- QJNIObjectPrivate jname = androidTimeZone.callObjectMethod("getID", "()Ljava/lang/String;");
- bool found = (jname.toString().toUtf8() == ianaId);
- for (int style = 1; !found && style-- > 0;) {
- for (int dst = 1; !found && dst-- > 0;) {
- jname = androidTimeZone.callObjectMethod("getDisplayName", "(ZI;)Ljava/lang/String;",
- bool(dst), style);
- found = (jname.toString().toUtf8() == ianaId);
+ m_id = match(androidTimeZone.callObjectMethod("getID", "()Ljava/lang/String;"));
+ for (int style = 1; m_id.isEmpty() && style-- > 0;) {
+ for (int dst = 1; m_id.isEmpty() && dst-- > 0;) {
+ m_id = match(androidTimeZone.callObjectMethod(
+ "getDisplayName", "(ZI;)Ljava/lang/String;", bool(dst), style));
}
}
-
- if (!found)
- m_id.clear();
- else if (ianaId.isEmpty())
- m_id = systemTimeZoneId();
- else
- m_id = ianaId;
}
QAndroidTimeZonePrivate *QAndroidTimeZonePrivate::clone() const
@@ -225,11 +228,10 @@ QTimeZonePrivate::Data QAndroidTimeZonePrivate::previousTransition(qint64 before
QByteArray QAndroidTimeZonePrivate::systemTimeZoneId() const
{
- QJNIObjectPrivate androidSystemTimeZone = QJNIObjectPrivate::callStaticObjectMethod("java.util.TimeZone", "getDefault", "()Ljava/util/TimeZone;");
- QJNIObjectPrivate systemTZIdAndroid = androidSystemTimeZone.callObjectMethod<jstring>("getID");
- QByteArray systemTZid = systemTZIdAndroid.toString().toUtf8();
-
- return systemTZid;
+ // Keep in sync with default constructor:
+ QJNIObjectPrivate androidSystemTimeZone = QJNIObjectPrivate::callStaticObjectMethod(
+ "java.util.TimeZone", "getDefault", "()Ljava/util/TimeZone;");
+ return androidSystemTimeZone.callObjectMethod<jstring>("getID").toString().toUtf8();
}
QList<QByteArray> QAndroidTimeZonePrivate::availableTimeZoneIds() const
diff --git a/src/corelib/time/qtimezoneprivate_mac.mm b/src/corelib/time/qtimezoneprivate_mac.mm
index d3c4fbe5da..4509e316f9 100644
--- a/src/corelib/time/qtimezoneprivate_mac.mm
+++ b/src/corelib/time/qtimezoneprivate_mac.mm
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2013 John Layt <jlayt@kde.org>
** Contact: https://www.qt.io/licensing/
**
@@ -94,6 +95,16 @@ void QMacTimeZonePrivate::init(const QByteArray &ianaId)
if (m_nstz)
m_id = ianaId;
}
+ if (!m_nstz) {
+ // macOS has been seen returning a systemTimeZone which reports its name
+ // as Asia/Kolkata, which doesn't appear in knownTimeZoneNames (which
+ // calls the zone Asia/Calcutta). So explicitly check for the name
+ // systemTimeZoneId() returns, and use systemTimeZone if we get it:
+ m_nstz = [NSTimeZone.systemTimeZone retain];
+ Q_ASSERT(m_nstz);
+ if (QString::fromNSString(m_nstz.name).toUtf8() == ianaId)
+ m_id = ianaId;
+ }
}
QString QMacTimeZonePrivate::comment() const
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 045dcf6e18..55702183fe 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -597,10 +597,7 @@ Q_INLINE_TEMPLATE QHash<Key, T> &QHash<Key, T>::unite(const QHash &other)
QHash copy(other);
const_iterator it = copy.constEnd();
while (it != copy.constBegin()) {
- QT_WARNING_PUSH
- QT_WARNING_DISABLE_DEPRECATED
- --it;
- QT_WARNING_POP
+ it.i = QHashData::previousNode(it.i);
insertMulti(it.key(), it.value());
}
#else
diff --git a/src/corelib/tools/qpoint.h b/src/corelib/tools/qpoint.h
index fe952f95da..f0a91c4ff8 100644
--- a/src/corelib/tools/qpoint.h
+++ b/src/corelib/tools/qpoint.h
@@ -352,6 +352,7 @@ Q_DECL_RELAXED_CONSTEXPR inline QPointF &QPointF::operator*=(qreal c)
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+QT_WARNING_DISABLE_INTEL(1572)
Q_DECL_CONSTEXPR inline bool operator==(const QPointF &p1, const QPointF &p2)
{
diff --git a/src/corelib/tools/qrect.h b/src/corelib/tools/qrect.h
index 7aa2312f38..c6bfc1a50d 100644
--- a/src/corelib/tools/qrect.h
+++ b/src/corelib/tools/qrect.h
@@ -665,6 +665,7 @@ Q_DECL_CONSTEXPR inline QRectF::QRectF(const QRect &r) noexcept
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+QT_WARNING_DISABLE_INTEL(1572)
Q_DECL_CONSTEXPR inline bool QRectF::isNull() const noexcept
{ return w == 0. && h == 0.; }
diff --git a/src/dbus/Qt5DBusMacros.cmake b/src/dbus/Qt5DBusMacros.cmake
index b381ab0934..9b69e77dc7 100644
--- a/src/dbus/Qt5DBusMacros.cmake
+++ b/src/dbus/Qt5DBusMacros.cmake
@@ -34,7 +34,7 @@ include(MacroAddFileDependencies)
include(CMakeParseArguments)
-function(QT5_ADD_DBUS_INTERFACE _sources _interface _basename)
+function(qt5_add_dbus_interface _sources _interface _basename)
get_filename_component(_infile ${_interface} ABSOLUTE)
set(_header "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h")
set(_impl "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp")
@@ -71,7 +71,7 @@ function(QT5_ADD_DBUS_INTERFACE _sources _interface _basename)
endfunction()
-function(QT5_ADD_DBUS_INTERFACES _sources)
+function(qt5_add_dbus_interfaces _sources)
foreach(_current_FILE ${ARGN})
get_filename_component(_infile ${_current_FILE} ABSOLUTE)
get_filename_component(_basename ${_current_FILE} NAME)
@@ -84,7 +84,7 @@ function(QT5_ADD_DBUS_INTERFACES _sources)
endfunction()
-function(QT5_GENERATE_DBUS_INTERFACE _header) # _customName OPTIONS -some -options )
+function(qt5_generate_dbus_interface _header) # _customName OPTIONS -some -options )
set(options)
set(oneValueArgs)
set(multiValueArgs OPTIONS)
@@ -117,7 +117,7 @@ function(QT5_GENERATE_DBUS_INTERFACE _header) # _customName OPTIONS -some -optio
endfunction()
-function(QT5_ADD_DBUS_ADAPTOR _sources _xml_file _include _parentClass) # _optionalBasename _optionalClassName)
+function(qt5_add_dbus_adaptor _sources _xml_file _include _parentClass) # _optionalBasename _optionalClassName)
get_filename_component(_infile ${_xml_file} ABSOLUTE)
set(_optionalBasename "${ARGV4}")
diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp
index 4dd02e8c76..b53c639b6d 100644
--- a/src/dbus/qdbusinterface.cpp
+++ b/src/dbus/qdbusinterface.cpp
@@ -204,7 +204,9 @@ QDBusInterfacePrivate::~QDBusInterfacePrivate()
interface \a interface on object at path \a path on service \a
service, using the given \a connection. If \a interface is an
empty string, the object created will refer to the merging of all
- interfaces found in that object.
+ interfaces found by introspecting that object. Otherwise if
+ \a interface is not empty, the QDBusInterface object will be cached
+ to speedup further creations of the same interface.
\a parent is passed to the base class constructor.
diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h
index 69c3510659..1439bfac59 100644
--- a/src/gui/math3d/qmatrix4x4.h
+++ b/src/gui/math3d/qmatrix4x4.h
@@ -215,6 +215,7 @@ private:
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+QT_WARNING_DISABLE_INTEL(1572)
Q_DECLARE_TYPEINFO(QMatrix4x4, Q_MOVABLE_TYPE);
inline QMatrix4x4::QMatrix4x4
diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index cd0d746e55..f01fab679e 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -171,6 +171,7 @@ inline QQuaternion::QQuaternion(float aScalar, float xpos, float ypos, float zpo
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+QT_WARNING_DISABLE_INTEL(1572)
inline bool QQuaternion::isNull() const
{
return wp == 0.0f && xp == 0.0f && yp == 0.0f && zp == 0.0f;
diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h
index 88d8bc199e..cbce94c199 100644
--- a/src/gui/math3d/qvector2d.h
+++ b/src/gui/math3d/qvector2d.h
@@ -207,6 +207,7 @@ inline QVector2D &QVector2D::operator/=(const QVector2D &vector)
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+QT_WARNING_DISABLE_INTEL(1572)
Q_DECL_CONSTEXPR inline bool operator==(const QVector2D &v1, const QVector2D &v2)
{
return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1];
diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h
index 1b49f3e7b9..d7ffb0bcc4 100644
--- a/src/gui/math3d/qvector3d.h
+++ b/src/gui/math3d/qvector3d.h
@@ -232,6 +232,7 @@ inline QVector3D &QVector3D::operator/=(const QVector3D &vector)
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+QT_WARNING_DISABLE_INTEL(1572)
Q_DECL_CONSTEXPR inline bool operator==(const QVector3D &v1, const QVector3D &v2)
{
return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1] && v1.v[2] == v2.v[2];
diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h
index 08cb423484..afcc71fa88 100644
--- a/src/gui/math3d/qvector4d.h
+++ b/src/gui/math3d/qvector4d.h
@@ -232,6 +232,7 @@ inline QVector4D &QVector4D::operator/=(const QVector4D &vector)
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+QT_WARNING_DISABLE_INTEL(1572)
Q_DECL_CONSTEXPR inline bool operator==(const QVector4D &v1, const QVector4D &v2)
{
return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1] && v1.v[2] == v2.v[2] && v1.v[3] == v2.v[3];
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 5d30891565..bb0dbdc9bd 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -658,13 +658,11 @@ void QOpenGLFramebufferObjectPrivate::initDepthStencilAttachments(QOpenGLContext
funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
- GLenum storageFormat = GL_DEPTH_STENCIL;
-
if (samples != 0 ) {
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- storageFormat, dsSize.width(), dsSize.height());
+ GL_DEPTH24_STENCIL8, dsSize.width(), dsSize.height());
} else {
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, storageFormat,
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL,
dsSize.width(), dsSize.height());
}
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 42186ace23..3e9eb3dd0a 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -388,8 +388,12 @@ static int qt_gl_resolve_extensions()
| QOpenGLExtensions::MapBufferRange
| QOpenGLExtensions::FramebufferBlit
| QOpenGLExtensions::FramebufferMultisample
- | QOpenGLExtensions::Sized8Formats
- | QOpenGLExtensions::TextureSwizzle;
+ | QOpenGLExtensions::Sized8Formats;
+#ifndef Q_OS_WASM
+ // WebGL 2.0 specification explicitly does not support texture swizzles
+ // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.19
+ extensions |= QOpenGLExtensions::TextureSwizzle;
+#endif
} else {
// Recognize features by extension name.
if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index b220770144..b2a634dd2a 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -303,6 +303,7 @@ inline qreal QTransform::dy() const
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+QT_WARNING_DISABLE_INTEL(1572)
inline QTransform &QTransform::operator*=(qreal num)
{
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index b0e9a149f1..b551980bb3 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -3142,8 +3142,7 @@ bool QGles2RenderBuffer::build()
switch (m_type) {
case QRhiRenderBuffer::DepthStencil:
if (rhiD->caps.msaaRenderBuffer && samples > 1) {
- const GLenum storage = rhiD->caps.needsDepthStencilCombinedAttach ? GL_DEPTH_STENCIL : GL_DEPTH24_STENCIL8;
- rhiD->f->glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage,
+ rhiD->f->glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8,
size.width(), size.height());
stencilRenderbuffer = 0;
} else if (rhiD->caps.packedDepthStencil || rhiD->caps.needsDepthStencilCombinedAttach) {
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 25a85a5a17..49ca2326bc 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -48,7 +48,7 @@
#include <qmath.h>
#include <QVulkanFunctions>
-#include <QVulkanWindow>
+#include <QtGui/qwindow.h>
QT_BEGIN_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 489d7a8ee6..f0775ba33b 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -92,6 +92,7 @@
#endif
#include <algorithm>
+#include <memory>
#include <string.h>
@@ -2169,6 +2170,7 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
errors << QSslError(QSslError::UnspecifiedError);
return errors;
}
+ const std::unique_ptr<X509_STORE, decltype(&q_X509_STORE_free)> storeGuard(certStore, q_X509_STORE_free);
if (s_loadRootCertsOnDemand) {
setDefaultCaCertificates(defaultCaCertificates() + systemCaCertificates());
@@ -2209,7 +2211,6 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
intermediates = (STACK_OF(X509) *) q_OPENSSL_sk_new_null();
if (!intermediates) {
- q_X509_STORE_free(certStore);
errors << QSslError(QSslError::UnspecifiedError);
return errors;
}
@@ -2227,14 +2228,12 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
X509_STORE_CTX *storeContext = q_X509_STORE_CTX_new();
if (!storeContext) {
- q_X509_STORE_free(certStore);
errors << QSslError(QSslError::UnspecifiedError);
return errors;
}
+ std::unique_ptr<X509_STORE_CTX, decltype(&q_X509_STORE_CTX_free)> ctxGuard(storeContext, q_X509_STORE_CTX_free);
if (!q_X509_STORE_CTX_init(storeContext, certStore, reinterpret_cast<X509 *>(certificateChain[0].handle()), intermediates)) {
- q_X509_STORE_CTX_free(storeContext);
- q_X509_STORE_free(certStore);
errors << QSslError(QSslError::UnspecifiedError);
return errors;
}
@@ -2243,8 +2242,7 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
// We ignore the result of this function since we process errors via the
// callback.
(void) q_X509_verify_cert(storeContext);
-
- q_X509_STORE_CTX_free(storeContext);
+ ctxGuard.reset();
q_OPENSSL_sk_free((OPENSSL_STACK *)intermediates);
// Now process the errors
@@ -2266,8 +2264,6 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
for (const auto &error : qAsConst(lastErrors))
errors << _q_OpenSSL_to_QSslError(error.code, certificateChain.value(error.depth));
- q_X509_STORE_free(certStore);
-
return errors;
}
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index daa3dc94ea..894919a1c8 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -374,17 +374,6 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::fontEngine
QCFType<CTFontDescriptorRef> descriptor = QCFType<CTFontDescriptorRef>::constructFromGet(
static_cast<CTFontDescriptorRef>(usrPtr));
- // CoreText will sometimes invalidate information in font descriptors that refer
- // to system fonts in certain function calls or application states. While the descriptor
- // looks the same from the outside, some internal plumbing is different, causing the results
- // of creating CTFonts from those descriptors unreliable. The work-around for this
- // is to copy the attributes of those descriptors each time we make a new CTFont
- // from them instead of referring to the original, as that may trigger the CoreText bug.
- if (m_systemFontDescriptors.contains(descriptor)) {
- QCFType<CFDictionaryRef> attributes = CTFontDescriptorCopyAttributes(descriptor);
- descriptor = CTFontDescriptorCreateWithAttributes(attributes);
- }
-
// Since we do not pass in the destination DPI to CoreText when making
// the font, we need to pass in a point size which is scaled to include
// the DPI. The default DPI for the screen is 72, thus the scale factor
diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro
index 0b2dd8974b..4b41b29c12 100644
--- a/src/platformsupport/platformsupport.pro
+++ b/src/platformsupport/platformsupport.pro
@@ -11,7 +11,7 @@ SUBDIRS = \
qtConfig(freetype)|darwin|win32: \
SUBDIRS += fontdatabases
-qtConfig(evdev)|qtConfig(tslib)|qtConfig(libinput)|qtConfig(integrityhid) {
+qtConfig(evdev)|qtConfig(tslib)|qtConfig(libinput)|qtConfig(integrityhid)|qtConfig(xkbcommon) {
SUBDIRS += input
input.depends += devicediscovery
}
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index 4cf9e64447..8f2956e7d4 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -87,6 +87,11 @@ qtConfig(accessibility) {
qcocoaaccessibility.h
}
+qtConfig(sessionmanager) {
+ SOURCES += qcocoasessionmanager.cpp
+ HEADERS += qcocoasessionmanager.h
+}
+
RESOURCES += qcocoaresources.qrc
LIBS += -framework AppKit -framework CoreServices -framework Carbon -framework IOKit -framework QuartzCore -framework CoreVideo -framework Metal -framework IOSurface -lcups
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index db4ec251ae..106c226adc 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -133,7 +133,7 @@ static void populateRoleMap()
roleMap[QAccessible::SpinBox] = NSAccessibilityIncrementorRole;
roleMap[QAccessible::Slider] = NSAccessibilitySliderRole;
roleMap[QAccessible::ProgressBar] = NSAccessibilityProgressIndicatorRole;
- roleMap[QAccessible::ComboBox] = NSAccessibilityPopUpButtonRole;
+ roleMap[QAccessible::ComboBox] = NSAccessibilityComboBoxRole;
roleMap[QAccessible::RadioButton] = NSAccessibilityRadioButtonRole;
roleMap[QAccessible::CheckBox] = NSAccessibilityCheckBoxRole;
roleMap[QAccessible::StaticText] = NSAccessibilityStaticTextRole;
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index f1fe2aa98b..3fb9e83d35 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -79,11 +79,14 @@
#include "qcocoamenuitem.h"
#include "qcocoansmenu.h"
+#if QT_CONFIG(sessionmanager)
+# include "qcocoasessionmanager.h"
+#endif
+
#include <qevent.h>
#include <qurl.h>
#include <qdebug.h>
#include <qguiapplication.h>
-#include <private/qguiapplication_p.h>
#include "qt_mac_p.h"
#include <qpa/qwindowsysteminterface.h>
#include <qwindowdefs.h>
@@ -157,6 +160,17 @@ QT_USE_NAMESPACE
return NSTerminateNow;
}
+#if QT_CONFIG(sessionmanager)
+ QCocoaSessionManager *cocoaSessionManager = QCocoaSessionManager::instance();
+ cocoaSessionManager->resetCancellation();
+ cocoaSessionManager->appCommitData();
+
+ if (cocoaSessionManager->wasCanceled()) {
+ qCDebug(lcQpaApplication) << "Session management canceled application termination";
+ return NSTerminateCancel;
+ }
+#endif
+
if (!QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>()) {
qCDebug(lcQpaApplication) << "Application termination canceled";
return NSTerminateCancel;
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index 09433194a6..95808b8a11 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -134,7 +134,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
NSImage *nsimage = qt_mac_create_nsimage(pm);
[nsimage setSize:NSSizeFromCGSize(pmDeviceIndependentSize.toCGSize())];
- QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND);
+ QMacPasteboard dragBoard(CFStringRef(NSPasteboardNameDrag), QMacInternalPasteboardMime::MIME_DND);
m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
dragBoard.setMimeData(m_drag->mimeData(), QMacPasteboard::LazyRequest);
@@ -145,7 +145,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
CGFloat flippedY = pmDeviceIndependentSize.height() - hotSpot.y();
event_location.y -= flippedY;
NSSize mouseOffset_unused = NSMakeSize(0.0, 0.0);
- NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
+ NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSPasteboardNameDrag];
[theWindow dragImage:nsimage
at:event_location
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 0e2656e046..30838ba254 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -92,6 +92,10 @@ public:
QCocoaVulkanInstance *getCocoaVulkanInstance() const;
#endif
+#if QT_CONFIG(sessionmanager)
+ QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const override;
+#endif
+
QCoreTextFontDatabase *fontDatabase() const override;
QCocoaNativeInterface *nativeInterface() const override;
QPlatformInputContext *inputContext() const override;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 67ad0b3492..a77b97f538 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -52,6 +52,9 @@
#include "qcocoamimetypes.h"
#include "qcocoaaccessibility.h"
#include "qcocoascreen.h"
+#if QT_CONFIG(sessionmanager)
+# include "qcocoasessionmanager.h"
+#endif
#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qplatformaccessibility.h>
@@ -197,16 +200,6 @@ QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
[cocoaApplication setMenu:[qtMenuLoader menu]];
}
- // The presentation options such as whether or not the dock and/or menu bar is
- // hidden (automatically by the system) affects the main screen's available
- // geometry. Since we're initializing the screens synchronously at application
- // startup we need to ensure that the presentation options have been propagated
- // to the screen before we read out its properties. Normally OS X does this in
- // an asynchronous callback, but that's too late for us. We force the propagation
- // by explicitly setting the presentation option to the magic 'default value',
- // which will resolve to an actual value and result in screen invalidation.
- cocoaApplication.presentationOptions = NSApplicationPresentationDefault;
-
QCocoaScreen::initializeScreens();
QMacInternalPasteboardMime::initializeMimeTypes();
@@ -255,6 +248,13 @@ QCocoaIntegration::Options QCocoaIntegration::options() const
return mOptions;
}
+#if QT_CONFIG(sessionmanager)
+QPlatformSessionManager *QCocoaIntegration::createPlatformSessionManager(const QString &id, const QString &key) const
+{
+ return new QCocoaSessionManager(id, key);
+}
+#endif
+
bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
diff --git a/src/plugins/platforms/cocoa/qcocoasessionmanager.cpp b/src/plugins/platforms/cocoa/qcocoasessionmanager.cpp
new file mode 100644
index 0000000000..74e318b5be
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoasessionmanager.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Samuel Gaist <samuel.gaist@idiap.ch>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_NO_SESSIONMANAGER
+#include <private/qsessionmanager_p.h>
+#include <private/qguiapplication_p.h>
+
+#include <qcocoasessionmanager.h>
+#include <qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+QCocoaSessionManager::QCocoaSessionManager(const QString &id, const QString &key)
+ : QPlatformSessionManager(id, key),
+ m_canceled(false)
+{
+}
+
+QCocoaSessionManager::~QCocoaSessionManager()
+{
+}
+
+bool QCocoaSessionManager::allowsInteraction()
+{
+ return false;
+}
+
+void QCocoaSessionManager::resetCancellation()
+{
+ m_canceled = false;
+}
+
+void QCocoaSessionManager::cancel()
+{
+ m_canceled = true;
+}
+
+bool QCocoaSessionManager::wasCanceled() const
+{
+ return m_canceled;
+}
+
+QCocoaSessionManager *QCocoaSessionManager::instance()
+{
+ auto *qGuiAppPriv = QGuiApplicationPrivate::instance();
+ auto *managerPrivate = static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(qGuiAppPriv->session_manager));
+ return static_cast<QCocoaSessionManager *>(managerPrivate->platformSessionManager);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SESSIONMANAGER
diff --git a/src/plugins/platforms/cocoa/qcocoasessionmanager.h b/src/plugins/platforms/cocoa/qcocoasessionmanager.h
new file mode 100644
index 0000000000..89ab7bd157
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoasessionmanager.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Samuel Gaist <samuel.gaist@idiap.ch>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOCOASESSIONMANAGER_H
+#define QCOCOASESSIONMANAGER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is part of the QPA API and is not meant to be used
+// in applications. Usage of this API may make your code
+// source and binary incompatible with future versions of Qt.
+//
+
+#ifndef QT_NO_SESSIONMANAGER
+
+#include <qpa/qplatformsessionmanager.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaSessionManager : public QPlatformSessionManager
+{
+public:
+ QCocoaSessionManager(const QString &id, const QString &key);
+ virtual ~QCocoaSessionManager();
+
+ bool allowsInteraction() override;
+ void cancel() override;
+ void resetCancellation();
+ bool wasCanceled() const;
+
+ static QCocoaSessionManager *instance();
+
+private:
+ bool m_canceled;
+
+ Q_DISABLE_COPY(QCocoaSessionManager)
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SESSIONMANAGER
+
+#endif // QCOCOASESSIONMANAGER_H
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 21366b4f67..643eac1e92 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1689,9 +1689,9 @@ void QCocoaWindow::registerTouch(bool enable)
{
m_registerTouchCount += enable ? 1 : -1;
if (enable && m_registerTouchCount == 1)
- [m_view setAcceptsTouchEvents:YES];
+ m_view.allowedTouchTypes |= NSTouchTypeMaskIndirect;
else if (m_registerTouchCount == 0)
- [m_view setAcceptsTouchEvents:NO];
+ m_view.allowedTouchTypes &= ~NSTouchTypeMaskIndirect;
}
void QCocoaWindow::setContentBorderThickness(int topThickness, int bottomThickness)
diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm
index 396c769be8..1bc9744528 100644
--- a/src/plugins/platforms/ios/qiostextresponder.mm
+++ b/src/plugins/platforms/ios/qiostextresponder.mm
@@ -781,12 +781,16 @@
- (UIView *)textInputView
{
+ auto *focusWindow = QGuiApplication::focusWindow();
+ if (!focusWindow)
+ return nil;
+
// iOS expects rects we return from other UITextInput methods
// to be relative to the view this method returns.
// Since QInputMethod returns rects relative to the top level
// QWindow, that is also the view we need to return.
- Q_ASSERT(qApp->focusWindow()->handle());
- QPlatformWindow *topLevel = qApp->focusWindow()->handle();
+ Q_ASSERT(focusWindow->handle());
+ QPlatformWindow *topLevel = focusWindow->handle();
while (QPlatformWindow *p = topLevel->parent())
topLevel = p;
return reinterpret_cast<UIView *>(topLevel->winId());
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 079c25f9eb..19d632dc10 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -283,8 +283,11 @@ void QWindowsInputContext::showInputPanel()
// We only call ShowCaret() on Windows 10 after 1703 as in earlier versions
// the caret would actually be visible (QTBUG-74492) and the workaround for
// the Surface seems unnecessary there anyway. But leave it hidden for IME.
- if (QOperatingSystemVersion::current() >=
- QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 16299)) {
+ // Only trigger the native OSK if the Qt OSK is not in use.
+ static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE");
+ if (imModuleEmpty
+ && QOperatingSystemVersion::current()
+ >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 16299)) {
ShowCaret(platformWindow->handle());
} else {
HideCaret(platformWindow->handle());
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index f589fd6b10..e5a9f275ae 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -390,7 +390,17 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
setVariantI4(UIA_WindowControlTypeId, pRetVal);
} else {
// Control type converted from role.
- setVariantI4(roleToControlTypeId(accessible->role()), pRetVal);
+ auto controlType = roleToControlTypeId(accessible->role());
+
+ // The native OSK should be disbled if the Qt OSK is in use.
+ static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE");
+
+ // If we want to disable the native OSK auto-showing
+ // we have to report text fields as non-editable.
+ if (controlType == UIA_EditControlTypeId && !imModuleEmpty)
+ controlType = UIA_TextControlTypeId;
+
+ setVariantI4(controlType, pRetVal);
}
break;
case UIA_HelpTextPropertyId:
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index e05bc15ce7..0da29cf6ee 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -1388,14 +1388,22 @@ void QMacStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *widg
// High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize
tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height()));
- *iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2,
- tabIconSize.width(), tabIconSize.height());
+ const int stylePadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2 - hpadding;
+
+ if (opt->documentMode) {
+ // documents show the icon as part of the the text
+ const int textWidth =
+ opt->fontMetrics.boundingRect(tr, Qt::AlignCenter | Qt::TextShowMnemonic, opt->text).width();
+ *iconRect = QRect(tr.center().x() - textWidth / 2 - stylePadding - tabIconSize.width(),
+ tr.center().y() - tabIconSize.height() / 2,
+ tabIconSize.width(), tabIconSize.height());
+ } else {
+ *iconRect = QRect(tr.left() + stylePadding, tr.center().y() - tabIconSize.height() / 2,
+ tabIconSize.width(), tabIconSize.height());
+ }
if (!verticalTabs)
*iconRect = proxyStyle->visualRect(opt->direction, opt->rect, *iconRect);
- int stylePadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
- stylePadding -= hpadding;
-
tr.setLeft(tr.left() + stylePadding + tabIconSize.width() + 4);
tr.setRight(tr.right() - stylePadding - tabIconSize.width() - 4);
}
diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h
index d6af18f01f..274936bd79 100644
--- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h
+++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h
@@ -284,7 +284,7 @@ public:
CocoaControlType windowButtonCocoaControl(QStyle::SubControl sc) const;
#if QT_CONFIG(tabbar)
- void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const;
+ void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const override;
static Direction tabDirection(QTabBar::Shape shape);
static bool verticalTabs(QMacStylePrivate::Direction tabDirection);
#endif
diff --git a/src/widgets/Qt5WidgetsMacros.cmake b/src/widgets/Qt5WidgetsMacros.cmake
index 737371a5ad..21e73d4f0c 100644
--- a/src/widgets/Qt5WidgetsMacros.cmake
+++ b/src/widgets/Qt5WidgetsMacros.cmake
@@ -41,7 +41,7 @@ include(CMakeParseArguments)
# qt5_wrap_ui(outfiles inputfile ... )
-function(QT5_WRAP_UI outfiles )
+function(qt5_wrap_ui outfiles )
set(options)
set(oneValueArgs)
set(multiValueArgs OPTIONS)
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 034c1f4b4f..442369c2ec 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -1892,6 +1892,8 @@ void QTreeView::mousePressEvent(QMouseEvent *event)
handled = d->expandOrCollapseItemAtPos(event->pos());
if (!handled && d->itemDecorationAt(event->pos()) == -1)
QAbstractItemView::mousePressEvent(event);
+ else
+ d->pressedIndex = QModelIndex();
}
/*!
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index b2653878c1..3b7110cfa0 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -7002,8 +7002,10 @@ void QWidget::resize(const QSize &s)
d->setGeometry_sys(geometry().x(), geometry().y(), s.width(), s.height(), false);
d->setDirtyOpaqueRegion();
} else {
+ const auto oldRect = data->crect;
data->crect.setSize(s.boundedTo(maximumSize()).expandedTo(minimumSize()));
- setAttribute(Qt::WA_PendingResizeEvent);
+ if (oldRect != data->crect)
+ setAttribute(Qt::WA_PendingResizeEvent);
}
}
@@ -7018,10 +7020,13 @@ void QWidget::setGeometry(const QRect &r)
d->setGeometry_sys(r.x(), r.y(), r.width(), r.height(), true);
d->setDirtyOpaqueRegion();
} else {
+ const auto oldRect = data->crect;
data->crect.setTopLeft(r.topLeft());
data->crect.setSize(r.size().boundedTo(maximumSize()).expandedTo(minimumSize()));
- setAttribute(Qt::WA_PendingMoveEvent);
- setAttribute(Qt::WA_PendingResizeEvent);
+ if (oldRect != data->crect) {
+ setAttribute(Qt::WA_PendingMoveEvent);
+ setAttribute(Qt::WA_PendingResizeEvent);
+ }
}
if (d->extra && d->extra->hasWindowContainer)
diff --git a/src/widgets/styles/qcommonstyle_p.h b/src/widgets/styles/qcommonstyle_p.h
index 4860dfe4c9..6223a26a54 100644
--- a/src/widgets/styles/qcommonstyle_p.h
+++ b/src/widgets/styles/qcommonstyle_p.h
@@ -122,7 +122,7 @@ public:
mutable QIcon tabBarcloseButtonIcon;
#if QT_CONFIG(tabbar)
- void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *pixmapRect) const;
+ virtual void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *pixmapRect) const;
#endif
int animationFps;
diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp
index 4e61b2d1ec..9477ca86da 100644
--- a/src/widgets/styles/qstylehelper.cpp
+++ b/src/widgets/styles/qstylehelper.cpp
@@ -274,6 +274,12 @@ void drawDial(const QStyleOptionSlider *option, QPainter *painter)
painter->drawLines(QStyleHelper::calcLines(option));
}
+ // setting color before BEGIN_STYLE_PIXMAPCACHE since
+ // otherwise it is not set when the image is in the cache
+ buttonColor.setHsv(buttonColor .hue(),
+ qMin(140, buttonColor .saturation()),
+ qMax(180, buttonColor.value()));
+
// Cache dial background
BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("qdial"));
p->setRenderHint(QPainter::Antialiasing);
@@ -285,9 +291,6 @@ void drawDial(const QStyleOptionSlider *option, QPainter *painter)
QRectF br = QRectF(dx + 0.5, dy + 0.5,
int(r * 2 - 2 * d_ - 2),
int(r * 2 - 2 * d_ - 2));
- buttonColor.setHsv(buttonColor .hue(),
- qMin(140, buttonColor .saturation()),
- qMax(180, buttonColor.value()));
if (enabled) {
// Drop shadow
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 37d2211a00..7dffc55a36 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -1200,12 +1200,18 @@ QMargins QLineEdit::textMargins() const
Unset the mask and return to normal QLineEdit operation by passing
an empty string ("").
- The table below shows the characters that can be used in an input mask.
- A space character, the default character for a blank, is needed for cases
- where a character is \e{permitted but not required}.
+ The input mask is an input template string. It can contain the following elements:
+ \table
+ \row \li Mask Characters \li Defines the class of input characters that are
+ considered valid in this position
+ \row \li Meta Characters \li Various special meanings
+ \row \li Separators \li All other characters are regarded as immutable separators
+ \endtable
+
+ The following table shows the mask and meta characters that can be used in an input mask.
\table
- \header \li Character \li Meaning
+ \header \li Mask Character \li Meaning
\row \li \c A \li ASCII alphabetic character required. A-Z, a-z.
\row \li \c a \li ASCII alphabetic character permitted but not required.
\row \li \c N \li ASCII alphanumeric character required. A-Z, a-z, 0-9.
@@ -1221,19 +1227,28 @@ QMargins QLineEdit::textMargins() const
\row \li \c h \li Hexadecimal character permitted but not required.
\row \li \c B \li Binary character required. 0-1.
\row \li \c b \li Binary character permitted but not required.
+ \header \li Meta Character \li Meaning
\row \li \c > \li All following alphabetic characters are uppercased.
\row \li \c < \li All following alphabetic characters are lowercased.
\row \li \c ! \li Switch off case conversion.
+ \row \li \c {;c} \li Terminates the input mask and sets the \e{blank} character to \e{c}.
\row \li \c {[ ] { }} \li Reserved.
\row \li \tt{\\} \li Use \tt{\\} to escape the special
characters listed above to use them as
separators.
\endtable
- The mask consists of a string of mask characters and separators,
- optionally followed by a semicolon and the character used for
- blanks. The blank characters are always removed from the text
- after editing.
+ When created or cleared, the line edit will be filled with a copy of the
+ input mask string where the meta characters have been removed, and the mask
+ characters have been replaced with the \e{blank} character (by default, a
+ \c space).
+
+ When an input mask is set, the text() method returns a modified copy of the
+ line edit content where all the \e{blank} characters have been removed. The
+ unmodified content can be read using displayText().
+
+ The hasAcceptableInput() method returns false if the current content of the
+ line edit does not fulfil the requirements of the input mask.
Examples:
\table
@@ -1242,7 +1257,7 @@ QMargins QLineEdit::textMargins() const
\row \li \c HH:HH:HH:HH:HH:HH;_ \li MAC address
\row \li \c 0000-00-00 \li ISO Date; blanks are \c space
\row \li \c >AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;# \li License number;
- blanks are \c - and all (alphabetic) characters are converted to
+ blanks are \c{#} and all (alphabetic) characters are converted to
uppercase.
\endtable
diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
index c6733205e5..47ad328d64 100644
--- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
+++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
@@ -40,6 +40,7 @@
#include <QtCore/qcborvalue.h>
#include <QtTest>
+Q_DECLARE_METATYPE(QCborKnownTags)
Q_DECLARE_METATYPE(QCborValue)
Q_DECLARE_METATYPE(QCborValue::EncodingOptions)
@@ -294,34 +295,77 @@ void tst_QCborValue::tagged()
void tst_QCborValue::extendedTypes_data()
{
QTest::addColumn<QCborValue>("extended");
- QTest::addColumn<QCborValue>("tagged");
+ QTest::addColumn<QCborKnownTags>("tag");
+ QTest::addColumn<QCborValue>("taggedValue");
+ QTest::addColumn<QCborValue>("correctedTaggedValue");
+ QCborValue v(QCborValue::Invalid);
QDateTime dt = QDateTime::currentDateTimeUtc();
+ QDateTime dtTzOffset(dt.date(), dt.time(), Qt::OffsetFromUTC, dt.offsetFromUtc());
QUuid uuid = QUuid::createUuid();
+ // non-correcting extended types (tagged value remains unchanged)
QTest::newRow("DateTime") << QCborValue(dt)
- << QCborValue(QCborKnownTags::DateTimeString, dt.toString(Qt::ISODateWithMs));
+ << QCborKnownTags::DateTimeString << QCborValue(dt.toString(Qt::ISODateWithMs)) << v;
+ QTest::newRow("DateTime:TzOffset") << QCborValue(dtTzOffset)
+ << QCborKnownTags::DateTimeString << QCborValue(dtTzOffset.toString(Qt::ISODateWithMs)) << v;
QTest::newRow("Url:Empty") << QCborValue(QUrl())
- << QCborValue(QCborKnownTags::Url, QString());
+ << QCborKnownTags::Url << QCborValue(QString()) << v;
QTest::newRow("Url:Authority") << QCborValue(QUrl("https://example.com"))
- << QCborValue(QCborKnownTags::Url, "https://example.com");
+ << QCborKnownTags::Url << QCborValue("https://example.com") << v;
QTest::newRow("Url:Path") << QCborValue(QUrl("file:///tmp/none"))
- << QCborValue(QCborKnownTags::Url, "file:///tmp/none");
+ << QCborKnownTags::Url << QCborValue("file:///tmp/none") << v;
QTest::newRow("Url:QueryFragment") << QCborValue(QUrl("whatever:?a=b&c=d#e"))
- << QCborValue(QCborKnownTags::Url, "whatever:?a=b&c=d#e");
+ << QCborKnownTags::Url << QCborValue("whatever:?a=b&c=d#e") << v;
QTest::newRow("Regex:Empty") << QCborValue(QRegularExpression())
- << QCborValue(QCborKnownTags::RegularExpression, QString());
+ << QCborKnownTags::RegularExpression << QCborValue(QString()) << v;
QTest::newRow("Regex") << QCborValue(QRegularExpression("^.*$"))
- << QCborValue(QCborKnownTags::RegularExpression, QString("^.*$"));
+ << QCborKnownTags::RegularExpression << QCborValue(QString("^.*$")) << v;
QTest::newRow("Uuid") << QCborValue(uuid)
- << QCborValue(QCborKnownTags::Uuid, uuid.toRfc4122());
+ << QCborKnownTags::Uuid << QCborValue(uuid.toRfc4122()) << v;
+
+ // correcting extended types
+ QDateTime dtNoMsecs = dt.fromSecsSinceEpoch(dt.toSecsSinceEpoch(), Qt::UTC);
+ QUrl url("https://example.com/\xc2\xa9 ");
+ QTest::newRow("UnixTime_t:Integer") << QCborValue(dtNoMsecs) << QCborKnownTags::UnixTime_t
+ << QCborValue(dtNoMsecs.toSecsSinceEpoch())
+ << QCborValue(dtNoMsecs.toString(Qt::ISODateWithMs));
+ QTest::newRow("UnixTime_t:Double") << QCborValue(dt) << QCborKnownTags::UnixTime_t
+ << QCborValue(dt.toMSecsSinceEpoch() / 1000.)
+ << QCborValue(dt.toString(Qt::ISODateWithMs));
+ QTest::newRow("DateTime::JustDate") << QCborValue(QDateTime({2018, 1, 1}, {}))
+ << QCborKnownTags::DateTimeString
+ << QCborValue("2018-01-01") << QCborValue("2018-01-01T00:00:00.000");
+ QTest::newRow("DateTime::TzOffset") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::UTC))
+ << QCborKnownTags::DateTimeString
+ << QCborValue("2018-01-01T09:00:00.000+00:00")
+ << QCborValue("2018-01-01T09:00:00.000Z");
+ QTest::newRow("Url:NotNormalized") << QCborValue(url) << QCborKnownTags::Url
+ << QCborValue("HTTPS://EXAMPLE.COM/%c2%a9%20")
+ << QCborValue(url.toString());
+ QTest::newRow("Uuid:Zero") << QCborValue(QUuid()) << QCborKnownTags::Uuid
+ << QCborValue(QByteArray())
+ << QCborValue(QByteArray(sizeof(QUuid), 0));
+ QTest::newRow("Uuid:TooShort") << QCborValue(QUuid(0x12345678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
+ << QCborKnownTags::Uuid
+ << QCborValue(raw("\x12\x34\x56\x78"))
+ << QCborValue(raw("\x12\x34\x56\x78" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0"));
+ QTest::newRow("Uuid:TooLong") << QCborValue(uuid) << QCborKnownTags::Uuid
+ << QCborValue(uuid.toRfc4122() + "\1\2\3\4") << QCborValue(uuid.toRfc4122());
}
void tst_QCborValue::extendedTypes()
{
QFETCH(QCborValue, extended);
- QFETCH(QCborValue, tagged);
+ QFETCH(QCborKnownTags, tag);
+ QFETCH(QCborValue, taggedValue);
+ QFETCH(QCborValue, correctedTaggedValue);
+ if (correctedTaggedValue.isInvalid())
+ correctedTaggedValue = taggedValue;
+
+ QCborValue tagged(tag, taggedValue);
QVERIFY(extended.isTag());
QVERIFY(tagged.isTag());
+ QCOMPARE(tagged.taggedValue(), correctedTaggedValue);
QVERIFY(extended == tagged);
QVERIFY(tagged == extended);
@@ -1224,8 +1268,11 @@ void tst_QCborValue::sorting()
QCborValue va1(QCborValue::Array), va2(QCborArray{1}), va3(QCborArray{0, 0});
QCborValue vm1(QCborValue::Map), vm2(QCborMap{{1, 0}}), vm3(QCborMap{{0, 0}, {1, 0}});
QCborValue vdt1(QDateTime::fromMSecsSinceEpoch(0, Qt::UTC)), vdt2(QDateTime::currentDateTimeUtc());
- QCborValue vtagged1(QCborKnownTags::UnixTime_t, 0), vtagged2(QCborKnownTags::UnixTime_t, 0.0),
- vtagged3(QCborKnownTags::Signature, 0), vtagged4(QCborTag(-2), 0), vtagged5(QCborTag(-1), 0);
+ QCborValue vtagged1(QCborKnownTags::PositiveBignum, QByteArray()),
+ vtagged2(QCborKnownTags::PositiveBignum, 0.0), // bignums are supposed to have byte arrays...
+ vtagged3(QCborKnownTags::Signature, 0),
+ vtagged4(QCborTag(-2), 0),
+ vtagged5(QCborTag(-1), 0);
QCborValue vurl1(QUrl("https://example.net")), vurl2(QUrl("https://example.com/"));
QCborValue vuuid1{QUuid()}, vuuid2(QUuid::createUuid());
QCborValue vsimple1(QCborSimpleType(1)), vsimple32(QCborSimpleType(32)), vsimple255(QCborSimpleType(255));
@@ -1391,6 +1438,9 @@ static void addCommonCborData()
QTest::newRow("Url") << QCborValue(QUrl("HTTPS://example.com/{%30%31}?q=%3Ca+b%20%C2%A9%3E&%26"))
<< raw("\xd8\x20\x78\x27" "https://example.com/{01}?q=<a+b \xC2\xA9>&%26")
<< noxfrm;
+ QTest::newRow("Url:NonAscii") << QCborValue(QUrl("https://example.com/\xc2\xa0"))
+ << raw("\xd8\x20\x76" "https://example.com/\xc2\xa0")
+ << noxfrm;
QTest::newRow("Regex:Empty") << QCborValue(QRegularExpression()) << raw("\xd8\x23\x60") << noxfrm;
QTest::newRow("Regex") << QCborValue(QRegularExpression("^.*$"))
<< raw("\xd8\x23\x64" "^.*$") << noxfrm;
diff --git a/tests/auto/corelib/time/qdate/tst_qdate.cpp b/tests/auto/corelib/time/qdate/tst_qdate.cpp
index 73384c35f4..dd2cb3eea8 100644
--- a/tests/auto/corelib/time/qdate/tst_qdate.cpp
+++ b/tests/auto/corelib/time/qdate/tst_qdate.cpp
@@ -1136,8 +1136,14 @@ void tst_QDate::fromStringDateFormat_data()
// Test Qt::RFC2822Date format (RFC 2822).
QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
<< Qt::RFC2822Date << QDate(1987, 2, 13);
+ QTest::newRow("RFC 2822 after space")
+ << QString::fromLatin1(" 13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDate(1987, 2, 13);
QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
<< Qt::RFC2822Date << QDate(1970, 1, 1);
+ QTest::newRow("RFC 2822 with day after space")
+ << QString::fromLatin1(" Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QDate(1970, 1, 1);
// No timezone
QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
<< Qt::RFC2822Date << QDate(1970, 1, 1);
@@ -1153,38 +1159,56 @@ void tst_QDate::fromStringDateFormat_data()
<< Qt::RFC2822Date << QDate();
QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
<< Qt::RFC2822Date << QDate();
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
+ // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038).
+ QTest::newRow("RFC 2822 invalid character at end")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
+ << Qt::RFC2822Date << QDate(2012, 1, 1);
+ QTest::newRow("RFC 2822 invalid character at front")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character both ends")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100!") << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character at front, 2 at back")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100..") << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character 2 at front")
+ << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << QDate();
+ // The common date text used by the "invalid character" tests, just to be
+ // sure *it's* not what's invalid:
+ QTest::newRow("RFC 2822 (not invalid)")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100")
<< Qt::RFC2822Date << QDate(2012, 1, 1);
- QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000")
- << Qt::RFC2822Date << QDate();
- // Test Qt::RFC2822Date format (RFC 850 and 1036).
+ // Test Qt::RFC2822Date format (RFC 850 and 1036, permissive).
QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
<< Qt::RFC2822Date << QDate(1987, 2, 13);
+ QTest::newRow("RFC 850 and 1036 after space")
+ << QString::fromLatin1(" Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QDate(1987, 2, 13);
// No timezone
QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
<< Qt::RFC2822Date << QDate(1970, 1, 1);
// No time specified
QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
<< Qt::RFC2822Date << QDate(2002, 11, 1);
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
+ // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038).
+ QTest::newRow("RFC 850 and 1036 invalid character at end")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
<< Qt::RFC2822Date << QDate(2012, 1, 1);
- QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000")
+ QTest::newRow("RFC 850 and 1036 invalid character at front")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100")
<< Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!")
+ QTest::newRow("RFC 850 and 1036 invalid character both ends")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100!")
<< Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..")
+ QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100..")
<< Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 850 and 1036 invalid character 2 at front") << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0000")
+ QTest::newRow("RFC 850 and 1036 invalid character 2 at front")
+ << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0100")
<< Qt::RFC2822Date << QDate();
+ // Again, check the text in the "invalid character" tests isn't the source of invalidity:
+ QTest::newRow("RFC 850 and 1036 (not invalid)")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << QDate(2012, 1, 1);
QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << QDate();
}
diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
index 216ae1f79e..7f13fd0aa5 100644
--- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
@@ -1003,8 +1003,9 @@ void tst_QDateTime::toString_rfcDate()
// Set to non-English locale to confirm still uses English
QLocale oldLocale;
QLocale::setDefault(QLocale("de_DE"));
- QCOMPARE(dt.toString(Qt::RFC2822Date), formatted);
+ QString actual(dt.toString(Qt::RFC2822Date));
QLocale::setDefault(oldLocale);
+ QCOMPARE(actual, formatted);
}
void tst_QDateTime::toString_enumformat()
@@ -2310,8 +2311,14 @@ void tst_QDateTime::fromStringDateFormat_data()
// Test Qt::RFC2822Date format (RFC 2822).
QTest::newRow("RFC 2822 +0100") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
<< Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
+ QTest::newRow("RFC 2822 after space +0100")
+ << QString::fromLatin1(" 13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
QTest::newRow("RFC 2822 with day +0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 +0100")
<< Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
+ QTest::newRow("RFC 2822 with day after space +0100")
+ << QString::fromLatin1(" Fri, 13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
QTest::newRow("RFC 2822 -0100") << QString::fromLatin1("13 Feb 1987 13:24:51 -0100")
<< Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC);
QTest::newRow("RFC 2822 with day -0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 -0100")
@@ -2324,6 +2331,11 @@ void tst_QDateTime::fromStringDateFormat_data()
<< Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
QTest::newRow("RFC 2822 with day +0000") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
<< Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
+ // Should be invalid, but current implementation would just ignore the
+ // offset as trailing junk if we insist on the space:
+ QTest::newRow("RFC 2822 missing space before +0100")
+ << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34+0100") << Qt::RFC2822Date
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::OffsetFromUTC, 3600);
// No timezone assume UTC
QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
<< Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
@@ -2339,21 +2351,34 @@ void tst_QDateTime::fromStringDateFormat_data()
<< Qt::RFC2822Date << invalidDateTime();
QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
<< Qt::RFC2822Date << invalidDateTime();
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
+ // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038).
+ QTest::newRow("RFC 2822 invalid character at end")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
<< Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC);
- QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000")
+ QTest::newRow("RFC 2822 invalid character at front")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100")
<< Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!")
+ QTest::newRow("RFC 2822 invalid character both ends")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100!")
<< Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..")
+ QTest::newRow("RFC 2822 invalid character at front, 2 at back")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100..")
<< Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000")
+ QTest::newRow("RFC 2822 invalid character 2 at front")
+ << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0100")
<< Qt::RFC2822Date << invalidDateTime();
+ // The common date text used by the "invalid character" tests, just to be
+ // sure *it's* not what's invalid:
+ QTest::newRow("RFC 2822 (not invalid)")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC);
- // Test Qt::RFC2822Date format (RFC 850 and 1036).
+ // Test Qt::RFC2822Date format (RFC 850 and 1036, permissive).
QTest::newRow("RFC 850 and 1036 +0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
<< Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
+ QTest::newRow("RFC 1036 after space +0100")
+ << QString::fromLatin1(" Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
QTest::newRow("RFC 850 and 1036 -0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 -0100")
<< Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC);
QTest::newRow("RFC 850 and 1036 +0000") << QString::fromLatin1("Thu Jan 01 00:12:34 1970 +0000")
@@ -2364,19 +2389,29 @@ void tst_QDateTime::fromStringDateFormat_data()
QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
<< Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
// No time specified
- QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
+ QTest::newRow("RFC 850 and 1036 date only")
+ << QString::fromLatin1("Fri Nov 01 2002")
<< Qt::RFC2822Date << invalidDateTime();
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
+ // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038).
+ QTest::newRow("RFC 850 and 1036 invalid character at end")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
<< Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC);
- QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000")
+ QTest::newRow("RFC 850 and 1036 invalid character at front")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100")
<< Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!")
+ QTest::newRow("RFC 850 and 1036 invalid character both ends")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100!")
<< Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..")
+ QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100..")
<< Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 850 and 1036 invalid character 2 at front") << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0000")
+ QTest::newRow("RFC 850 and 1036 invalid character 2 at front")
+ << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0100")
<< Qt::RFC2822Date << invalidDateTime();
+ // Again, check the text in the "invalid character" tests isn't the source of invalidity:
+ QTest::newRow("RFC 850 and 1036 (not invalid)")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC);
QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidDateTime();
}
diff --git a/tests/auto/corelib/time/qtime/tst_qtime.cpp b/tests/auto/corelib/time/qtime/tst_qtime.cpp
index 3403c5bf7f..d8de6e585d 100644
--- a/tests/auto/corelib/time/qtime/tst_qtime.cpp
+++ b/tests/auto/corelib/time/qtime/tst_qtime.cpp
@@ -619,8 +619,14 @@ void tst_QTime::fromStringDateFormat_data()
// Test Qt::RFC2822Date format (RFC 2822).
QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
<< Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 2822 after space")
+ << QString::fromLatin1(" 13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
<< Qt::RFC2822Date << QTime(0, 12, 34);
+ QTest::newRow("RFC 2822 with day after space")
+ << QString::fromLatin1(" Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QTime(0, 12, 34);
// No timezone
QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
<< Qt::RFC2822Date << QTime(0, 12, 34);
@@ -636,36 +642,58 @@ void tst_QTime::fromStringDateFormat_data()
<< Qt::RFC2822Date << QTime(13, 24, 51);
QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
<< Qt::RFC2822Date << QTime(13, 24, 51);
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
+ // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038).
+ QTest::newRow("RFC 2822 invalid character at end")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
<< Qt::RFC2822Date << QTime(8, 0, 0);
- QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000")
+ QTest::newRow("RFC 2822 invalid character at front")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100")
<< Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!")
+ QTest::newRow("RFC 2822 invalid character both ends")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100!")
<< Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..")
+ QTest::newRow("RFC 2822 invalid character at front, 2 at back")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100..")
<< Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000")
+ QTest::newRow("RFC 2822 invalid character 2 at front")
+ << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0100")
<< Qt::RFC2822Date << invalidTime();
+ // The common date text used by the "invalid character" tests, just to be
+ // sure *it's* not what's invalid:
+ QTest::newRow("RFC 2822 invalid character at end")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100")
+ << Qt::RFC2822Date << QTime(8, 0, 0);
- // Test Qt::RFC2822Date format (RFC 850 and 1036).
+ // Test Qt::RFC2822Date format (RFC 850 and 1036, permissive).
QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
<< Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 850 and 1036 after space")
+ << QString::fromLatin1(" Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
// No timezone
QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
<< Qt::RFC2822Date << QTime(0, 12, 34);
// No time specified
QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
<< Qt::RFC2822Date << invalidTime();
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
+ // Test invalid characters (currently ignoring trailing junk, but see QTBUG-80038).
+ QTest::newRow("RFC 850 and 1036 invalid character at end")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
<< Qt::RFC2822Date << QTime(8, 0, 0);
- QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000")
+ QTest::newRow("RFC 850 and 1036 invalid character at front")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100")
<< Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!")
+ QTest::newRow("RFC 850 and 1036 invalid character both ends")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100!")
<< Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..")
+ QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100..")
<< Qt::RFC2822Date << invalidTime();
+ // The common date text used by the "invalid character" tests, just to be
+ // sure *it's* not what's invalid:
+ QTest::newRow("RFC 850 and 1036 invalid character at end")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << QTime(8, 0, 0);
QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidTime();
}
diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
index d0ef8023b9..332a00efb5 100644
--- a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
@@ -46,6 +46,7 @@ private slots:
// Public class default system tests
void createTest();
void nullTest();
+ void systemZone();
void dataStreamTest();
void isTimeZoneIdAvailable();
void availableTimeZoneIds();
@@ -317,6 +318,14 @@ void tst_QTimeZone::nullTest()
QCOMPARE(data.daylightTimeOffset, std::numeric_limits<int>::min());
}
+void tst_QTimeZone::systemZone()
+{
+ const QTimeZone zone = QTimeZone::systemTimeZone();
+ QVERIFY(zone.isValid());
+ QCOMPARE(zone.id(), QTimeZone::systemTimeZoneId());
+ QCOMPARE(zone, QTimeZone(QTimeZone::systemTimeZoneId()));
+}
+
void tst_QTimeZone::dataStreamTest()
{
// Test the OffsetFromUtc backend serialization. First with a custom timezone:
diff --git a/tests/auto/network/kernel/qnetworkinterface/BLACKLIST b/tests/auto/network/kernel/qnetworkinterface/BLACKLIST
index 33bdf540b6..e28cc38ee0 100644
--- a/tests/auto/network/kernel/qnetworkinterface/BLACKLIST
+++ b/tests/auto/network/kernel/qnetworkinterface/BLACKLIST
@@ -1,4 +1,3 @@
# QTBUG-65667
[localAddress:linklocal-ipv4]
-msvc-2015 ci
-msvc-2017 ci
+windows ci
diff --git a/tests/auto/network/ssl/qsslcertificate/BLACKLIST b/tests/auto/network/ssl/qsslcertificate/BLACKLIST
deleted file mode 100644
index 9494ee2278..0000000000
--- a/tests/auto/network/ssl/qsslcertificate/BLACKLIST
+++ /dev/null
@@ -1,13 +0,0 @@
-# OpenSSL version is too new. Rich will fix :)
-[subjectAndIssuerAttributes]
-ubuntu-16.04
-rhel-7.6
-opensuse-leap
-windows-7sp1
-ubuntu-18.04
-rhel-7.4
-b2qt
-windows-10 msvc-2017
-windows-10 msvc-2015
-opensuse-42.3
-
diff --git a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp
index efc0c26076..14718ad373 100644
--- a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp
+++ b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp
@@ -33,6 +33,10 @@
#include <qsslsocket.h>
#include <qsslcertificateextension.h>
+#ifndef QT_NO_OPENSSL
+#include <openssl/obj_mac.h>
+#endif
+
class tst_QSslCertificate : public QObject
{
Q_OBJECT
@@ -960,8 +964,12 @@ void tst_QSslCertificate::subjectAndIssuerAttributes()
certList = QSslCertificate::fromPath(testDataDir + "more-certificates/natwest-banking.pem");
QVERIFY(certList.count() > 0);
+ QByteArray shortName("1.3.6.1.4.1.311.60.2.1.3");
+#if !defined(QT_NO_OPENSSL) && defined(SN_jurisdictionCountryName)
+ shortName = SN_jurisdictionCountryName;
+#endif
attributes = certList[0].subjectInfoAttributes();
- QVERIFY(attributes.contains(QByteArray("1.3.6.1.4.1.311.60.2.1.3")));
+ QVERIFY(attributes.contains(shortName));
}
void tst_QSslCertificate::verify()
diff --git a/tests/auto/other/sessionmanagement_macos/sessionmanagement_macos.pro b/tests/auto/other/sessionmanagement_macos/sessionmanagement_macos.pro
new file mode 100644
index 0000000000..cef53bdf28
--- /dev/null
+++ b/tests/auto/other/sessionmanagement_macos/sessionmanagement_macos.pro
@@ -0,0 +1,10 @@
+CONFIG += testcase
+TARGET = tst_sessionmanagement_macos
+
+OBJECTIVE_SOURCES += tst_sessionmanagement_macos.mm
+
+QT = testlib gui core
+LIBS += -framework AppKit
+
+requires(mac)
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/other/sessionmanagement_macos/tst_sessionmanagement_macos.mm b/tests/auto/other/sessionmanagement_macos/tst_sessionmanagement_macos.mm
new file mode 100644
index 0000000000..934b15ca44
--- /dev/null
+++ b/tests/auto/other/sessionmanagement_macos/tst_sessionmanagement_macos.mm
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Samuel Gaist <samuel.gaist@idiap.ch>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QSignalSpy>
+#include <QSessionManager>
+#include <AppKit/AppKit.h>
+
+// Q_DECLARE_METATYPE(QSessionManager)
+
+class tst_SessionManagement_macOS : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void stopApplication();
+};
+
+/*
+ Test that session handling code is properly called
+*/
+void tst_SessionManagement_macOS::stopApplication()
+{
+ int argc = 0;
+ QGuiApplication app(argc, nullptr);
+ QSignalSpy spy(&app, &QGuiApplication::commitDataRequest);
+ QTimer::singleShot(1000, []() {
+ [NSApp terminate:nil];
+ });
+ app.exec();
+ QCOMPARE(spy.count(), 1);
+}
+
+QTEST_APPLESS_MAIN(tst_SessionManagement_macOS)
+#include "tst_sessionmanagement_macos.moc"
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index 23e2ec8516..8396fd4ec7 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -4922,13 +4922,27 @@ void tst_QTreeView::taskQTBUG_61476()
const QPoint pos = rect.center();
QTest::mousePress(tv.viewport(), Qt::LeftButton, {}, pos);
- if (tv.style()->styleHint(QStyle::SH_ListViewExpand_SelectMouseType, nullptr, &tv) ==
- QEvent::MouseButtonPress)
+ const bool expandsOnPress =
+ (tv.style()->styleHint(QStyle::SH_ListViewExpand_SelectMouseType, nullptr, &tv) == QEvent::MouseButtonPress);
+ if (expandsOnPress)
QTRY_VERIFY(!tv.isExpanded(mi));
QTest::mouseRelease(tv.viewport(), Qt::LeftButton, {}, pos);
QTRY_VERIFY(!tv.isExpanded(mi));
QCOMPARE(lastTopLevel->checkState(), Qt::Checked);
+
+ // Test that it does not toggle the check state of a previously selected item when collapsing an
+ // item causes it to position the item under the mouse to be the decoration for the selected item
+ tv.expandAll();
+ tv.verticalScrollBar()->setValue(tv.verticalScrollBar()->maximum());
+ // It is not enough to programmatically select the item, we need to have it clicked on
+ QTest::mouseClick(tv.viewport(), Qt::LeftButton, {}, tv.visualRect(lastTopLevel->index()).center());
+ QTest::mousePress(tv.viewport(), Qt::LeftButton, {}, pos);
+ if (expandsOnPress)
+ QTRY_VERIFY(!tv.isExpanded(mi));
+ QTest::mouseRelease(tv.viewport(), Qt::LeftButton, nullptr, pos);
+ QTRY_VERIFY(!tv.isExpanded(mi));
+ QCOMPARE(lastTopLevel->checkState(), Qt::Checked);
}
QTEST_MAIN(tst_QTreeView)
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 07f84595fd..6f8fd5dcbe 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -53,6 +53,7 @@
#include <qmainwindow.h>
#include <qdockwidget.h>
#include <qrandom.h>
+#include <qstylehints.h>
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <QtCore/qoperatingsystemversion.h>
@@ -198,6 +199,7 @@ private slots:
void hideWhenFocusWidgetIsChild();
void normalGeometry();
void setGeometry();
+ void setGeometryHidden();
void windowOpacity();
void raise();
void lower();
@@ -2946,6 +2948,38 @@ void tst_QWidget::setGeometry()
QCOMPARE(tlw.geometry(), tr);
}
+void tst_QWidget::setGeometryHidden()
+{
+ if (QGuiApplication::styleHints()->showIsMaximized())
+ QSKIP("Platform does not support QWidget::setGeometry() - skipping");
+
+ QWidget tlw;
+ tlw.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
+ QWidget child(&tlw);
+
+ const QRect tr(m_availableTopLeft + QPoint(100, 100), 2 * m_testWidgetSize);
+ const QRect cr(QPoint(50, 50), m_testWidgetSize);
+ tlw.setGeometry(tr);
+ child.setGeometry(cr);
+ tlw.showNormal();
+
+ tlw.hide();
+ QTRY_VERIFY(tlw.isHidden());
+ tlw.setGeometry(cr);
+ QVERIFY(tlw.testAttribute(Qt::WA_PendingMoveEvent));
+ QVERIFY(tlw.testAttribute(Qt::WA_PendingResizeEvent));
+ QImage img(tlw.size(), QImage::Format_ARGB32); // just needed to call QWidget::render()
+ tlw.render(&img);
+ QVERIFY(!tlw.testAttribute(Qt::WA_PendingMoveEvent));
+ QVERIFY(!tlw.testAttribute(Qt::WA_PendingResizeEvent));
+ tlw.setGeometry(cr);
+ QVERIFY(!tlw.testAttribute(Qt::WA_PendingMoveEvent));
+ QVERIFY(!tlw.testAttribute(Qt::WA_PendingResizeEvent));
+ tlw.resize(cr.size());
+ QVERIFY(!tlw.testAttribute(Qt::WA_PendingMoveEvent));
+ QVERIFY(!tlw.testAttribute(Qt::WA_PendingResizeEvent));
+}
+
void tst_QWidget::windowOpacity()
{
QWidget widget;
diff --git a/tests/manual/highdpi/dragwidget.cpp b/tests/manual/highdpi/dragwidget.cpp
index 11bbc1d127..8ad3d3ca47 100644
--- a/tests/manual/highdpi/dragwidget.cpp
+++ b/tests/manual/highdpi/dragwidget.cpp
@@ -42,7 +42,7 @@ public:
};
DragWidget::DragWidget(QString text, QWidget *parent)
- : QWidget(parent), otherWindow(nullptr)
+ : QWidget(parent)
{
int x = 5;
int y = 5;
@@ -52,9 +52,9 @@ DragWidget::DragWidget(QString text, QWidget *parent)
text = "You can drag from this window and drop text here";
QStringList words = text.split(' ');
- foreach (QString word, words) {
+ for (const QString &word : words) {
if (!word.isEmpty()) {
- FramedLabel *wordLabel = new FramedLabel(word, this);
+ auto wordLabel = new FramedLabel(word, this);
wordLabel->move(x, y);
wordLabel->show();
x += wordLabel->width() + 2;
@@ -105,7 +105,6 @@ void DragWidget::dragLeaveEvent(QDragLeaveEvent *)
update();
}
-
void DragWidget::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasText()) {
@@ -141,9 +140,9 @@ void DragWidget::dropEvent(QDropEvent *event)
} else {
event->ignore();
}
- foreach (QObject *child, children()) {
- if (child->inherits("QWidget")) {
- QWidget *widget = static_cast<QWidget *>(child);
+ for (QObject *child : children()) {
+ if (child->isWidgetType()) {
+ auto widget = static_cast<QWidget *>(child);
if (!widget->isVisible())
widget->deleteLater();
}
@@ -170,7 +169,7 @@ void DragWidget::mousePressEvent(QMouseEvent *event)
pixmap.setDevicePixelRatio(dpr);
child->render(&pixmap);
- QDrag *drag = new QDrag(this);
+ auto drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(pixmap);
drag->setHotSpot(hotSpot);
diff --git a/tests/manual/highdpi/dragwidget.h b/tests/manual/highdpi/dragwidget.h
index 8b67b20410..06663fc74a 100644
--- a/tests/manual/highdpi/dragwidget.h
+++ b/tests/manual/highdpi/dragwidget.h
@@ -40,7 +40,7 @@ QT_END_NAMESPACE
class DragWidget : public QWidget
{
public:
- DragWidget(QString text = QString(), QWidget *parent = 0);
+ DragWidget(QString text = QString(), QWidget *parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
@@ -52,12 +52,13 @@ protected:
void timerEvent(QTimerEvent *event) override;
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
+
private:
QPoint dragPos;
QPoint dropPos;
QBasicTimer dragTimer;
QBasicTimer dropTimer;
- QWidget *otherWindow;
+ QWidget *otherWindow = nullptr;
};
#endif // DRAGWIDGET_H
diff --git a/tests/manual/highdpi/main.cpp b/tests/manual/highdpi/main.cpp
index 0329e62387..c025f251a2 100644
--- a/tests/manual/highdpi/main.cpp
+++ b/tests/manual/highdpi/main.cpp
@@ -30,6 +30,7 @@
#include <QMenuBar>
#include <QLabel>
#include <QHBoxLayout>
+#include <QFormLayout>
#include <QApplication>
#include <QAction>
#include <QStyle>
@@ -61,27 +62,38 @@
#include "dragwidget.h"
+#include <utility>
+
static QTextStream &operator<<(QTextStream &str, const QRect &r)
{
str << r.width() << 'x' << r.height() << Qt::forcesign << r.x() << r.y() << Qt::noforcesign;
return str;
}
+static QString formatWindowTitle(const QString &title)
+{
+ QString result;
+ QTextStream(&result) << title << ' ' << QT_VERSION_STR << " ("
+ << QGuiApplication::platformName()
+ << '/' << QApplication::style()->objectName() << ')';
+ return result;
+}
+
class DemoContainerBase
{
public:
- DemoContainerBase() : m_widget(nullptr) {}
- virtual ~DemoContainerBase() {}
- QString name() { return option().names().first(); }
+ DemoContainerBase() = default;
+ virtual ~DemoContainerBase() = default;
+ QString name() { return option().names().constFirst(); }
virtual QCommandLineOption &option() = 0;
virtual void makeVisible(bool visible, QWidget *parent) = 0;
- QWidget *widget() { return m_widget; }
+ QWidget *widget() const { return m_widget; }
+
protected:
- QWidget *m_widget;
+ QWidget *m_widget = nullptr;
};
-typedef QList<DemoContainerBase*> DemoContainerList ;
-
+using DemoContainerList = QVector<DemoContainerBase*>;
template <class T>
class DemoContainer : public DemoContainerBase
@@ -93,16 +105,25 @@ public:
}
~DemoContainer() { delete m_widget; }
- QCommandLineOption &option() { return m_option; }
+ QCommandLineOption &option() override { return m_option; }
- void makeVisible(bool visible, QWidget *parent) {
+ void makeVisible(bool visible, QWidget *parent) override
+ {
if (visible && !m_widget) {
m_widget = new T;
+ if (m_widget->windowTitle().isEmpty()) {
+ QString title = m_option.description();
+ if (title.startsWith("Test ", Qt::CaseInsensitive))
+ title.remove(0, 5);
+ title[0] = title.at(0).toUpper();
+ m_widget->setWindowTitle(formatWindowTitle(title));
+ }
m_widget->installEventFilter(parent);
}
if (m_widget)
m_widget->setVisible(visible);
}
+
private:
QCommandLineOption m_option;
};
@@ -134,12 +155,15 @@ public:
connect(m_slider, &QSlider::sliderMoved, this, &LabelSlider::updateLabel);
connect(m_slider, &QSlider::valueChanged, this, &LabelSlider::valueChanged);
}
- void setValue(int scaleFactor) {
+ void setValue(int scaleFactor)
+ {
m_slider->setValue(scaleFactor);
updateLabel(scaleFactor);
}
+
private slots:
- void updateLabel(int scaleFactor) {
+ void updateLabel(int scaleFactor)
+ {
// slider value is scale factor times ten;
qreal scalefactorF = qreal(scaleFactor) / 10.0;
@@ -149,8 +173,10 @@ private slots:
number.append(".0");
m_label->setText(number);
}
+
signals:
void valueChanged(int scaleFactor);
+
private:
QSlider *m_slider;
QLabel *m_label;
@@ -172,31 +198,35 @@ static inline qreal getGlobalScaleFactor()
class DemoController : public QWidget
{
-Q_OBJECT
+ Q_OBJECT
public:
- DemoController(DemoContainerList *demos, QCommandLineParser *parser);
+ DemoController(DemoContainerList demos, QCommandLineParser *parser);
~DemoController();
+
protected:
- bool eventFilter(QObject *object, QEvent *event);
- void closeEvent(QCloseEvent *) { qApp->quit(); }
+ bool eventFilter(QObject *object, QEvent *event) override;
+ void closeEvent(QCloseEvent *) override { QCoreApplication::quit(); }
+
private slots:
void handleButton(int id, bool toggled);
+
private:
- DemoContainerList *m_demos;
+ DemoContainerList m_demos;
QButtonGroup *m_group;
};
-DemoController::DemoController(DemoContainerList *demos, QCommandLineParser *parser)
- : m_demos(demos)
+DemoController::DemoController(DemoContainerList demos, QCommandLineParser *parser)
+ : m_demos(std::move(demos))
{
- setWindowTitle("screen scale factors");
+ setWindowTitle(formatWindowTitle("Screen Scale Factors"));
setObjectName("controller"); // make WindowScaleFactorSetter skip this window
- QGridLayout *layout = new QGridLayout;
- setLayout(layout);
+ auto mainLayout = new QVBoxLayout(this);
+ auto scaleLayout = new QGridLayout;
+ mainLayout->addLayout(scaleLayout);
int layoutRow = 0;
- LabelSlider *globalScaleSlider = new LabelSlider(this, "Global scale factor", layout, layoutRow++);
+ LabelSlider *globalScaleSlider = new LabelSlider(this, "Global scale factor", scaleLayout, layoutRow++);
globalScaleSlider->setValue(int(getGlobalScaleFactor() * 10));
connect(globalScaleSlider, &LabelSlider::valueChanged, [](int scaleFactor){
// slider value is scale factor times ten;
@@ -205,13 +235,13 @@ DemoController::DemoController(DemoContainerList *demos, QCommandLineParser *par
});
// set up one scale control line per screen
- QList<QScreen *> screens = QGuiApplication::screens();
- foreach (QScreen *screen, screens) {
+ const auto screens = QGuiApplication::screens();
+ for (QScreen *screen : screens) {
// create scale control line
QSize screenSize = screen->geometry().size();
QString screenId = screen->name() + QLatin1Char(' ') + QString::number(screenSize.width())
+ QLatin1Char(' ') + QString::number(screenSize.height());
- LabelSlider *slider = new LabelSlider(this, screenId, layout, layoutRow++);
+ LabelSlider *slider = new LabelSlider(this, screenId, scaleLayout, layoutRow++);
slider->setValue(getScreenFactorWithoutPixelDensity(screen) * 10);
// handle slider value change
@@ -228,15 +258,18 @@ DemoController::DemoController(DemoContainerList *demos, QCommandLineParser *par
});
}
+ auto demoLayout = new QFormLayout;
+ mainLayout->addLayout(demoLayout);
m_group = new QButtonGroup(this);
m_group->setExclusive(false);
- for (int i = 0; i < m_demos->size(); ++i) {
- DemoContainerBase *demo = m_demos->at(i);
- QPushButton *button = new QPushButton(demo->name());
- button->setToolTip(demo->option().description());
+ for (int i = 0; i < m_demos.size(); ++i) {
+ DemoContainerBase *demo = m_demos.at(i);
+ QString name = demo->name();
+ name[0] = name.at(0).toUpper();
+ auto button = new QPushButton(name);
button->setCheckable(true);
- layout->addWidget(button, layoutRow++, 0, 1, -1);
+ demoLayout->addRow(demo->option().description(), button);
m_group->addButton(button, i);
if (parser->isSet(demo->option())) {
@@ -244,19 +277,20 @@ DemoController::DemoController(DemoContainerList *demos, QCommandLineParser *par
button->setChecked(true);
}
}
- connect(m_group, SIGNAL(buttonToggled(int, bool)), this, SLOT(handleButton(int, bool)));
+ connect(m_group, QOverload<int,bool>::of(&QButtonGroup::buttonToggled),
+ this, &DemoController::handleButton);
}
DemoController::~DemoController()
{
- qDeleteAll(*m_demos);
+ qDeleteAll(m_demos);
}
bool DemoController::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::Close) {
- for (int i = 0; i < m_demos->size(); ++i) {
- DemoContainerBase *demo = m_demos->at(i);
+ for (int i = 0; i < m_demos.size(); ++i) {
+ DemoContainerBase *demo = m_demos.at(i);
if (demo->widget() == object) {
m_group->button(i)->setChecked(false);
break;
@@ -268,15 +302,17 @@ bool DemoController::eventFilter(QObject *object, QEvent *event)
void DemoController::handleButton(int id, bool toggled)
{
- m_demos->at(id)->makeVisible(toggled, this);
+ m_demos.at(id)->makeVisible(toggled, this);
}
class PixmapPainter : public QWidget
{
public:
PixmapPainter();
- void paintEvent(QPaintEvent *event);
+ void paintEvent(QPaintEvent *event) override;
+
+private:
QPixmap pixmap1X;
QPixmap pixmap2X;
QPixmap pixmapLarge;
@@ -348,12 +384,14 @@ void PixmapPainter::paintEvent(QPaintEvent *)
class TiledPixmapPainter : public QWidget
{
public:
+ TiledPixmapPainter();
+
+ void paintEvent(QPaintEvent *event) override;
+
+private:
QPixmap pixmap1X;
QPixmap pixmap2X;
QPixmap pixmapLarge;
-
- TiledPixmapPainter();
- void paintEvent(QPaintEvent *event);
};
TiledPixmapPainter::TiledPixmapPainter()
@@ -404,6 +442,7 @@ class Labels : public QWidget
public:
Labels();
+private:
QPixmap pixmap1X;
QPixmap pixmap2X;
QPixmap pixmapLarge;
@@ -419,7 +458,7 @@ Labels::Labels()
qtIcon.addFile(":/qticon32.png");
qtIcon.addFile(":/qticon32@2x.png");
setWindowIcon(qtIcon);
- setWindowTitle("Labels");
+ setWindowTitle(formatWindowTitle("Labels"));
QLabel *label1x = new QLabel();
label1x->setPixmap(pixmap1X);
@@ -454,18 +493,17 @@ private:
QIcon qtIcon2x;
QToolBar *fileToolBar;
- int menuCount;
QAction *m_maskAction;
+ int menuCount = 0;
};
MainWindow::MainWindow()
- :menuCount(0)
{
// beware that QIcon auto-loads the @2x versions.
qtIcon1x.addFile(":/qticon16.png");
qtIcon2x.addFile(":/qticon32.png");
setWindowIcon(qtIcon);
- setWindowTitle("MainWindow");
+ setWindowTitle(formatWindowTitle("MainWindow"));
fileToolBar = addToolBar(tr("File"));
// fileToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
@@ -484,7 +522,6 @@ MainWindow::MainWindow()
addNewMenu("&Help", 2);
}
-
QMenu *MainWindow::addNewMenu(const QString &title, int itemCount)
{
QMenu *menu = menuBar()->addMenu(title);
@@ -516,7 +553,7 @@ void MainWindow::maskActionToggled(bool t)
class StandardIcons : public QWidget
{
public:
- void paintEvent(QPaintEvent *)
+ void paintEvent(QPaintEvent *) override
{
int x = 10;
int y = 10;
@@ -538,7 +575,7 @@ public:
class Caching : public QWidget
{
public:
- void paintEvent(QPaintEvent *)
+ void paintEvent(QPaintEvent *) override
{
QSize layoutSize(75, 75);
@@ -576,16 +613,12 @@ public:
}
};
-class Style : public QWidget {
+class Style : public QWidget
+{
public:
- QPushButton *button;
- QLineEdit *lineEdit;
- QSlider *slider;
- QHBoxLayout *row1;
-
- Style() {
- row1 = new QHBoxLayout();
- setLayout(row1);
+ Style()
+ {
+ row1 = new QHBoxLayout(this);
button = new QPushButton();
button->setText("Test Button");
@@ -601,17 +634,23 @@ public:
row1->addWidget(new QSpinBox);
row1->addWidget(new QScrollBar);
- QTabBar *tab = new QTabBar();
+ auto tab = new QTabBar();
tab->addTab("Foo");
tab->addTab("Bar");
row1->addWidget(tab);
}
+
+private:
+ QPushButton *button;
+ QLineEdit *lineEdit;
+ QSlider *slider;
+ QHBoxLayout *row1;
};
class Fonts : public QWidget
{
public:
- void paintEvent(QPaintEvent *)
+ void paintEvent(QPaintEvent *) override
{
QPainter painter(this);
@@ -690,7 +729,7 @@ public:
iconNormalDpi.reset(new QIcon(path32_2)); // does not have a 2x version.
}
- void paintEvent(QPaintEvent *)
+ void paintEvent(QPaintEvent *) override
{
int x = 10;
int y = 10;
@@ -782,7 +821,7 @@ public:
tab->move(10, 100);
tab->show();
- QToolBar *toolBar = new QToolBar(this);
+ auto toolBar = new QToolBar(this);
toolBar->addAction(QIcon(":/qticon16.png"), "16");
toolBar->addAction(QIcon(":/qticon16@2x.png"), "16@2x");
toolBar->addAction(QIcon(":/qticon32.png"), "32");
@@ -796,11 +835,12 @@ public:
class LinePainter : public QWidget
{
public:
- void paintEvent(QPaintEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
+ void paintEvent(QPaintEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+private:
QPoint lastMousePoint;
QVector<QPoint> linePoints;
};
@@ -855,17 +895,15 @@ void LinePainter::mouseMoveEvent(QMouseEvent *event)
class CursorTester : public QWidget
{
public:
- CursorTester()
- :moveLabel(nullptr), moving(false)
- {
- }
+ CursorTester() = default;
inline QRect getRect(int idx) const
{
int h = height() / 2;
return QRect(10, 10 + h * (idx - 1), width() - 20, h - 20);
}
- void paintEvent(QPaintEvent *)
+
+ void paintEvent(QPaintEvent *) override
{
QPainter p(this);
QRect r1 = getRect(1);
@@ -899,7 +937,7 @@ public:
}
}
- void mousePressEvent(QMouseEvent *e)
+ void mousePressEvent(QMouseEvent *e) override
{
if (moving)
return;
@@ -923,7 +961,7 @@ public:
moveLabel->show();
}
- void mouseReleaseEvent(QMouseEvent *)
+ void mouseReleaseEvent(QMouseEvent *) override
{
if (moveLabel)
moveLabel->hide();
@@ -931,7 +969,7 @@ public:
moving = false;
}
- void mouseMoveEvent(QMouseEvent *e)
+ void mouseMoveEvent(QMouseEvent *e) override
{
if (!moving)
return;
@@ -943,32 +981,32 @@ public:
}
private:
- QLabel *moveLabel;
- bool useCursorPos;
- bool moving;
+ QLabel *moveLabel = nullptr;
QPoint mousePos;
+ bool useCursorPos = false;
+ bool moving = false;
};
-
class ScreenDisplayer : public QWidget
{
public:
- ScreenDisplayer()
- : QWidget(), moveLabel(nullptr), scaleFactor(1.0)
- {
- }
+ ScreenDisplayer() = default;
- void timerEvent(QTimerEvent *) {
+ void timerEvent(QTimerEvent *) override
+ {
update();
}
- void mousePressEvent(QMouseEvent *) {
+ void mousePressEvent(QMouseEvent *) override
+ {
if (!moveLabel)
moveLabel = new QLabel(this,Qt::BypassWindowManagerHint|Qt::FramelessWindowHint|Qt::Window );
moveLabel->setText("Hello, Qt this is a label\nwith some text");
moveLabel->show();
}
- void mouseMoveEvent(QMouseEvent *e) {
+
+ void mouseMoveEvent(QMouseEvent *e) override
+ {
if (!moveLabel)
return;
moveLabel->move(e->pos() / scaleFactor);
@@ -978,23 +1016,30 @@ public:
dbg << moveLabel->geometry();
moveLabel->setText(str);
}
- void mouseReleaseEvent(QMouseEvent *) {
+
+ void mouseReleaseEvent(QMouseEvent *) override
+ {
if (moveLabel)
moveLabel->hide();
}
- void showEvent(QShowEvent *) {
+
+ void showEvent(QShowEvent *) override
+ {
refreshTimer.start(300, this);
}
- void hideEvent(QHideEvent *) {
+
+ void hideEvent(QHideEvent *) override
+ {
refreshTimer.stop();
}
- void paintEvent(QPaintEvent *) {
+
+ void paintEvent(QPaintEvent *) override
+ {
QPainter p(this);
QRectF total;
- QList<QScreen*> screens = qApp->screens();
- foreach (QScreen *screen, screens) {
+ const auto screens = QGuiApplication::screens();
+ for (const QScreen *screen : screens)
total |= screen->geometry();
- }
if (total.isEmpty())
return;
@@ -1006,8 +1051,7 @@ public:
p.setPen(QPen(Qt::white, 10));
p.setBrush(Qt::gray);
-
- foreach (QScreen *screen, screens) {
+ for (const QScreen *screen : screens) {
p.drawRect(screen->geometry());
QFont f = font();
f.setPixelSize(screen->geometry().height() / 8);
@@ -1015,7 +1059,9 @@ public:
p.drawText(screen->geometry(), Qt::AlignCenter, screen->name());
}
p.setBrush(QColor(200,220,255,127));
- foreach (QWidget *widget, QApplication::topLevelWidgets()) {
+
+ const auto topLevels = QApplication::topLevelWidgets();
+ for (QWidget *widget : topLevels) {
if (!widget->isHidden())
p.drawRect(widget->geometry());
}
@@ -1028,42 +1074,51 @@ public:
cursorShape.translate(QCursor::pos());
p.drawPolygon(cursorShape);
}
+
private:
- QLabel *moveLabel;
+ QLabel *moveLabel = nullptr;
+ qreal scaleFactor = 1;
QBasicTimer refreshTimer;
- qreal scaleFactor;
};
class PhysicalSizeTest : public QWidget
{
-Q_OBJECT
+ Q_OBJECT
public:
- PhysicalSizeTest() : QWidget(), m_ignoreResize(false) {}
- void paintEvent(QPaintEvent *event);
- void resizeEvent(QResizeEvent *) {
+ PhysicalSizeTest() = default;
+
+ void paintEvent(QPaintEvent *event) override;
+
+ void resizeEvent(QResizeEvent *) override
+ {
qreal ppi = window()->windowHandle()->screen()->physicalDotsPerInchX();
QSizeF s = size();
if (!m_ignoreResize)
m_physicalSize = s / ppi;
}
- bool event(QEvent *event) {
+
+ bool event(QEvent *event) override
+ {
if (event->type() == QEvent::ScreenChangeInternal) {
// we will get resize events when the scale factor changes
m_ignoreResize = true;
- QTimer::singleShot(100, this, SLOT(handleScreenChange()));
+ QTimer::singleShot(100, this, &PhysicalSizeTest::handleScreenChange);
}
return QWidget::event(event);
}
+
public slots:
- void handleScreenChange() {
+ void handleScreenChange()
+ {
qreal ppi = window()->windowHandle()->screen()->physicalDotsPerInchX();
QSizeF newSize = m_physicalSize * ppi;
resize(newSize.toSize());
m_ignoreResize = false;
}
+
private:
QSizeF m_physicalSize;
- bool m_ignoreResize;
+ bool m_ignoreResize = false;
};
void PhysicalSizeTest::paintEvent(QPaintEvent *)
@@ -1166,8 +1221,9 @@ void PhysicalSizeTest::paintEvent(QPaintEvent *)
class GraphicsViewCaching : public QGraphicsView
{
public:
- GraphicsViewCaching() {
- QGraphicsScene *scene = new QGraphicsScene(0, 0, 400, 400);
+ GraphicsViewCaching()
+ {
+ auto scene = new QGraphicsScene(0, 0, 400, 400);
QGraphicsTextItem *item = scene->addText("NoCache");
item->setCacheMode(QGraphicsItem::NoCache);
@@ -1187,14 +1243,13 @@ public:
class MetricsTest : public QWidget
{
- QPlainTextEdit *m_textEdit;
-
+ Q_OBJECT
public:
MetricsTest()
{
- qDebug() << R"(
-MetricsTest
-Relevant environment variables are:
+ qDebug().noquote().nospace() << "MetricsTest " << QT_VERSION_STR
+ << ' ' << QGuiApplication::platformName() << '\n'
+<< R"(Relevant environment variables are:
QT_FONT_DPI=N
QT_SCALE_FACTOR=n
QT_ENABLE_HIGHDPI_SCALING=0|1
@@ -1205,12 +1260,23 @@ QT_DPI_ADJUSTMENT_POLICY=AdjustDpi|DontAdjustDpi|AdjustUpOnly)";
resize(480, 360);
- QVBoxLayout *layout = new QVBoxLayout();
- setLayout(layout);
+ auto layout = new QVBoxLayout(this);
m_textEdit = new QPlainTextEdit;
m_textEdit->setReadOnly(true);
layout->addWidget(m_textEdit);
+ setWindowTitle(formatWindowTitle("Screens"));
+ }
+
+ void setVisible(bool visible) override
+ {
+ QWidget::setVisible(visible);
+ if (visible && !m_screenChangedConnected) {
+ m_screenChangedConnected = true;
+ QObject::connect(windowHandle(), &QWindow::screenChanged,
+ this, &MetricsTest::screenChanged);
+ updateMetrics();
+ }
}
void updateMetrics()
@@ -1254,24 +1320,42 @@ QT_DPI_ADJUSTMENT_POLICY=AdjustDpi|DontAdjustDpi|AdjustUpOnly)";
m_textEdit->setPlainText(text);
}
- void paintEvent(QPaintEvent *ev)
+private slots:
+ void screenChanged()
{
- // We get a paint event on screen change, so this is a convenient place
- // to update the metrics, at the possible risk of doing something else
- // than painting in a paint event.
+ qDebug().noquote() << __FUNCTION__ << windowHandle()->screen()->name();
updateMetrics();
- QWidget::paintEvent(ev);
}
+
+private:
+ QPlainTextEdit *m_textEdit;
+ bool m_screenChangedConnected = false;
};
int main(int argc, char **argv)
{
+#define NOSCALINGOPTION "noscaling"
+#define SCALINGOPTION "scaling"
+
+ qInfo("High DPI tester %s", QT_VERSION_STR);
+
+ int preAppOptionCount = 0;
+ for (int a = 1; a < argc; ++a) {
+ if (qstrcmp(argv[a], "--" NOSCALINGOPTION) == 0) {
+ QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
+ preAppOptionCount++;
+ qInfo("AA_DisableHighDpiScaling");
+ } else if (qstrcmp(argv[a], "--" SCALINGOPTION) == 0) {
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ preAppOptionCount++;
+ qInfo("AA_EnableHighDpiScaling");
+ }
+ }
+
QApplication app(argc, argv);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
- int argumentCount = QCoreApplication::arguments().count();
-
QCommandLineParser parser;
parser.setApplicationDescription("High DPI tester. Pass one or more of the options to\n"
"test various high-dpi aspects. \n"
@@ -1281,7 +1365,8 @@ int main(int argc, char **argv)
parser.addVersionOption();
QCommandLineOption controllerOption("interactive", "Show configuration window.");
parser.addOption(controllerOption);
-
+ parser.addOption(QCommandLineOption(NOSCALINGOPTION, "Set AA_DisableHighDpiScaling"));
+ parser.addOption(QCommandLineOption(SCALINGOPTION, "Set AA_EnableHighDpiScaling"));
DemoContainerList demoList;
demoList << new DemoContainer<PixmapPainter>("pixmap", "Test pixmap painter");
@@ -1300,17 +1385,17 @@ int main(int argc, char **argv)
demoList << new DemoContainer<ScreenDisplayer>("screens", "Test screen and window positioning");
demoList << new DemoContainer<PhysicalSizeTest>("physicalsize", "Test manual highdpi support using physicalDotsPerInch");
demoList << new DemoContainer<GraphicsViewCaching>("graphicsview", "Test QGraphicsView caching");
- demoList << new DemoContainer<MetricsTest>("metrics", "Show display metrics");
+ demoList << new DemoContainer<MetricsTest>("metrics", "Show screen metrics");
- foreach (DemoContainerBase *demo, demoList)
+ for (DemoContainerBase *demo : qAsConst(demoList))
parser.addOption(demo->option());
parser.process(app);
//controller takes ownership of all demos
- DemoController controller(&demoList, &parser);
+ DemoController controller(demoList, &parser);
- if (parser.isSet(controllerOption) || argumentCount <= 1)
+ if (parser.isSet(controllerOption) || (QCoreApplication::arguments().count() - preAppOptionCount) <= 1)
controller.show();
if (QApplication::topLevelWidgets().isEmpty())